Skip to content

Commit d68b3fb

Browse files
authored
[Utilities] improve code coverage (#2637)
1 parent 90c7e46 commit d68b3fb

File tree

6 files changed

+341
-1
lines changed

6 files changed

+341
-1
lines changed

src/Utilities/cachingoptimizer.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1166,7 +1166,7 @@ function MOI.get(
11661166
MOI.get(
11671167
m.optimizer,
11681168
attr.attr,
1169-
getindex.(m.model_to_optimizer_map, idx),
1169+
map_indices_to_optimizer(m, idx),
11701170
)::Vector{<:MOI.attribute_value_type(attr.attr)},
11711171
)
11721172
end

test/Utilities/CleverDicts.jl

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,29 @@ function test_convert()
264264
return
265265
end
266266

267+
function test_inverse_hash()
268+
d = CleverDicts.CleverDict{Int64,String}(identity, identity)
269+
key = CleverDicts.add_item(d, "a")
270+
@test d[key] == "a"
271+
return
272+
end
273+
274+
function test_resize()
275+
d = CleverDicts.CleverDict{MOI.VariableIndex,String}()
276+
resize!(d, 1)
277+
@test length(d.vector) == 1
278+
x = CleverDicts.add_item(d, "a")
279+
@test_throws(
280+
ErrorException(
281+
"CleverDict cannot be resized to a size smaller than the current",
282+
),
283+
resize!(d, 0),
284+
)
285+
delete!(d, x)
286+
resize!(d, 0)
287+
return
288+
end
289+
267290
end # module
268291

269292
TestCleverDicts.runtests()

test/Utilities/cachingoptimizer.jl

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,6 +1109,198 @@ function test_show()
11091109
return
11101110
end
11111111

1112+
function test_add_variable()
1113+
for mode in (MOI.Utilities.AUTOMATIC, MOI.Utilities.MANUAL)
1114+
cache = MOI.Utilities.Model{Float64}()
1115+
optimizer = MOI.Utilities.MockOptimizer(MOI.Utilities.Model{Float64}())
1116+
model = MOI.Utilities.CachingOptimizer(cache, mode)
1117+
MOI.Utilities.reset_optimizer(model, optimizer)
1118+
MOI.Utilities.attach_optimizer(model)
1119+
x = MOI.add_variable(model)
1120+
@test MOI.is_valid(optimizer, model.model_to_optimizer_map[x])
1121+
end
1122+
return
1123+
end
1124+
1125+
function test_add_variables()
1126+
for mode in (MOI.Utilities.AUTOMATIC, MOI.Utilities.MANUAL)
1127+
cache = MOI.Utilities.Model{Float64}()
1128+
optimizer = MOI.Utilities.MockOptimizer(MOI.Utilities.Model{Float64}())
1129+
model = MOI.Utilities.CachingOptimizer(cache, mode)
1130+
MOI.Utilities.reset_optimizer(model, optimizer)
1131+
MOI.Utilities.attach_optimizer(model)
1132+
x = MOI.add_variables(model, 2)
1133+
for xi in x
1134+
@test MOI.is_valid(optimizer, model.model_to_optimizer_map[xi])
1135+
end
1136+
end
1137+
return
1138+
end
1139+
1140+
function test_add_constrained_variable()
1141+
for mode in (MOI.Utilities.AUTOMATIC, MOI.Utilities.MANUAL)
1142+
cache = MOI.Utilities.Model{Float64}()
1143+
optimizer = MOI.Utilities.MockOptimizer(MOI.Utilities.Model{Float64}())
1144+
model = MOI.Utilities.CachingOptimizer(cache, mode)
1145+
MOI.Utilities.reset_optimizer(model, optimizer)
1146+
MOI.Utilities.attach_optimizer(model)
1147+
x, c = MOI.add_constrained_variable(model, MOI.ZeroOne())
1148+
@test MOI.is_valid(optimizer, model.model_to_optimizer_map[x])
1149+
@test MOI.is_valid(optimizer, model.model_to_optimizer_map[c])
1150+
end
1151+
return
1152+
end
1153+
1154+
function test_add_constrained_variables()
1155+
for mode in (MOI.Utilities.AUTOMATIC, MOI.Utilities.MANUAL)
1156+
cache = MOI.Utilities.Model{Float64}()
1157+
optimizer = MOI.Utilities.MockOptimizer(MOI.Utilities.Model{Float64}())
1158+
model = MOI.Utilities.CachingOptimizer(cache, mode)
1159+
MOI.Utilities.reset_optimizer(model, optimizer)
1160+
MOI.Utilities.attach_optimizer(model)
1161+
x, c = MOI.add_constrained_variables(model, MOI.Zeros(2))
1162+
for xi in x
1163+
@test MOI.is_valid(optimizer, model.model_to_optimizer_map[xi])
1164+
end
1165+
@test MOI.is_valid(optimizer, model.model_to_optimizer_map[c])
1166+
end
1167+
return
1168+
end
1169+
1170+
function test_modify_constraint()
1171+
for mode in (MOI.Utilities.AUTOMATIC, MOI.Utilities.MANUAL)
1172+
cache = MOI.Utilities.Model{Float64}()
1173+
optimizer = MOI.Utilities.MockOptimizer(MOI.Utilities.Model{Float64}())
1174+
model = MOI.Utilities.CachingOptimizer(cache, mode)
1175+
MOI.Utilities.reset_optimizer(model, optimizer)
1176+
MOI.Utilities.attach_optimizer(model)
1177+
x = MOI.add_variable(model)
1178+
c = MOI.add_constraint(model, 1.0 * x, MOI.EqualTo(1.0))
1179+
c_opt = model.model_to_optimizer_map[c]
1180+
f = MOI.get(optimizer, MOI.ConstraintFunction(), c_opt)
1181+
@test f 1.0 * model.model_to_optimizer_map[x]
1182+
MOI.modify(model, c, MOI.ScalarCoefficientChange(x, 2.0))
1183+
c_opt = model.model_to_optimizer_map[c]
1184+
f = MOI.get(optimizer, MOI.ConstraintFunction(), c_opt)
1185+
@test f 2.0 * model.model_to_optimizer_map[x]
1186+
end
1187+
return
1188+
end
1189+
1190+
function test_modify_constraint()
1191+
for mode in (MOI.Utilities.AUTOMATIC, MOI.Utilities.MANUAL)
1192+
cache = MOI.Utilities.Model{Float64}()
1193+
optimizer = MOI.Utilities.MockOptimizer(MOI.Utilities.Model{Float64}())
1194+
model = MOI.Utilities.CachingOptimizer(cache, mode)
1195+
MOI.Utilities.reset_optimizer(model, optimizer)
1196+
MOI.Utilities.attach_optimizer(model)
1197+
x = MOI.add_variable(model)
1198+
f = 1.0 * x
1199+
attr = MOI.ObjectiveFunction{typeof(f)}()
1200+
MOI.set(model, attr, f)
1201+
@test MOI.get(optimizer, attr) 1.0 * model.model_to_optimizer_map[x]
1202+
MOI.modify(model, attr, MOI.ScalarCoefficientChange(x, 2.0))
1203+
@test MOI.get(optimizer, attr) 2.0 * model.model_to_optimizer_map[x]
1204+
end
1205+
return
1206+
end
1207+
1208+
function test_delete_invalid_index()
1209+
for mode in (MOI.Utilities.AUTOMATIC, MOI.Utilities.MANUAL)
1210+
cache = MOI.Utilities.Model{Float64}()
1211+
optimizer = MOI.Utilities.MockOptimizer(MOI.Utilities.Model{Float64}())
1212+
model = MOI.Utilities.CachingOptimizer(cache, mode)
1213+
MOI.Utilities.reset_optimizer(model, optimizer)
1214+
MOI.Utilities.attach_optimizer(model)
1215+
x = MOI.add_variable(model)
1216+
@test MOI.is_valid(optimizer, model.model_to_optimizer_map[x])
1217+
MOI.delete(model, x)
1218+
@test_throws(KeyError, model.model_to_optimizer_map[x])
1219+
@test_throws(MOI.InvalidIndex, MOI.delete(model, x))
1220+
end
1221+
return
1222+
end
1223+
1224+
function test_delete_variables()
1225+
for mode in (MOI.Utilities.AUTOMATIC, MOI.Utilities.MANUAL)
1226+
cache = MOI.Utilities.Model{Float64}()
1227+
optimizer = MOI.Utilities.MockOptimizer(MOI.Utilities.Model{Float64}())
1228+
model = MOI.Utilities.CachingOptimizer(cache, mode)
1229+
MOI.Utilities.reset_optimizer(model, optimizer)
1230+
MOI.Utilities.attach_optimizer(model)
1231+
x, y = MOI.add_variables(model, 2)
1232+
@test MOI.is_valid(optimizer, model.model_to_optimizer_map[x])
1233+
@test MOI.is_valid(optimizer, model.model_to_optimizer_map[y])
1234+
MOI.delete(model, [x])
1235+
@test_throws KeyError model.model_to_optimizer_map[x]
1236+
@test MOI.is_valid(optimizer, model.model_to_optimizer_map[y])
1237+
@test_throws(MOI.InvalidIndex, MOI.delete(model, x))
1238+
end
1239+
return
1240+
end
1241+
1242+
function test_set_attribute()
1243+
for mode in (MOI.Utilities.AUTOMATIC, MOI.Utilities.MANUAL)
1244+
cache = MOI.Utilities.UniversalFallback(MOI.Utilities.Model{Float64}())
1245+
optimizer = MOI.Utilities.MockOptimizer(
1246+
MOI.Utilities.UniversalFallback(MOI.Utilities.Model{Float64}()),
1247+
)
1248+
model = MOI.Utilities.CachingOptimizer(cache, mode)
1249+
MOI.Utilities.reset_optimizer(model, optimizer)
1250+
MOI.Utilities.attach_optimizer(model)
1251+
x = MOI.add_variable(model)
1252+
@test MOI.is_valid(optimizer, model.model_to_optimizer_map[x])
1253+
attr = MOI.VariablePrimalStart()
1254+
MOI.set(model, attr, x, 1.23)
1255+
opt_attr = MOI.Utilities.AttributeFromOptimizer(attr)
1256+
cache_attr = MOI.Utilities.AttributeFromModelCache(attr)
1257+
@test MOI.get(model, opt_attr, x) == 1.23
1258+
@test MOI.get(model, cache_attr, x) == 1.23
1259+
end
1260+
return
1261+
end
1262+
1263+
function test_get_AttributeFromOptimizer()
1264+
cache = MOI.Utilities.Model{Float64}()
1265+
optimizer = MOI.Utilities.MockOptimizer(MOI.Utilities.Model{Float64}())
1266+
model = MOI.Utilities.CachingOptimizer(cache, optimizer)
1267+
x = MOI.add_variable(model)
1268+
MOI.Utilities.attach_optimizer(model)
1269+
attr = MOI.VariableName()
1270+
optimizer_attr = MOI.Utilities.AttributeFromOptimizer(attr)
1271+
@test MOI.supports(model, optimizer_attr, MOI.VariableIndex)
1272+
MOI.set(model, optimizer_attr, x, "x")
1273+
@test MOI.get(model, attr, x) == ""
1274+
@test MOI.get(model, optimizer_attr, x) == "x"
1275+
@test MOI.get(model, optimizer_attr, [x]) == ["x"]
1276+
return
1277+
end
1278+
1279+
function test_get_AttributeFromModelCache()
1280+
cache = MOI.Utilities.Model{Float64}()
1281+
optimizer = MOI.Utilities.MockOptimizer(MOI.Utilities.Model{Float64}())
1282+
model = MOI.Utilities.CachingOptimizer(cache, optimizer)
1283+
x = MOI.add_variable(model)
1284+
MOI.Utilities.attach_optimizer(model)
1285+
# VariableName
1286+
attr = MOI.VariableName()
1287+
cache_attr = MOI.Utilities.AttributeFromModelCache(attr)
1288+
MOI.set(model, cache_attr, x, "x")
1289+
@test MOI.supports(model, cache_attr, MOI.VariableIndex)
1290+
@test MOI.get(model, attr, x) == "x"
1291+
@test MOI.get(model, cache_attr, x) == "x"
1292+
@test MOI.get(model, MOI.Utilities.AttributeFromOptimizer(attr), x) == ""
1293+
# Name
1294+
attr = MOI.Name()
1295+
cache_attr = MOI.Utilities.AttributeFromModelCache(attr)
1296+
MOI.set(model, cache_attr, "m")
1297+
@test MOI.supports(model, cache_attr)
1298+
@test MOI.get(model, attr) == "m"
1299+
@test MOI.get(model, cache_attr) == "m"
1300+
@test MOI.get(model, MOI.Utilities.AttributeFromOptimizer(attr)) == ""
1301+
return
1302+
end
1303+
11121304
end # module
11131305

11141306
TestCachingOptimizer.runtests()

test/Utilities/copy.jl

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,109 @@ function test_copy_to_sorted_sets()
10031003
return
10041004
end
10051005

1006+
function test_deprecated_try_constrain_variables_scalar()
1007+
src = MOI.Utilities.Model{Float64}()
1008+
x, c_z = MOI.add_constrained_variable(src, MOI.ZeroOne())
1009+
c = MOI.add_constraint(src, x, MOI.EqualTo(0.0))
1010+
dest = MOI.Utilities.Model{Float64}()
1011+
index_map = MOI.Utilities.IndexMap()
1012+
not_added = MOI.Utilities._try_constrain_variables_on_creation(
1013+
dest,
1014+
src,
1015+
index_map,
1016+
MOI.ZeroOne,
1017+
)
1018+
@test isempty(not_added)
1019+
not_added = MOI.Utilities._try_constrain_variables_on_creation(
1020+
dest,
1021+
src,
1022+
index_map,
1023+
MOI.EqualTo{Float64},
1024+
)
1025+
@test not_added == [c]
1026+
@test MOI.is_valid(dest, index_map[x])
1027+
@test MOI.is_valid(dest, index_map[c_z])
1028+
@test_throws KeyError index_map[c]
1029+
return
1030+
end
1031+
1032+
function test_deprecated_try_constrain_variables_vector()
1033+
src = MOI.Utilities.Model{Float64}()
1034+
x, c_z = MOI.add_constrained_variables(src, MOI.Nonnegatives(2))
1035+
y = MOI.add_variable(src)
1036+
c_duplicate = MOI.add_constraint(
1037+
src,
1038+
MOI.VectorOfVariables([x[1], x[1]]),
1039+
MOI.Zeros(2),
1040+
)
1041+
c_already_added = MOI.add_constraint(
1042+
src,
1043+
MOI.VectorOfVariables([y, x[1]]),
1044+
MOI.Nonpositives(2),
1045+
)
1046+
dest = MOI.Utilities.Model{Float64}()
1047+
index_map = MOI.Utilities.IndexMap()
1048+
not_added = MOI.Utilities._try_constrain_variables_on_creation(
1049+
dest,
1050+
src,
1051+
index_map,
1052+
MOI.Nonnegatives,
1053+
)
1054+
@test isempty(not_added)
1055+
@test MOI.is_valid(dest, index_map[x[1]])
1056+
@test MOI.is_valid(dest, index_map[x[2]])
1057+
@test MOI.is_valid(dest, index_map[c_z])
1058+
not_added = MOI.Utilities._try_constrain_variables_on_creation(
1059+
dest,
1060+
src,
1061+
index_map,
1062+
MOI.Zeros,
1063+
)
1064+
@test not_added == [c_duplicate]
1065+
not_added = MOI.Utilities._try_constrain_variables_on_creation(
1066+
dest,
1067+
src,
1068+
index_map,
1069+
MOI.Nonpositives,
1070+
)
1071+
@test not_added == [c_already_added]
1072+
return
1073+
end
1074+
1075+
function test_deprecated_copy_free_variables()
1076+
src = MOI.Utilities.Model{Float64}()
1077+
x, c_z = MOI.add_constrained_variable(src, MOI.ZeroOne())
1078+
y = MOI.add_variable(src)
1079+
dest = MOI.Utilities.Model{Float64}()
1080+
index_map = MOI.Utilities.IndexMap()
1081+
not_added = MOI.Utilities._try_constrain_variables_on_creation(
1082+
dest,
1083+
src,
1084+
index_map,
1085+
MOI.ZeroOne,
1086+
)
1087+
MOI.Utilities._copy_free_variables(dest, index_map, [x, y])
1088+
@test MOI.is_valid(dest, index_map[x])
1089+
@test MOI.is_valid(dest, index_map[y])
1090+
MOI.Utilities._copy_free_variables(dest, index_map, [x, y])
1091+
@test MOI.is_valid(dest, index_map[x])
1092+
@test MOI.is_valid(dest, index_map[y])
1093+
return
1094+
end
1095+
1096+
function test_index_map()
1097+
src = MOI.Utilities.Model{Float64}()
1098+
x, c_z = MOI.add_constrained_variable(src, MOI.ZeroOne())
1099+
dest = MOI.Utilities.Model{Float64}()
1100+
index_map = MOI.copy_to(dest, src)
1101+
@test collect(keys(index_map)) == Any[x, c_z]
1102+
delete!(index_map, x)
1103+
@test collect(keys(index_map)) == Any[c_z]
1104+
delete!(index_map, c_z)
1105+
@test collect(keys(index_map)) == Any[]
1106+
return
1107+
end
1108+
10061109
end # module
10071110

10081111
TestCopy.runtests()

test/Utilities/functions.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2217,6 +2217,27 @@ function test_VectorQuadraticFunction_row_constructor()
22172217
return
22182218
end
22192219

2220+
function test_cannonicalize_Variable()
2221+
x = MOI.VariableIndex.(1:2)
2222+
f = MOI.VectorOfVariables(x)
2223+
@test MOI.Utilities.canonicalize!(x[1]) === x[1]
2224+
@test MOI.Utilities.canonicalize!(f) === f
2225+
return
2226+
end
2227+
2228+
function test_filter_variables_variable_index()
2229+
f = MOI.VariableIndex(1)
2230+
@test MOI.Utilities.filter_variables(x -> x.value == 1, f) === f
2231+
@test_throws(
2232+
ErrorException(
2233+
"Cannot remove variable from a `VariableIndex` function of the " *
2234+
"same variable.",
2235+
),
2236+
MOI.Utilities.filter_variables(x -> x.value == 0, f),
2237+
)
2238+
return
2239+
end
2240+
22202241
end # module
22212242

22222243
TestUtilitiesFunctions.runtests()

test/Utilities/sets.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ function test_set_dot_scaling(n = 10)
222222
N = div(n * (n + 1), 2)
223223
M = N + div(n * (n - 1), 2)
224224
v = MOI.Utilities.SymmetricMatrixScalingVector{Float64}(1.5, 0.5, N)
225+
@test size(v) == (N,)
225226
w = MOI.Utilities.SymmetricMatrixScalingVector{Float64}(1.5, N)
226227
s = MOI.Utilities.symmetric_matrix_scaling_vector(Float64, N)
227228
s32 = MOI.Utilities.symmetric_matrix_scaling_vector(Float32, N)

0 commit comments

Comments
 (0)