static void _new_local_candidate (FsStream *stream, FsCandidate *candidate) { struct SimpleTestStream *st = g_object_get_data (G_OBJECT (stream), "SimpleTestStream"); gboolean ret; GError *error = NULL; struct SimpleTestStream *other_st; GList *candidates = NULL; TEST_LOCK (); if (st->target == NULL) { TEST_UNLOCK (); return; } other_st = find_pointback_stream (st->target, st->dat); if (other_st->stream == NULL || (candidate->component_id == FS_COMPONENT_RTCP && no_rtcp)) { TEST_UNLOCK (); return; } st->got_candidates = TRUE; GST_DEBUG ("%d:%d: Setting remote candidate for component %d", other_st->dat->id, other_st->target->id, candidate->component_id); if (other_st->stream == NULL) { TEST_UNLOCK (); return; } candidates = g_list_prepend (NULL, candidate); ret = fs_stream_add_remote_candidates (other_st->stream, candidates, &error); if (ret == FALSE && error && error->domain == FS_ERROR && error->code == FS_ERROR_NOT_IMPLEMENTED) { g_clear_error (&error); ret = fs_stream_force_remote_candidates (other_st->stream, candidates, &error); } g_list_free (candidates); if (error) ts_fail ("Error while adding candidate: (%s:%d) %s", g_quark_to_string (error->domain), error->code, error->message); ts_fail_unless (ret == TRUE, "No detailed error from add_remote_candidate"); TEST_UNLOCK (); }
static int run_test0 (struct run_args *run_args) { struct test *test = run_args->test; test_timing_t t_run; int r; char stats_file[256]; rd_snprintf(stats_file, sizeof(stats_file), "stats_%s_%"PRIu64".json", test->name, test_id_generate()); if (!(test->stats_fp = fopen(stats_file, "w+"))) TEST_SAY("=== Failed to create stats file %s: %s ===\n", stats_file, strerror(errno)); test_curr = test; TEST_SAY("================= Running test %s =================\n", test->name); if (test->stats_fp) TEST_SAY("==== Stats written to file %s ====\n", stats_file); TIMING_START(&t_run, test->name); test->start = t_run.ts_start; r = test->mainfunc(run_args->argc, run_args->argv); TIMING_STOP(&t_run); TEST_LOCK(); test->duration = TIMING_DURATION(&t_run); if (r) { test->state = TEST_FAILED; TEST_SAY("\033[31m" "================= Test %s FAILED =================" "\033[0m\n", run_args->test->name); } else { test->state = TEST_PASSED; TEST_SAY("\033[32m" "================= Test %s PASSED =================" "\033[0m\n", run_args->test->name); } TEST_UNLOCK(); if (test->stats_fp) { long pos = ftell(test->stats_fp); fclose(test->stats_fp); test->stats_fp = NULL; /* Delete file if nothing was written */ if (pos == 0) { #ifndef _MSC_VER unlink(stats_file); #else _unlink(stats_file); #endif } } return r; }
static void sig_alarm (int sig) { int do_unlock; TEST_SAY0(_C_RED "\nTEST WATCHDOG TRIGGERED\n" _C_CLR); /* The lock may already be held */ do_unlock = mtx_trylock(&test_mtx) == thrd_success; test_summary(0/*no-locks*/); if (do_unlock) TEST_UNLOCK(); TEST_FAIL("Test timed out (%d tests running)", tests_running_cnt); assert(!*"test timeout"); }
static void unref_session_on_src_pad_added (FsStream *stream, GstPad *pad, FsCodec *codec, struct SimpleTestStream *st) { TEST_LOCK (); ASSERT_CRITICAL (fs_session_destroy (st->dat->session)); TEST_UNLOCK (); g_main_loop_quit (loop); }
static int run_test (struct test *test, int argc, char **argv) { thrd_t thr; struct run_args *run_args = calloc(1, sizeof(*run_args)); int wait_cnt = 0; run_args->test = test; run_args->argc = argc; run_args->argv = argv; TEST_LOCK(); while (tests_running_cnt >= test_concurrent_max) { if (!(wait_cnt++ % 10)) TEST_SAY("Too many tests running (%d >= %d): " "postponing %s start...\n", tests_running_cnt, test_concurrent_max, test->name); TEST_UNLOCK(); rd_sleep(1); TEST_LOCK(); } tests_running_cnt++; test->state = TEST_RUNNING; TEST_UNLOCK(); if (thrd_create(&thr, run_test_from_thread, run_args) != thrd_success) { TEST_LOCK(); tests_running_cnt--; test->state = TEST_FAILED; TEST_UNLOCK(); TEST_FAIL("Failed to start thread for test %s\n", test->name); } return 0; }
static int run_test_from_thread (void *arg) { struct run_args *run_args = arg; thrd_detach(thrd_current()); run_test0(run_args); TEST_LOCK(); tests_running_cnt--; TEST_UNLOCK(); free(run_args); return 0; }
/** * @brief Sockem connect, called from **internal librdkafka thread** through * librdkafka's connect_cb */ static int connect_cb (struct test *test, sockem_t *skm, const char *id) { int r; TEST_LOCK(); r = simulate_network_down; TEST_UNLOCK(); if (r) { sockem_close(skm); return ECONNREFUSED; } else { /* Let it go real slow so we dont consume all * the messages right away. */ sockem_set(skm, "rx.thruput", 100000, NULL); } return 0; }
static void run_tests (const char *tests_to_run, int test_flags, int argc, char **argv) { struct test *test; for (test = tests ; test->name ; test++) { char testnum[128]; char *t; const char *skip_reason = NULL; if (!test->mainfunc) continue; /* Extract test number, as string */ strncpy(testnum, test->name, sizeof(testnum)-1); testnum[sizeof(testnum)-1] = '\0'; if ((t = strchr(testnum, '_'))) *t = '\0'; if ((test_flags && (test_flags & test->flags) != test_flags)) skip_reason = "filtered due to test flags"; if (tests_to_run && !strstr(tests_to_run, testnum)) skip_reason = "not included in TESTS list"; if (!skip_reason) { run_test(test, argc, argv); } else { TEST_SAY("================= Skipping test %s (%s)" "================\n", test->name, skip_reason); TEST_LOCK(); test->state = TEST_SKIPPED; TEST_UNLOCK(); } } }
int main(int argc, char **argv) { const char *tests_to_run = NULL; /* all */ int test_flags = 0; int i, r; test_timing_t t_all; mtx_init(&test_mtx, mtx_plain); test_init(); #ifndef _MSC_VER tests_to_run = getenv("TESTS"); #endif for (i = 1 ; i < argc ; i++) { if (!strncmp(argv[i], "-p", 2) && strlen(argv[i]) > 2) test_concurrent_max = strtod(argv[i]+2, NULL); else if (!strcmp(argv[i], "-l")) test_flags |= TEST_F_LOCAL; else if (!strcmp(argv[i], "-a")) test_assert_on_fail = 1; else if (*argv[i] != '-') tests_to_run = argv[i]; else { printf("Unknown option: %s\n" "\n" "Usage: %s [options] [<test-match-substr>]\n" "Options:\n" " -p<N> Run N tests in parallel\n" " -l Only run local tests (no broker needed)\n" " -a Assert on failures\n" "\n", argv[0], argv[i]); exit(1); } } test_curr = &tests[0]; test_curr->state = TEST_PASSED; test_curr->start = test_clock(); TEST_SAY("Tests to run: %s\n", tests_to_run ? tests_to_run : "all"); TEST_SAY("Test filter: %s\n", (test_flags & TEST_F_LOCAL) ? "local tests only" : "no filter"); TEST_SAY("Action on test failure: %s\n", test_assert_on_fail ? "assert crash" : "continue other tests"); test_timeout_set(20); TIMING_START(&t_all, "ALL-TESTS"); run_tests(tests_to_run, test_flags, argc, argv); TEST_LOCK(); while (tests_running_cnt > 0) { struct test *test; TEST_SAY("%d test(s) running:", tests_running_cnt); for (test = tests ; test->name ; test++) if (test->state == TEST_RUNNING) TEST_SAY0(" %s", test->name); TEST_SAY0("\n"); TEST_UNLOCK(); rd_sleep(1); TEST_LOCK(); } TIMING_STOP(&t_all); test_curr = &tests[0]; test_curr->duration = test_clock() - test_curr->start; TEST_UNLOCK(); /* Wait for everything to be cleaned up since broker destroys are * handled in its own thread. */ test_wait_exit(10); r = test_summary(1/*lock*/) ? 1 : 0; /* If we havent failed at this point then * there were no threads leaked */ if (r == 0) TEST_SAY("\n============== ALL TESTS PASSED ==============\n"); return r; }
/** * @brief Print summary for all tests. * * @returns the number of failed tests. */ static int test_summary (int do_lock) { struct test *test; FILE *report_fp; char report_path[128]; time_t t; struct tm *tm; char datestr[64]; int64_t total_duration; int tests_run = 0; int tests_failed = 0; int tests_passed = 0; t = time(NULL); tm = localtime(&t); strftime(datestr, sizeof(datestr), "%Y%m%d%H%M%S", tm); rd_snprintf(report_path, sizeof(report_path), "test_report_%s.json", datestr); report_fp = fopen(report_path, "w+"); if (!report_fp) TEST_WARN("Failed to create report file %s: %s\n", report_path, strerror(errno)); else fprintf(report_fp, "{ \"date\": \"%s\", \"tests\": [", datestr); printf("TEST SUMMARY\n" "#==================================================================#\n"); if (do_lock) TEST_LOCK(); for (test = tests ; test->name ; test++) { const char *color; int64_t duration; if (!(duration = test->duration) && test->start > 0) duration = test_clock() - test->start; if (test == tests) /* <MAIN> test accounts for total runtime */ total_duration = duration; switch (test->state) { case TEST_PASSED: color = _C_GRN; tests_passed++; tests_run++; break; case TEST_FAILED: color = _C_RED; tests_failed++; tests_run++; break; case TEST_RUNNING: color = _C_MAG; tests_run++; break; case TEST_NOT_STARTED: color = _C_YEL; break; default: color = _C_CYA; break; } printf("|%s %-40s | %10s | %7.3fs %s|\n", color, test->name, test_states[test->state], (double)duration/1000000.0, _C_CLR); if (report_fp) fprintf(report_fp, "%s{" "\"name\": \"%s\", " "\"state\": \"%s\", " "\"duration\": %.3f" "}", test == tests ? "": ", ", test->name, test_states[test->state], (double)duration/1000000.0); } if (do_lock) TEST_UNLOCK(); printf("#==================================================================#\n"); if (report_fp) { fprintf(report_fp, "], " "\"tests_run\": %d, " "\"tests_passed\": %d, " "\"tests_failed\": %d, " "\"duration\": %.3f" "}\n", tests_run, tests_passed, tests_failed, (double)total_duration/1000000.0); fclose(report_fp); TEST_SAY("# Test report written to %s\n", report_path); } return tests_failed; }
static void test_read_conf_file (const char *conf_path, rd_kafka_conf_t *conf, rd_kafka_topic_conf_t *topic_conf, int *timeoutp) { FILE *fp; char buf[512]; int line = 0; #ifndef _MSC_VER fp = fopen(conf_path, "r"); #else fp = NULL; errno = fopen_s(&fp, conf_path, "r"); #endif if (!fp) { if (errno == ENOENT) { TEST_SAY("Test config file %s not found\n", conf_path); return; } else TEST_FAIL("Failed to read %s: %s", conf_path, strerror(errno)); } while (fgets(buf, sizeof(buf)-1, fp)) { char *t; char *b = buf; rd_kafka_conf_res_t res = RD_KAFKA_CONF_UNKNOWN; char *name, *val; char errstr[512]; line++; if ((t = strchr(b, '\n'))) *t = '\0'; if (*b == '#' || !*b) continue; if (!(t = strchr(b, '='))) TEST_FAIL("%s:%i: expected name=value format\n", conf_path, line); name = b; *t = '\0'; val = t+1; if (!strcmp(name, "test.timeout.multiplier")) { TEST_LOCK(); test_timeout_multiplier = strtod(val, NULL); TEST_UNLOCK(); *timeoutp = tmout_multip((*timeoutp)*1000) / 1000; res = RD_KAFKA_CONF_OK; } else if (!strcmp(name, "test.topic.prefix")) { rd_snprintf(test_topic_prefix, sizeof(test_topic_prefix), "%s", val); res = RD_KAFKA_CONF_OK; } else if (!strcmp(name, "test.topic.random")) { if (!strcmp(val, "true") || !strcmp(val, "1")) test_topic_random = 1; else test_topic_random = 0; res = RD_KAFKA_CONF_OK; } else if (!strcmp(name, "test.concurrent.max")) { TEST_LOCK(); test_concurrent_max = strtod(val, NULL); TEST_UNLOCK(); res = RD_KAFKA_CONF_OK; } else if (!strncmp(name, "topic.", strlen("topic."))) { name += strlen("topic."); if (topic_conf) res = rd_kafka_topic_conf_set(topic_conf, name, val, errstr, sizeof(errstr)); else res = RD_KAFKA_CONF_OK; name -= strlen("topic."); } if (res == RD_KAFKA_CONF_UNKNOWN) { if (conf) res = rd_kafka_conf_set(conf, name, val, errstr, sizeof(errstr)); else res = RD_KAFKA_CONF_OK; } if (res != RD_KAFKA_CONF_OK) TEST_FAIL("%s:%i: %s\n", conf_path, line, errstr); } fclose(fp); }
static void nway_test (int in_count, extra_conf_init extra_conf_init, extra_stream_init extra_stream_init, const gchar *transmitter, guint st_param_count, GParameter *st_params) { int i, j; GParameter *params = NULL; if (!strcmp ("rawudp", transmitter)) { params = g_new0 (GParameter, st_param_count+2); memcpy (params, st_params, st_param_count * sizeof (GParameter)); params[st_param_count].name = "upnp-discovery"; g_value_init (¶ms[st_param_count].value, G_TYPE_BOOLEAN); g_value_set_boolean (¶ms[st_param_count].value, FALSE); params[st_param_count+1].name = "upnp-mapping"; g_value_init (¶ms[st_param_count+1].value, G_TYPE_BOOLEAN); g_value_set_boolean (¶ms[st_param_count+1].value, FALSE); st_param_count += 2; st_params = params; } count = in_count; loop = g_main_loop_new (NULL, FALSE); dats = g_new0 (struct SimpleTestConference *, count); for (i = 0; i < count; i++) { gchar *tmp = g_strdup_printf ("tester%d@hostname", i); dats[i] = setup_simple_conference (i, "fsrtpconference", tmp); g_free (tmp); g_object_set (G_OBJECT (dats[i]->session), "no-rtcp-timeout", -1, NULL); if (extra_conf_init) extra_conf_init (dats[i], i); rtpconference_connect_signals (dats[i]); g_idle_add (_start_pipeline, dats[i]); setup_fakesrc (dats[i]); if (i != 0) g_signal_connect (dats[i]->session, "notify::codecs", G_CALLBACK (_negotiated_codecs_notify), dats[i]); } TEST_LOCK (); for (i = 0; i < count; i++) for (j = 0; j < count; j++) if (i != j) { struct SimpleTestStream *st = NULL; st = simple_conference_add_stream (dats[i], dats[j], transmitter, st_param_count, st_params); st->handoff_handler = G_CALLBACK (_handoff_handler); g_signal_connect (st->stream, "src-pad-added", G_CALLBACK (_src_pad_added), st); if (extra_stream_init) extra_stream_init (st, i, j); } for (i = 1; i < count; i++) { struct SimpleTestStream *st = find_pointback_stream (dats[i], dats[0]); set_initial_codecs (dats[0], st); } TEST_UNLOCK (); g_main_loop_run (loop); for (i = 0; i < count; i++) gst_element_set_state (dats[i]->pipeline, GST_STATE_NULL); for (i = 0; i < count; i++) cleanup_simple_conference (dats[i]); g_free (dats); g_main_loop_unref (loop); g_free (params); }
int main_0049_consume_conn_close (int argc, char **argv) { rd_kafka_t *rk; const char *topic = test_mk_topic_name("0049_consume_conn_close", 1); uint64_t testid; int msgcnt = test_on_ci ? 1000 : 10000; test_msgver_t mv; rd_kafka_conf_t *conf; rd_kafka_topic_conf_t *tconf; rd_kafka_topic_partition_list_t *assignment; rd_kafka_resp_err_t err; if (!test_conf_match(NULL, "sasl.mechanisms", "GSSAPI")) { TEST_SKIP("KNOWN ISSUE: ApiVersionRequest+SaslHandshake " "will not play well with sudden disconnects\n"); return 0; } test_conf_init(&conf, &tconf, 60); /* Want an even number so it is divisable by two without surprises */ msgcnt = (msgcnt / (int)test_timeout_multiplier) & ~1; testid = test_id_generate(); test_produce_msgs_easy(topic, testid, RD_KAFKA_PARTITION_UA, msgcnt); test_socket_enable(conf); test_curr->connect_cb = connect_cb; test_curr->is_fatal_cb = is_fatal_cb; test_topic_conf_set(tconf, "auto.offset.reset", "smallest"); rk = test_create_consumer(topic, NULL, conf, tconf); test_consumer_subscribe(rk, topic); test_msgver_init(&mv, testid); test_consumer_poll("consume.up", rk, testid, -1, 0, msgcnt/2, &mv); err = rd_kafka_assignment(rk, &assignment); TEST_ASSERT(!err, "assignment() failed: %s", rd_kafka_err2str(err)); TEST_ASSERT(assignment->cnt > 0, "empty assignment"); TEST_SAY("Bringing down the network\n"); TEST_LOCK(); simulate_network_down = 1; TEST_UNLOCK(); test_socket_close_all(test_curr, 1/*reinit*/); TEST_SAY("Waiting for session timeout to expire (6s), and then some\n"); /* Commit an offset, which should fail, to trigger the offset commit * callback fallback (CONSUMER_ERR) */ assignment->elems[0].offset = 123456789; TEST_SAY("Committing offsets while down, should fail eventually\n"); err = rd_kafka_commit(rk, assignment, 1/*async*/); TEST_ASSERT(!err, "async commit failed: %s", rd_kafka_err2str(err)); rd_kafka_topic_partition_list_destroy(assignment); rd_sleep(10); TEST_SAY("Bringing network back up\n"); TEST_LOCK(); simulate_network_down = 0; TEST_UNLOCK(); TEST_SAY("Continuing to consume..\n"); test_consumer_poll("consume.up2", rk, testid, -1, msgcnt/2, msgcnt/2, &mv); test_msgver_verify("consume", &mv, TEST_MSGVER_ORDER|TEST_MSGVER_DUP, 0, msgcnt); test_msgver_clear(&mv); test_consumer_close(rk); rd_kafka_destroy(rk); return 0; }