diff options
author | Chenhao Qu <chenhao.qu@mongodb.com> | 2021-10-06 06:49:56 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-10-06 07:30:19 +0000 |
commit | 1fd449eb819c5cf87b4b58f607f62cae763b1cb7 (patch) | |
tree | 59f398d635fd945a396f17a0950122a15b33a004 | |
parent | a393aecbf12975bcd76f338b28524afe63dc88c6 (diff) | |
download | mongo-1fd449eb819c5cf87b4b58f607f62cae763b1cb7.tar.gz |
Import wiredtiger: 13d0ea2af1922bbf52bdfa257e9e6666d55b0db5 from branch mongodb-master
ref: e5c230df27..13d0ea2af1
for: 5.2.0
WT-8171 Implement a C style test in the CPP testing framework
8 files changed, 210 insertions, 11 deletions
diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data index 279154919c0..649f44f6589 100644 --- a/src/third_party/wiredtiger/import.data +++ b/src/third_party/wiredtiger/import.data @@ -2,5 +2,5 @@ "vendor": "wiredtiger", "github": "wiredtiger/wiredtiger.git", "branch": "mongodb-master", - "commit": "e5c230df2773ea131e76bc73ec2ec059748f2dde" + "commit": "13d0ea2af1922bbf52bdfa257e9e6666d55b0db5" } diff --git a/src/third_party/wiredtiger/test/cppsuite/Makefile.am b/src/third_party/wiredtiger/test/cppsuite/Makefile.am index 82c30442482..5e896ce2e04 100644 --- a/src/third_party/wiredtiger/test/cppsuite/Makefile.am +++ b/src/third_party/wiredtiger/test/cppsuite/Makefile.am @@ -11,7 +11,7 @@ all: all_TESTS= noinst_PROGRAMS= -run_SOURCES = test_harness/core/component.cxx \ +test_harness = test_harness/core/component.cxx \ test_harness/core/configuration.cxx \ test_harness/core/throttle.cxx \ test_harness/util/logger.cxx \ @@ -28,9 +28,15 @@ run_SOURCES = test_harness/core/component.cxx \ test_harness/test.cxx \ test_harness/thread_manager.cxx \ test_harness/timestamp_manager.cxx \ - test_harness/workload_generator.cxx \ - tests/run.cxx + test_harness/workload_generator.cxx +# If you prefer to not use the run binary you can add a test via this +# mechanism but it is generally frowned upon. +csuite_style_example_test_SOURCES = $(test_harness) tests/csuite_style_example_test.cxx +noinst_PROGRAMS += csuite_style_example_test +all_TESTS += csuite_style_example_test + +run_SOURCES = $(test_harness) tests/run.cxx noinst_PROGRAMS += run all_TESTS += run diff --git a/src/third_party/wiredtiger/test/cppsuite/test_harness/connection_manager.cxx b/src/third_party/wiredtiger/test/cppsuite/test_harness/connection_manager.cxx index 6ff134c7c96..8a8b75b7b8f 100644 --- a/src/third_party/wiredtiger/test/cppsuite/test_harness/connection_manager.cxx +++ b/src/third_party/wiredtiger/test/cppsuite/test_harness/connection_manager.cxx @@ -80,6 +80,12 @@ connection_manager::create_session() return (session); } +WT_CONNECTION * +connection_manager::get_connection() +{ + return (_conn); +} + /* * set_timestamp calls into the connection API in a thread safe manner to set global timestamps. */ diff --git a/src/third_party/wiredtiger/test/cppsuite/test_harness/connection_manager.h b/src/third_party/wiredtiger/test/cppsuite/test_harness/connection_manager.h index ce0c9598318..a5d44903717 100644 --- a/src/third_party/wiredtiger/test/cppsuite/test_harness/connection_manager.h +++ b/src/third_party/wiredtiger/test/cppsuite/test_harness/connection_manager.h @@ -64,6 +64,8 @@ class connection_manager { void create(const std::string &config, const std::string &home = DEFAULT_DIR); scoped_session create_session(); + WT_CONNECTION *get_connection(); + /* * set_timestamp calls into the connection API in a thread safe manner to set global timestamps. */ diff --git a/src/third_party/wiredtiger/test/cppsuite/test_harness/workload/random_generator.cxx b/src/third_party/wiredtiger/test/cppsuite/test_harness/workload/random_generator.cxx index c539fbc34fc..3973af7242c 100644 --- a/src/third_party/wiredtiger/test/cppsuite/test_harness/workload/random_generator.cxx +++ b/src/third_party/wiredtiger/test/cppsuite/test_harness/workload/random_generator.cxx @@ -44,10 +44,11 @@ random_generator::instance() std::string random_generator::generate_random_string(std::size_t length, characters_type type) { + const std::string characters = get_characters(type); std::string str; while (str.size() < length) - str += get_characters(type); + str += characters; std::shuffle(str.begin(), str.end(), _generator); return (str.substr(0, length)); diff --git a/src/third_party/wiredtiger/test/cppsuite/tests/csuite_style_example_test.cxx b/src/third_party/wiredtiger/test/cppsuite/tests/csuite_style_example_test.cxx new file mode 100644 index 00000000000..d0059880446 --- /dev/null +++ b/src/third_party/wiredtiger/test/cppsuite/tests/csuite_style_example_test.cxx @@ -0,0 +1,169 @@ +/*- + * 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. + */ + +/* + * This file provides an example of how to create a test in C++ using a few features from the + * framework if any. This file can be used as a template for quick testing and/or when stress + * testing is not required. For any stress testing, it is encouraged to use the framework, see + * example_test.cxx and create_script.sh. + */ + +#include "test_harness/connection_manager.h" +#include "test_harness/thread_manager.h" +#include "test_harness/util/api_const.h" +#include "test_harness/util/logger.h" +#include "test_harness/workload/random_generator.h" + +extern "C" { +#include "wiredtiger.h" +} + +using namespace test_harness; + +bool do_inserts = false; +bool do_reads = false; + +void +insert_op(WT_CURSOR *cursor, int key_size, int value_size) +{ + logger::log_msg(LOG_INFO, "called insert_op"); + + /* Insert random data. */ + std::string key, value; + while (do_inserts) { + key = random_generator::instance().generate_random_string(key_size); + value = random_generator::instance().generate_random_string(value_size); + cursor->set_key(cursor, key.c_str()); + cursor->set_value(cursor, value.c_str()); + testutil_check(cursor->insert(cursor)); + } +} + +void +read_op(WT_CURSOR *cursor, int key_size) +{ + logger::log_msg(LOG_INFO, "called read_op"); + + /* Read random data. */ + std::string key; + while (do_reads) { + key = random_generator::instance().generate_random_string(key_size); + cursor->set_key(cursor, key.c_str()); + cursor->search(cursor); + } +} + +int +main(int argc, char *argv[]) +{ + /* Set the program name for error messages. */ + const std::string progname = testutil_set_progname(argv); + + /* Set the tracing level for the logger component. */ + logger::trace_level = LOG_INFO; + + /* Printing some messages. */ + logger::log_msg(LOG_INFO, "Starting " + progname); + logger::log_msg(LOG_ERROR, "This could be an error."); + + /* Create a connection, set the cache size and specify the home directory. */ + const std::string conn_config = std::string(CONNECTION_CREATE) + ",cache_size=500MB"; + const std::string home_dir = std::string(DEFAULT_DIR) + '_' + progname; + connection_manager::instance().create(conn_config, home_dir); + WT_CONNECTION *conn = connection_manager::instance().get_connection(); + + /* Open different sessions. */ + WT_SESSION *insert_session, *read_session; + testutil_check(conn->open_session(conn, nullptr, nullptr, &insert_session)); + testutil_check(conn->open_session(conn, nullptr, nullptr, &read_session)); + + /* Create a collection. */ + const std::string collection_name = "table:my_collection"; + testutil_check( + insert_session->create(insert_session, collection_name.c_str(), DEFAULT_FRAMEWORK_SCHEMA)); + + /* Open different cursors. */ + WT_CURSOR *insert_cursor, *read_cursor; + const std::string cursor_config = ""; + testutil_check(insert_session->open_cursor( + insert_session, collection_name.c_str(), nullptr, cursor_config.c_str(), &insert_cursor)); + testutil_check(read_session->open_cursor( + read_session, collection_name.c_str(), nullptr, cursor_config.c_str(), &read_cursor)); + + /* Store cursors. */ + std::vector<WT_CURSOR *> cursors; + cursors.push_back(insert_cursor); + cursors.push_back(read_cursor); + + /* Insert some data. */ + std::string key = "a"; + const std::string value = "b"; + insert_cursor->set_key(insert_cursor, key.c_str()); + insert_cursor->set_value(insert_cursor, value.c_str()); + testutil_check(insert_cursor->insert(insert_cursor)); + + /* Read some data. */ + key = "b"; + read_cursor->set_key(read_cursor, key.c_str()); + testutil_assert(read_cursor->search(read_cursor) == WT_NOTFOUND); + + key = "a"; + read_cursor->set_key(read_cursor, key.c_str()); + testutil_check(read_cursor->search(read_cursor)); + + /* Create a thread manager and spawn some threads that will work. */ + thread_manager t; + int key_size = 1, value_size = 2; + + do_inserts = true; + t.add_thread(insert_op, insert_cursor, key_size, value_size); + + do_reads = true; + t.add_thread(read_op, read_cursor, key_size); + + /* Sleep for the test duration. */ + int test_duration_s = 5; + std::this_thread::sleep_for(std::chrono::seconds(test_duration_s)); + + /* Stop the threads. */ + do_reads = false; + do_inserts = false; + t.join(); + + /* Close cursors. */ + for (auto c : cursors) + testutil_check(c->close(c)); + + /* Close the connection. */ + connection_manager::instance().close(); + + /* Another message. */ + logger::log_msg(LOG_INFO, "End of test."); + + return (0); +} diff --git a/src/third_party/wiredtiger/test/cppsuite/tests/example_test.cxx b/src/third_party/wiredtiger/test/cppsuite/tests/example_test.cxx index 5a1996b45a1..4b49ad2b148 100644 --- a/src/third_party/wiredtiger/test/cppsuite/tests/example_test.cxx +++ b/src/third_party/wiredtiger/test/cppsuite/tests/example_test.cxx @@ -37,6 +37,13 @@ class example_test : public test_harness::test { example_test(const test_harness::test_args &args) : test(args) {} void + run() + { + /* You can remove the call to the base class to fully customized your test. */ + test::run(); + } + + void populate(test_harness::database &, test_harness::timestamp_manager *, test_harness::configuration *, test_harness::workload_tracking *) override final { diff --git a/src/third_party/wiredtiger/test/cppsuite/tests/run.cxx b/src/third_party/wiredtiger/test/cppsuite/tests/run.cxx index ead761964cb..627921a9aa4 100755 --- a/src/third_party/wiredtiger/test/cppsuite/tests/run.cxx +++ b/src/third_party/wiredtiger/test/cppsuite/tests/run.cxx @@ -225,12 +225,20 @@ main(int argc, char *argv[]) } } else { current_test_name = test_name; - /* Configuration parsing. */ - if (!config_filename.empty()) - cfg = parse_configuration_from_file(config_filename); - else if (cfg.empty()) - cfg = parse_configuration_from_file(get_default_config_path(current_test_name)); - error_code = run_test(current_test_name, cfg, wt_open_config); + /* Check the test exists. */ + if (std::find(all_tests.begin(), all_tests.end(), current_test_name) == + all_tests.end()) { + test_harness::logger::log_msg( + LOG_ERROR, "The test " + current_test_name + " was not found."); + error_code = -1; + } else { + /* Configuration parsing. */ + if (!config_filename.empty()) + cfg = parse_configuration_from_file(config_filename); + else if (cfg.empty()) + cfg = parse_configuration_from_file(get_default_config_path(current_test_name)); + error_code = run_test(current_test_name, cfg, wt_open_config); + } } if (error_code != 0) |