Skip to content

Commit

Permalink
add tests (#958)
Browse files Browse the repository at this point in the history
The pull request introduces several changes to the project, including:

1. Updating the build scripts for various platforms (CentOS 7, Oracle 8,
Ubuntu, and Windows) to use a new Cucumber test feature for Benders
Outputs.

2. Modifying the C++ code for the Benders Math Logger to include
delimiters in the output files. This change ensures that the data in the
output files is properly formatted and easy to parse.

3. Adding new C++ tests for the Benders Math Logger to verify that the
data is being written to the output files correctly.

4. Updating the Cucumber test framework to include a new feature for
testing Benders criterion outputs. This feature includes steps for
running the simulation, checking the simulation time, and verifying the
expected positive unsupplied energy and loss of load.

5. Adding a new example test for the SmallTestFiveCandidatesWithWeights
study, which includes steps for running the simulation and checking the
expected overall cost, investment cost, and solution.

6. Updating the utils_functions.py file to include a new function for
reading outputs from the simulation, which can handle both archived and
non-archived output files.

Overall, these changes improves the testing and logging capabilities of
the project, as well as adding new functionality for handling Benders
criterion outputs.
  • Loading branch information
a-zakir authored Nov 12, 2024
1 parent 48e1474 commit 6a3ba09
Show file tree
Hide file tree
Showing 19 changed files with 494 additions and 206 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build_centos7.yml
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,10 @@ jobs:
cmake --build _build --config Release -j$(nproc)
- name: Run cucumber on outer_loop tests
- name: Tests with Cucumber
uses: ./.github/workflows/cucumber-tests
with:
feature: "features/outer_loop_tests.feature"
# feature: "features/outer_loop_tests.feature"
mpi_path: ${GITHUB_WORKSPACE}/_build/vcpkg_installed/x64-linux-release/tools/openmpi/bin

- name: Cache vcpkg binary dir
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build_oracle8.yml
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,10 @@ jobs:
cmake --build _build --config Release -j$(nproc)
- name: Run cucumber on outer_loop tests
- name: Tests with Cucumber
uses: ./.github/workflows/cucumber-tests
with:
feature: "features/outer_loop_tests.feature"
# feature: "features/outer_loop_tests.feature"
mpi_path: ${GITHUB_WORKSPACE}/_build/vcpkg_installed/x64-linux-release/tools/openmpi/bin

- name: Running unit tests
Expand Down
5 changes: 2 additions & 3 deletions .github/workflows/build_ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,12 @@ jobs:
run: |
cmake --build _build --config Release -j$(nproc)
- name: Run cucumber on outer_loop tests
- name: Tests with Cucumber
uses: ./.github/workflows/cucumber-tests
with:
feature: "features/outer_loop_tests.feature"
# feature: "features/outer_loop_tests.feature"
mpi_path: ${{ github.workspace }}/_build/vcpkg_installed/x64-linux-release/tools/openmpi/bin


- name: Test
run: |
export PATH=${GITHUB_WORKSPACE}/_build/vcpkg_installed/x64-linux-release/tools/openmpi/bin:$PATH
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build_windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,10 @@ jobs:
cmake --build _build --config Release -j4
- name: Run cucumber on outer_loop tests
- name: Tests with Cucumber
uses: ./.github/workflows/cucumber-tests
with:
feature: "features/outer_loop_tests.feature"
# feature: "features/outer_loop_tests.feature"
mpi_path: /c/Program Files/Microsoft MPI/Bin


Expand Down
File renamed without changes.
30 changes: 30 additions & 0 deletions src/cpp/benders/benders_core/BendersMathLogger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,16 @@ LogDestination::LogDestination(const std::filesystem::path& file_path,
std::cerr << err_msg.str();
}
}
void LogDestination::setDelimiter(const std::string& delimiter) {
delimiter_ = delimiter;
}

