The Test submodule

Functions to help test implementations of MOI. See The Test submodule for more details.

MathOptInterface.Test.ConfigType
Config(
    ::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 to MOI.LOCALLY_SOLVED if the solver cannot prove global optimality.
  • infeasible_status = MOI.INFEASIBLE: Set to MOI.LOCALLY_INFEASIBLE if the solver cannot prove global infeasibility.
  • exclude = Vector{Any}: Pass attributes or functions to exclude to skip parts of tests that require certain functionality. Common arguments include:
    • MOI.delete to skip deletion-related tests
    • MOI.optimize! to skip optimize-related tests
    • MOI.ConstraintDual to skip dual-related tests
    • MOI.VariableName to skip setting variable names
    • MOI.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,
           ],
       );
source
MathOptInterface.Test.runtestsFunction
runtests(
    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 a Test.Config object that can be used to modify the behavior of tests.
  • If include is not empty, only run tests if an element from include occursin the name of the test.
  • If exclude is not empty, skip tests if an element from exclude occursin the name of the test.
  • exclude takes priority over include.
  • If warn_unsupported is false, runtests will silently skip tests that fail with a MOI.NotAllowedError, MOI.UnsupportedError, or RequirementUnmet error. (The latter is thrown when an @requires statement returns false.) When warn_unsupported is true, 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 by model. However, it can be useful to run warn_unsupported = true to check you are not skipping tests due to a missing supports_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 a Bool 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",
)
source
MathOptInterface.Test.setup_testFunction
setup_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
source
MathOptInterface.Test.version_addedFunction
version_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.

source
MathOptInterface.Test.@requiresMacro
@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())
source
MathOptInterface.Test.HS071Type
HS071(
    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].

source