SERVER_HANDLE_V1 *get_mock_server_api(void) { static SERVER_CORE_API core_api = { .server_version = mock_get_server_version, .hash = mock_hash, .realtime = mock_realtime, .get_current_time = mock_get_current_time, .abstime = mock_abstime, .parse_config = mock_parse_config }; static SERVER_COOKIE_API server_cookie_api = { .get_auth_data = mock_get_auth_data, .store_engine_specific = mock_store_engine_specific, .get_engine_specific = mock_get_engine_specific, .get_socket_fd = mock_get_socket_fd, .set_tap_nack_mode = mock_set_tap_nack_mode, .notify_io_complete = mock_notify_io_complete, .reserve = mock_cookie_reserve, .release = mock_cookie_release }; static SERVER_STAT_API server_stat_api = { .new_stats = mock_new_independent_stats, .release_stats = mock_release_independent_stats, .evicting = mock_count_eviction }; static SERVER_EXTENSION_API extension_api = { .register_extension = mock_register_extension, .unregister_extension = mock_unregister_extension, .get_extension = mock_get_extension }; static SERVER_CALLBACK_API callback_api = { .register_callback = mock_register_callback, .perform_callbacks = mock_perform_callbacks }; static SERVER_HANDLE_V1 rv = { .interface = 1, .core = &core_api, .stat = &server_stat_api, .extension = &extension_api, .callback = &callback_api, .cookie = &server_cookie_api }; return &rv; } void init_mock_server(ENGINE_HANDLE *server_engine) { process_started = time(0); null_logger = get_null_logger(); stderr_logger = get_stderr_logger(); engine = server_engine; extensions.logger = null_logger; }
int main(int argc, char **argv) { int c, exitcode = 0, num_cases = 0; const char *engine = NULL; const char *engine_args = NULL; const char *test_suite = NULL; engine_test_t *testcases = NULL; logger_descriptor = get_null_logger(); /* Hack to remove the warning from C99 */ union { GET_TESTS get_tests; void* voidptr; } my_get_test = {.get_tests = NULL }; /* Hack to remove the warning from C99 */ union { SETUP_SUITE setup_suite; void* voidptr; } my_setup_suite = {.setup_suite = NULL }; /* Hack to remove the warning from C99 */ union { TEARDOWN_SUITE teardown_suite; void* voidptr; } my_teardown_suite = {.teardown_suite = NULL }; /* Use unbuffered stdio */ setbuf(stdout, NULL); setbuf(stderr, NULL); /* process arguments */ while (-1 != (c = getopt(argc, argv, "h" /* usage */ "E:" /* Engine to load */ "e:" /* Engine options */ "T:" /* Library with tests to load */ ))) { switch (c) { case 'E': engine = optarg; break; case 'e': engine_args = optarg; break; case 'h': usage(); return 0; case 'T': test_suite = optarg; break; default: fprintf(stderr, "Illegal argument \"%c\"\n", c); return 1; } } //validate args if (engine == NULL) { fprintf(stderr, "You must provide a path to the storage engine library.\n"); return 1; } if (test_suite == NULL) { fprintf(stderr, "You must provide a path to the testsuite library.\n"); return 1; } //load test_suite void* handle = dlopen(test_suite, RTLD_NOW | RTLD_LOCAL); if (handle == NULL) { const char *msg = dlerror(); fprintf(stderr, "Failed to load testsuite %s: %s\n", test_suite, msg ? msg : "unknown error"); return 1; } //get the test cases void *symbol = dlsym(handle, "get_tests"); if (symbol == NULL) { const char *msg = dlerror(); fprintf(stderr, "Could not find get_tests function in testsuite %s: %s\n", test_suite, msg ? msg : "unknown error"); return 1; } my_get_test.voidptr = symbol; testcases = (*my_get_test.get_tests)(); //set up the suite if needed struct test_harness harness = { .default_engine_cfg = engine_args, .engine_path = engine, .reload_engine = reload_engine, .start_engine = start_your_engines, .create_cookie = create_mock_cookie, .destroy_cookie = destroy_mock_cookie, .set_ewouldblock_handling = mock_set_ewouldblock_handling, .lock_cookie = lock_mock_cookie, .unlock_cookie = unlock_mock_cookie, .waitfor_cookie = waitfor_mock_cookie}; symbol = dlsym(handle, "setup_suite"); if (symbol != NULL) { my_setup_suite.voidptr = symbol; if (!(*my_setup_suite.setup_suite)(&harness)) { fprintf(stderr, "Failed to set up test suite %s \n", test_suite); return 1; } } for (num_cases = 0; testcases[num_cases].name; num_cases++) { /* Just counting */ } printf("1..%d\n", num_cases); int i; for (i = 0; testcases[i].name; i++) { printf("Running %s... ", testcases[i].name); fflush(stdout); exitcode += report_test(run_test(testcases[i], engine, engine_args)); } //tear down the suite if needed symbol = dlsym(handle, "teardown_suite"); if (symbol != NULL) { my_teardown_suite.voidptr = symbol; if (!(*my_teardown_suite.teardown_suite)()) { fprintf(stderr, "Failed to teardown up test suite %s \n", test_suite); } } return exitcode; }
int main(int argc, char **argv) { int c, exitcode = 0, num_cases = 0, timeout = 0, loop_count = 0; bool verbose = false; bool quiet = false; bool dot = false; bool loop = false; bool terminate_on_error = false; const char *engine = NULL; const char *engine_args = NULL; const char *test_suite = NULL; const char *test_case = NULL; engine_test_t *testcases = NULL; logger_descriptor = get_null_logger(); /* Hack to remove the warning from C99 */ union { GET_TESTS get_tests; void* voidptr; } my_get_test = {.get_tests = NULL }; /* Hack to remove the warning from C99 */ union { SETUP_SUITE setup_suite; void* voidptr; } my_setup_suite = {.setup_suite = NULL }; /* Hack to remove the warning from C99 */ union { TEARDOWN_SUITE teardown_suite; void* voidptr; } my_teardown_suite = {.teardown_suite = NULL }; color_enabled = getenv("TESTAPP_ENABLE_COLOR") != NULL; /* Use unbuffered stdio */ setbuf(stdout, NULL); setbuf(stderr, NULL); setup_alarm_handler(); /* process arguments */ while (-1 != (c = getopt(argc, argv, "h" /* usage */ "E:" /* Engine to load */ "e:" /* Engine options */ "T:" /* Library with tests to load */ "t:" /* Timeout */ "L" /* Loop until failure */ "q" /* Be more quiet (only report failures) */ "." /* dot mode. */ "n:" /* test case to run */ "v" /* verbose output */ "Z" /* Terminate on first error */ ))) { switch (c) { case 'E': engine = optarg; break; case 'e': engine_args = optarg; break; case 'h': usage(); return 0; case 'T': test_suite = optarg; break; case 't': timeout = atoi(optarg); break; case 'L': loop = true; break; case 'n': test_case = optarg; break; case 'v' : verbose = true; break; case 'q': quiet = true; break; case '.': dot = true; break; case 'Z' : terminate_on_error = true; break; default: fprintf(stderr, "Illegal argument \"%c\"\n", c); return 1; } } //validate args if (engine == NULL) { fprintf(stderr, "You must provide a path to the storage engine library.\n"); return 1; } if (test_suite == NULL) { fprintf(stderr, "You must provide a path to the testsuite library.\n"); return 1; } //load test_suite void* handle = dlopen(test_suite, RTLD_NOW | RTLD_LOCAL); if (handle == NULL) { const char *msg = dlerror(); fprintf(stderr, "Failed to load testsuite %s: %s\n", test_suite, msg ? msg : "unknown error"); return 1; } //get the test cases void *symbol = dlsym(handle, "get_tests"); if (symbol == NULL) { const char *msg = dlerror(); fprintf(stderr, "Could not find get_tests function in testsuite %s: %s\n", test_suite, msg ? msg : "unknown error"); return 1; } my_get_test.voidptr = symbol; testcases = (*my_get_test.get_tests)(); //set up the suite if needed struct test_harness harness = { .default_engine_cfg = engine_args, .engine_path = engine, .reload_engine = reload_engine, .start_engine = start_your_engines, .create_cookie = create_mock_cookie, .destroy_cookie = destroy_mock_cookie, .set_ewouldblock_handling = mock_set_ewouldblock_handling, .lock_cookie = lock_mock_cookie, .unlock_cookie = unlock_mock_cookie, .waitfor_cookie = waitfor_mock_cookie, .time_travel = mock_time_travel, .get_current_testcase = get_current_testcase }; symbol = dlsym(handle, "setup_suite"); if (symbol != NULL) { my_setup_suite.voidptr = symbol; if (!(*my_setup_suite.setup_suite)(&harness)) { fprintf(stderr, "Failed to set up test suite %s \n", test_suite); return 1; } } for (num_cases = 0; testcases[num_cases].name; num_cases++) { /* Just counting */ } if (!quiet) { printf("1..%d\n", num_cases); } do { int i; bool need_newline = false; for (i = 0; testcases[i].name; i++) { int error; if (test_case != NULL && strcmp(test_case, testcases[i].name) != 0) continue; if (!quiet) { printf("Running [%04d/%04d]: %s...", i + num_cases * loop_count, num_cases * (loop_count + 1), testcases[i].name); fflush(stdout); } else if(dot) { printf("."); need_newline = true; /* Add a newline every few tests */ if ((i+1) % 70 == 0) { printf("\n"); need_newline = false; } } set_test_timeout(timeout); error = report_test(testcases[i].name, run_test(testcases[i], engine, engine_args), quiet, !verbose); clear_test_timeout(); if (error != 0) { ++exitcode; if (terminate_on_error) { exit(EXIT_FAILURE); } } } if (need_newline) { printf("\n"); } ++loop_count; } while (loop && exitcode == 0); //tear down the suite if needed symbol = dlsym(handle, "teardown_suite"); if (symbol != NULL) { my_teardown_suite.voidptr = symbol; if (!(*my_teardown_suite.teardown_suite)()) { fprintf(stderr, "Failed to teardown up test suite %s \n", test_suite); } } printf("# Passed %d of %d tests\n", num_cases - exitcode, num_cases); return exitcode; }