Skip to content

Commit b926af6

Browse files
committed
Makes mock server accept multiple stages
1 parent fdd0da3 commit b926af6

File tree

1 file changed

+55
-16
lines changed

1 file changed

+55
-16
lines changed

src/mock_server.jl

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,72 @@
11
using CloudBase: CloudCredentials, AWSCredentials, AbstractStore, AWS
22
using JSON3, HTTP, Sockets, Base64
33
using RustyObjectStore: SnowflakeConfig, ClientOptions
4+
using Base: UUID
45

56
export SFGatewayMock, start, with
67

78
struct SFConfig
89
account::String
10+
database::String
11+
default_schema::String
12+
end
13+
14+
struct Stage
915
database::String
1016
schema::String
11-
stage::String
17+
name::String
1218
end
1319

1420
mutable struct SFGatewayMock
1521
credentials::CloudCredentials
1622
store::AbstractStore
1723
opts::ClientOptions
1824
config::SFConfig
25+
allowed_stages::Vector{Stage}
1926
encrypted::Bool
2027
keys_lock::ReentrantLock
2128
next_key_id::Int
2229
keys::Dict{String, String}
2330
end
2431

25-
function SFGatewayMock(credentials::CloudCredentials, store::AbstractStore, encrypted::Bool; opts=ClientOptions())
26-
stage_name = "teststage" * string(rand(UInt64), base=16)
32+
33+
function to_stage(stage::AbstractString, config::SFConfig)
34+
parts = split(stage, ".")
35+
if length(parts) == 1
36+
return Stage(uppercase(config.database), uppercase(config.default_schema), uppercase(parts[1]))
37+
elseif length(parts) == 2
38+
return Stage(uppercase(config.database), uppercase(parts[1]), uppercase(parts[2]))
39+
elseif length(parts) == 3
40+
return Stage(uppercase(parts[1]), uppercase(parts[2]), uppercase(parts[3]))
41+
else
42+
error("Invalid stage spec")
43+
end
44+
end
45+
46+
fqsn(s::Stage) = "$(s.database).$(s.schema).$(s.name)"
47+
stage_uuid(s::Stage) = UUID((hash(fqsn(s)), hash(fqsn(s))))
48+
stage_path(s::Stage) = "stages/$(stage_uuid(s))/"
49+
50+
function SFGatewayMock(
51+
credentials::CloudCredentials,
52+
store::AbstractStore,
53+
encrypted::Bool;
54+
opts=ClientOptions(),
55+
default_schema::String="testschema",
56+
allowed_stages::Vector{String}=["teststage" * string(rand(UInt64), base=16)]
57+
)
2758
config = SFConfig(
2859
"testaccount",
2960
"testdatabase",
30-
"testschema",
31-
stage_name
61+
default_schema
3262
)
63+
allowed_stages_parsed = map(s -> to_stage(s, config), allowed_stages)
3364
SFGatewayMock(
3465
credentials,
3566
store,
3667
opts,
3768
config,
69+
allowed_stages_parsed,
3870
encrypted,
3971
ReentrantLock(),
4072
1,
@@ -160,9 +192,13 @@ function start(gw::SFGatewayMock)
160192
return error_json_response("Missing stage name or file path")
161193
end
162194

163-
stage_name = m.captures[1]
195+
stage = try
196+
to_stage(m.captures[1], gw.config)
197+
catch e
198+
return error_json_response("$(e)")
199+
end
164200

165-
if stage_name != gw.config.stage
201+
if !(stage in gw.allowed_stages)
166202
return error_json_response("Stage not found")
167203
end
168204

@@ -179,9 +215,8 @@ function start(gw::SFGatewayMock)
179215
end
180216

181217

182-
stage_path = "stages/a6688b33-acb4-44ed-bd46-30ff12238c2a/"
183218
stage_info = if isa(gw.credentials, AWSCredentials) && isa(gw.store, AWS.Bucket)
184-
construct_stage_info(gw.credentials, gw.store, stage_path, gw.encrypted)
219+
construct_stage_info(gw.credentials, gw.store, stage_path(stage), gw.encrypted)
185220
else
186221
error("unimplemented")
187222
end
@@ -203,16 +238,20 @@ function start(gw::SFGatewayMock)
203238
return error_json_response("Missing stage name or file path")
204239
end
205240

206-
stage_name = m.captures[1]
207-
path = m.captures[2]
241+
stage = try
242+
to_stage(m.captures[1], gw.config)
243+
catch e
244+
return error_json_response("$(e)")
245+
end
208246

209-
if stage_name != gw.config.stage
247+
if !(stage in gw.allowed_stages)
210248
return error_json_response("Stage not found")
211249
end
212250

213-
stage_path = "stages/a6688b33-acb4-44ed-bd46-30ff12238c2a/"
251+
path = m.captures[2]
252+
214253
stage_info = if isa(gw.credentials, AWSCredentials) && isa(gw.store, AWS.Bucket)
215-
construct_stage_info(gw.credentials, gw.store, stage_path, gw.encrypted)
254+
construct_stage_info(gw.credentials, gw.store, stage_path(stage), gw.encrypted)
216255
else
217256
error("unimplemented")
218257
end
@@ -257,10 +296,10 @@ function start(gw::SFGatewayMock)
257296
master_path, fileio = mktemp()
258297
write(fileio, "dummy-file-master-token")
259298
sfconfig = SnowflakeConfig(
260-
stage=gw.config.stage,
299+
stage=fqsn(gw.allowed_stages[1]),
261300
account=gw.config.account,
262301
database=gw.config.database,
263-
schema=gw.config.schema,
302+
schema=gw.allowed_stages[1].schema,
264303
endpoint="http://127.0.0.1:$(port)",
265304
master_token_path=master_path,
266305
opts=gw.opts

0 commit comments

Comments
 (0)