Add absl::Stringify for protobufs in base/logging.h; fixes all around
This commit is contained in:
@@ -193,6 +193,7 @@ cc_library(
|
||||
"//ortools/base:hash",
|
||||
"//ortools/base:map_util",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/container:btree",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -204,6 +205,7 @@ cc_library(
|
||||
"//ortools/base",
|
||||
"//ortools/base:file",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/container:btree",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -215,6 +217,7 @@ cc_library(
|
||||
"//ortools/base",
|
||||
"//ortools/base:map_util",
|
||||
"//ortools/constraint_solver:cp",
|
||||
"@com_google_absl//absl/container:btree",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
#ifndef OR_TOOLS_EXAMPLES_FAP_MODEL_PRINTER_H_
|
||||
#define OR_TOOLS_EXAMPLES_FAP_MODEL_PRINTER_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/container/btree_map.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "examples/cpp/fap_parser.h"
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace operations_research {
|
||||
// Prints the instance of the Frequency Assignment Problem.
|
||||
class FapModelPrinter {
|
||||
public:
|
||||
FapModelPrinter(const std::map<int, FapVariable>& variables,
|
||||
FapModelPrinter(const absl::btree_map<int, FapVariable>& variables,
|
||||
const std::vector<FapConstraint>& constraints,
|
||||
const std::string& objective, const std::vector<int>& values);
|
||||
~FapModelPrinter();
|
||||
@@ -42,14 +42,14 @@ class FapModelPrinter {
|
||||
void PrintFapValues();
|
||||
|
||||
private:
|
||||
const std::map<int, FapVariable> variables_;
|
||||
const absl::btree_map<int, FapVariable> variables_;
|
||||
const std::vector<FapConstraint> constraints_;
|
||||
const std::string objective_;
|
||||
const std::vector<int> values_;
|
||||
DISALLOW_COPY_AND_ASSIGN(FapModelPrinter);
|
||||
};
|
||||
|
||||
FapModelPrinter::FapModelPrinter(const std::map<int, FapVariable>& variables,
|
||||
FapModelPrinter::FapModelPrinter(const absl::btree_map<int, FapVariable>& variables,
|
||||
const std::vector<FapConstraint>& constraints,
|
||||
const std::string& objective,
|
||||
const std::vector<int>& values)
|
||||
|
||||
@@ -110,7 +110,7 @@ struct FapConstraint {
|
||||
struct FapComponent {
|
||||
// Fields:
|
||||
// the variable set of the sub-problem, i.e. the vertices of the component
|
||||
std::map<int, FapVariable> variables;
|
||||
absl::btree_map<int, FapVariable> variables;
|
||||
|
||||
// the constraint set of the sub-problem, i.e. the edges of the component
|
||||
std::vector<FapConstraint> constraints;
|
||||
@@ -124,7 +124,7 @@ class VariableParser {
|
||||
explicit VariableParser(const std::string& data_directory);
|
||||
~VariableParser();
|
||||
|
||||
const std::map<int, FapVariable>& variables() const { return variables_; }
|
||||
const absl::btree_map<int, FapVariable>& variables() const { return variables_; }
|
||||
|
||||
void Parse();
|
||||
|
||||
@@ -133,7 +133,7 @@ class VariableParser {
|
||||
// A map is used because in the model, the variables have ids which may not
|
||||
// be consecutive, may be very sparse and don't have a specific upper-bound.
|
||||
// The key of the map, is the link's id.
|
||||
std::map<int, FapVariable> variables_;
|
||||
absl::btree_map<int, FapVariable> variables_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(VariableParser);
|
||||
};
|
||||
@@ -146,7 +146,7 @@ class DomainParser {
|
||||
explicit DomainParser(const std::string& data_directory);
|
||||
~DomainParser();
|
||||
|
||||
const std::map<int, std::vector<int> >& domains() const { return domains_; }
|
||||
const absl::btree_map<int, std::vector<int> >& domains() const { return domains_; }
|
||||
|
||||
void Parse();
|
||||
|
||||
@@ -155,7 +155,7 @@ class DomainParser {
|
||||
// A map is used because in the model, the ids of the different available
|
||||
// domains may be random values, since they are used as names. The key of the
|
||||
// map is the subset's id.
|
||||
std::map<int, std::vector<int> > domains_;
|
||||
absl::btree_map<int, std::vector<int> > domains_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DomainParser);
|
||||
};
|
||||
@@ -216,18 +216,18 @@ int strtoint32(const std::string& word) {
|
||||
|
||||
// Function that finds the disjoint sub-graphs of the graph of the instance.
|
||||
void FindComponents(const std::vector<FapConstraint>& constraints,
|
||||
const std::map<int, FapVariable>& variables,
|
||||
const absl::btree_map<int, FapVariable>& variables,
|
||||
const int maximum_variable_id,
|
||||
absl::flat_hash_map<int, FapComponent>* components);
|
||||
|
||||
// Function that computes the impact of a constraint.
|
||||
int EvaluateConstraintImpact(const std::map<int, FapVariable>& variables,
|
||||
int EvaluateConstraintImpact(const absl::btree_map<int, FapVariable>& variables,
|
||||
const int max_weight_cost,
|
||||
const FapConstraint constraint);
|
||||
|
||||
// Function that parses an instance of frequency assignment problem.
|
||||
void ParseInstance(const std::string& data_directory, bool find_components,
|
||||
std::map<int, FapVariable>* variables,
|
||||
absl::btree_map<int, FapVariable>* variables,
|
||||
std::vector<FapConstraint>* constraints,
|
||||
std::string* objective, std::vector<int>* frequencies,
|
||||
absl::flat_hash_map<int, FapComponent>* components);
|
||||
@@ -400,7 +400,7 @@ void ParametersParser::Parse() {
|
||||
|
||||
// TODO(user): Make FindComponents linear instead of quadratic.
|
||||
void FindComponents(const std::vector<FapConstraint>& constraints,
|
||||
const std::map<int, FapVariable>& variables,
|
||||
const absl::btree_map<int, FapVariable>& variables,
|
||||
const int maximum_variable_id,
|
||||
absl::flat_hash_map<int, FapComponent>* components) {
|
||||
std::vector<int> in_component(maximum_variable_id + 1, -1);
|
||||
@@ -485,7 +485,7 @@ void FindComponents(const std::vector<FapConstraint>& constraints,
|
||||
}
|
||||
}
|
||||
|
||||
int EvaluateConstraintImpact(const std::map<int, FapVariable>& variables,
|
||||
int EvaluateConstraintImpact(const absl::btree_map<int, FapVariable>& variables,
|
||||
const int max_weight_cost,
|
||||
const FapConstraint constraint) {
|
||||
const FapVariable& variable1 =
|
||||
@@ -509,7 +509,7 @@ int EvaluateConstraintImpact(const std::map<int, FapVariable>& variables,
|
||||
}
|
||||
|
||||
void ParseInstance(const std::string& data_directory, bool find_components,
|
||||
std::map<int, FapVariable>* variables,
|
||||
absl::btree_map<int, FapVariable>* variables,
|
||||
std::vector<FapConstraint>* constraints,
|
||||
std::string* objective, std::vector<int>* frequencies,
|
||||
absl::flat_hash_map<int, FapComponent>* components) {
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
#define OR_TOOLS_EXAMPLES_FAP_UTILITIES_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/container/btree_map.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "examples/cpp/fap_parser.h"
|
||||
#include "ortools/base/logging.h"
|
||||
@@ -36,13 +36,13 @@ namespace operations_research {
|
||||
bool CheckConstraintSatisfaction(
|
||||
const std::vector<FapConstraint>& data_constraints,
|
||||
const std::vector<int>& variables,
|
||||
const std::map<int, int>& index_from_key);
|
||||
const absl::btree_map<int, int>& index_from_key);
|
||||
|
||||
// Checks if the solution given from the Solver has not modified the values of
|
||||
// the variables that were initially assigned and denoted as hard in var.txt.
|
||||
bool CheckVariablePosition(const std::map<int, FapVariable>& data_variables,
|
||||
bool CheckVariablePosition(const absl::btree_map<int, FapVariable>& data_variables,
|
||||
const std::vector<int>& variables,
|
||||
const std::map<int, int>& index_from_key);
|
||||
const absl::btree_map<int, int>& index_from_key);
|
||||
|
||||
// Counts the number of different values in the variable vector.
|
||||
int NumberOfAssignedValues(const std::vector<int>& variables);
|
||||
@@ -54,26 +54,26 @@ void PrintElapsedTime(const int64_t time1, const int64_t time2);
|
||||
void PrintResultsHard(SolutionCollector* const collector,
|
||||
const std::vector<IntVar*>& variables,
|
||||
IntVar* const objective_var,
|
||||
const std::map<int, FapVariable>& data_variables,
|
||||
const absl::btree_map<int, FapVariable>& data_variables,
|
||||
const std::vector<FapConstraint>& data_constraints,
|
||||
const std::map<int, int>& index_from_key,
|
||||
const absl::btree_map<int, int>& index_from_key,
|
||||
const std::vector<int>& key_from_index);
|
||||
|
||||
// Prints the solution found by the Soft Solver for unfeasible instances.
|
||||
void PrintResultsSoft(SolutionCollector* const collector,
|
||||
const std::vector<IntVar*>& variables,
|
||||
IntVar* const total_cost,
|
||||
const std::map<int, FapVariable>& hard_variables,
|
||||
const absl::btree_map<int, FapVariable>& hard_variables,
|
||||
const std::vector<FapConstraint>& hard_constraints,
|
||||
const std::map<int, FapVariable>& soft_variables,
|
||||
const absl::btree_map<int, FapVariable>& soft_variables,
|
||||
const std::vector<FapConstraint>& soft_constraints,
|
||||
const std::map<int, int>& index_from_key,
|
||||
const absl::btree_map<int, int>& index_from_key,
|
||||
const std::vector<int>& key_from_index);
|
||||
|
||||
bool CheckConstraintSatisfaction(
|
||||
const std::vector<FapConstraint>& data_constraints,
|
||||
const std::vector<int>& variables,
|
||||
const std::map<int, int>& index_from_key) {
|
||||
const absl::btree_map<int, int>& index_from_key) {
|
||||
bool status = true;
|
||||
for (const FapConstraint& ct : data_constraints) {
|
||||
const int index1 = gtl::FindOrDie(index_from_key, ct.variable1);
|
||||
@@ -101,9 +101,9 @@ bool CheckConstraintSatisfaction(
|
||||
return status;
|
||||
}
|
||||
|
||||
bool CheckVariablePosition(const std::map<int, FapVariable>& data_variables,
|
||||
bool CheckVariablePosition(const absl::btree_map<int, FapVariable>& data_variables,
|
||||
const std::vector<int>& variables,
|
||||
const std::map<int, int>& index_from_key) {
|
||||
const absl::btree_map<int, int>& index_from_key) {
|
||||
bool status = true;
|
||||
for (const auto& it : data_variables) {
|
||||
const int index = gtl::FindOrDie(index_from_key, it.first);
|
||||
@@ -135,9 +135,9 @@ void PrintElapsedTime(const int64_t time1, const int64_t time2) {
|
||||
void PrintResultsHard(SolutionCollector* const collector,
|
||||
const std::vector<IntVar*>& variables,
|
||||
IntVar* const objective_var,
|
||||
const std::map<int, FapVariable>& data_variables,
|
||||
const absl::btree_map<int, FapVariable>& data_variables,
|
||||
const std::vector<FapConstraint>& data_constraints,
|
||||
const std::map<int, int>& index_from_key,
|
||||
const absl::btree_map<int, int>& index_from_key,
|
||||
const std::vector<int>& key_from_index) {
|
||||
LOG(INFO) << "Printing...";
|
||||
LOG(INFO) << "Number of Solutions: " << collector->solution_count();
|
||||
@@ -175,11 +175,11 @@ void PrintResultsHard(SolutionCollector* const collector,
|
||||
void PrintResultsSoft(SolutionCollector* const collector,
|
||||
const std::vector<IntVar*>& variables,
|
||||
IntVar* const total_cost,
|
||||
const std::map<int, FapVariable>& hard_variables,
|
||||
const absl::btree_map<int, FapVariable>& hard_variables,
|
||||
const std::vector<FapConstraint>& hard_constraints,
|
||||
const std::map<int, FapVariable>& soft_variables,
|
||||
const absl::btree_map<int, FapVariable>& soft_variables,
|
||||
const std::vector<FapConstraint>& soft_constraints,
|
||||
const std::map<int, int>& index_from_key,
|
||||
const absl::btree_map<int, int>& index_from_key,
|
||||
const std::vector<int>& key_from_index) {
|
||||
LOG(INFO) << "Printing...";
|
||||
LOG(INFO) << "Number of Solutions: " << collector->solution_count();
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -172,7 +171,7 @@ class OrderingBuilder : public DecisionBuilder {
|
||||
public:
|
||||
enum Order { LESS = -1, EQUAL = 0, GREATER = 1 };
|
||||
|
||||
OrderingBuilder(const std::map<int, FapVariable>& data_variables,
|
||||
OrderingBuilder(const absl::btree_map<int, FapVariable>& data_variables,
|
||||
const std::vector<FapConstraint>& data_constraints,
|
||||
const std::vector<IntVar*>& variables,
|
||||
const std::vector<IntVar*>& violated_constraints,
|
||||
@@ -310,7 +309,7 @@ class OrderingBuilder : public DecisionBuilder {
|
||||
}
|
||||
|
||||
// Passed as arguments from the function that creates the Decision Builder.
|
||||
const std::map<int, FapVariable> data_variables_;
|
||||
const absl::btree_map<int, FapVariable> data_variables_;
|
||||
const std::vector<FapConstraint> data_constraints_;
|
||||
const std::vector<IntVar*> variables_;
|
||||
const std::vector<IntVar*> violated_constraints_;
|
||||
@@ -375,7 +374,7 @@ int64_t ValueEvaluator(
|
||||
// The variables which participate in more constraints and have the
|
||||
// smaller domain should be in higher priority for assignment.
|
||||
int64_t VariableEvaluator(const std::vector<int>& key_from_index,
|
||||
const std::map<int, FapVariable>& data_variables,
|
||||
const absl::btree_map<int, FapVariable>& data_variables,
|
||||
int64_t variable_index) {
|
||||
FapVariable variable =
|
||||
gtl::FindOrDie(data_variables, key_from_index[variable_index]);
|
||||
@@ -384,7 +383,7 @@ int64_t VariableEvaluator(const std::vector<int>& key_from_index,
|
||||
}
|
||||
|
||||
// Creates the variables of the solver from the parsed data.
|
||||
void CreateModelVariables(const std::map<int, FapVariable>& data_variables,
|
||||
void CreateModelVariables(const absl::btree_map<int, FapVariable>& data_variables,
|
||||
Solver* solver, std::vector<IntVar*>* model_variables,
|
||||
absl::btree_map<int, int>* index_from_key,
|
||||
std::vector<int>* key_from_index) {
|
||||
@@ -516,7 +515,7 @@ void CreateAdditionalMonitors(OptimizeVar* const objective, Solver* solver,
|
||||
// instances of the problem with objective either the minimization of
|
||||
// the largest frequency assigned or the minimization of the number
|
||||
// of frequencies used to the solution.
|
||||
void HardFapSolver(const std::map<int, FapVariable>& data_variables,
|
||||
void HardFapSolver(const absl::btree_map<int, FapVariable>& data_variables,
|
||||
const std::vector<FapConstraint>& data_constraints,
|
||||
absl::string_view data_objective,
|
||||
const std::vector<int>& values) {
|
||||
@@ -631,9 +630,9 @@ void HardFapSolver(const std::map<int, FapVariable>& data_variables,
|
||||
}
|
||||
|
||||
// Splits variables of the instance to hard and soft.
|
||||
void SplitVariablesHardSoft(const std::map<int, FapVariable>& data_variables,
|
||||
std::map<int, FapVariable>* hard_variables,
|
||||
std::map<int, FapVariable>* soft_variables) {
|
||||
void SplitVariablesHardSoft(const absl::btree_map<int, FapVariable>& data_variables,
|
||||
absl::btree_map<int, FapVariable>* hard_variables,
|
||||
absl::btree_map<int, FapVariable>* soft_variables) {
|
||||
for (const auto& it : data_variables) {
|
||||
if (it.second.initial_position != -1) {
|
||||
if (it.second.hard) {
|
||||
@@ -665,7 +664,7 @@ void SplitConstraintHardSoft(const std::vector<FapConstraint>& data_constraints,
|
||||
// Penalize the modification of the initial position of soft variable of
|
||||
// the instance.
|
||||
void PenalizeVariablesViolation(
|
||||
const std::map<int, FapVariable>& soft_variables,
|
||||
const absl::btree_map<int, FapVariable>& soft_variables,
|
||||
const absl::btree_map<int, int>& index_from_key,
|
||||
const std::vector<IntVar*>& variables, std::vector<IntVar*>* cost,
|
||||
Solver* solver) {
|
||||
@@ -729,7 +728,7 @@ void PenalizeConstraintsViolation(
|
||||
// The Soft Solver is dealing with the optimization of unfeasible instances
|
||||
// and aims to minimize the total cost of violated constraints. Returning value
|
||||
// equal to 0 denotes that the instance is feasible.
|
||||
int SoftFapSolver(const std::map<int, FapVariable>& data_variables,
|
||||
int SoftFapSolver(const absl::btree_map<int, FapVariable>& data_variables,
|
||||
const std::vector<FapConstraint>& data_constraints,
|
||||
absl::string_view data_objective,
|
||||
const std::vector<int>& values) {
|
||||
@@ -737,8 +736,8 @@ int SoftFapSolver(const std::map<int, FapVariable>& data_variables,
|
||||
std::vector<SearchMonitor*> monitors;
|
||||
|
||||
// Split variables to hard and soft.
|
||||
std::map<int, FapVariable> hard_variables;
|
||||
std::map<int, FapVariable> soft_variables;
|
||||
absl::btree_map<int, FapVariable> hard_variables;
|
||||
absl::btree_map<int, FapVariable> soft_variables;
|
||||
SplitVariablesHardSoft(data_variables, &hard_variables, &soft_variables);
|
||||
|
||||
// Order instance's constraints by their impact and then split them to
|
||||
@@ -833,7 +832,7 @@ int SoftFapSolver(const std::map<int, FapVariable>& data_variables,
|
||||
return violation_sum;
|
||||
}
|
||||
|
||||
void SolveProblem(const std::map<int, FapVariable>& variables,
|
||||
void SolveProblem(const absl::btree_map<int, FapVariable>& variables,
|
||||
const std::vector<FapConstraint>& constraints,
|
||||
const std::string& objective, const std::vector<int>& values,
|
||||
bool soft) {
|
||||
@@ -870,7 +869,7 @@ int main(int argc, char** argv) {
|
||||
LOG(INFO) << "Solving instance in directory "
|
||||
<< absl::GetFlag(FLAGS_directory);
|
||||
// Parse!
|
||||
std::map<int, operations_research::FapVariable> variables;
|
||||
absl::btree_map<int, operations_research::FapVariable> variables;
|
||||
std::vector<operations_research::FapConstraint> constraints;
|
||||
std::string objective;
|
||||
std::vector<int> values;
|
||||
|
||||
@@ -70,10 +70,8 @@ using operations_research::glop::ToDouble;
|
||||
void ReadGlopParameters(GlopParameters* parameters) {
|
||||
if (!absl::GetFlag(FLAGS_params_file).empty()) {
|
||||
std::string params;
|
||||
operations_research::file::GetContents(
|
||||
absl::GetFlag(FLAGS_params_file), ¶ms,
|
||||
operations_research::file::Defaults())
|
||||
.CheckSuccess();
|
||||
CHECK_OK(file::GetContents(absl::GetFlag(FLAGS_params_file), ¶ms,
|
||||
file::Defaults()));
|
||||
CHECK(TextFormat::ParseFromString(params, parameters)) << params;
|
||||
}
|
||||
if (!absl::GetFlag(FLAGS_params).empty()) {
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
#include "ortools/base/file.h"
|
||||
#include "ortools/base/init_google.h"
|
||||
#include "ortools/base/logging.h"
|
||||
#include "ortools/pdlp/iteration_stats.h"
|
||||
#include "ortools/pdlp/primal_dual_hybrid_gradient.h"
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
#include "ortools/base/commandlineflags.h"
|
||||
#include "ortools/base/file.h"
|
||||
#include "ortools/base/integral_types.h"
|
||||
#include "ortools/base/init_google.h"
|
||||
#include "ortools/base/logging.h"
|
||||
#include "ortools/base/timer.h"
|
||||
#include "ortools/linear_solver/linear_solver.h"
|
||||
|
||||
@@ -319,6 +319,7 @@ cc_library(
|
||||
"@com_google_absl//absl/memory",
|
||||
"@com_google_absl//absl/status",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_protobuf//:protobuf",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -363,19 +364,6 @@ cc_library(
|
||||
deps = [],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "mock_log",
|
||||
hdrs = ["mock-log.h"],
|
||||
deps = [
|
||||
":logging",
|
||||
":macros",
|
||||
"@com_google_absl//absl/base",
|
||||
"@com_google_absl//absl/log:log_sink",
|
||||
"@com_google_absl//absl/log:log_sink_registry",
|
||||
"@com_google_googletest//:gtest",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "murmur",
|
||||
hdrs = ["murmur.h"],
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "google/protobuf/message.h"
|
||||
#include "ortools/base/macros.h"
|
||||
#include "ortools/base/vlog.h"
|
||||
|
||||
@@ -48,14 +49,15 @@ enum LogSeverity {
|
||||
};
|
||||
} // namespace google
|
||||
|
||||
// Compatibility layer for mock_log
|
||||
namespace base_logging {
|
||||
enum LogSeverity {
|
||||
INFO = static_cast<int>(absl::LogSeverity::kInfo),
|
||||
WARNING = static_cast<int>(absl::LogSeverity::kWarning),
|
||||
ERROR = static_cast<int>(absl::LogSeverity::kError),
|
||||
FATAL = static_cast<int>(absl::LogSeverity::kFatal),
|
||||
};
|
||||
// Implementation of the `AbslStringify` interface. This adds `DebugString()`
|
||||
// to the sink. Do not rely on exact format.
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
template <typename Sink>
|
||||
void AbslStringify(Sink& sink, const Message& msg) {
|
||||
sink.Append(msg.DebugString());
|
||||
}
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // OR_TOOLS_BASE_LOGGING_H_
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
// Copyright 2010-2022 Google LLC
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef OR_TOOLS_BASE_MOCK_LOG_H_
|
||||
#define OR_TOOLS_BASE_MOCK_LOG_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "absl/log/log_sink.h"
|
||||
#include "absl/log/log_sink_registry.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "ortools/base/logging.h"
|
||||
#include "ortools/base/macros.h"
|
||||
|
||||
namespace testing {
|
||||
|
||||
// A ScopedMockLog object intercepts LOG() messages issued during its
|
||||
// lifespan. Using this together with gMock, it's very easy to test
|
||||
// how a piece of code calls LOG().
|
||||
|
||||
// Used only for invoking the single-argument ScopedMockLog
|
||||
// constructor. Do not use the type LogCapturingState_ directly.
|
||||
// It's OK and expected for a user to use the enum value
|
||||
// kDoNotCaptureLogsYet.
|
||||
enum LogCapturingState_ { kDoNotCaptureLogsYet };
|
||||
|
||||
class ScopedMockLog : public absl::LogSink {
|
||||
public:
|
||||
// A user can use the syntax
|
||||
// ScopedMockLog log(kDoNotCaptureLogsYet);
|
||||
// to invoke this constructor. A ScopedMockLog object created this way
|
||||
// does not start capturing logs until StartCapturingLogs() is called.
|
||||
explicit ScopedMockLog(LogCapturingState_ /* dummy */)
|
||||
: is_capturing_logs_(false) {}
|
||||
|
||||
// When the object is destructed, it stops intercepting logs.
|
||||
~ScopedMockLog() override {
|
||||
if (is_capturing_logs_) StopCapturingLogs();
|
||||
}
|
||||
|
||||
// Starts log capturing if the object isn't already doing so.
|
||||
// Otherwise crashes. Usually this method is called in the same
|
||||
// thread that created this object. It is the user's responsibility
|
||||
// to not call this method if another thread may be calling it or
|
||||
// StopCapturingLogs() at the same time.
|
||||
void StartCapturingLogs() {
|
||||
// We don't use CHECK(), which can generate a new LOG message, and
|
||||
// thus can confuse ScopedMockLog objects or other registered
|
||||
// LogSinks.
|
||||
ABSL_RAW_CHECK(
|
||||
!is_capturing_logs_,
|
||||
"StartCapturingLogs() can be called only when the ScopedMockLog "
|
||||
"object is not capturing logs.");
|
||||
|
||||
is_capturing_logs_ = true;
|
||||
absl::AddLogSink(this);
|
||||
}
|
||||
|
||||
// Stops log capturing if the object is capturing logs. Otherwise
|
||||
// crashes. Usually this method is called in the same thread that
|
||||
// created this object. It is the user's responsibility to not call
|
||||
// this method if another thread may be calling it or
|
||||
// StartCapturingLogs() at the same time.
|
||||
void StopCapturingLogs() {
|
||||
// We don't use CHECK(), which can generate a new LOG message, and
|
||||
// thus can confuse ScopedMockLog objects or other registered
|
||||
// LogSinks.
|
||||
ABSL_RAW_CHECK(
|
||||
is_capturing_logs_,
|
||||
"StopCapturingLogs() can be called only when the ScopedMockLog "
|
||||
"object is capturing logs.");
|
||||
|
||||
is_capturing_logs_ = false;
|
||||
absl::RemoveLogSink(this);
|
||||
}
|
||||
|
||||
// Implements the mock method:
|
||||
//
|
||||
// void Log(LogSeverity severity, const string& file_path,
|
||||
// const string& message);
|
||||
//
|
||||
// The second argument to Log() is the full path of the source file
|
||||
// in which the LOG() was issued.
|
||||
//
|
||||
// Note, that in a multi-threaded environment, all LOG() messages from a
|
||||
// single thread will be handled in sequence, but that cannot be guaranteed
|
||||
// for messages from different threads. In fact, if the same or multiple
|
||||
// expectations are matched on two threads concurrently, their actions will
|
||||
// be executed concurrently as well and may interleave.
|
||||
MOCK_METHOD(void, Log,
|
||||
(absl::LogSeverity severity, const std::string& file_path,
|
||||
const std::string& message));
|
||||
|
||||
private:
|
||||
// Implements the Send() virtual function in class LogSink.
|
||||
// Whenever a LOG() statement is executed, this function will be
|
||||
// invoked with information presented in the LOG().
|
||||
void Send(const absl::LogEntry& entry) override {
|
||||
// We are only interested in the log severity, full file name, and
|
||||
// log message.
|
||||
Log(static_cast<absl::LogSeverity>(entry.log_severity()),
|
||||
std::string(entry.source_filename()),
|
||||
std::string(entry.text_message()));
|
||||
}
|
||||
|
||||
bool is_capturing_logs_;
|
||||
};
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#endif // OR_TOOLS_BASE_MOCK_LOG_H_
|
||||
@@ -131,6 +131,10 @@ void RevisedSimplex::NotifyThatMatrixIsUnchangedForNextSolve() {
|
||||
notify_that_matrix_is_unchanged_ = true;
|
||||
}
|
||||
|
||||
void RevisedSimplex::NotifyThatMatrixIsChangedForNextSolve() {
|
||||
notify_that_matrix_is_unchanged_ = false;
|
||||
}
|
||||
|
||||
Status RevisedSimplex::Solve(const LinearProgram& lp, TimeLimit* time_limit) {
|
||||
SCOPED_TIME_STAT(&function_stats_);
|
||||
DCHECK(lp.IsCleanedUp());
|
||||
|
||||
@@ -166,6 +166,7 @@ class RevisedSimplex {
|
||||
// matrices. Note that this call will be ignored if Solve() was never called
|
||||
// or if ClearStateForNextSolve() was called.
|
||||
void NotifyThatMatrixIsUnchangedForNextSolve();
|
||||
void NotifyThatMatrixIsChangedForNextSolve();
|
||||
|
||||
// Getters to retrieve all the information computed by the last Solve().
|
||||
RowIndex GetProblemNumRows() const;
|
||||
|
||||
@@ -150,8 +150,8 @@ MPSolver::ResultStatus HighsInterface::Solve(const MPSolverParameters& param) {
|
||||
// The solution must be marked as synchronized even when no solution exists.
|
||||
sync_status_ = SOLUTION_SYNCHRONIZED;
|
||||
result_status_ = static_cast<MPSolver::ResultStatus>(response->status());
|
||||
LOG_IF(DFATAL, !response->has_solver_specific_info())
|
||||
<< response->DebugString();
|
||||
LOG_IF(ERROR, DEBUG_MODE && !response->has_solver_specific_info())
|
||||
<< *response;
|
||||
// if (!solve_log_.ParseFromString(response->solver_specific_info())) {
|
||||
// LOG(DFATAL) << "Unable to parse Highs's SolveLog from
|
||||
// solver_specific_info";
|
||||
|
||||
@@ -152,8 +152,8 @@ MPSolver::ResultStatus PdlpInterface::Solve(const MPSolverParameters& param) {
|
||||
// The solution must be marked as synchronized even when no solution exists.
|
||||
sync_status_ = SOLUTION_SYNCHRONIZED;
|
||||
result_status_ = static_cast<MPSolver::ResultStatus>(response->status());
|
||||
LOG_IF(DFATAL, !response->has_solver_specific_info())
|
||||
<< response->DebugString();
|
||||
LOG_IF(FATAL, DEBUG_MODE && !response->has_solver_specific_info())
|
||||
<< *response;
|
||||
if (!solve_log_.ParseFromString(response->solver_specific_info())) {
|
||||
LOG(DFATAL) << "Unable to parse PDLP's SolveLog from solver_specific_info";
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ bool VbpParser::ParseFile(const std::string& data_filename) {
|
||||
|
||||
// Checks status.
|
||||
if (load_status_ == ERROR_FOUND) {
|
||||
LOG(INFO) << vbp_.DebugString();
|
||||
LOG(INFO) << vbp_;
|
||||
return false;
|
||||
}
|
||||
return vbp_.item_size() == num_declared_items_;
|
||||
|
||||
@@ -96,10 +96,11 @@ cc_test(
|
||||
],
|
||||
deps = [
|
||||
":carp_parser",
|
||||
"//ortools/base:mock_log",
|
||||
"//ortools/base:path",
|
||||
"@com_google_absl//absl/base:log_severity",
|
||||
"@com_google_absl//absl/flags:flag",
|
||||
"@com_google_absl//absl/hash:hash_testing",
|
||||
"@com_google_absl//absl/log:scoped_mock_log",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
@@ -130,7 +131,6 @@ cc_test(
|
||||
deps = [
|
||||
":nearp_parser",
|
||||
"//ortools/base:file",
|
||||
"//ortools/base:mock_log",
|
||||
"//ortools/base:path",
|
||||
"@com_google_absl//absl/flags:flag",
|
||||
"@com_google_absl//absl/hash:hash_testing",
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/flags/flag.h"
|
||||
#include "absl/log/scoped_mock_log.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "ortools/base/mock-log.h"
|
||||
#include "ortools/base/path.h"
|
||||
|
||||
ABSL_FLAG(std::string, test_srcdir, "", "REQUIRED: src dir");
|
||||
@@ -50,7 +51,7 @@ TEST(CarpParserTest, LoadNonExistingFile) {
|
||||
}
|
||||
|
||||
TEST(CarpParserTest, LoadInvalidFileIncorrectNumberOfNodes) {
|
||||
testing::ScopedMockLog log(testing::kDoNotCaptureLogsYet);
|
||||
absl::ScopedMockLog log;
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kError, testing::_,
|
||||
"Error when parsing the number of nodes: -4"));
|
||||
EXPECT_CALL(
|
||||
@@ -67,7 +68,7 @@ TEST(CarpParserTest, LoadInvalidFileIncorrectNumberOfNodes) {
|
||||
}
|
||||
|
||||
TEST(CarpParserTest, LoadInvalidFileIncorrectNumberOfArcsWithServicings) {
|
||||
testing::ScopedMockLog log(testing::kDoNotCaptureLogsYet);
|
||||
absl::ScopedMockLog log;
|
||||
EXPECT_CALL(
|
||||
log, Log(absl::LogSeverity::kError, testing::_,
|
||||
"Error when parsing the number of edges with servicing: -11"));
|
||||
@@ -84,7 +85,7 @@ TEST(CarpParserTest, LoadInvalidFileIncorrectNumberOfArcsWithServicings) {
|
||||
}
|
||||
|
||||
TEST(CarpParserTest, LoadInvalidFileIncorrectNumberOfArcsWithoutServicings) {
|
||||
testing::ScopedMockLog log(testing::kDoNotCaptureLogsYet);
|
||||
absl::ScopedMockLog log;
|
||||
EXPECT_CALL(
|
||||
log, Log(absl::LogSeverity::kError, testing::_,
|
||||
"Error when parsing the number of edges without servicing: a"));
|
||||
@@ -101,7 +102,7 @@ TEST(CarpParserTest, LoadInvalidFileIncorrectNumberOfArcsWithoutServicings) {
|
||||
}
|
||||
|
||||
TEST(CarpParserTest, LoadInvalidFileIncorrectNumberOfVehicles) {
|
||||
testing::ScopedMockLog log(testing::kDoNotCaptureLogsYet);
|
||||
absl::ScopedMockLog log;
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kError, testing::_,
|
||||
"Error when parsing the number of vehicles: 0"));
|
||||
EXPECT_CALL(
|
||||
@@ -118,7 +119,7 @@ TEST(CarpParserTest, LoadInvalidFileIncorrectNumberOfVehicles) {
|
||||
}
|
||||
|
||||
TEST(CarpParserTest, LoadInvalidFileIncorrectCapacity) {
|
||||
testing::ScopedMockLog log(testing::kDoNotCaptureLogsYet);
|
||||
absl::ScopedMockLog log;
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kError, testing::_,
|
||||
"Error when parsing the capacity: 0"));
|
||||
EXPECT_CALL(
|
||||
@@ -135,7 +136,7 @@ TEST(CarpParserTest, LoadInvalidFileIncorrectCapacity) {
|
||||
}
|
||||
|
||||
TEST(CarpParserTest, LoadInvalidFileIncorrectTypeOfArcCost) {
|
||||
testing::ScopedMockLog log(testing::kDoNotCaptureLogsYet);
|
||||
absl::ScopedMockLog log;
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kError, testing::_,
|
||||
"Value of TIPO_COSTES_ARISTAS is unexpected, only "
|
||||
"EXPLICITOS is supported, but IMPLICITOS was found"));
|
||||
@@ -152,7 +153,7 @@ TEST(CarpParserTest, LoadInvalidFileIncorrectTypeOfArcCost) {
|
||||
}
|
||||
|
||||
TEST(CarpParserTest, LoadInvalidFileIncorrectTotalServicingCost) {
|
||||
testing::ScopedMockLog log(testing::kDoNotCaptureLogsYet);
|
||||
absl::ScopedMockLog log;
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kError, testing::_,
|
||||
"Error when parsing the total servicing cost: qwertz"));
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kError, testing::_,
|
||||
@@ -168,7 +169,7 @@ TEST(CarpParserTest, LoadInvalidFileIncorrectTotalServicingCost) {
|
||||
}
|
||||
|
||||
TEST(CarpParserTest, LoadInvalidFileIncorrectDepot) {
|
||||
testing::ScopedMockLog log(testing::kDoNotCaptureLogsYet);
|
||||
absl::ScopedMockLog log;
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kError, testing::_,
|
||||
"Could not parse node index: -1"));
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kError, testing::_,
|
||||
@@ -187,7 +188,7 @@ TEST(CarpParserTest, LoadInvalidFileIncorrectDepot) {
|
||||
}
|
||||
|
||||
TEST(CarpParserTest, LoadInvalidFileNoEdgeWithServicing) {
|
||||
testing::ScopedMockLog log(testing::kDoNotCaptureLogsYet);
|
||||
absl::ScopedMockLog log;
|
||||
EXPECT_CALL(log,
|
||||
Log(absl::LogSeverity::kError, testing::_,
|
||||
"Error when parsing the number of edges with servicing: 0"));
|
||||
@@ -205,7 +206,7 @@ TEST(CarpParserTest, LoadInvalidFileNoEdgeWithServicing) {
|
||||
}
|
||||
|
||||
TEST(CarpParserTest, LoadInvalidFileServicingForArcsWithoutServicing) {
|
||||
testing::ScopedMockLog log(testing::kDoNotCaptureLogsYet);
|
||||
absl::ScopedMockLog log;
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kError, testing::_,
|
||||
"Extraneous elements in line, starting with: demanda"));
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kError, testing::_,
|
||||
@@ -221,7 +222,7 @@ TEST(CarpParserTest, LoadInvalidFileServicingForArcsWithoutServicing) {
|
||||
}
|
||||
|
||||
TEST(CarpParserTest, LoadInvalidFileServicingForArcsInWrongOrder) {
|
||||
testing::ScopedMockLog log(testing::kDoNotCaptureLogsYet);
|
||||
absl::ScopedMockLog log;
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kError, testing::_,
|
||||
"Unexpected keyword: demanda"));
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kError, testing::_,
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
#include "absl/flags/flag.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "ortools/base/mock-log.h"
|
||||
#include "ortools/base/path.h"
|
||||
|
||||
ABSL_FLAG(std::string, test_srcdir, "", "REQUIRED: src dir");
|
||||
|
||||
@@ -57,7 +57,7 @@ bool RcpspParser::ParseFile(const std::string& file_name) {
|
||||
ProcessRcpspLine(line);
|
||||
}
|
||||
if (load_status_ == ERROR_FOUND) {
|
||||
LOG(INFO) << rcpsp_.DebugString();
|
||||
LOG(INFO) << rcpsp_;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user