diff options
Diffstat (limited to 'src/third_party/wiredtiger/test/csuite/wt4803_cache_overflow_abort/main.c')
-rw-r--r-- | src/third_party/wiredtiger/test/csuite/wt4803_cache_overflow_abort/main.c | 334 |
1 files changed, 155 insertions, 179 deletions
diff --git a/src/third_party/wiredtiger/test/csuite/wt4803_cache_overflow_abort/main.c b/src/third_party/wiredtiger/test/csuite/wt4803_cache_overflow_abort/main.c index 7d9b0baf132..264dbbb5679 100644 --- a/src/third_party/wiredtiger/test/csuite/wt4803_cache_overflow_abort/main.c +++ b/src/third_party/wiredtiger/test/csuite/wt4803_cache_overflow_abort/main.c @@ -31,209 +31,185 @@ #include <sys/wait.h> /* - * JIRA ticket reference: WT-4803 - * Test case description: This test is checking the functionality of the - * lookaside file_max configuration. When the size of the lookaside file exceeds - * this value, we expect to panic. - * Failure mode: If we receive a panic in the test cases we weren't expecting to + * JIRA ticket reference: WT-4803 Test case description: This test is checking the functionality of + * the lookaside file_max configuration. When the size of the lookaside file exceeds this value, we + * expect to panic. Failure mode: If we receive a panic in the test cases we weren't expecting to * and vice versa. */ -#define NUM_KEYS 2000 +#define NUM_KEYS 2000 /* - * This is a global flag that should be set before running test_las_workload. - * It lets the child process know whether it should be expecting a panic or not - * so that it can adjust its exit code as needed. + * This is a global flag that should be set before running test_las_workload. It lets the child + * process know whether it should be expecting a panic or not so that it can adjust its exit code as + * needed. */ static bool expect_panic; static int -handle_message(WT_EVENT_HANDLER *handler, - WT_SESSION *session, int error, const char *message) +handle_message(WT_EVENT_HANDLER *handler, WT_SESSION *session, int error, const char *message) { - WT_UNUSED(handler); - WT_UNUSED(session); - - (void)fprintf( - stderr, "%s: %s\n", message, session->strerror(session, error)); - - if (error == WT_PANIC && - strstr(message, "exceeds maximum size") != NULL) { - fprintf(stderr, "Got cache overflow error (expect_panic=%s)\n", - expect_panic ? "true" : "false"); - - /* - * If we're expecting a panic, exit with zero to indicate to the - * parent that this test was successful. - * - * If not, don't intercept. We'll naturally exit with non-zero - * if we're terminating due to panic. - */ - if (expect_panic) - exit(EXIT_SUCCESS); - } - - return (0); + WT_UNUSED(handler); + WT_UNUSED(session); + + (void)fprintf(stderr, "%s: %s\n", message, session->strerror(session, error)); + + if (error == WT_PANIC && strstr(message, "exceeds maximum size") != NULL) { + fprintf( + stderr, "Got cache overflow error (expect_panic=%s)\n", expect_panic ? "true" : "false"); + + /* + * If we're expecting a panic, exit with zero to indicate to the + * parent that this test was successful. + * + * If not, don't intercept. We'll naturally exit with non-zero + * if we're terminating due to panic. + */ + if (expect_panic) + exit(EXIT_SUCCESS); + } + + return (0); } -static WT_EVENT_HANDLER event_handler = { - handle_message, - NULL, - NULL, - NULL -}; +static WT_EVENT_HANDLER event_handler = {handle_message, NULL, NULL, NULL}; static void las_workload(TEST_OPTS *opts, const char *las_file_max) { - WT_CURSOR *cursor; - WT_SESSION *other_session, *session; - int i; - char buf[WT_MEGABYTE], open_config[128]; - - testutil_check(__wt_snprintf(open_config, sizeof(open_config), - "create,cache_size=50MB,cache_overflow=(file_max=%s)", - las_file_max)); - - testutil_check(wiredtiger_open( - opts->home, &event_handler, open_config, &opts->conn)); - testutil_check( - opts->conn->open_session(opts->conn, NULL, NULL, &session)); - testutil_check( - session->create(session, opts->uri, "key_format=i,value_format=S")); - testutil_check( - session->open_cursor(session, opts->uri, NULL, NULL, &cursor)); - - memset(buf, 0xA, WT_MEGABYTE); - buf[WT_MEGABYTE - 1] = '\0'; - - /* Populate the table. */ - for (i = 0; i < NUM_KEYS; ++i) { - cursor->set_key(cursor, i); - cursor->set_value(cursor, buf); - testutil_check(cursor->insert(cursor)); - } - - /* - * Open a snapshot isolation transaction in another session. This forces - * the cache to retain all previous values. Then update all keys with a - * new value in the original session while keeping that snapshot - * transaction open. With the large value buffer, small cache and lots - * of keys, this will force a lot of lookaside usage. - * - * When the file_max setting is small, the maximum size should easily be - * reached and we should panic. When the maximum size is large or not - * set, then we should succeed. - */ - testutil_check( - opts->conn->open_session(opts->conn, NULL, NULL, &other_session)); - testutil_check(other_session->begin_transaction( - other_session, "isolation=snapshot")); - - memset(buf, 0xB, WT_MEGABYTE); - buf[WT_MEGABYTE - 1] = '\0'; - - for (i = 0; i < NUM_KEYS; ++i) { - cursor->set_key(cursor, i); - cursor->set_value(cursor, buf); - testutil_check(cursor->update(cursor)); - } - - /* - * Cleanup. - * We do not get here when the file_max size is small because we will - * have already hit the maximum and exited. This code only executes on - * the successful path. - */ - testutil_check( - other_session->rollback_transaction(other_session, NULL)); - testutil_check(other_session->close(other_session, NULL)); - - testutil_check(cursor->close(cursor)); - testutil_check(session->close(session, NULL)); + WT_CURSOR *cursor; + WT_SESSION *other_session, *session; + int i; + char buf[WT_MEGABYTE], open_config[128]; + + testutil_check(__wt_snprintf(open_config, sizeof(open_config), + "create,cache_size=50MB,cache_overflow=(file_max=%s)", las_file_max)); + + testutil_check(wiredtiger_open(opts->home, &event_handler, open_config, &opts->conn)); + testutil_check(opts->conn->open_session(opts->conn, NULL, NULL, &session)); + testutil_check(session->create(session, opts->uri, "key_format=i,value_format=S")); + testutil_check(session->open_cursor(session, opts->uri, NULL, NULL, &cursor)); + + memset(buf, 0xA, WT_MEGABYTE); + buf[WT_MEGABYTE - 1] = '\0'; + + /* Populate the table. */ + for (i = 0; i < NUM_KEYS; ++i) { + cursor->set_key(cursor, i); + cursor->set_value(cursor, buf); + testutil_check(cursor->insert(cursor)); + } + + /* + * Open a snapshot isolation transaction in another session. This forces + * the cache to retain all previous values. Then update all keys with a + * new value in the original session while keeping that snapshot + * transaction open. With the large value buffer, small cache and lots + * of keys, this will force a lot of lookaside usage. + * + * When the file_max setting is small, the maximum size should easily be + * reached and we should panic. When the maximum size is large or not + * set, then we should succeed. + */ + testutil_check(opts->conn->open_session(opts->conn, NULL, NULL, &other_session)); + testutil_check(other_session->begin_transaction(other_session, "isolation=snapshot")); + + memset(buf, 0xB, WT_MEGABYTE); + buf[WT_MEGABYTE - 1] = '\0'; + + for (i = 0; i < NUM_KEYS; ++i) { + cursor->set_key(cursor, i); + cursor->set_value(cursor, buf); + testutil_check(cursor->update(cursor)); + } + + /* + * Cleanup. We do not get here when the file_max size is small because we will have already hit + * the maximum and exited. This code only executes on the successful path. + */ + testutil_check(other_session->rollback_transaction(other_session, NULL)); + testutil_check(other_session->close(other_session, NULL)); + + testutil_check(cursor->close(cursor)); + testutil_check(session->close(session, NULL)); } static int test_las_workload(TEST_OPTS *opts, const char *las_file_max) { - pid_t pid; - int status; - - /* - * We're going to run this workload for different configurations of - * file_max. So clean out the work directory each time. - */ - testutil_make_work_dir(opts->home); - - /* - * Since it's possible that the workload will panic and abort, we will - * fork the process and execute the workload in the child process. - * - * This way, we can safely check the exit code of the child process and - * confirm that it is what we expected. - */ - pid = fork(); - if (pid < 0) - /* Failed fork. */ - testutil_die(errno, "fork"); - else if (pid == 0) { - /* Child process from here. */ - las_workload(opts, las_file_max); - - /* - * If we're expecting a panic during the workload, we shouldn't - * get to this point. Exit with non-zero to indicate to parent - * that we should fail this test. - */ - fprintf(stderr, - "Successfully completed workload (expect_panic=%s)\n", - expect_panic ? "true" : "false"); - - if (expect_panic) - exit(EXIT_FAILURE); - else - exit(EXIT_SUCCESS); - } - - /* Parent process from here. */ - if (waitpid(pid, &status, 0) == -1) - testutil_die(errno, "waitpid"); - - return (status); + pid_t pid; + int status; + + /* + * We're going to run this workload for different configurations of file_max. So clean out the + * work directory each time. + */ + testutil_make_work_dir(opts->home); + + /* + * Since it's possible that the workload will panic and abort, we will + * fork the process and execute the workload in the child process. + * + * This way, we can safely check the exit code of the child process and + * confirm that it is what we expected. + */ + pid = fork(); + if (pid < 0) + /* Failed fork. */ + testutil_die(errno, "fork"); + else if (pid == 0) { + /* Child process from here. */ + las_workload(opts, las_file_max); + + /* + * If we're expecting a panic during the workload, we shouldn't get to this point. Exit with + * non-zero to indicate to parent that we should fail this test. + */ + fprintf(stderr, "Successfully completed workload (expect_panic=%s)\n", + expect_panic ? "true" : "false"); + + if (expect_panic) + exit(EXIT_FAILURE); + else + exit(EXIT_SUCCESS); + } + + /* Parent process from here. */ + if (waitpid(pid, &status, 0) == -1) + testutil_die(errno, "waitpid"); + + return (status); } int main(int argc, char **argv) { - TEST_OPTS opts; - - memset(&opts, 0x0, sizeof(opts)); - testutil_check(testutil_parse_opts(argc, argv, &opts)); - - /* - * The lookaside is unbounded. - * We don't expect any failure since we can use as much as needed. - */ - expect_panic = false; - testutil_check(test_las_workload(&opts, "0")); - - /* - * The lookaside is limited to 5GB. - * This is more than enough for this workload so we don't expect any - * failure. - */ - expect_panic = false; - testutil_check(test_las_workload(&opts, "5GB")); - - /* - * The lookaside is limited to 100MB. - * This is insufficient for this workload so we're expecting a failure. - */ - expect_panic = true; - testutil_check(test_las_workload(&opts, "100MB")); - - testutil_cleanup(&opts); - - return (0); + TEST_OPTS opts; + + memset(&opts, 0x0, sizeof(opts)); + testutil_check(testutil_parse_opts(argc, argv, &opts)); + + /* + * The lookaside is unbounded. We don't expect any failure since we can use as much as needed. + */ + expect_panic = false; + testutil_check(test_las_workload(&opts, "0")); + + /* + * The lookaside is limited to 5GB. This is more than enough for this workload so we don't + * expect any failure. + */ + expect_panic = false; + testutil_check(test_las_workload(&opts, "5GB")); + + /* + * The lookaside is limited to 100MB. This is insufficient for this workload so we're expecting + * a failure. + */ + expect_panic = true; + testutil_check(test_las_workload(&opts, "100MB")); + + testutil_cleanup(&opts); + + return (0); } |