Skip to content

Commit 5386a13

Browse files
authored
[Bridges] allow variable bridges to use runtests without unbridged_variable (#2498)
1 parent 5a2a107 commit 5386a13

File tree

2 files changed

+56
-4
lines changed

2 files changed

+56
-4
lines changed

src/Bridges/Bridges.jl

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,11 @@ MOI.get_fallback(model::MOI.ModelLike, ::ListOfNonstandardBridges) = Type[]
144144

145145
include("precompile.jl")
146146

147-
function _test_structural_identical(a::MOI.ModelLike, b::MOI.ModelLike)
147+
function _test_structural_identical(
148+
a::MOI.ModelLike,
149+
b::MOI.ModelLike;
150+
cannot_unbridge::Bool = false,
151+
)
148152
# Test that the variables are the same. We make the strong assumption that
149153
# the variables are added in the same order to both models.
150154
a_x = MOI.get(a, MOI.ListOfVariableIndices())
@@ -190,7 +194,16 @@ function _test_structural_identical(a::MOI.ModelLike, b::MOI.ModelLike)
190194
Test.@test MOI.supports_constraint(b, F, S)
191195
# Check that each function in `b` matches a function in `a`
192196
for ci in MOI.get(b, MOI.ListOfConstraintIndices{F,S}())
193-
f_b = MOI.get(b, MOI.ConstraintFunction(), ci)
197+
f_b = try
198+
MOI.get(b, MOI.ConstraintFunction(), ci)
199+
catch err
200+
if cannot_unbridge &&
201+
err isa MOI.GetAttributeNotAllowed{MOI.ConstraintFunction}
202+
continue
203+
else
204+
rethrow(err)
205+
end
206+
end
194207
f_b = MOI.Utilities.map_indices(x_map, f_b)
195208
s_b = MOI.get(b, MOI.ConstraintSet(), ci)
196209
# We don't care about the order that constraints are added, only
@@ -225,13 +238,18 @@ end
225238
variable_start = 1.2,
226239
constraint_start = 1.2,
227240
eltype = Float64,
241+
cannot_unbridge::Bool = false,
228242
)
229243
230244
Run a series of tests that check the correctness of `Bridge`.
231245
232246
`input_fn` and `output_fn` are functions such that `input_fn(model)`
233247
and `output_fn(model)` load the corresponding model into `model`.
234248
249+
Set `cannot_unbridge` to `true` if the bridge is a variable bridge
250+
for which [`Variable.unbridged_map`](@ref) returns `nothing` so that
251+
the tests allow errors that can be raised due to this.
252+
235253
## Example
236254
237255
```jldoctest; setup=:(import MathOptInterface as MOI)
@@ -253,6 +271,7 @@ function runtests(
253271
constraint_start = 1.2,
254272
eltype = Float64,
255273
print_inner_model::Bool = false,
274+
cannot_unbridge::Bool = false,
256275
)
257276
# Load model and bridge it
258277
inner = MOI.Utilities.UniversalFallback(MOI.Utilities.Model{eltype}())
@@ -267,7 +286,7 @@ function runtests(
267286
# Load a non-bridged input model, and check that getters are the same.
268287
test = MOI.Utilities.UniversalFallback(MOI.Utilities.Model{eltype}())
269288
input_fn(test)
270-
_test_structural_identical(test, model)
289+
_test_structural_identical(test, model; cannot_unbridge = cannot_unbridge)
271290
# Load a bridged target model, and check that getters are the same.
272291
target = MOI.Utilities.UniversalFallback(MOI.Utilities.Model{eltype}())
273292
output_fn(target)
@@ -291,7 +310,17 @@ function runtests(
291310
# Test ConstraintPrimalStart and ConstraintDualStart
292311
for (F, S) in MOI.get(model, MOI.ListOfConstraintTypesPresent())
293312
for ci in MOI.get(model, MOI.ListOfConstraintIndices{F,S}())
294-
set = MOI.get(model, MOI.ConstraintSet(), ci)
313+
set = try
314+
MOI.get(model, MOI.ConstraintSet(), ci)
315+
catch err
316+
# Could be thrown by `unbridged_function`
317+
if cannot_unbridge &&
318+
err isa MOI.GetAttributeNotAllowed{MOI.ConstraintFunction}
319+
continue
320+
else
321+
rethrow(err)
322+
end
323+
end
295324
for attr in (MOI.ConstraintPrimalStart(), MOI.ConstraintDualStart())
296325
if MOI.supports(model, attr, MOI.ConstraintIndex{F,S})
297326
MOI.set(model, attr, ci, nothing)

test/Bridges/Variable/zeros.jl

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,29 @@ end
2323

2424
include("../utilities.jl")
2525

26+
function test_runtests()
27+
MOI.Bridges.runtests(
28+
MOI.Bridges.Variable.ZerosBridge,
29+
model -> begin
30+
x, _ = MOI.add_constrained_variables(model, MOI.Zeros(2))
31+
MOI.add_constraint(
32+
model,
33+
1.0 * x[1] + 2.0 * x[2],
34+
MOI.EqualTo(3.0),
35+
)
36+
end,
37+
model -> begin
38+
MOI.add_constraint(
39+
model,
40+
zero(MOI.ScalarAffineFunction{Float64}),
41+
MOI.EqualTo(3.0),
42+
)
43+
end;
44+
cannot_unbridge = true,
45+
)
46+
return
47+
end
48+
2649
function test_zeros()
2750
mock = MOI.Utilities.MockOptimizer(MOI.Utilities.Model{Float64}())
2851
bridged_mock = MOI.Bridges.Variable.Zeros{Float64}(mock)

0 commit comments

Comments
 (0)