diff --git a/src/Test/test_attribute.jl b/src/Test/test_attribute.jl index 16948f37e8..93cae893cc 100644 --- a/src/Test/test_attribute.jl +++ b/src/Test/test_attribute.jl @@ -1,10 +1,10 @@ """ - test_attribute_NumberThreads(model::MOI.ModelLike, config::Config) + test_attribute_NumberThreads(model::MOI.AbstractOptimizer, config::Config) Test that the [`MOI.NumberOfThreads`](@ref) attribute is implemented for `model`. """ -function test_attribute_NumberThreads(model::MOI.ModelLike, ::Config) +function test_attribute_NumberThreads(model::MOI.AbstractOptimizer, ::Config) @requires MOI.supports(model, MOI.NumberOfThreads()) # Get the current value to restore it at the end of the test value = MOI.get(model, MOI.NumberOfThreads()) @@ -16,6 +16,7 @@ function test_attribute_NumberThreads(model::MOI.ModelLike, ::Config) @test value == MOI.get(model, MOI.NumberOfThreads()) return end +test_attribute_NumberThreads(::MOI.ModelLike, ::Config) = nothing function setup_test( ::typeof(test_attribute_NumberThreads), @@ -27,12 +28,15 @@ function setup_test( end """ - test_attribute_RawStatusString(model::MOI.ModelLike, config::Config) + test_attribute_RawStatusString(model::MOI.AbstractOptimizer, config::Config) Test that the [`MOI.RawStatusString`](@ref) attribute is implemented for `model`. """ -function test_attribute_RawStatusString(model::MOI.ModelLike, config::Config) +function test_attribute_RawStatusString( + model::MOI.AbstractOptimizer, + config::Config, +) @requires _supports(config, MOI.optimize!) @requires _supports(config, MOI.RawStatusString) MOI.add_variable(model) @@ -40,6 +44,7 @@ function test_attribute_RawStatusString(model::MOI.ModelLike, config::Config) @test MOI.get(model, MOI.RawStatusString()) isa AbstractString return end +test_attribute_RawStatusString(::MOI.ModelLike, ::Config) = nothing function setup_test( ::typeof(test_attribute_RawStatusString), @@ -60,11 +65,11 @@ function setup_test( end """ - test_attribute_Silent(model::MOI.ModelLike, config::Config) + test_attribute_Silent(model::MOI.AbstractOptimizer, config::Config) Test that the [`MOI.Silent`](@ref) attribute is implemented for `model`. """ -function test_attribute_Silent(model::MOI.ModelLike, ::Config) +function test_attribute_Silent(model::MOI.AbstractOptimizer, ::Config) @requires MOI.supports(model, MOI.Silent()) # Get the current value to restore it at the end of the test value = MOI.get(model, MOI.Silent()) @@ -77,6 +82,7 @@ function test_attribute_Silent(model::MOI.ModelLike, ::Config) @test value == MOI.get(model, MOI.Silent()) return end +test_attribute_Silent(::MOI.ModelLike, ::Config) = nothing function setup_test( ::typeof(test_attribute_Silent), @@ -88,23 +94,27 @@ function setup_test( end """ - test_attribute_SolverName(model::MOI.ModelLike, config::Config) + test_attribute_SolverName(model::MOI.AbstractOptimizer, config::Config) Test that the [`MOI.SolverName`](@ref) attribute is implemented for `model`. """ -function test_attribute_SolverName(model::MOI.ModelLike, config::Config) +function test_attribute_SolverName(model::MOI.AbstractOptimizer, config::Config) if _supports(config, MOI.SolverName) @test MOI.get(model, MOI.SolverName()) isa AbstractString end return end +test_attribute_SolverName(::MOI.ModelLike, ::Config) = nothing """ - test_attribute_SolveTimeSec(model::MOI.ModelLike, config::Config) + test_attribute_SolveTimeSec(model::MOI.AbstractOptimizer, config::Config) Test that the [`MOI.SolveTimeSec`](@ref) attribute is implemented for `model`. """ -function test_attribute_SolveTimeSec(model::MOI.ModelLike, config::Config) +function test_attribute_SolveTimeSec( + model::MOI.AbstractOptimizer, + config::Config, +) @requires _supports(config, MOI.optimize!) @requires _supports(config, MOI.SolveTimeSec) MOI.add_variable(model) @@ -112,6 +122,7 @@ function test_attribute_SolveTimeSec(model::MOI.ModelLike, config::Config) @test MOI.get(model, MOI.SolveTimeSec()) >= 0.0 return end +test_attribute_SolveTimeSec(::MOI.ModelLike, ::Config) = nothing function setup_test( ::typeof(test_attribute_SolveTimeSec), @@ -126,11 +137,11 @@ function setup_test( end """ - test_attribute_TimeLimitSec(model::MOI.ModelLike, config::Config) + test_attribute_TimeLimitSec(model::MOI.AbstractOptimizer, config::Config) Test that the [`MOI.TimeLimitSec`](@ref) attribute is implemented for `model`. """ -function test_attribute_TimeLimitSec(model::MOI.ModelLike, ::Config) +function test_attribute_TimeLimitSec(model::MOI.AbstractOptimizer, ::Config) @requires MOI.supports(model, MOI.TimeLimitSec()) # Get the current value to restore it at the end of the test value = MOI.get(model, MOI.TimeLimitSec()) @@ -142,6 +153,7 @@ function test_attribute_TimeLimitSec(model::MOI.ModelLike, ::Config) @test value == MOI.get(model, MOI.TimeLimitSec()) # Equality should hold return end +test_attribute_TimeLimitSec(::MOI.ModelLike, ::Config) = nothing function setup_test( ::typeof(test_attribute_TimeLimitSec), diff --git a/src/Test/test_constraint.jl b/src/Test/test_constraint.jl index d45c928bb7..4ab7b8802f 100644 --- a/src/Test/test_constraint.jl +++ b/src/Test/test_constraint.jl @@ -728,6 +728,11 @@ function test_constraint_ConstraintPrimalStart( MOI.VectorAffineFunction{T}, MOI.Nonnegatives, ) + @requires MOI.supports( + model, + MOI.ConstraintPrimalStart(), + MOI.ConstraintIndex{MOI.VectorAffineFunction{T},MOI.Nonnegatives}, + ) x = MOI.add_variable(model) f = MOI.VectorAffineFunction( [MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(one(T), x))], @@ -759,6 +764,11 @@ function test_constraint_ConstraintDualStart( MOI.VectorAffineFunction{T}, MOI.Nonnegatives, ) + @requires MOI.supports( + model, + MOI.ConstraintDualStart(), + MOI.ConstraintIndex{MOI.VectorAffineFunction{T},MOI.Nonnegatives}, + ) x = MOI.add_variable(model) f = MOI.VectorAffineFunction( [MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(one(T), x))], diff --git a/src/Test/test_model.jl b/src/Test/test_model.jl index 3188915079..62d8cea500 100644 --- a/src/Test/test_model.jl +++ b/src/Test/test_model.jl @@ -742,11 +742,10 @@ end config::Config, ) -Test that `MOI.ScalarFunctionConstantNotZero` is thrown when a constraint with -a function with nonzero constant is added. +Test adding a linear constraint with a non-zero function constant. -**This test is optional because solvers could choose to support scalar functions -with nonzero constants.** +This should either work, or error with `MOI.ScalarFunctionConstantNotZero` if +the model does not support it. To skip this test, pass `MOI.ScalarFunctionConstantNotZero` to the `exclude` argument of [`Config`](@ref). @@ -756,33 +755,30 @@ function test_model_ScalarFunctionConstantNotZero( config::Config, ) @requires _supports(config, MOI.ScalarFunctionConstantNotZero) - err = MOI.ScalarFunctionConstantNotZero{ - Float64, - MOI.ScalarAffineFunction{Float64}, - MOI.EqualTo{Float64}, - }( - 1.0, - ) - @test_throws err begin - MOI.add_constraint( - model, - MOI.ScalarAffineFunction(MOI.ScalarAffineTerm{Float64}[], 1.0), - MOI.EqualTo(2.0), + function _error(S, value) + return MOI.ScalarFunctionConstantNotZero{ + Float64, + MOI.ScalarAffineFunction{Float64}, + S, + }( + value, ) end - err = MOI.ScalarFunctionConstantNotZero{ - Float64, - MOI.ScalarAffineFunction{Float64}, - MOI.GreaterThan{Float64}, - }( - 2.0, - ) - @test_throws err begin - MOI.add_constraint( - model, - MOI.ScalarAffineFunction(MOI.ScalarAffineTerm{Float64}[], 2.0), - MOI.GreaterThan(1.0), - ) + try + f = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm{Float64}[], 1.0) + c = MOI.add_constraint(model, f, MOI.EqualTo(2.0)) + @requires _supports(config, MOI.ConstraintFunction) + @test MOI.get(model, MOI.ConstraintFunction(), c) ≈ f + catch err + @test err == _error(MOI.EqualTo{Float64}, 1.0) + end + try + f = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm{Float64}[], 2.0) + c = MOI.add_constraint(model, f, MOI.GreaterThan(1.0)) + @requires _supports(config, MOI.ConstraintFunction) + @test MOI.get(model, MOI.ConstraintFunction(), c) ≈ f + catch err + @test err == _error(MOI.GreaterThan{Float64}, 2.0) end return end diff --git a/test/Utilities/cachingoptimizer.jl b/test/Utilities/cachingoptimizer.jl index 5c530c9b77..4b70ac4905 100644 --- a/test/Utilities/cachingoptimizer.jl +++ b/test/Utilities/cachingoptimizer.jl @@ -114,14 +114,7 @@ function test_MOI_Test() MOI.Test.runtests( model, MOI.Test.Config(exclude = Any[MOI.optimize!]), - exclude = String[ - # This test is optional. - "test_model_ScalarFunctionConstantNotZero", - # MockOptimizer doesnt' support these - "test_attribute_SolverName", - "test_constraint_ConstraintDualStart", - "test_constraint_ConstraintPrimalStart", - ], + exclude = ["test_attribute_SolverName"], ) end end diff --git a/test/Utilities/model.jl b/test/Utilities/model.jl index eeb7532c0f..184b257eac 100644 --- a/test/Utilities/model.jl +++ b/test/Utilities/model.jl @@ -87,15 +87,7 @@ struct SetNotSupportedBySolvers <: MOI.AbstractSet end function test_MOI_Test() MOI.Test.runtests( MOI.Utilities.Model{Float64}(), - MOI.Test.Config(exclude = Any[MOI.optimize!]), - exclude = String[ - # This test is optional. - "test_model_ScalarFunctionConstantNotZero", - # Unsupported attributes - "test_constraint_ConstraintPrimalStart", - "test_constraint_ConstraintDualStart", - "test_attribute_SolverName", - ], + MOI.Test.Config(exclude = Any[MOI.optimize!,]), ) return end diff --git a/test/Utilities/universalfallback.jl b/test/Utilities/universalfallback.jl index cde177e20d..704660f68f 100644 --- a/test/Utilities/universalfallback.jl +++ b/test/Utilities/universalfallback.jl @@ -71,8 +71,6 @@ function test_MOI_Test() model, MOI.Test.Config(exclude = Any[MOI.optimize!]), exclude = String[ - # This test is optional. - "test_model_ScalarFunctionConstantNotZero", # UniversalFallback fails all these tests because it supports # everything... "test_attribute_",