static gboolean bus_message_cb (InsanityGstPipelineTest * ptest, GstMessage * msg) { InsanityTest *test = INSANITY_TEST (ptest); switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_EOS: { /* If we are waiting for a segment, keep waiting for it */ if (glob_waiting_segment) { LOG (test, "EOS but waiting for a new segment... keep waiting"); return FALSE; } LOG (test, "EOS... current %s next test", test_get_name (glob_in_progress)); next_test (test); return FALSE; } default: break; } return TRUE; }
static gboolean next_test (InsanityTest * test) { switch (glob_in_progress) { case TEST_NONE: glob_in_progress = TEST_QUERIES; test_queries (test); break; case TEST_QUERIES: glob_in_progress = TEST_POSITION; break; case TEST_POSITION: if (glob_seekable == FALSE) { /* Do not enter seek mode tests and finnish the test */ unvalidate_seeking_tests (test); insanity_test_done (test); return FALSE; } glob_in_progress = TEST_BACKWARD_PLAYBACK; glob_waiting_segment = TRUE; g_timeout_add (1000, (GSourceFunc) & seek_mode_testing, test); break; case TEST_BACKWARD_PLAYBACK: glob_in_progress = TEST_FAST_FORWARD; glob_waiting_segment = TRUE; g_timeout_add (1000, (GSourceFunc) & seek_mode_testing, test); break; case TEST_FAST_FORWARD: glob_in_progress = TEST_FAST_BACKWARD; glob_waiting_segment = TRUE; g_timeout_add (1000, (GSourceFunc) & seek_mode_testing, test); break; default: insanity_test_done (test); return FALSE; } LOG (test, "%s in progress", test_get_name (glob_in_progress)); return FALSE; }
static gboolean next_test (InsanityTest * test) { gchar *sublocation = NULL, *xmllocation = NULL; GError *err = NULL; switch (glob_in_progress) { case TEST_SUBTTILE_DESCRIPTOR_GENERATION: { insanity_test_get_string_argument (test, "sublocation", &sublocation); xmllocation = g_strconcat (sublocation, ".subs.xml", NULL); LOG (test, "Done generation XML file, saving it to %s", xmllocation); if (media_descriptor_writer_write (glob_writer, xmllocation) == FALSE) { ERROR (test, "Could not write media descriptor"); insanity_test_done (test); goto done; } glob_parser = media_descriptor_parser_new (test, xmllocation, &err); if (glob_parser == NULL) { ERROR (test, "Could not create media descriptor after writing it"); insanity_test_done (test); goto done; } glob_subtitled_frames = media_descriptor_parser_get_buffers (glob_parser, NULL, (GCompareFunc) sort_subtitle_bufs); if (glob_subtitled_frames == NULL) { ERROR (test, "No subtitles frames found"); insanity_test_done (test); goto done; } else glob_first_subtitle_ts = GST_BUFFER_PTS (glob_subtitled_frames->data); /* We reset the test so it starts again from the beginning */ glob_in_progress = TEST_NONE; g_idle_add ((GSourceFunc) idle_restart_pipeline, NULL); break; } case TEST_NONE: glob_in_progress = TEST_SUBTITLE_DETECTION; break; case TEST_SUBTITLE_DETECTION: insanity_test_done (test); break; } LOG (test, "%s in progress", test_get_name (glob_in_progress)); done: g_free (sublocation); g_free (xmllocation); return FALSE; }
/* Pipeline Callbacks */ static gboolean probe_cb (InsanityGstTest * ptest, GstPad * pad, GstMiniObject * object, gpointer userdata) { InsanityTest *test = INSANITY_TEST (ptest); global_last_probe = g_get_monotonic_time (); DECODER_TEST_LOCK (); if (GST_IS_BUFFER (object)) { GstBuffer *buf; GstClockTime ts; buf = GST_BUFFER (object); ts = GST_BUFFER_PTS (buf); /* First check clipping */ if (glob_testing_parser == FALSE && GST_CLOCK_TIME_IS_VALID (ts) && glob_waiting_segment == FALSE) { GstClockTime ts_end, cstart, cstop; /* Check if buffer is completely outside the segment */ ts_end = ts; if (GST_BUFFER_DURATION_IS_VALID (buf)) ts_end += GST_BUFFER_DURATION (buf); /* Check if buffer is completely outside the segment */ ts_end = ts; if (!gst_segment_clip (&glob_last_segment, glob_last_segment.format, ts, ts_end, &cstart, &cstop)) { char *msg = g_strdup_printf ("Got timestamp %" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT ", outside configured segment (%" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT "), method %s", GST_TIME_ARGS (ts), GST_TIME_ARGS (ts_end), GST_TIME_ARGS (glob_last_segment.start), GST_TIME_ARGS (glob_last_segment.stop), test_get_name (glob_in_progress)); insanity_test_validate_checklist_item (INSANITY_TEST (ptest), "segment-clipping", FALSE, msg); g_free (msg); glob_bad_segment_clipping = TRUE; } } switch (glob_in_progress) { case TEST_NONE: if (glob_waiting_first_segment == TRUE) insanity_test_validate_checklist_item (test, "first-segment", FALSE, "Got a buffer before the first segment"); /* Got the first buffer, starting testing dance */ next_test (test); break; case TEST_POSITION: test_position (test, buf); break; case TEST_FAST_FORWARD: case TEST_BACKWARD_PLAYBACK: case TEST_FAST_BACKWARD: { gint64 stime_ts; if (GST_CLOCK_TIME_IS_VALID (ts) == FALSE || glob_waiting_segment == TRUE) { break; } stime_ts = gst_segment_to_stream_time (&glob_last_segment, glob_last_segment.format, ts); if (GST_CLOCK_TIME_IS_VALID (glob_seek_first_buf_ts) == FALSE) { GstClockTime expected_ts = gst_segment_to_stream_time (&glob_last_segment, glob_last_segment.format, glob_seek_rate < 0 ? glob_seek_stop_ts : glob_seek_segment_seektime); GstClockTimeDiff diff = ABS (GST_CLOCK_DIFF (stime_ts, expected_ts)); if (diff > SEEK_THRESHOLD) { gchar *valmsg = g_strdup_printf ("Received buffer timestamp %" GST_TIME_FORMAT " Seeek wanted %" GST_TIME_FORMAT "", GST_TIME_ARGS (stime_ts), GST_TIME_ARGS (expected_ts)); validate_current_test (test, FALSE, valmsg); next_test (test); g_free (valmsg); } else glob_seek_first_buf_ts = stime_ts; } else { GstClockTimeDiff diff = GST_CLOCK_DIFF (stime_ts, glob_seek_first_buf_ts); if (diff < 0) diff = -diff; if (diff >= glob_playback_duration * GST_SECOND) { validate_current_test (test, TRUE, NULL); next_test (test); } } break; } default: break; } } else if (GST_IS_EVENT (object)) { GstEvent *event = GST_EVENT (object); guint seqnum = gst_event_get_seqnum (event); if (G_LIKELY (glob_seqnum_found == FALSE) && seqnum == glob_seqnum) glob_seqnum_found = TRUE; if (glob_seqnum_found == TRUE && seqnum != glob_seqnum) { gchar *message = g_strdup_printf ("Current seqnum %i != " "received %i", glob_seqnum, seqnum); insanity_test_validate_checklist_item (test, "seqnum-management", FALSE, message); glob_wrong_seqnum = TRUE; g_free (message); } switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEGMENT: { gst_event_copy_segment (event, &glob_last_segment); if (glob_waiting_segment == FALSE) /* Cache the segment as it will be our reference but don't look * further */ goto done; glob_last_segment_start_time = glob_last_segment.start; if (glob_waiting_first_segment == TRUE) { insanity_test_validate_checklist_item (test, "first-segment", TRUE, NULL); glob_waiting_first_segment = FALSE; } else if (glob_in_progress >= TEST_FAST_FORWARD && glob_in_progress <= TEST_FAST_BACKWARD) { GstClockTimeDiff diff; gboolean valid_stop = TRUE; GstClockTimeDiff wdiff, rdiff; rdiff = ABS (GST_CLOCK_DIFF (glob_last_segment.stop, glob_last_segment.start)) * ABS (glob_last_segment.rate * glob_last_segment.applied_rate); wdiff = ABS (GST_CLOCK_DIFF (glob_seek_stop_ts, glob_seek_segment_seektime)); diff = GST_CLOCK_DIFF (glob_last_segment.position, glob_seek_segment_seektime); if (diff < 0) diff = -diff; /* Now compare with the expected segment */ if ((glob_last_segment.rate * glob_last_segment.applied_rate) == glob_seek_rate && diff <= SEEK_THRESHOLD && valid_stop) { glob_seek_got_segment = TRUE; } else { GstClockTime stopdiff = ABS (GST_CLOCK_DIFF (rdiff, wdiff)); gchar *validate_msg = g_strdup_printf ("Wrong segment received, Rate %f expected " "%f, start time diff %" GST_TIME_FORMAT " stop diff %" GST_TIME_FORMAT, (glob_last_segment.rate * glob_last_segment.applied_rate), glob_seek_rate, GST_TIME_ARGS (diff), GST_TIME_ARGS (stopdiff)); validate_current_test (test, FALSE, validate_msg); next_test (test); g_free (validate_msg); } } glob_waiting_segment = FALSE; break; } default: break; } } done: DECODER_TEST_UNLOCK (); return TRUE; }
int main(int argc, char **argv) { int ch, test_cur, test_total, i; int *result; test_ctx_t ctx; char namebuf[100] = { '\0' }; int skip[256] = { -1 }; int skipcount = 0; int skipflag; test_init(&ctx); memset(skip, -1, 256*sizeof(int)); while ((ch = getopt(argc, argv, "hCd:r:z:s:")) != -1) { switch (ch) { case 'h': usage(); return EXIT_SUCCESS; case 'C': ctx.cleanup = 0; break; case 'd': if (NULL != optarg) hlp_path_clean(optarg, ctx.workdir, 2048); else return EXIT_FAILURE; break; case 'r': if (NULL != optarg) hlp_path_clean(optarg, ctx.random_device, 2048); else return EXIT_FAILURE; break; case 's': skip[skipcount] = atoi(optarg); skipcount++; if (skipcount > 255) skipcount--; break; case 'z': if (NULL != optarg) hlp_path_clean(optarg, ctx.zero_device, 2048); else return EXIT_FAILURE; break; default: printf("\n"); usage(); return EXIT_FAILURE; } } if (strlen(ctx.workdir) == 0) hlp_path_clean(DEFAULT_DIR, ctx.workdir, 2048); if (strlen(ctx.random_device) == 0) hlp_path_clean(DEFAULT_RANDOM, ctx.random_device, 2048); if (strlen(ctx.zero_device) == 0) hlp_path_clean(DEFAULT_ZERO, ctx.zero_device, 2048); /* determine total number of tests */ test_total = test_max(); result = (int *)malloc(test_total * sizeof(int)); if (NULL == result) { hlp_report_error(errno); return EXIT_FAILURE; } /* Standard message */ printf("\n=============================\nlibsynctory testing framework\n=============================\n\n"); /* display settings */ printf("Settings for current test run:\n------------------------------\n\n"); printf("Working directory: %s\n", ctx.workdir); printf("Random device: %s\n", ctx.random_device); printf("Zero device: %s\n", ctx.zero_device); printf("Delete temporary files: "); if (ctx.cleanup) printf("YES\n"); else printf("NO\n"); printf("\n\n\n"); /* run tests */ for (test_cur = 0; test_cur < test_total; test_cur++) { memset(namebuf, (int)'\0', 100); test_get_name(test_cur, namebuf, 100); printf("Test %02d of %02d: %s\n---------------", test_cur + 1, test_total, namebuf); for (i = 0; i < (int)strlen(namebuf); i++) printf("-"); printf("\n\n"); skipflag = 0; for (i = 0; i < 256; i++) { if (skip[i] == (test_cur + 1)) { skipflag = 1; break; } } if (skipflag ) { result[test_cur] = 0; printf("\nTest %02d of %02d skipped.\n\n\n", test_cur + 1, test_total); } else { test_run(test_cur, &ctx, &i); printf("\nTest %02d of %02d ", test_cur + 1, test_total); if (i) { printf("failed: "); result[test_cur] = 1; hlp_report_error(i); printf("\n\n"); } else { result[test_cur] = 2; printf("passed.\n\n\n"); } } } printf("\nTest Summary\n============\n\n"); printf("Test No. Description Result\n" "-------- -------------------------------------------------------------- -------\n"); for (test_cur = 0; test_cur < test_total; test_cur++) { memset(namebuf, (int)'\0', 100); test_get_name(test_cur, namebuf, 100); printf("%02d ", test_cur + 1); if (strlen(namebuf) > 62) printf("%62s ", namebuf); else { printf("%s", namebuf); for (i = 0; i < (62 - (int)strlen(namebuf)); i++) printf(" "); printf(" "); } if (result[test_cur] == 1) printf("failed\n"); else if (result[test_cur] == 2) printf("passed\n"); else printf("skipped\n"); } printf("\n"); return EXIT_SUCCESS; }