The Test submodule
Functions to help test implementations of MOI. See The Test submodule for more details.
MathOptInterface.Test.Config
— TypeConfig(
::Type{T} = Float64;
atol::Real = Base.rtoldefault(T),
rtol::Real = Base.rtoldefault(T),
optimal_status::MOI.TerminationStatusCode = MOI.OPTIMAL,
infeasible_status::MOI.TerminationStatusCode = MOI.INFEASIBLE,
exclude::Vector{Any} = Any[],
) where {T}
Return an object that is used to configure various tests.
Configuration arguments
atol::Real = Base.rtoldefault(T)
: Control the absolute tolerance used when comparing solutions.rtol::Real = Base.rtoldefault(T)
: Control the relative tolerance used when comparing solutions.optimal_status = MOI.OPTIMAL
: Set toMOI.LOCALLY_SOLVED
if the solver cannot prove global optimality.infeasible_status = MOI.INFEASIBLE
: Set toMOI.LOCALLY_INFEASIBLE
if the solver cannot prove global infeasibility.exclude = Vector{Any}
: Pass attributes or functions toexclude
to skip parts of tests that require certain functionality. Common arguments include:MOI.delete
to skip deletion-related testsMOI.optimize!
to skip optimize-related testsMOI.ConstraintDual
to skip dual-related testsMOI.VariableName
to skip setting variable namesMOI.ConstraintName
to skip setting constraint names
Example
For a nonlinear solver that finds local optima and does not support finding dual variables or constraint names:
julia> import MathOptInterface as MOI
julia> config = MOI.Test.Config(
Float64;
optimal_status = MOI.LOCALLY_SOLVED,
exclude = Any[
MOI.ConstraintDual,
MOI.VariableName,
MOI.ConstraintName,
MOI.delete,
],
);
MathOptInterface.Test.runtests
— Functionruntests(
model::MOI.ModelLike,
config::Config;
include::Vector{Union{String,Regex}} = String[],
exclude::Vector{Union{String,Regex}} = String[],
warn_unsupported::Bool = false,
exclude_tests_after::VersionNumber = v"999.0.0",
verbose::Bool = false,
)
Run all tests in MathOptInterface.Test
on model
.
Configuration arguments
config
is aTest.Config
object that can be used to modify the behavior of tests.- If
include
is not empty, only run tests if an element frominclude
occursin
the name of the test. - If
exclude
is not empty, skip tests if an element fromexclude
occursin
the name of the test. exclude
takes priority overinclude
.- If
warn_unsupported
isfalse
,runtests
will silently skip tests that fail with aMOI.NotAllowedError
,MOI.UnsupportedError
, orRequirementUnmet
error. (The latter is thrown when an@requires
statement returnsfalse
.) Whenwarn_unsupported
istrue
, a warning will be printed. For most cases the default behavior,false
, is what you want, since these tests likely test functionality that is not supported bymodel
. However, it can be useful to runwarn_unsupported = true
to check you are not skipping tests due to a missingsupports_constraint
method or equivalent. exclude_tests_after
is a version number that excludes any tests to MOI added after that version number. This is useful for solvers who can declare a fixed set of tests, and not cause their tests to break if a new patch of MOI is released with a new test.verbose
is aBool
that controls whether the name of the test is printed before executing it. This can be helpful when debugging.
See also: setup_test
.
Example
config = MathOptInterface.Test.Config()
MathOptInterface.Test.runtests(
model,
config;
include = ["test_linear_", r"^test_model_Name$"],
exclude = ["VariablePrimalStart"],
warn_unsupported = true,
verbose = true,
exclude_tests_after = v"0.10.5",
)
MathOptInterface.Test.setup_test
— Functionsetup_test(::typeof(f), model::MOI.ModelLike, config::Config)
Overload this method to modify model
before running the test function f
on model
with config
. You can also modify the fields in config
(for example, to loosen the default tolerances).
This function should either return nothing
, or return a function which, when called with zero arguments, undoes the setup to return the model to its previous state. You do not need to undo any modifications to config
.
This function is most useful when writing new tests of the tests for MOI, but it can also be used to set test-specific tolerances, etc.
See also: runtests
Example
function MOI.Test.setup_test(
::typeof(MOI.Test.test_linear_VariablePrimalStart_partial),
mock::MOIU.MockOptimizer,
::MOI.Test.Config,
)
MOIU.set_mock_optimize!(
mock,
(mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [1.0, 0.0]),
)
mock.eval_variable_constraint_dual = false
function reset_function()
mock.eval_variable_constraint_dual = true
return
end
return reset_function
end
MathOptInterface.Test.version_added
— Functionversion_added(::typeof(function_name))
Returns the version of MOI in which the test function_name
was added.
This method should be implemented for all new tests.
See the exclude_tests_after
keyword of runtests
for more details.
MathOptInterface.Test.@requires
— Macro@requires(x)
Check that the condition x
is true
. Otherwise, throw an RequirementUnmet
error to indicate that the model does not support something required by the test function.
Example
@requires MOI.supports(model, MOI.Silent())
@test MOI.get(model, MOI.Silent())
MathOptInterface.Test.RequirementUnmet
— TypeRequirementUnmet(msg::String) <: Exception
An error for throwing in tests to indicate that the model does not support some requirement expected by the test function.
MathOptInterface.Test.HS071
— TypeHS071(
enable_hessian::Bool,
enable_hessian_vector_product::Bool = false,
)
An MOI.AbstractNLPEvaluator
for the problem:
\[\begin{aligned} \text{min} \ & x_1 * x_4 * (x_1 + x_2 + x_3) + x_3 \\ \text{subject to}\ & x_1 * x_2 * x_3 * x_4 \ge 25 \\ & x_1^2 + x_2^2 + x_3^2 + x_4^2 = 40 \\ & 1 \le x_1, x_2, x_3, x_4 \le 5 \end{aligned}\]
The optimal solution is [1.000, 4.743, 3.821, 1.379]
.