diff options
Diffstat (limited to 't/helper')
| -rw-r--r-- | t/helper/test-bundle-uri.c | 95 | ||||
| -rw-r--r-- | t/helper/test-path-utils.c | 3 | ||||
| -rw-r--r-- | t/helper/test-proc-receive.c | 2 | ||||
| -rw-r--r-- | t/helper/test-run-command.c | 77 | ||||
| -rw-r--r-- | t/helper/test-tool.c | 1 | ||||
| -rw-r--r-- | t/helper/test-tool.h | 1 | ||||
| -rw-r--r-- | t/helper/test-trace2.c | 187 |
7 files changed, 336 insertions, 30 deletions
diff --git a/t/helper/test-bundle-uri.c b/t/helper/test-bundle-uri.c new file mode 100644 index 0000000000..25afd39342 --- /dev/null +++ b/t/helper/test-bundle-uri.c @@ -0,0 +1,95 @@ +#include "test-tool.h" +#include "parse-options.h" +#include "bundle-uri.h" +#include "strbuf.h" +#include "string-list.h" + +enum input_mode { + KEY_VALUE_PAIRS, + CONFIG_FILE, +}; + +static int cmd__bundle_uri_parse(int argc, const char **argv, enum input_mode mode) +{ + const char *key_value_usage[] = { + "test-tool bundle-uri parse-key-values <input>", + NULL + }; + const char *config_usage[] = { + "test-tool bundle-uri parse-config <input>", + NULL + }; + const char **usage = key_value_usage; + struct option options[] = { + OPT_END(), + }; + struct strbuf sb = STRBUF_INIT; + struct bundle_list list; + int err = 0; + FILE *fp; + + if (mode == CONFIG_FILE) + usage = config_usage; + + argc = parse_options(argc, argv, NULL, options, usage, + PARSE_OPT_STOP_AT_NON_OPTION); + + init_bundle_list(&list); + + switch (mode) { + case KEY_VALUE_PAIRS: + if (argc != 1) + goto usage; + fp = fopen(argv[0], "r"); + if (!fp) + die("failed to open '%s'", argv[0]); + while (strbuf_getline(&sb, fp) != EOF) { + if (bundle_uri_parse_line(&list, sb.buf)) + err = error("bad line: '%s'", sb.buf); + } + fclose(fp); + break; + + case CONFIG_FILE: + if (argc != 1) + goto usage; + err = bundle_uri_parse_config_format("<uri>", argv[0], &list); + break; + } + strbuf_release(&sb); + + print_bundle_list(stdout, &list); + + clear_bundle_list(&list); + + return !!err; + +usage: + usage_with_options(usage, options); +} + +int cmd__bundle_uri(int argc, const char **argv) +{ + const char *usage[] = { + "test-tool bundle-uri <subcommand> [<options>]", + NULL + }; + struct option options[] = { + OPT_END(), + }; + + argc = parse_options(argc, argv, NULL, options, usage, + PARSE_OPT_STOP_AT_NON_OPTION | + PARSE_OPT_KEEP_ARGV0); + if (argc == 1) + goto usage; + + if (!strcmp(argv[1], "parse-key-values")) + return cmd__bundle_uri_parse(argc - 1, argv + 1, KEY_VALUE_PAIRS); + if (!strcmp(argv[1], "parse-config")) + return cmd__bundle_uri_parse(argc - 1, argv + 1, CONFIG_FILE); + error("there is no test-tool bundle-uri tool '%s'", argv[1]); + +usage: + usage_with_options(usage, options); +} diff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c index d20e1b7a18..f69709d674 100644 --- a/t/helper/test-path-utils.c +++ b/t/helper/test-path-utils.c @@ -8,7 +8,8 @@ * GIT_CEILING_DIRECTORIES. If the path is unusable for some reason, * die with an explanation. */ -static int normalize_ceiling_entry(struct string_list_item *item, void *unused) +static int normalize_ceiling_entry(struct string_list_item *item, + void *data UNUSED) { char *ceil = item->string; diff --git a/t/helper/test-proc-receive.c b/t/helper/test-proc-receive.c index cc08506cf0..a4b305f494 100644 --- a/t/helper/test-proc-receive.c +++ b/t/helper/test-proc-receive.c @@ -6,7 +6,7 @@ #include "test-tool.h" static const char *proc_receive_usage[] = { - "test-tool proc-receive [<options>...]", + "test-tool proc-receive [<options>]", NULL }; diff --git a/t/helper/test-run-command.c b/t/helper/test-run-command.c index c9283b47af..3ecb830f4a 100644 --- a/t/helper/test-run-command.c +++ b/t/helper/test-run-command.c @@ -136,7 +136,7 @@ static const char * const testsuite_usage[] = { static int testsuite(int argc, const char **argv) { struct testsuite suite = TESTSUITE_INIT; - int max_jobs = 1, i, ret; + int max_jobs = 1, i, ret = 0; DIR *dir; struct dirent *d; struct option options[] = { @@ -152,6 +152,12 @@ static int testsuite(int argc, const char **argv) "write JUnit-style XML files"), OPT_END() }; + struct run_process_parallel_opts opts = { + .get_next_task = next_test, + .start_failure = test_failed, + .task_finished = test_finished, + .data = &suite, + }; argc = parse_options(argc, argv, NULL, options, testsuite_usage, PARSE_OPT_STOP_AT_NON_OPTION); @@ -192,8 +198,8 @@ static int testsuite(int argc, const char **argv) fprintf(stderr, "Running %"PRIuMAX" tests (%d at a time)\n", (uintmax_t)suite.tests.nr, max_jobs); - ret = run_processes_parallel(max_jobs, next_test, test_failed, - test_finished, &suite); + opts.processes = max_jobs; + run_processes_parallel(&opts); if (suite.failed.nr > 0) { ret = 1; @@ -206,7 +212,7 @@ static int testsuite(int argc, const char **argv) string_list_clear(&suite.tests, 0); string_list_clear(&suite.failed, 0); - return !!ret; + return ret; } static uint64_t my_random_next = 1234; @@ -381,13 +387,17 @@ int cmd__run_command(int argc, const char **argv) { struct child_process proc = CHILD_PROCESS_INIT; int jobs; + int ret; + struct run_process_parallel_opts opts = { + .data = &proc, + }; if (argc > 1 && !strcmp(argv[1], "testsuite")) - exit(testsuite(argc - 1, argv + 1)); + return testsuite(argc - 1, argv + 1); if (!strcmp(argv[1], "inherited-handle")) - exit(inherit_handle(argv[0])); + return inherit_handle(argv[0]); if (!strcmp(argv[1], "inherited-handle-child")) - exit(inherit_handle_child()); + return inherit_handle_child(); if (argc >= 2 && !strcmp(argv[1], "quote-stress-test")) return !!quote_stress_test(argc - 1, argv + 1); @@ -404,41 +414,52 @@ int cmd__run_command(int argc, const char **argv) argv += 2; argc -= 2; } - if (argc < 3) - return 1; + if (argc < 3) { + ret = 1; + goto cleanup; + } strvec_pushv(&proc.args, (const char **)argv + 2); if (!strcmp(argv[1], "start-command-ENOENT")) { - if (start_command(&proc) < 0 && errno == ENOENT) - return 0; + if (start_command(&proc) < 0 && errno == ENOENT) { + ret = 0; + goto cleanup; + } fprintf(stderr, "FAIL %s\n", argv[1]); return 1; } - if (!strcmp(argv[1], "run-command")) - exit(run_command(&proc)); + if (!strcmp(argv[1], "run-command")) { + ret = run_command(&proc); + goto cleanup; + } if (!strcmp(argv[1], "--ungroup")) { argv += 1; argc -= 1; - run_processes_parallel_ungroup = 1; + opts.ungroup = 1; } jobs = atoi(argv[2]); strvec_clear(&proc.args); strvec_pushv(&proc.args, (const char **)argv + 3); - if (!strcmp(argv[1], "run-command-parallel")) - exit(run_processes_parallel(jobs, parallel_next, - NULL, NULL, &proc)); - - if (!strcmp(argv[1], "run-command-abort")) - exit(run_processes_parallel(jobs, parallel_next, - NULL, task_finished, &proc)); - - if (!strcmp(argv[1], "run-command-no-jobs")) - exit(run_processes_parallel(jobs, no_job, - NULL, task_finished, &proc)); - - fprintf(stderr, "check usage\n"); - return 1; + if (!strcmp(argv[1], "run-command-parallel")) { + opts.get_next_task = parallel_next; + } else if (!strcmp(argv[1], "run-command-abort")) { + opts.get_next_task = parallel_next; + opts.task_finished = task_finished; + } else if (!strcmp(argv[1], "run-command-no-jobs")) { + opts.get_next_task = no_job; + opts.task_finished = task_finished; + } else { + ret = 1; + fprintf(stderr, "check usage\n"); + goto cleanup; + } + opts.processes = jobs; + run_processes_parallel(&opts); + ret = 0; +cleanup: + child_process_clear(&proc); + return ret; } diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c index d1d013bcd9..01cda9358d 100644 --- a/t/helper/test-tool.c +++ b/t/helper/test-tool.c @@ -13,6 +13,7 @@ static struct test_cmd cmds[] = { { "advise", cmd__advise_if_enabled }, { "bitmap", cmd__bitmap }, { "bloom", cmd__bloom }, + { "bundle-uri", cmd__bundle_uri }, { "chmtime", cmd__chmtime }, { "config", cmd__config }, { "crontab", cmd__crontab }, diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h index 6b46b6444b..ca2948066f 100644 --- a/t/helper/test-tool.h +++ b/t/helper/test-tool.h @@ -7,6 +7,7 @@ int cmd__advise_if_enabled(int argc, const char **argv); int cmd__bitmap(int argc, const char **argv); int cmd__bloom(int argc, const char **argv); +int cmd__bundle_uri(int argc, const char **argv); int cmd__chmtime(int argc, const char **argv); int cmd__config(int argc, const char **argv); int cmd__crontab(int argc, const char **argv); diff --git a/t/helper/test-trace2.c b/t/helper/test-trace2.c index a714130ece..1b092c6071 100644 --- a/t/helper/test-trace2.c +++ b/t/helper/test-trace2.c @@ -229,6 +229,187 @@ static int ut_010bug_BUG(int argc, const char **argv) } /* + * Single-threaded timer test. Create several intervals using the + * TEST1 timer. The test script can verify that an aggregate Trace2 + * "timer" event is emitted indicating that we started+stopped the + * timer the requested number of times. + */ +static int ut_100timer(int argc, const char **argv) +{ + const char *usage_error = + "expect <count> <ms_delay>"; + + int count = 0; + int delay = 0; + int k; + + if (argc != 2) + die("%s", usage_error); + if (get_i(&count, argv[0])) + die("%s", usage_error); + if (get_i(&delay, argv[1])) + die("%s", usage_error); + + for (k = 0; k < count; k++) { + trace2_timer_start(TRACE2_TIMER_ID_TEST1); + sleep_millisec(delay); + trace2_timer_stop(TRACE2_TIMER_ID_TEST1); + } + + return 0; +} + +struct ut_101_data { + int count; + int delay; +}; + +static void *ut_101timer_thread_proc(void *_ut_101_data) +{ + struct ut_101_data *data = _ut_101_data; + int k; + + trace2_thread_start("ut_101"); + + for (k = 0; k < data->count; k++) { + trace2_timer_start(TRACE2_TIMER_ID_TEST2); + sleep_millisec(data->delay); + trace2_timer_stop(TRACE2_TIMER_ID_TEST2); + } + + trace2_thread_exit(); + return NULL; +} + +/* + * Multi-threaded timer test. Create several threads that each create + * several intervals using the TEST2 timer. The test script can verify + * that an individual Trace2 "th_timer" events for each thread and an + * aggregate "timer" event are generated. + */ +static int ut_101timer(int argc, const char **argv) +{ + const char *usage_error = + "expect <count> <ms_delay> <threads>"; + + struct ut_101_data data = { 0, 0 }; + int nr_threads = 0; + int k; + pthread_t *pids = NULL; + + if (argc != 3) + die("%s", usage_error); + if (get_i(&data.count, argv[0])) + die("%s", usage_error); + if (get_i(&data.delay, argv[1])) + die("%s", usage_error); + if (get_i(&nr_threads, argv[2])) + die("%s", usage_error); + + CALLOC_ARRAY(pids, nr_threads); + + for (k = 0; k < nr_threads; k++) { + if (pthread_create(&pids[k], NULL, ut_101timer_thread_proc, &data)) + die("failed to create thread[%d]", k); + } + + for (k = 0; k < nr_threads; k++) { + if (pthread_join(pids[k], NULL)) + die("failed to join thread[%d]", k); + } + + free(pids); + + return 0; +} + +/* + * Single-threaded counter test. Add several values to the TEST1 counter. + * The test script can verify that the final sum is reported in the "counter" + * event. + */ +static int ut_200counter(int argc, const char **argv) +{ + const char *usage_error = + "expect <v1> [<v2> [...]]"; + int value; + int k; + + if (argc < 1) + die("%s", usage_error); + + for (k = 0; k < argc; k++) { + if (get_i(&value, argv[k])) + die("invalid value[%s] -- %s", + argv[k], usage_error); + trace2_counter_add(TRACE2_COUNTER_ID_TEST1, value); + } + + return 0; +} + +/* + * Multi-threaded counter test. Create seveal threads that each increment + * the TEST2 global counter. The test script can verify that an individual + * "th_counter" event is generated with a partial sum for each thread and + * that a final aggregate "counter" event is generated. + */ + +struct ut_201_data { + int v1; + int v2; +}; + +static void *ut_201counter_thread_proc(void *_ut_201_data) +{ + struct ut_201_data *data = _ut_201_data; + + trace2_thread_start("ut_201"); + + trace2_counter_add(TRACE2_COUNTER_ID_TEST2, data->v1); + trace2_counter_add(TRACE2_COUNTER_ID_TEST2, data->v2); + + trace2_thread_exit(); + return NULL; +} + +static int ut_201counter(int argc, const char **argv) +{ + const char *usage_error = + "expect <v1> <v2> <threads>"; + + struct ut_201_data data = { 0, 0 }; + int nr_threads = 0; + int k; + pthread_t *pids = NULL; + + if (argc != 3) + die("%s", usage_error); + if (get_i(&data.v1, argv[0])) + die("%s", usage_error); + if (get_i(&data.v2, argv[1])) + die("%s", usage_error); + if (get_i(&nr_threads, argv[2])) + die("%s", usage_error); + + CALLOC_ARRAY(pids, nr_threads); + + for (k = 0; k < nr_threads; k++) { + if (pthread_create(&pids[k], NULL, ut_201counter_thread_proc, &data)) + die("failed to create thread[%d]", k); + } + + for (k = 0; k < nr_threads; k++) { + if (pthread_join(pids[k], NULL)) + die("failed to join thread[%d]", k); + } + + free(pids); + + return 0; +} + +/* * Usage: * test-tool trace2 <ut_name_1> <ut_usage_1> * test-tool trace2 <ut_name_2> <ut_usage_2> @@ -248,6 +429,12 @@ static struct unit_test ut_table[] = { { ut_008bug, "008bug", "" }, { ut_009bug_BUG, "009bug_BUG","" }, { ut_010bug_BUG, "010bug_BUG","" }, + + { ut_100timer, "100timer", "<count> <ms_delay>" }, + { ut_101timer, "101timer", "<count> <ms_delay> <threads>" }, + + { ut_200counter, "200counter", "<v1> [<v2> [<v3> [...]]]" }, + { ut_201counter, "201counter", "<v1> <v2> <threads>" }, }; /* clang-format on */ |
