OR-Tools  9.6
solvers_proto_validation_test.cc
Go to the documentation of this file.
1 // Copyright 2010-2022 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
15 
16 #include <limits>
17 #include <string>
18 
19 #include "absl/status/status.h"
20 #include "absl/strings/str_cat.h"
21 #include "absl/strings/string_view.h"
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
25 #include "ortools/pdlp/solvers.pb.h"
26 
27 namespace operations_research::pdlp {
28 namespace {
29 
31 
32 using ::testing::HasSubstr;
33 
34 TEST(ValidateTerminationCriteria, DefaultIsValid) {
35  TerminationCriteria criteria;
36  const absl::Status status = ValidateTerminationCriteria(criteria);
37  EXPECT_TRUE(status.ok()) << status;
38 }
39 
40 TEST(ValidateTerminationCriteria, BadOptimalityNorm) {
41  TerminationCriteria criteria;
42  criteria.set_optimality_norm(OPTIMALITY_NORM_UNSPECIFIED);
43  const absl::Status status = ValidateTerminationCriteria(criteria);
44  EXPECT_EQ(status.code(), absl::StatusCode::kInvalidArgument);
45  EXPECT_THAT(status.message(), HasSubstr("optimality_norm"));
46 }
47 
48 void TestTerminationCriteriaValidation(
49  absl::string_view termination_criteria_string,
50  absl::string_view error_substring) {
51  TerminationCriteria termination_criteria =
52  ParseTextOrDie<TerminationCriteria>(
53  std::string(termination_criteria_string));
54  const absl::Status status = ValidateTerminationCriteria(termination_criteria);
55  EXPECT_EQ(status.code(), absl::StatusCode::kInvalidArgument)
56  << "With termination criteria \"" << termination_criteria_string << "\"";
57  EXPECT_THAT(status.message(), HasSubstr(error_substring))
58  << "With termination criteria \"" << termination_criteria_string << "\"";
59 }
60 
61 // Tests that the given `DetailedOptimalityCriteria` field can't be negative or
62 // NAN.
63 void TestDetailedOptimalityCriteriaFieldValidation(
64  absl::string_view field_name) {
65  const std::string full_field_name =
66  absl::StrCat("detailed_optimality_criteria.", field_name);
67  TestTerminationCriteriaValidation(
68  absl::StrCat("detailed_optimality_criteria { ", field_name, ": -1.0 }"),
69  full_field_name);
70  TestTerminationCriteriaValidation(
71  absl::StrCat("detailed_optimality_criteria { ", field_name, ": nan }"),
72  full_field_name);
73 }
74 
75 TEST(ValidateTerminationCriteria, BadEpsOptimalAbsolute) {
76  TestTerminationCriteriaValidation("eps_optimal_absolute: -1.0",
77  "eps_optimal_absolute");
78  TestTerminationCriteriaValidation("eps_optimal_absolute: nan",
79  "eps_optimal_absolute");
80 }
81 
82 TEST(ValidateTerminationCriteria, BadEpsOptimalRelative) {
83  TestTerminationCriteriaValidation("eps_optimal_relative: -1.0",
84  "eps_optimal_relative");
85  TestTerminationCriteriaValidation("eps_optimal_relative: nan",
86  "eps_optimal_relative");
87 }
88 
89 TEST(ValidateTerminationCriteria, BadSimpleEpsOptimalAbsolute) {
90  TestTerminationCriteriaValidation(
91  "simple_optimality_criteria { eps_optimal_absolute: -1.0}",
92  "simple_optimality_criteria.eps_optimal_absolute");
93  TestTerminationCriteriaValidation(
94  "simple_optimality_criteria { eps_optimal_absolute: nan}",
95  "simple_optimality_criteria.eps_optimal_absolute");
96 }
97 
98 TEST(ValidateTerminationCriteria, BadSimpleEpsOptimalRelative) {
99  TestTerminationCriteriaValidation(
100  "simple_optimality_criteria { eps_optimal_relative: -1.0}",
101  "simple_optimality_criteria.eps_optimal_relative");
102  TestTerminationCriteriaValidation(
103  "simple_optimality_criteria { eps_optimal_relative: nan}",
104  "simple_optimality_criteria.eps_optimal_relative");
105 }
106 
107 TEST(ValidateTerminationCriteria, BadDetailedEpsOptimalPrimalResidualAbsolute) {
108  TestDetailedOptimalityCriteriaFieldValidation(
109  "eps_optimal_primal_residual_absolute");
110 }
111 
112 TEST(ValidateTerminationCriteria, BadDetailedEpsOptimalPrimalResidualRelative) {
113  TestDetailedOptimalityCriteriaFieldValidation(
114  "eps_optimal_primal_residual_relative");
115 }
116 
117 TEST(ValidateTerminationCriteria, BadDetailedEpsOptimalDualResidualAbsolute) {
118  TestDetailedOptimalityCriteriaFieldValidation(
119  "eps_optimal_dual_residual_absolute");
120 }
121 
122 TEST(ValidateTerminationCriteria, BadDetailedEpsOptimalDualResidualRelative) {
123  TestDetailedOptimalityCriteriaFieldValidation(
124  "eps_optimal_dual_residual_relative");
125 }
126 
127 TEST(ValidateTerminationCriteria, BadDetailedEpsOptimalDualityGapAbsolute) {
128  TestDetailedOptimalityCriteriaFieldValidation(
129  "eps_optimal_objective_gap_absolute");
130 }
131 
132 TEST(ValidateTerminationCriteria, BadDetailedEpsOptimalDualityGapRelative) {
133  TestDetailedOptimalityCriteriaFieldValidation(
134  "eps_optimal_objective_gap_relative");
135 }
136 
137 TEST(ValidateTerminationCriteria, AbsoluteAndSimpleOptimalityCriteria) {
138  TerminationCriteria termination_criteria =
139  ParseTextOrDie<TerminationCriteria>(
140  "eps_optimal_absolute: 1.0 simple_optimality_criteria { }");
141  const absl::Status status = ValidateTerminationCriteria(termination_criteria);
142  EXPECT_EQ(status.code(), absl::StatusCode::kInvalidArgument);
143  EXPECT_THAT(status.message(), HasSubstr("simple_optimality_criteria"));
144 }
145 
146 TEST(ValidateTerminationCriteria, RelativeAndSimpleOptimalityCriteria) {
147  TerminationCriteria termination_criteria =
148  ParseTextOrDie<TerminationCriteria>(
149  "eps_optimal_relative: 1.0 simple_optimality_criteria { }");
150  const absl::Status status = ValidateTerminationCriteria(termination_criteria);
151  EXPECT_EQ(status.code(), absl::StatusCode::kInvalidArgument);
152  EXPECT_THAT(status.message(), HasSubstr("simple_optimality_criteria"));
153 }
154 
155 TEST(ValidateTerminationCriteria, AbsoluteAndDetailedOptimalityCriteria) {
156  TerminationCriteria termination_criteria =
157  ParseTextOrDie<TerminationCriteria>(
158  "eps_optimal_absolute: 1.0 detailed_optimality_criteria { }");
159  const absl::Status status = ValidateTerminationCriteria(termination_criteria);
160  EXPECT_EQ(status.code(), absl::StatusCode::kInvalidArgument);
161  EXPECT_THAT(status.message(), HasSubstr("detailed_optimality_criteria"));
162 }
163 
164 TEST(ValidateTerminationCriteria, RelativeAndDetailedOptimalityCriteria) {
165  TerminationCriteria termination_criteria =
166  ParseTextOrDie<TerminationCriteria>(
167  "eps_optimal_relative: 1.0 detailed_optimality_criteria { }");
168  const absl::Status status = ValidateTerminationCriteria(termination_criteria);
169  EXPECT_EQ(status.code(), absl::StatusCode::kInvalidArgument);
170  EXPECT_THAT(status.message(), HasSubstr("detailed_optimality_criteria"));
171 }
172 
173 TEST(ValidateTerminationCriteria, BadEpsPriamlInfeasible) {
174  TerminationCriteria criteria_negative;
175  criteria_negative.set_eps_primal_infeasible(-1.0);
176  const absl::Status status_negative =
177  ValidateTerminationCriteria(criteria_negative);
178  EXPECT_EQ(status_negative.code(), absl::StatusCode::kInvalidArgument);
179  EXPECT_THAT(status_negative.message(), HasSubstr("eps_primal_infeasible"));
180 
181  TerminationCriteria criteria_nan;
182  criteria_nan.set_eps_primal_infeasible(
183  std::numeric_limits<double>::quiet_NaN());
184  const absl::Status status_nan = ValidateTerminationCriteria(criteria_nan);
185  EXPECT_EQ(status_nan.code(), absl::StatusCode::kInvalidArgument);
186  EXPECT_THAT(status_nan.message(), HasSubstr("eps_primal_infeasible"));
187 }
188 
189 TEST(ValidateTerminationCriteria, BadEpsDualInfeasible) {
190  TerminationCriteria criteria_negative;
191  criteria_negative.set_eps_dual_infeasible(-1.0);
192  const absl::Status status_negative =
193  ValidateTerminationCriteria(criteria_negative);
194  EXPECT_EQ(status_negative.code(), absl::StatusCode::kInvalidArgument);
195  EXPECT_THAT(status_negative.message(), HasSubstr("eps_dual_infeasible"));
196 
197  TerminationCriteria criteria_nan;
198  criteria_nan.set_eps_dual_infeasible(
199  std::numeric_limits<double>::quiet_NaN());
200  const absl::Status status_nan = ValidateTerminationCriteria(criteria_nan);
201  EXPECT_EQ(status_nan.code(), absl::StatusCode::kInvalidArgument);
202  EXPECT_THAT(status_nan.message(), HasSubstr("eps_dual_infeasible"));
203 }
204 
205 TEST(ValidateTerminationCriteria, BadTimeSecLimit) {
206  TerminationCriteria criteria_negative;
207  criteria_negative.set_time_sec_limit(-1.0);
208  const absl::Status status_negative =
209  ValidateTerminationCriteria(criteria_negative);
210  EXPECT_EQ(status_negative.code(), absl::StatusCode::kInvalidArgument);
211  EXPECT_THAT(status_negative.message(), HasSubstr("time_sec_limit"));
212 
213  TerminationCriteria criteria_nan;
214  criteria_nan.set_time_sec_limit(std::numeric_limits<double>::quiet_NaN());
215  const absl::Status status_nan = ValidateTerminationCriteria(criteria_nan);
216  EXPECT_EQ(status_nan.code(), absl::StatusCode::kInvalidArgument);
217  EXPECT_THAT(status_nan.message(), HasSubstr("time_sec_limit"));
218 }
219 
220 TEST(ValidateTerminationCriteria, BadIterationLimit) {
221  TerminationCriteria criteria;
222  criteria.set_iteration_limit(-1);
223  const absl::Status status = ValidateTerminationCriteria(criteria);
224  EXPECT_EQ(status.code(), absl::StatusCode::kInvalidArgument);
225  EXPECT_THAT(status.message(), HasSubstr("iteration_limit"));
226 }
227 
228 TEST(ValidateTerminationCriteria, BadKktMatrixPassLimit) {
229  TerminationCriteria criteria_negative;
230  criteria_negative.set_kkt_matrix_pass_limit(-1.0);
231  const absl::Status status_negative =
232  ValidateTerminationCriteria(criteria_negative);
233  EXPECT_EQ(status_negative.code(), absl::StatusCode::kInvalidArgument);
234  EXPECT_THAT(status_negative.message(), HasSubstr("kkt_matrix_pass_limit"));
235 
236  TerminationCriteria criteria_nan;
237  criteria_nan.set_kkt_matrix_pass_limit(
238  std::numeric_limits<double>::quiet_NaN());
239  const absl::Status status_nan = ValidateTerminationCriteria(criteria_nan);
240  EXPECT_EQ(status_nan.code(), absl::StatusCode::kInvalidArgument);
241  EXPECT_THAT(status_nan.message(), HasSubstr("kkt_matrix_pass_limit"));
242 }
243 
244 TEST(ValidateAdaptiveLinesearchParams, DefaultIsValid) {
245  AdaptiveLinesearchParams params;
246  const absl::Status status = ValidateAdaptiveLinesearchParams(params);
247  EXPECT_TRUE(status.ok()) << status;
248 }
249 
250 TEST(ValidateAdaptiveLinesearchParams, BadReductionExponent) {
251  AdaptiveLinesearchParams params_low;
252  params_low.set_step_size_reduction_exponent(0.0);
253  const absl::Status status_low = ValidateAdaptiveLinesearchParams(params_low);
254  EXPECT_EQ(status_low.code(), absl::StatusCode::kInvalidArgument);
255  EXPECT_THAT(status_low.message(), HasSubstr("step_size_reduction_exponent"));
256 
257  AdaptiveLinesearchParams params_nan;
258  params_nan.set_step_size_reduction_exponent(
259  std::numeric_limits<double>::quiet_NaN());
260  const absl::Status status_nan = ValidateAdaptiveLinesearchParams(params_nan);
261  EXPECT_EQ(status_nan.code(), absl::StatusCode::kInvalidArgument);
262  EXPECT_THAT(status_nan.message(), HasSubstr("step_size_reduction_exponent"));
263 }
264 
265 TEST(ValidateAdaptiveLinesearchParams, BadGrowthExponent) {
266  AdaptiveLinesearchParams params_low;
267  params_low.set_step_size_growth_exponent(0.0);
268  const absl::Status status_low = ValidateAdaptiveLinesearchParams(params_low);
269  EXPECT_EQ(status_low.code(), absl::StatusCode::kInvalidArgument);
270  EXPECT_THAT(status_low.message(), HasSubstr("step_size_growth_exponent"));
271 
272  AdaptiveLinesearchParams params_nan;
273  params_nan.set_step_size_growth_exponent(
274  std::numeric_limits<double>::quiet_NaN());
275  const absl::Status status_nan = ValidateAdaptiveLinesearchParams(params_nan);
276  EXPECT_EQ(status_nan.code(), absl::StatusCode::kInvalidArgument);
277  EXPECT_THAT(status_nan.message(), HasSubstr("step_size_growth_exponent"));
278 }
279 
280 TEST(ValidateMalitskyPockParams, DefaultIsValid) {
281  MalitskyPockParams params;
282  const absl::Status status = ValidateMalitskyPockParams(params);
283  EXPECT_TRUE(status.ok()) << status;
284 }
285 
286 TEST(ValidateMalitskyPockParams, BadDownscalingFactor) {
287  MalitskyPockParams params_low;
288  params_low.set_step_size_downscaling_factor(0.0);
289  const absl::Status status_low = ValidateMalitskyPockParams(params_low);
290  EXPECT_EQ(status_low.code(), absl::StatusCode::kInvalidArgument);
291  EXPECT_THAT(status_low.message(), HasSubstr("step_size_downscaling_factor"));
292 
293  MalitskyPockParams params_high;
294  params_high.set_step_size_downscaling_factor(1.0);
295  const absl::Status status_high = ValidateMalitskyPockParams(params_high);
296  EXPECT_EQ(status_high.code(), absl::StatusCode::kInvalidArgument);
297  EXPECT_THAT(status_high.message(), HasSubstr("step_size_downscaling_factor"));
298 
299  MalitskyPockParams params_nan;
300  params_nan.set_step_size_downscaling_factor(
301  std::numeric_limits<double>::quiet_NaN());
302  const absl::Status status_nan = ValidateMalitskyPockParams(params_nan);
303  EXPECT_EQ(status_nan.code(), absl::StatusCode::kInvalidArgument);
304  EXPECT_THAT(status_nan.message(), HasSubstr("step_size_downscaling_factor"));
305 }
306 
307 TEST(ValidateMalitskyPockParams, BadContractionFactor) {
308  MalitskyPockParams params_low;
309  params_low.set_linesearch_contraction_factor(0.0);
310  const absl::Status status_low = ValidateMalitskyPockParams(params_low);
311  EXPECT_EQ(status_low.code(), absl::StatusCode::kInvalidArgument);
312  EXPECT_THAT(status_low.message(), HasSubstr("linesearch_contraction_factor"));
313 
314  MalitskyPockParams params_high;
315  params_high.set_linesearch_contraction_factor(1.0);
316  const absl::Status status_high = ValidateMalitskyPockParams(params_high);
317  EXPECT_EQ(status_high.code(), absl::StatusCode::kInvalidArgument);
318  EXPECT_THAT(status_high.message(),
319  HasSubstr("linesearch_contraction_factor"));
320 
321  MalitskyPockParams params_nan;
322  params_nan.set_linesearch_contraction_factor(
323  std::numeric_limits<double>::quiet_NaN());
324  const absl::Status status_nan = ValidateMalitskyPockParams(params_nan);
325  EXPECT_EQ(status_nan.code(), absl::StatusCode::kInvalidArgument);
326  EXPECT_THAT(status_nan.message(), HasSubstr("linesearch_contraction_factor"));
327 }
328 
329 TEST(ValidateMalitskyPockParams, BadStepSizeInterpolation) {
330  MalitskyPockParams params_negative;
331  params_negative.set_step_size_interpolation(-1.0);
332  const absl::Status status_negative =
333  ValidateMalitskyPockParams(params_negative);
334  EXPECT_EQ(status_negative.code(), absl::StatusCode::kInvalidArgument);
335  EXPECT_THAT(status_negative.message(), HasSubstr("step_size_interpolation"));
336 
337  MalitskyPockParams params_nan;
338  params_nan.set_step_size_interpolation(
339  std::numeric_limits<double>::quiet_NaN());
340  const absl::Status status_nan = ValidateMalitskyPockParams(params_nan);
341  EXPECT_EQ(status_nan.code(), absl::StatusCode::kInvalidArgument);
342  EXPECT_THAT(status_nan.message(), HasSubstr("step_size_interpolation"));
343 }
344 
346  PrimalDualHybridGradientParams params;
347  const absl::Status status = ValidatePrimalDualHybridGradientParams(params);
348  EXPECT_TRUE(status.ok()) << status;
349 }
350 
351 TEST(ValidatePrimalDualHybridGradientParams, BadTerminationCriteria) {
352  PrimalDualHybridGradientParams params;
353  params.mutable_termination_criteria()->set_eps_dual_infeasible(-1.0);
354  const absl::Status status = ValidatePrimalDualHybridGradientParams(params);
355  EXPECT_EQ(status.code(), absl::StatusCode::kInvalidArgument);
356  EXPECT_THAT(status.message(), HasSubstr("eps_dual_infeasible"));
357 }
358 
360  PrimalDualHybridGradientParams params;
361  params.set_num_threads(0);
362  const absl::Status status = ValidatePrimalDualHybridGradientParams(params);
363  EXPECT_EQ(status.code(), absl::StatusCode::kInvalidArgument);
364  EXPECT_THAT(status.message(), HasSubstr("num_threads"));
365 }
366 
367 TEST(ValidatePrimalDualHybridGradientParams, BadVerbosityLevel) {
368  PrimalDualHybridGradientParams params;
369  params.set_verbosity_level(-1);
370  const absl::Status status = ValidatePrimalDualHybridGradientParams(params);
371  EXPECT_EQ(status.code(), absl::StatusCode::kInvalidArgument);
372  EXPECT_THAT(status.message(), HasSubstr("verbosity_level"));
373 }
374 
375 TEST(ValidatePrimalDualHybridGradientParams, BadMajorIterationFrequency) {
376  PrimalDualHybridGradientParams params;
377  params.set_major_iteration_frequency(0);
378  const absl::Status status = ValidatePrimalDualHybridGradientParams(params);
379  EXPECT_EQ(status.code(), absl::StatusCode::kInvalidArgument);
380  EXPECT_THAT(status.message(), HasSubstr("major_iteration_frequency"));
381 }
382 
383 TEST(ValidatePrimalDualHybridGradientParams, BadTerminationCheckFrequency) {
384  PrimalDualHybridGradientParams params;
385  params.set_termination_check_frequency(0);
386  const absl::Status status = ValidatePrimalDualHybridGradientParams(params);
387  EXPECT_EQ(status.code(), absl::StatusCode::kInvalidArgument);
388  EXPECT_THAT(status.message(), HasSubstr("termination_check_frequency"));
389 }
390 
391 TEST(ValidatePrimalDualHybridGradientParams, BadRestartStrategy) {
392  PrimalDualHybridGradientParams params;
393  params.set_restart_strategy(
394  PrimalDualHybridGradientParams::RESTART_STRATEGY_UNSPECIFIED);
395  const absl::Status status = ValidatePrimalDualHybridGradientParams(params);
396  EXPECT_EQ(status.code(), absl::StatusCode::kInvalidArgument);
397  EXPECT_THAT(status.message(), HasSubstr("restart_strategy"));
398 }
399 
400 TEST(ValidatePrimalDualHybridGradientParams, BadPrimalWeightUpdateSmoothing) {
401  PrimalDualHybridGradientParams params_high;
402  params_high.set_primal_weight_update_smoothing(1.1);
403  const absl::Status status_high =
405  EXPECT_EQ(status_high.code(), absl::StatusCode::kInvalidArgument);
406  EXPECT_THAT(status_high.message(),
407  HasSubstr("primal_weight_update_smoothing"));
408 
409  PrimalDualHybridGradientParams params_low;
410  params_low.set_primal_weight_update_smoothing(-0.1);
411  const absl::Status status_low =
413  EXPECT_EQ(status_low.code(), absl::StatusCode::kInvalidArgument);
414  EXPECT_THAT(status_low.message(),
415  HasSubstr("primal_weight_update_smoothing"));
416 
417  PrimalDualHybridGradientParams params_nan;
418  params_nan.set_primal_weight_update_smoothing(
419  std::numeric_limits<double>::quiet_NaN());
420  const absl::Status status_nan =
422  EXPECT_EQ(status_nan.code(), absl::StatusCode::kInvalidArgument);
423  EXPECT_THAT(status_nan.message(),
424  HasSubstr("primal_weight_update_smoothing"));
425 }
426 
427 TEST(ValidatePrimalDualHybridGradientParams, BadInitialPrimalWeight) {
428  PrimalDualHybridGradientParams params_negative;
429  params_negative.set_initial_primal_weight(-1.0);
430  const absl::Status status_negative =
432  EXPECT_EQ(status_negative.code(), absl::StatusCode::kInvalidArgument);
433  EXPECT_THAT(status_negative.message(), HasSubstr("initial_primal_weight"));
434 
435  PrimalDualHybridGradientParams params_nan;
436  params_nan.set_initial_primal_weight(
437  std::numeric_limits<double>::quiet_NaN());
438  const absl::Status status_nan =
440  EXPECT_EQ(status_nan.code(), absl::StatusCode::kInvalidArgument);
441  EXPECT_THAT(status_nan.message(), HasSubstr("initial_primal_weight"));
442 }
443 
444 TEST(ValidatePrimalDualHybridGradientParams, BadLInfRuizIterations) {
445  PrimalDualHybridGradientParams params;
446  params.set_l_inf_ruiz_iterations(-1);
447  const absl::Status status_low =
449  EXPECT_EQ(status_low.code(), absl::StatusCode::kInvalidArgument);
450  EXPECT_THAT(status_low.message(), HasSubstr("l_inf_ruiz_iterations"));
451 
452  params.set_l_inf_ruiz_iterations(1000);
453  const absl::Status status_high =
455  EXPECT_EQ(status_high.code(), absl::StatusCode::kInvalidArgument);
456  EXPECT_THAT(status_high.message(), HasSubstr("l_inf_ruiz_iterations"));
457 }
458 
459 TEST(ValidatePrimalDualHybridGradientParams, BadSufficientReductionForRestart) {
460  PrimalDualHybridGradientParams params_high;
461  params_high.set_sufficient_reduction_for_restart(1.0);
462  const absl::Status status_high =
464  EXPECT_EQ(status_high.code(), absl::StatusCode::kInvalidArgument);
465  EXPECT_THAT(status_high.message(),
466  HasSubstr("sufficient_reduction_for_restart"));
467 
468  PrimalDualHybridGradientParams params_low;
469  params_low.set_sufficient_reduction_for_restart(0.0);
470  const absl::Status status_low =
472  EXPECT_EQ(status_low.code(), absl::StatusCode::kInvalidArgument);
473  EXPECT_THAT(status_low.message(),
474  HasSubstr("sufficient_reduction_for_restart"));
475 
476  PrimalDualHybridGradientParams params_nan;
477  params_nan.set_sufficient_reduction_for_restart(
478  std::numeric_limits<double>::quiet_NaN());
479  const absl::Status status_nan =
481  EXPECT_EQ(status_nan.code(), absl::StatusCode::kInvalidArgument);
482  EXPECT_THAT(status_nan.message(),
483  HasSubstr("sufficient_reduction_for_restart"));
484 }
485 
486 TEST(ValidatePrimalDualHybridGradientParams, BadNecessaryReductionForRestart) {
487  PrimalDualHybridGradientParams params_high;
488  params_high.set_necessary_reduction_for_restart(1.0);
489  const absl::Status status_high =
491  EXPECT_EQ(status_high.code(), absl::StatusCode::kInvalidArgument);
492  EXPECT_THAT(status_high.message(),
493  HasSubstr("necessary_reduction_for_restart"));
494 
495  PrimalDualHybridGradientParams params_low;
496  params_low.set_sufficient_reduction_for_restart(0.5);
497  params_low.set_necessary_reduction_for_restart(0.4);
498  const absl::Status status_low =
500  EXPECT_EQ(status_low.code(), absl::StatusCode::kInvalidArgument);
501  EXPECT_THAT(status_low.message(),
502  HasSubstr("necessary_reduction_for_restart"));
503 
504  PrimalDualHybridGradientParams params_nan;
505  params_nan.set_necessary_reduction_for_restart(
506  std::numeric_limits<double>::quiet_NaN());
507  const absl::Status status_nan =
509  EXPECT_EQ(status_nan.code(), absl::StatusCode::kInvalidArgument);
510  EXPECT_THAT(status_nan.message(),
511  HasSubstr("necessary_reduction_for_restart"));
512 }
513 
514 TEST(ValidatePrimalDualHybridGradientParams, BadLinesearchRule) {
515  PrimalDualHybridGradientParams params;
516  params.set_linesearch_rule(
517  PrimalDualHybridGradientParams::LINESEARCH_RULE_UNSPECIFIED);
518  const absl::Status status = ValidatePrimalDualHybridGradientParams(params);
519  EXPECT_EQ(status.code(), absl::StatusCode::kInvalidArgument);
520  EXPECT_THAT(status.message(), HasSubstr("linesearch_rule"));
521 }
522 
523 TEST(ValidatePrimalDualHybridGradientParams, BadAdaptiveLinesearchParameters) {
524  PrimalDualHybridGradientParams params;
525  params.mutable_adaptive_linesearch_parameters()
526  ->set_step_size_reduction_exponent(-1.0);
527  const absl::Status status = ValidatePrimalDualHybridGradientParams(params);
528  EXPECT_EQ(status.code(), absl::StatusCode::kInvalidArgument);
529  EXPECT_THAT(status.message(), HasSubstr("step_size_reduction_exponent"));
530 }
531 
532 TEST(ValidatePrimalDualHybridGradientParams, BadMalitskyPockParameters) {
533  PrimalDualHybridGradientParams params;
534  params.mutable_malitsky_pock_parameters()->set_linesearch_contraction_factor(
535  -1.0);
536  const absl::Status status = ValidatePrimalDualHybridGradientParams(params);
537  EXPECT_EQ(status.code(), absl::StatusCode::kInvalidArgument);
538  EXPECT_THAT(status.message(), HasSubstr("linesearch_contraction_factor"));
539 }
540 
541 TEST(ValidatePrimalDualHybridGradientParams, BadInitialStepSizeScaling) {
542  PrimalDualHybridGradientParams params_negative;
543  params_negative.set_initial_step_size_scaling(-1.0);
544  const absl::Status status_negative =
546  EXPECT_EQ(status_negative.code(), absl::StatusCode::kInvalidArgument);
547  EXPECT_THAT(status_negative.message(),
548  HasSubstr("initial_step_size_scaling"));
549 
550  PrimalDualHybridGradientParams params_nan;
551  params_nan.set_initial_step_size_scaling(
552  std::numeric_limits<double>::quiet_NaN());
553  const absl::Status status_nan =
555  EXPECT_EQ(status_nan.code(), absl::StatusCode::kInvalidArgument);
556  EXPECT_THAT(status_nan.message(), HasSubstr("initial_step_size_scaling"));
557 }
558 
560  BadInfiniteConstraintBoundThreshold) {
561  PrimalDualHybridGradientParams params_negative;
562  params_negative.set_infinite_constraint_bound_threshold(-1.0);
563  const absl::Status status_negative =
565  EXPECT_EQ(status_negative.code(), absl::StatusCode::kInvalidArgument);
566  EXPECT_THAT(status_negative.message(),
567  HasSubstr("infinite_constraint_bound_threshold"));
568 
569  PrimalDualHybridGradientParams params_nan;
570  params_nan.set_infinite_constraint_bound_threshold(
571  std::numeric_limits<double>::quiet_NaN());
572  const absl::Status status_nan =
574  EXPECT_EQ(status_nan.code(), absl::StatusCode::kInvalidArgument);
575  EXPECT_THAT(status_nan.message(),
576  HasSubstr("infinite_constraint_bound_threshold"));
577 }
578 
580  BadDiagonalTrustRegionSolverTolerance) {
581  PrimalDualHybridGradientParams params_negative;
582  params_negative.set_diagonal_qp_trust_region_solver_tolerance(-1.0);
583  const absl::Status status_negative =
585  EXPECT_EQ(status_negative.code(), absl::StatusCode::kInvalidArgument);
586  EXPECT_THAT(status_negative.message(),
587  HasSubstr("diagonal_qp_trust_region_solver_tolerance"));
588 
589  PrimalDualHybridGradientParams params_nan;
590  params_nan.set_diagonal_qp_trust_region_solver_tolerance(
591  std::numeric_limits<double>::quiet_NaN());
592  const absl::Status status_nan =
594  EXPECT_EQ(status_nan.code(), absl::StatusCode::kInvalidArgument);
595  EXPECT_THAT(status_nan.message(),
596  HasSubstr("diagonal_qp_trust_region_solver_tolerance"));
597 }
598 
599 } // namespace
600 } // namespace operations_research::pdlp
absl::Status status
Definition: g_gurobi.cc:41
T ParseTextOrDie(const std::string &input)
Definition: protobuf_util.h:77
absl::Status ValidateTerminationCriteria(const TerminationCriteria &criteria)
absl::Status ValidateMalitskyPockParams(const MalitskyPockParams &params)
absl::Status ValidateAdaptiveLinesearchParams(const AdaptiveLinesearchParams &params)
absl::Status ValidatePrimalDualHybridGradientParams(const PrimalDualHybridGradientParams &params)
TEST(LinearAssignmentTest, NullMatrix)