void MathLoggerBehaviour::write_header() {
setHeadersList();
LogsDestination().InsertDelimiter();
for (const auto& header : Headers()) {
LogsDestination() << header;
LogsDestination().InsertDelimiter();
}
LogsDestination() << std::endl;
}
Expand Down Expand Up @@ -154,36 +159,54 @@ double getDurationNotSolving(double iteration, double master,
void PrintBendersData(LogDestination& log_destination,
const CurrentIterationData& data, const HEADERSTYPE& type,
const BENDERSMETHOD& method) {
log_destination.InsertDelimiter();
log_destination << data.it;
log_destination.InsertDelimiter();
log_destination << std::scientific << std::setprecision(10) << data.lb;
log_destination.InsertDelimiter();
if (method == BENDERSMETHOD::BENDERS) {
log_destination << std::scientific << std::setprecision(10) << data.ub;
log_destination.InsertDelimiter();
log_destination << std::scientific << std::setprecision(10) << data.best_ub;
log_destination.InsertDelimiter();
log_destination << std::scientific << std::setprecision(2)
<< data.best_ub - data.lb;
log_destination.InsertDelimiter();
log_destination << std::scientific << std::setprecision(2)
<< (data.best_ub - data.lb) / data.best_ub;
log_destination.InsertDelimiter();
}
log_destination << data.min_simplexiter;
log_destination.InsertDelimiter();
log_destination << data.max_simplexiter;
log_destination.InsertDelimiter();
if (type == HEADERSTYPE::LONG || method == BENDERSMETHOD::BENDERS_BY_BATCH) {
log_destination << data.number_of_subproblem_solved;
log_destination.InsertDelimiter();
}
if (type == HEADERSTYPE::LONG) {
log_destination << data.cumulative_number_of_subproblem_solved;
log_destination.InsertDelimiter();
}

log_destination << std::setprecision(2) << data.iteration_time;
log_destination.InsertDelimiter();

log_destination << std::setprecision(2) << data.timer_master;
log_destination.InsertDelimiter();

log_destination << std::setprecision(2) << data.subproblems_walltime;
log_destination.InsertDelimiter();

if (type == HEADERSTYPE::LONG) {
log_destination << std::setprecision(2)
<< data.subproblems_cumulative_cputime;
log_destination.InsertDelimiter();
log_destination << std::setprecision(2)
<< getDurationNotSolving(data.iteration_time,
data.timer_master,
data.subproblems_walltime);
log_destination.InsertDelimiter();
}
log_destination << std::endl;
}
Expand All @@ -192,20 +215,27 @@ void PrintExternalLoopData(LogDestination& log_destination,
const CurrentIterationData& data,
const HEADERSTYPE& type,
const BENDERSMETHOD& method) {
log_destination.InsertDelimiter();
log_destination << data.outer_loop_current_iteration_data.benders_num_run;
log_destination.InsertDelimiter();
log_destination << std::scientific << std::setprecision(10)
<< data.outer_loop_current_iteration_data.max_criterion;
log_destination.InsertDelimiter();
log_destination << data.outer_loop_current_iteration_data.max_criterion_area;
log_destination.InsertDelimiter();

log_destination
<< std::scientific << std::setprecision(10)
<< data.outer_loop_current_iteration_data.outer_loop_bilevel_best_ub;
log_destination.InsertDelimiter();
log_destination
<< std::scientific << std::setprecision(10)
<< data.outer_loop_current_iteration_data.external_loop_lambda;
log_destination.InsertDelimiter();
log_destination
<< std::scientific << std::setprecision(10)
<< data.outer_loop_current_iteration_data.external_loop_lambda_min;
log_destination.InsertDelimiter();
log_destination
<< std::scientific << std::setprecision(10)
<< data.outer_loop_current_iteration_data.external_loop_lambda_max;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,16 @@ class LogDestination {

template <class T>
std::ostream& operator<<(const T& obj);
std::ostream& InsertDelimiter() { return *stream_ << delimiter_; }

private:
std::ofstream file_stream_;
std::ostream* stream_;
std::streamsize width_ = 40;
std::string delimiter_ = "\t";

public:
void setDelimiter(const std::string& delimiter);
};
template <class T>
std::ostream& LogDestination::operator<<(const T& obj) {
Expand Down Expand Up @@ -214,10 +219,14 @@ void MathLoggerExternalLoopSpecific<T>::setHeadersList() {
template <class T>
void MathLoggerExternalLoopSpecific<T>::Print(
const CurrentIterationData& data) {
LogsDestination().InsertDelimiter();
LogsDestination() << data.outer_loop_current_iteration_data.benders_num_run;
LogsDestination().InsertDelimiter();
LogsDestination() << data.it;
LogsDestination().InsertDelimiter();
for (const auto& t : data.outer_loop_current_iteration_data.*ptr_) {
LogsDestination() << std::scientific << std::setprecision(10) << t;
LogsDestination().InsertDelimiter();
}
LogsDestination() << std::endl;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ struct OuterLoopCurrentIterationData{
double external_loop_lambda = 0.;
double external_loop_lambda_min = 0.;
double external_loop_lambda_max = 0.;
std::string max_criterion_area;
std::string max_criterion_area_best_it;
std::string max_criterion_area = "N/A";
std::string max_criterion_area_best_it = "N/A";
};
/*! \struct
* struct that hold current Benders iteration
Expand Down
54 changes: 54 additions & 0 deletions tests/cpp/logger/logger_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,7 @@ TEST_F(MasterLoggerTest, LogSwitchToInteger) {
ASSERT_TRUE(_logger->_switchToIntegerCall);
ASSERT_TRUE(_logger2->_switchToIntegerCall);
}
static constexpr const char* const DELIMITER = "\t";

TEST(LogDestinationTest, WithInvalidEmptyFilePath) {
const std::filesystem::path invalid_file_path("");
Expand Down Expand Up @@ -867,8 +868,10 @@ TEST(MathLoggerBendersByBatchTest, HeadersListStdOutShort) {
std::streamsize width = 25;

std::ostringstream expected_msg;
expected_msg << DELIMITER;
for (const auto& header : headers_manager.HeadersList()) {
expected_msg << std::setw(width) << std::left << header;
expected_msg << DELIMITER;
}
expected_msg << std::endl;
std::stringstream redirectedStdout;
Expand All @@ -886,8 +889,10 @@ TEST(MathLoggerBendersByBatchTest, HeadersListFileLong) {
std::streamsize width = 25;

std::ostringstream expected_msg;
expected_msg << DELIMITER;
for (const auto& header : headers_manager.HeadersList()) {
expected_msg << std::setw(width) << std::left << header;
expected_msg << DELIMITER;
}
expected_msg << std::endl;
auto log_file =
Expand Down Expand Up @@ -919,27 +924,39 @@ TEST(MathLoggerBendersByBatchTest, DataInFileLong) {
data.iteration_time - data.timer_master - data.subproblems_walltime;

std::ostringstream expected_msg;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << data.it;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << std::scientific
<< std::setprecision(10) << data.lb;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << data.min_simplexiter;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << data.max_simplexiter;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width)
<< data.number_of_subproblem_solved;
expected_msg << DELIMITER;

expected_msg << std::left << std::setw(width)
<< data.cumulative_number_of_subproblem_solved;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << std::setprecision(2)
<< data.iteration_time;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << std::setprecision(2)
<< data.timer_master;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << std::setprecision(2)
<< data.subproblems_walltime;
expected_msg << DELIMITER;

expected_msg << std::left << std::setw(width) << std::setprecision(2)
<< data.subproblems_cumulative_cputime;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << std::setprecision(2)
<< time_not_solving;
expected_msg << DELIMITER;
expected_msg << std::endl;
auto log_file =
CreateRandomSubDir(std::filesystem::temp_directory_path()) / "log.txt";
Expand Down Expand Up @@ -970,20 +987,29 @@ TEST(MathLoggerBendersByBatchTest, DataInStdOutShort) {
data.iteration_time - data.timer_master - data.subproblems_walltime;

std::ostringstream expected_msg;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << data.it;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << std::scientific
<< std::setprecision(10) << data.lb;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << data.min_simplexiter;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << data.max_simplexiter;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width)
<< data.number_of_subproblem_solved;
expected_msg << DELIMITER;

expected_msg << std::left << std::setw(width) << std::setprecision(2)
<< data.iteration_time;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << std::setprecision(2)
<< data.timer_master;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << std::setprecision(2)
<< data.subproblems_walltime;
expected_msg << DELIMITER;

expected_msg << std::endl;
std::stringstream redirectedStdout;
Expand Down Expand Up @@ -1016,36 +1042,52 @@ TEST(MathLoggerBendersBaseTest, DataInFileLong) {
data.iteration_time - data.timer_master - data.subproblems_walltime;

std::ostringstream expected_msg;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << data.it;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << std::scientific
<< std::setprecision(10) << data.lb;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << std::scientific
<< std::setprecision(10) << data.ub;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << std::scientific
<< std::setprecision(10) << data.best_ub;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << std::scientific
<< std::setprecision(2) << data.best_ub - data.lb;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << std::scientific
<< std::setprecision(2)
<< (data.best_ub - data.lb) / data.best_ub;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << data.min_simplexiter;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << data.max_simplexiter;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width)
<< data.number_of_subproblem_solved;
expected_msg << DELIMITER;

expected_msg << std::left << std::setw(width)
<< data.cumulative_number_of_subproblem_solved;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << std::setprecision(2)
<< data.iteration_time;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << std::setprecision(2)
<< data.timer_master;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << std::setprecision(2)
<< data.subproblems_walltime;
expected_msg << DELIMITER;

expected_msg << std::left << std::setw(width) << std::setprecision(2)
<< data.subproblems_cumulative_cputime;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << std::setprecision(2)
<< time_not_solving;
expected_msg << DELIMITER;
expected_msg << std::endl;
auto log_file =
CreateRandomSubDir(std::filesystem::temp_directory_path()) / "log.txt";
Expand Down Expand Up @@ -1076,28 +1118,40 @@ TEST(MathLoggerBendersBaseTest, DataInStdOutShort) {
data.iteration_time - data.timer_master - data.subproblems_walltime;

std::ostringstream expected_msg;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << data.it;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << std::scientific
<< std::setprecision(10) << data.lb;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << std::scientific
<< std::setprecision(10) << data.ub;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << std::scientific
<< std::setprecision(10) << data.best_ub;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << std::scientific
<< std::setprecision(2) << data.best_ub - data.lb;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << std::scientific
<< std::setprecision(2)
<< (data.best_ub - data.lb) / data.best_ub;
expected_msg << DELIMITER;

expected_msg << std::left << std::setw(width) << data.min_simplexiter;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << data.max_simplexiter;
expected_msg << DELIMITER;

expected_msg << std::left << std::setw(width) << std::setprecision(2)
<< data.iteration_time;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << std::setprecision(2)
<< data.timer_master;
expected_msg << DELIMITER;
expected_msg << std::left << std::setw(width) << std::setprecision(2)
<< data.subproblems_walltime;
expected_msg << DELIMITER;

expected_msg << std::endl;
std::stringstream redirectedStdout;
Expand Down
Empty file.
Loading

0 comments on commit 6a3ba09

Please sign in to comment.