diff options
Diffstat (limited to 'src/third_party/wiredtiger/test/cppsuite/test_harness/test.cpp')
-rw-r--r-- | src/third_party/wiredtiger/test/cppsuite/test_harness/test.cpp | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/src/third_party/wiredtiger/test/cppsuite/test_harness/test.cpp b/src/third_party/wiredtiger/test/cppsuite/test_harness/test.cpp new file mode 100644 index 00000000000..9f93415ac64 --- /dev/null +++ b/src/third_party/wiredtiger/test/cppsuite/test_harness/test.cpp @@ -0,0 +1,198 @@ +/*- + * Public Domain 2014-present MongoDB, Inc. + * Public Domain 2008-2014 WiredTiger, Inc. + * + * This is free and unencumbered software released into the public domain. + * + * Anyone is free to copy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize copyright laws, the author or authors + * of this software dedicate any and all copyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under copyright law. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* Required to build using older versions of g++. */ +#include <cinttypes> +#include <memory> +#include <mutex> + +#include "connection_manager.h" +#include "core/component.h" +#include "core/configuration.h" +#include "test.h" +#include "thread_manager.h" +#include "timestamp_manager.h" +#include "util/api_const.h" +#include "util/perf_plotter.h" + +namespace test_harness { +test::test(const test_args &args) : _args(args) +{ + _config = new configuration(args.test_name, args.test_config); + _checkpoint_manager = new checkpoint_manager(_config->get_subconfig(CHECKPOINT_MANAGER)); + _runtime_monitor = + new runtime_monitor(args.test_name, _config->get_subconfig(RUNTIME_MONITOR), _database); + _timestamp_manager = new timestamp_manager(_config->get_subconfig(TIMESTAMP_MANAGER)); + _workload_generator = new workload_generator( + _config->get_subconfig(WORKLOAD_GENERATOR), this, _timestamp_manager, _database); + _thread_manager = new thread_manager(); + + _database.set_timestamp_manager(_timestamp_manager); + _database.set_create_config( + _config->get_bool(COMPRESSION_ENABLED), _config->get_bool(REVERSE_COLLATOR)); + + /* + * Ordering is not important here, any dependencies between components should be resolved + * internally by the components. + */ + _components = {_workload_generator, _timestamp_manager, _runtime_monitor, _checkpoint_manager}; +} + +void +test::init_tracking(workload_tracking *tracking) +{ + delete _workload_tracking; + if (tracking == nullptr) { + /* Fallback to default behavior. */ + tracking = new workload_tracking(_config->get_subconfig(WORKLOAD_TRACKING), + _config->get_bool(COMPRESSION_ENABLED), *_timestamp_manager); + } + _workload_tracking = tracking; + _workload_generator->set_workload_tracking(_workload_tracking); + _database.set_workload_tracking(_workload_tracking); + _components.push_back(_workload_tracking); +} + +test::~test() +{ + delete _config; + delete _checkpoint_manager; + delete _runtime_monitor; + delete _timestamp_manager; + delete _thread_manager; + delete _workload_generator; + delete _workload_tracking; + _config = nullptr; + _checkpoint_manager = nullptr; + _runtime_monitor = nullptr; + _timestamp_manager = nullptr; + _thread_manager = nullptr; + _workload_generator = nullptr; + _workload_tracking = nullptr; + + _components.clear(); +} + +void +test::run() +{ + int64_t cache_max_wait_ms, cache_size_mb, duration_seconds; + bool enable_logging, statistics_logging; + configuration *statistics_config; + std::string statistics_type; + /* Build the database creation config string. */ + std::string db_create_config = CONNECTION_CREATE; + + /* Enable snappy compression or reverse collator if required. */ + if (_config->get_bool(COMPRESSION_ENABLED) || _config->get_bool(REVERSE_COLLATOR)) { + db_create_config += ",extensions=["; + db_create_config += + _config->get_bool(COMPRESSION_ENABLED) ? std::string(SNAPPY_PATH) + "," : ""; + db_create_config += + _config->get_bool(REVERSE_COLLATOR) ? std::string(REVERSE_COLLATOR_PATH) : ""; + db_create_config += "]"; + } + + /* Get the cache size. */ + cache_size_mb = _config->get_int(CACHE_SIZE_MB); + db_create_config += ",cache_size=" + std::to_string(cache_size_mb) + "MB"; + + /* Get the statistics configuration for this run. */ + statistics_config = _config->get_subconfig(STATISTICS_CONFIG); + statistics_type = statistics_config->get_string(TYPE); + statistics_logging = statistics_config->get_bool(ENABLE_LOGGING); + db_create_config += statistics_logging ? "," + STATISTICS_LOG : ""; + db_create_config += ",statistics=(" + statistics_type + ")"; + /* Don't forget to delete. */ + delete statistics_config; + + /* Enable or disable write ahead logging. */ + enable_logging = _config->get_bool(ENABLE_LOGGING); + db_create_config += ",log=(enabled=" + std::string(enable_logging ? "true" : "false") + ")"; + + /* Maximum waiting time for the cache to get unstuck. */ + cache_max_wait_ms = _config->get_int(CACHE_MAX_WAIT_MS); + db_create_config += ",cache_max_wait_ms=" + std::to_string(cache_max_wait_ms); + + /* Add the user supplied wiredtiger open config. */ + db_create_config += _args.wt_open_config; + + /* + * Set up the test environment. A smart pointer is used here so that the connection can + * automatically be closed by the scoped_connection's destructor when the test finishes and the + * pointer goes out of scope. + */ + _scoped_conn = std::make_shared<scoped_connection>(db_create_config); + + /* Initiate the load stage of each component. */ + for (const auto &it : _components) + it->load(); + + /* Spawn threads for all component::run() functions. */ + for (const auto &it : _components) + _thread_manager->add_thread(&component::run, it); + + /* The initial population phase needs to be finished before starting the actual test. */ + while (_workload_generator->enabled() && !_workload_generator->db_populated()) + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + + /* The test will run for the duration as defined in the config. */ + duration_seconds = _config->get_int(DURATION_SECONDS); + testutil_assert(duration_seconds >= 0); + logger::log_msg(LOG_INFO, + "Waiting {" + std::to_string(duration_seconds) + "} seconds for testing to complete."); + std::this_thread::sleep_for(std::chrono::seconds(duration_seconds)); + + /* Notify components that they should complete their last iteration. */ + for (const auto &it : _components) + it->end_run(); + + /* Call join on the components threads so we know they have finished their loop. */ + logger::log_msg(LOG_INFO, + "Joining all component threads.\n This could take a while as we need to wait" + " for all components to finish their current loop."); + _thread_manager->join(); + + /* End the test by calling finish on all known components. */ + for (const auto &it : _components) + it->finish(); + + /* Validation stage. */ + if (_workload_tracking->enabled()) { + std::unique_ptr<configuration> tracking_config(_config->get_subconfig(WORKLOAD_TRACKING)); + this->validate(_workload_tracking->get_operation_table_name(), + _workload_tracking->get_schema_table_name(), + _workload_generator->get_database().get_collection_ids()); + } + + /* Log perf stats. */ + perf_plotter::instance().output_perf_file(_args.test_name); + + logger::log_msg(LOG_INFO, "SUCCESS"); +} +} // namespace test_harness |