From f9983cf2a7db63f7b30049cfcec3cb103042341f Mon Sep 17 00:00:00 2001 From: Nicole Lemaster Slattengren Date: Wed, 3 Aug 2022 15:01:18 -0700 Subject: [PATCH] #1896: tests: use unique filenames to allow parallel testing --- .../collection/test_checkpoint.extended.cc | 16 ++++++++++---- tests/unit/runtime/test_initialization.cc | 21 +++++++++++++++---- tests/unit/test_helpers.h | 15 +++++++++++++ tests/unit/test_parallel_harness.h | 3 +++ tests/unit/trace/test_trace_spec_reader.cc | 17 +++++++++++---- 5 files changed, 60 insertions(+), 12 deletions(-) diff --git a/tests/unit/collection/test_checkpoint.extended.cc b/tests/unit/collection/test_checkpoint.extended.cc index a9b5af15c6..eaaac748f2 100644 --- a/tests/unit/collection/test_checkpoint.extended.cc +++ b/tests/unit/collection/test_checkpoint.extended.cc @@ -172,7 +172,9 @@ TEST_F(TestCheckpoint, test_checkpoint_1) { auto num_nodes = static_cast(theContext()->getNumNodes()); auto range = vt::Index3D(num_nodes, num_elms, 4); - std::string const checkpoint_name{"test_checkpoint_dir"}; + std::string const checkpoint_name(addNumNodesToFilename( + "test_checkpoint_1_dir_" + )); std::string const expected_label{"test_checkpoint_1"}; { @@ -251,7 +253,9 @@ TEST_F(TestCheckpoint, test_checkpoint_in_place_2) { auto num_nodes = static_cast(theContext()->getNumNodes()); auto range = vt::Index3D(num_nodes, num_elms, 4); - auto checkpoint_name = "test_checkpoint_dir"; + std::string const checkpoint_name(addNumNodesToFilename( + "test_checkpoint_in_place_2_dir_" + )); auto proxy = vt::theCollection()->constructCollective( range, "test_checkpoint_in_place_2" ); @@ -323,7 +327,9 @@ TEST_F(TestCheckpoint, test_checkpoint_in_place_3) { auto num_nodes = static_cast(theContext()->getNumNodes()); auto range = vt::Index3D(num_nodes, num_elms, 4); - auto checkpoint_name = "test_checkpoint_dir_2"; + std::string const checkpoint_name(addNumNodesToFilename( + "test_checkpoint_in_place_3_dir_" + )); auto proxy = vt::theCollection()->constructCollective( range, "test_checkpoint_in_place_3" ); @@ -400,7 +406,9 @@ TEST_F(TestCheckpoint, test_checkpoint_no_elements_on_root_rank) { auto num_nodes = static_cast(theContext()->getNumNodes()); auto range = vt::Index3D(num_nodes, num_elms, 4); - auto checkpoint_name = "test_null_elm_checkpoint_dir"; + std::string const checkpoint_name(addNumNodesToFilename( + "test_null_elm_checkpoint_dir_" + )); { auto proxy = vt::makeCollection("test_checkpoint_no_elements_on_root_rank") diff --git a/tests/unit/runtime/test_initialization.cc b/tests/unit/runtime/test_initialization.cc index 6ab4899e3e..70bb676e75 100644 --- a/tests/unit/runtime/test_initialization.cc +++ b/tests/unit/runtime/test_initialization.cc @@ -44,6 +44,7 @@ #include #include "test_parallel_harness.h" +#include "test_helpers.h" #include @@ -170,7 +171,13 @@ TEST_F(TestInitialization, test_initialize_with_file_and_args) { static char cli_argument[]{"--cli_argument=100"}; static char vt_no_terminate[]{"--vt_no_terminate"}; static char vt_lb_name[]{"--vt_lb_name=RotateLB"}; - static char vt_input_config[]{"--vt_input_config=test_cfg.toml"}; + + std::string config_file(addNumNodesToFilename("test_cfg_", ".toml")); + std::string config_flag("--vt_input_config="); + std::string config_arg = config_flag + config_file; + char vt_input_config[100]; + memset(vt_input_config, 0, 100); + strncpy(vt_input_config, config_arg.c_str(), config_arg.size()); std::vector custom_args; custom_args.emplace_back(prog_name); @@ -188,7 +195,7 @@ TEST_F(TestInitialization, test_initialize_with_file_and_args) { int this_rank; MPI_Comm_rank(comm, &this_rank); if (this_rank == 0) { - std::ofstream cfg_file_{"test_cfg.toml", std::ofstream::out | std::ofstream::trunc}; + std::ofstream cfg_file_{config_file.c_str(), std::ofstream::out | std::ofstream::trunc}; cfg_file_ << "vt_lb_name = RandomLB\n"; cfg_file_.close(); } @@ -213,7 +220,13 @@ TEST_F(TestInitialization, test_initialize_with_file_args_and_appconfig) { static char cli_argument[]{"--cli_argument=100"}; static char vt_no_terminate[]{"--vt_no_terminate"}; static char vt_lb_name[]{"--vt_lb_name=RotateLB"}; - static char vt_input_config[]{"--vt_input_config=test_cfg.toml"}; + + std::string config_file(addNumNodesToFilename("test_appcfg_", ".toml")); + std::string config_flag("--vt_input_config="); + std::string config_arg = config_flag + config_file; + char vt_input_config[100]; + memset(vt_input_config, 0, 100); + strncpy(vt_input_config, config_arg.c_str(), config_arg.size()); std::vector custom_args; custom_args.emplace_back(prog_name); @@ -234,7 +247,7 @@ TEST_F(TestInitialization, test_initialize_with_file_args_and_appconfig) { int this_rank; MPI_Comm_rank(comm, &this_rank); if (this_rank == 0) { - std::ofstream cfg_file_{"test_cfg.toml", std::ofstream::out | std::ofstream::trunc}; + std::ofstream cfg_file_{config_file.c_str(), std::ofstream::out | std::ofstream::trunc}; cfg_file_ << "vt_lb_name = RandomLB\n"; cfg_file_.close(); } diff --git a/tests/unit/test_helpers.h b/tests/unit/test_helpers.h index 9fc1e422ed..027fb17f2d 100644 --- a/tests/unit/test_helpers.h +++ b/tests/unit/test_helpers.h @@ -47,6 +47,7 @@ #include "vt/context/context.h" #include #include +#include namespace vt { namespace tests { namespace unit { @@ -75,6 +76,20 @@ inline bool isOversubscribed() { return num_ranks > CMAKE_DETECTED_MAX_NUM_NODES; } +/** + * Construct a filename containing the number of ranks so that + * concurrently-running tests will not cause file system race conditions. + * Do not call this from .nompi.cc tests. + */ +inline std::string addNumNodesToFilename( + const std::string &before_num_ranks, const std::string &after_num_ranks = "" +) { + auto ranks = theContext()->getNumNodes(); + std::stringstream ss; + ss << before_num_ranks << ranks << after_num_ranks; + return ss.str(); +} + /** * The following helper macros (these have to be macros, because GTEST_SKIP * won't work from nested call) are meant to ensure that the test will be diff --git a/tests/unit/test_parallel_harness.h b/tests/unit/test_parallel_harness.h index 6c93dc437d..2b2581db60 100644 --- a/tests/unit/test_parallel_harness.h +++ b/tests/unit/test_parallel_harness.h @@ -161,6 +161,9 @@ struct TestParallelHarnessAny : TestHarnessAny { * addArgs(vt_lb_data, vt_lb_data_dir, vt_lb_data_file); * } * }; + * + * Make sure all filenames used will be unique across all tests, + * parameterizations, and MPI rank counts. */ virtual void addAdditionalArgs() {} diff --git a/tests/unit/trace/test_trace_spec_reader.cc b/tests/unit/trace/test_trace_spec_reader.cc index 1439da4a8f..d5112f65a3 100644 --- a/tests/unit/trace/test_trace_spec_reader.cc +++ b/tests/unit/trace/test_trace_spec_reader.cc @@ -47,6 +47,7 @@ #include #include "test_parallel_harness.h" +#include "test_helpers.h" #include @@ -57,7 +58,9 @@ using TestTraceSpec = TestParallelHarness; TEST_F(TestTraceSpec, test_trace_spec_1) { using Spec = vt::trace::file_spec::TraceSpec; - std::string file_name = "test_trace_spec_1.txt"; + std::string const file_name(addNumNodesToFilename( + "test_trace_spec_1_", ".txt" + )); if (theContext()->getNode() == 0) { std::ofstream out(file_name); out << "" @@ -88,7 +91,9 @@ TEST_F(TestTraceSpec, test_trace_spec_1) { TEST_F(TestTraceSpec, test_trace_spec_2) { using Spec = vt::trace::file_spec::TraceSpec; - std::string file_name = "test_trace_spec_2.txt"; + std::string const file_name(addNumNodesToFilename( + "test_trace_spec_2_", ".txt" + )); if (theContext()->getNode() == 0) { std::ofstream out(file_name); out << "" @@ -122,7 +127,9 @@ TEST_F(TestTraceSpec, test_trace_spec_2) { TEST_F(TestTraceSpec, test_trace_spec_3) { using Spec = vt::trace::file_spec::TraceSpec; - std::string file_name = "test_trace_spec_3.txt"; + std::string const file_name(addNumNodesToFilename( + "test_trace_spec_3_", ".txt" + )); if (theContext()->getNode() == 0) { std::ofstream out(file_name); out << "" @@ -167,7 +174,9 @@ TEST_F(TestTraceSpec, test_trace_spec_3) { TEST_F(TestTraceSpec, test_trace_spec_4) { using Spec = vt::trace::file_spec::TraceSpec; - std::string file_name = "test_trace_spec_4.txt"; + std::string const file_name(addNumNodesToFilename( + "test_trace_spec_4_", ".txt" + )); if (theContext()->getNode() == 0) { std::ofstream out(file_name); out << ""