Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor test pool to be less optional #75

Merged
merged 16 commits into from
Aug 18, 2023
9 changes: 1 addition & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,7 @@ Run multiple tests concurrently with a custom engine provider.
using RAITest
using Test
# Always use `my_existing_engine_name` as the engine name. This must already be created as
# RAITest will not create the engine itself
set_engine_name_provider!()->"my_existing_engine_name")
# Releasing the engine does nothing. Controlling the engine use and cleanup is not handled
# by RAITest
set_engine_name_releaser!(name::String)->return)
set_engine_creater!((name)->create_default_engine(name, "M"))
@testset "My tests" begin
for i in 1:10
query = "def output = $i ic { output = $i }"
Expand Down
2 changes: 0 additions & 2 deletions src/RAITest.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ export add_test_engine!

export set_context!

export set_engine_name_provider!
export set_engine_name_releaser!
export set_engine_creater!

include("code-util.jl")
Expand Down
92 changes: 13 additions & 79 deletions src/engines.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
mutable struct TestEngineProvision
mmcgr marked this conversation as resolved.
Show resolved Hide resolved
# Returns the name of a provisioned, currently valid, engine
provider::Function
# Sends a notification that the engine represented by a string name is no longer in use
releaser::Function
# Create an engine. This is expected to be used by the provider as needed.
creater::Function
end
Expand Down Expand Up @@ -32,96 +28,34 @@ function _wait_till_provisioned(engine_name, max_wait_time_s=600)
end

"""
create_default_engine(name::String)
create_default_engine(name::String, size::String)

Create an XS engine with default settings and the provided name.
mmcgr marked this conversation as resolved.
Show resolved Hide resolved

If the engine already exists, return immediately. If not, create the engine then
return once the provisioning process is complete, or failed.
"""
function create_default_engine(name::String)
size = "XS"
function create_default_engine(name::String, size::String="XS")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in case there are other attributes we want to add later, can we make size a kwarg instead of a positional optional arg?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. The name isn't so great now, since there are no defaults. create_engine_and_wait, maybe?

max_wait_time_s = 600

try
get_engine(get_context(), name; readtimeout=max_wait_time_s)
# The engine already exists so return it immediately
return name
catch
# Engine does not exist yet so we'll need to create it
create_engine(get_context(), name; size=size, readtimeout=max_wait_time_s)
mmcgr marked this conversation as resolved.
Show resolved Hide resolved
catch e
# If the status code is 409 then the engine already exists and we can wait for it
# to be ready
if e.status_code != 409
mmcgr marked this conversation as resolved.
Show resolved Hide resolved
rethrow()
end
end

# Request engine creation
create_engine(get_context(), name; size=size, readtimeout=max_wait_time_s)

# Wait for engine to be provisioned
return _wait_till_provisioned(name, max_wait_time_s)
end

# Get test engine. If a name is provided, the corresponding engine will be provided.
get_test_engine()::String = TEST_ENGINE_PROVISION.provider()
# Get test engine.
get_test_engine()::String = get_free_test_engine_name()

# Release test engine. Notifies the provider that this engine is no longer in use.
release_test_engine(name::String) = TEST_ENGINE_PROVISION.releaser(name)

"""
set_engine_name_provider!(provider::Function)

Set a provider for test engine names.

The provider is called by each test to select an engine to run the test with. The default
provider selects a name from a pool of available test engines.

# Examples

```
set_engine_name_provider!() -> "MyEngine")
set_engine_name_provider!() -> my_custom_engine_selector())

```
"""
function set_engine_name_provider!(provider::Function)
return TEST_ENGINE_PROVISION.provider = provider
end

"""
set_engine_name_releaser!(releaser::Function)

Set a releaser for test engine names.

The releaser will be called after a test has been run. The default releaser
marks an engine in the test engine pool as available for use by another test.

# Examples

```
set_engine_name_releaser!(::String) -> nothing)
set_engine_name_releaser!(name::String) -> my_custom_engine_releaser(name))
```
"""
function set_engine_name_releaser!(releaser::Function)
return TEST_ENGINE_PROVISION.releaser = releaser
end

"""
set_engine_creater!(creater::Function)

Set a function used to create engines.

# Examples

```
set_engine_creater!(create_default_engine)
```
"""
function set_engine_creater!(creater::Function)
return TEST_ENGINE_PROVISION.creater = creater
end

TEST_ENGINE_POOL = TestEnginePool(Dict{String, Int64}(), 0, get_next_engine_name)
release_test_engine(name::String) = release_pooled_test_engine(name)

TEST_ENGINE_PROVISION = TestEngineProvision(
get_pooled_test_engine,
release_pooled_test_engine,
create_default_engine,
)
TEST_ENGINE_POOL = TestEnginePool()
Loading