From fab36be2d9a4517fda34a72eab7cbea04bc2c4d2 Mon Sep 17 00:00:00 2001 From: Thiago Tonelli Bartolomei Date: Tue, 16 Jul 2024 16:22:46 -0400 Subject: [PATCH] Global setting of test_engine and clone_db --- src/RAITest.jl | 2 +- src/code-util.jl | 12 +++---- src/engines.jl | 6 +++- src/testpool.jl | 4 +-- src/testrel.jl | 79 +++++++++++++++++++++++++++++++++++++++++---- test/integration.jl | 51 ++++++++++------------------- test/runtests.jl | 2 +- 7 files changed, 105 insertions(+), 51 deletions(-) diff --git a/src/RAITest.jl b/src/RAITest.jl index 794bdf6..95edd56 100644 --- a/src/RAITest.jl +++ b/src/RAITest.jl @@ -15,7 +15,7 @@ export resize_test_engine_pool! export provision_all_test_engines export add_test_engine! -export set_context! +export set_context!, set_test_engine!, set_clone_db! export set_engine_creater! diff --git a/src/code-util.jl b/src/code-util.jl index e6fe2c2..ead1bf5 100644 --- a/src/code-util.jl +++ b/src/code-util.jl @@ -116,11 +116,11 @@ end # Vectors. # :a => [3, 4, 5] -type_string(::Vector{T}) where T = type_string(T) +type_string(::Vector{T}) where {T} = type_string(T) # :a => [(1, 2)] # :a => (1, 2) -function type_string(::Union{T, Vector{T}}) where { T <: Tuple } +function type_string(::Union{T, Vector{T}}) where {T <: Tuple} result = "" for e_type in fieldtypes(T) result *= type_string(e_type) @@ -134,10 +134,10 @@ type_string(::Type{Any}) = "" # Generate a string representing the Rel type for single values # :a => 1 -type_string(::Union{T, Type{T}}) where T = "/" * string(T) +type_string(::Union{T, Type{T}}) where {T} = "/" * string(T) # The value tuple contains an inner tuple. Recurse into it. -function type_string(::Type{T}) where { T <: Tuple } +function type_string(::Type{T}) where {T <: Tuple} result = "/(" for e_type in fieldtypes(T) result *= type_string(e_type) @@ -288,7 +288,7 @@ end # Extract the IC results for a given hash # These are stored in the form: # /:rel/:catalog/:ic_violation/:xxxx/HashValue/Type[/Type]* -function filter_ic_results(results::Dict, path::String, h, limit::Int = 10) +function filter_ic_results(results::Dict, path::String, h, limit::Int=10) ics = [] # Find all the rows with the given path prefix in the key @@ -315,7 +315,7 @@ function extract_ics(results::Nothing) return [] end -function extract_ics(results, limit::Int = 10) +function extract_ics(results, limit::Int=10) ics = [] if !haskey(results, IC_LINE_KEY) diff --git a/src/engines.jl b/src/engines.jl index a64ff27..61d62d2 100644 --- a/src/engines.jl +++ b/src/engines.jl @@ -48,7 +48,11 @@ function create_default_engine(name::String; size::String="XS") end # Get test engine. -get_test_engine()::String = get_free_test_engine_name() +get_test_engine()::String = if isnothing(get_default_test_engine()) + get_free_test_engine_name() +else + get_default_test_engine() +end # Release test engine. Notifies the provider that this engine is no longer in use. release_test_engine(name::String) = release_pooled_test_engine(name) diff --git a/src/testpool.jl b/src/testpool.jl index 35d23bf..f91cb8e 100644 --- a/src/testpool.jl +++ b/src/testpool.jl @@ -77,7 +77,7 @@ end function replace_engine(name::String) delete_test_engine!(name) new_name = TEST_ENGINE_POOL.name_generator(_get_new_id()) - add_test_engine!(new_name) + return add_test_engine!(new_name) end function list_test_engines() @@ -168,7 +168,7 @@ function resize_test_engine_pool!(size::Int64, name_generator::Option{Function}= _create_and_add_engines!(size) _validate_engine_pool!() # Remove engines if size < length - _trim_engine_pool!(size) + return _trim_engine_pool!(size) end # Test all engines and remove if they are unavailable or not successfully provisioned diff --git a/src/testrel.jl b/src/testrel.jl index 1eb9363..5d9ddd4 100644 --- a/src/testrel.jl +++ b/src/testrel.jl @@ -16,10 +16,23 @@ function gen_safe_name(basename) return name[1:min(sizeof(name), 63)] end -const TEST_CONTEXT = Ref{Option{Context}}(nothing) +mutable struct TestDefaults + context::Option{Context} + engine::Option{AbstractString} + clone_db::Option{AbstractString} +end +const TEST_DEFAULTS = Ref{TestDefaults}(TestDefaults(nothing, nothing, nothing)) function get_context() - return TEST_CONTEXT[] + return TEST_DEFAULTS[].context +end + +function get_default_test_engine() + return TEST_DEFAULTS[].engine +end + +function get_default_clone_db() + return TEST_DEFAULTS[].clone_db end """ @@ -36,7 +49,59 @@ set_context!(Context(RAI.load_config(fname="/Users/testing/.rai"))) ``` """ function set_context!(new_context::Context) - return TEST_CONTEXT[] = new_context + return TEST_DEFAULTS[].context = new_context +end + +""" + set_test_engine!(new_engine::Option{AbstractString}) + +Set the engine to be used by the testing framework. + +If the engine is `nothing` and no `engine` is passed to a `@test_rel` call, the testing +framework will take engines from the engine pool. + +# Examples + +To use a specific engine on tests: + +``` +set_test_engine!("my_engine") +``` + +To use the engine pool: + +``` +set_test_engine!(nothing) +``` +""" +function set_test_engine!(new_engine::Option{AbstractString}) + return TEST_DEFAULTS[].engine = new_engine +end + +""" + set_clone_db!(new_clone_db::Option{AbstractString}) + +Set the name of the database to be cloned by the testing framework. + +If the clone_db is `nothing` and no `clone_db` is passed to a `@test_rel` call, the testing +framework will create an empty new databases to run tests. + +# Examples + +To clone a specific database on tests: + +``` +set_clone_db!("my_prototype_db") +``` + +To create empty databases on tests. + +``` +set_clone_db!(nothing) +``` +""" +function set_clone_db!(new_clone_db::Option{AbstractString}) + return TEST_DEFAULTS[].clone_db = new_clone_db end function create_test_database_name()::String @@ -49,8 +114,10 @@ function create_test_database( clone_db::Option{String}=nothing; retries_remaining=3, ) + db = isnothing(clone_db) ? get_default_clone_db() : clone_db + !isnothing(db) && @debug("Cloning '$name' from '$db'") try - create_database(get_context(), name; source=clone_db, readtimeout=30).database + create_database(get_context(), name; source=db, readtimeout=30).database return name catch e # If the status code is 409 and we have retries remaining then let's try a new name @@ -59,7 +126,7 @@ function create_test_database( @warn "[DB CONFLICT] Conflict when creating database $name. Trying again with new name $new_name." return create_test_database( new_name, - clone_db; + db; retries_remaining=retries_remaining - 1, ) else @@ -367,7 +434,7 @@ Note that `test_rel` creates a new schema for each test. - `debug_trace::Bool`: boolean that specifies printing out the debug_trace - `engine::String` (optional): the name of an existing engine where tests will be executed - `disable_corerel_deprecations::Bool`: control CoreRel deprecations - """ +""" function test_rel_steps(; steps::Vector{Step}, name::Option{String}=nothing, diff --git a/test/integration.jl b/test/integration.jl index b220008..7c6383a 100644 --- a/test/integration.jl +++ b/test/integration.jl @@ -1,18 +1,13 @@ # Basic Rel # -------------------------------------------------------- -@test_rel( - name = "No input, expected, or output", - query = """ - def result { 1 } - """,) +@test_rel(name = "No input, expected, or output", query = """ + def result { 1 } + """,) -@test_rel( - name = "No input or expected, has output", - query = """ - def output { 1 } - """, -) +@test_rel(name = "No input or expected, has output", query = """ + def output { 1 } + """,) @test_rel( name = "Input, no expected or output", @@ -73,23 +68,15 @@ broken = true, ) -@test_rel( - name = "Expected abort", - query = """ - def result { 1 } - ic () requires result = 2 - """, - expect_abort = true, -) +@test_rel(name = "Expected abort", query = """ + def result { 1 } + ic () requires result = 2 + """, expect_abort = true,) -@test_rel( - name = "Broken abort", - query = """ - def result { 1 } - ic () requires result = 2 - """, - broken = true, -) +@test_rel(name = "Broken abort", query = """ + def result { 1 } + ic () requires result = 2 + """, broken = true,) @test_rel( name = "Expected problem", @@ -139,13 +126,9 @@ allow_unexpected = :error, ) -@test_rel( - name = "Unexpected problem, broken", - query = """ - def output { a } - """, - broken = true, -) +@test_rel(name = "Unexpected problem, broken", query = """ + def output { a } + """, broken = true,) @test_rel( name = "abort_on_error", diff --git a/test/runtests.jl b/test/runtests.jl index b4c1264..92bb3b1 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -49,7 +49,7 @@ if isnothing(RAITest.get_context()) @warn "No RAI config provided. Skipping integration tests" else try - resize_test_engine_pool!(2, (i)->"RAITest-test-$i") + resize_test_engine_pool!(2, (i) -> "RAITest-test-$i") @testset RAITestSet "Basic Integration" begin include("integration.jl")