/* * Unittest for curlfilesink */ #include #include #include #include static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY); static GstPad *srcpad; static GstElement *sink; static GstElement * setup_curlfilesink (void) { GST_DEBUG ("setup_curlfielsink"); sink = gst_check_setup_element ("curlfilesink"); srcpad = gst_check_setup_src_pad (sink, &srctemplate); gst_pad_set_active (srcpad, TRUE); return sink; } static void cleanup_curlfilesink (GstElement * sink) { GST_DEBUG ("cleanup_curlfilesink"); gst_check_teardown_src_pad (sink); gst_check_teardown_element (sink); } static void test_verify_file_data (const gchar * dir, gchar * file_name, const gchar * expected_file_content) { GError *err = NULL; gchar *res_file_content = NULL; gchar *path = NULL; path = g_strdup_printf ("%s/%s", dir, file_name); g_free (file_name); if (!g_file_get_contents (path, &res_file_content, NULL, &err)) { GST_WARNING ("Error loading file: %s (%s)", file_name, err->message); g_error_free (err); } fail_unless (res_file_content != NULL); fail_unless (strncmp (res_file_content, expected_file_content, strlen (expected_file_content)) == 0); g_free (res_file_content); g_unlink (path); g_free (path); } static void test_set_and_play_buffer (const gchar * _data) { gpointer data = (gpointer) _data; GstBuffer *buffer; gint num_bytes; num_bytes = strlen (data); buffer = gst_buffer_new (); gst_buffer_insert_memory (buffer, 0, gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY, data, num_bytes, 0, num_bytes, data, NULL)); fail_unless (gst_pad_push (srcpad, buffer) == GST_FLOW_OK); } static void test_set_and_fail_to_play_buffer (const gchar * _data) { gpointer data = (gpointer) _data; GstBuffer *buffer; gint num_bytes; num_bytes = strlen (data); buffer = gst_buffer_new (); gst_buffer_insert_memory (buffer, 0, gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY, data, num_bytes, 0, num_bytes, data, NULL)); fail_unless (gst_pad_push (srcpad, buffer) == GST_FLOW_ERROR); } GST_START_TEST (test_properties) { GstElement *sink; GstCaps *caps; const gchar *location = "file:///tmp/"; const gchar *file_contents = "line 1\r\n"; gchar *file_name = g_strdup_printf ("curlfilesink_%d", g_random_int ()); gchar *res_location = NULL; gchar *res_file_name = NULL; gboolean res_create_dirs = FALSE; gchar *path = NULL; sink = setup_curlfilesink (); g_object_set (G_OBJECT (sink), "location", "mylocation", NULL); g_object_set (G_OBJECT (sink), "file-name", "myfile", NULL); g_object_set (G_OBJECT (sink), "create-dirs", TRUE, NULL); g_object_get (sink, "location", &res_location, "file-name", &res_file_name, "create-dirs", &res_create_dirs, NULL); fail_unless (strncmp (res_location, "mylocation", strlen ("mylocation")) == 0); fail_unless (strncmp (res_file_name, "myfile", strlen ("myfile")) == 0); fail_unless (res_create_dirs == TRUE); g_free (res_location); g_free (res_file_name); /* change properties */ g_object_set (G_OBJECT (sink), "location", location, NULL); g_object_set (G_OBJECT (sink), "file-name", file_name, NULL); g_object_set (G_OBJECT (sink), "create-dirs", FALSE, NULL); g_object_get (sink, "location", &res_location, "file-name", &res_file_name, "create-dirs", &res_create_dirs, NULL); fail_unless (strncmp (res_location, location, strlen (location)) == 0); fail_unless (strncmp (res_file_name, file_name, strlen (file_name)) == 0); fail_unless (res_create_dirs == FALSE); g_free (res_location); g_free (res_file_name); /* start playing */ ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC); caps = gst_caps_from_string ("application/x-gst-check"); fail_unless (gst_pad_set_caps (srcpad, caps)); /* setup buffer */ test_set_and_play_buffer (file_contents); /* try to change location property while in PLAYING state */ g_object_set (G_OBJECT (sink), "location", "newlocation", NULL); g_object_get (sink, "location", &res_location, NULL); /* verify that locaiton has not been altered */ fail_unless (strncmp (res_location, location, strlen (location)) == 0); g_free (res_location); /* eos */ fail_unless (gst_pad_push_event (srcpad, gst_event_new_eos ())); ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS); gst_caps_unref (caps); cleanup_curlfilesink (sink); path = g_strdup_printf ("/tmp/%s", file_name); g_unlink (path); g_free (file_name); g_free (path); } GST_END_TEST; GST_START_TEST (test_one_file) { GstElement *sink; GstCaps *caps; const gchar *location = "file:///tmp/"; gchar *file_name = g_strdup_printf ("curlfilesink_%d", g_random_int ()); const gchar *file_content = "line 1\r\n"; gchar *res_location = NULL; gchar *res_file_name = NULL; sink = setup_curlfilesink (); g_object_set (G_OBJECT (sink), "location", location, NULL); g_object_set (G_OBJECT (sink), "file-name", file_name, NULL); g_object_get (sink, "location", &res_location, "file-name", &res_file_name, NULL); fail_unless (strncmp (res_location, location, strlen (location)) == 0); fail_unless (strncmp (res_file_name, file_name, strlen (file_name)) == 0); g_free (res_location); g_free (res_file_name); /* start playing */ ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC); caps = gst_caps_from_string ("application/x-gst-check"); fail_unless (gst_pad_set_caps (srcpad, caps)); /* setup buffer */ test_set_and_play_buffer (file_content); /* eos */ fail_unless (gst_pad_push_event (srcpad, gst_event_new_eos ())); ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS); gst_caps_unref (caps); cleanup_curlfilesink (sink); /* verify file content */ test_verify_file_data ("/tmp", file_name, file_content); } GST_END_TEST; GST_START_TEST (test_one_big_file) { GstElement *sink; GstCaps *caps; const gchar *location = "file:///tmp/"; gchar *file_name = g_strdup_printf ("curlfilesink_%d", g_random_int ()); const gchar *file_line1 = "line 1\r\n"; const gchar *file_line2 = "line 2\r\n"; const gchar *file_line3 = "line 3\r\n"; const gchar *expected_file_content = "line 1\r\n" "line 2\r\n" "line 3\r\n"; gchar *res_location = NULL; gchar *res_file_name = NULL; sink = setup_curlfilesink (); g_object_set (G_OBJECT (sink), "location", location, NULL); g_object_set (G_OBJECT (sink), "file-name", file_name, NULL); g_object_get (sink, "location", &res_location, "file-name", &res_file_name, NULL); fail_unless (strncmp (res_location, location, strlen (location)) == 0); fail_unless (strncmp (res_file_name, file_name, strlen (file_name)) == 0); g_free (res_location); g_free (res_file_name); /* start playing */ ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC); caps = gst_caps_from_string ("application/x-gst-check"); fail_unless (gst_pad_set_caps (srcpad, caps)); /* setup first buffer */ test_set_and_play_buffer (file_line1); /* setup second buffer */ test_set_and_play_buffer (file_line2); /* setup third buffer */ test_set_and_play_buffer (file_line3); /* eos */ fail_unless (gst_pad_push_event (srcpad, gst_event_new_eos ())); ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS); gst_caps_unref (caps); cleanup_curlfilesink (sink); /* verify file content */ test_verify_file_data ("/tmp", file_name, expected_file_content); } GST_END_TEST; GST_START_TEST (test_two_files) { GstElement *sink; GstCaps *caps; const gchar *location = "file:///tmp/"; gchar *file_name1 = g_strdup_printf ("curlfilesink_%d", g_random_int ()); gchar *file_name2 = g_strdup_printf ("curlfilesink_%d", g_random_int ()); const gchar *file_content1 = "file content 1\r\n"; const gchar *file_content2 = "file content 2\r\n"; gchar *res_location = NULL; gchar *res_file_name = NULL; sink = setup_curlfilesink (); g_object_set (G_OBJECT (sink), "location", location, NULL); g_object_set (G_OBJECT (sink), "file-name", file_name1, NULL); g_object_get (sink, "location", &res_location, "file-name", &res_file_name, NULL); fail_unless (strncmp (res_location, location, strlen (location)) == 0); fail_unless (strncmp (res_file_name, file_name1, strlen (file_name1)) == 0); g_free (res_location); g_free (res_file_name); /* start playing */ ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC); caps = gst_caps_from_string ("application/x-gst-check"); fail_unless (gst_pad_set_caps (srcpad, caps)); /* setup first buffer - content of the first file */ test_set_and_play_buffer (file_content1); g_object_set (G_OBJECT (sink), "file-name", file_name2, NULL); g_object_get (sink, "file-name", &res_file_name, NULL); fail_unless (strncmp (res_file_name, file_name2, strlen (file_name2)) == 0); g_free (res_file_name); /* setup second buffer - content of the second file */ test_set_and_play_buffer (file_content2); /* eos */ fail_unless (gst_pad_push_event (srcpad, gst_event_new_eos ())); ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS); gst_caps_unref (caps); cleanup_curlfilesink (sink); /* verify file contents of the first file */ test_verify_file_data ("/tmp", file_name1, file_content1); test_verify_file_data ("/tmp", file_name2, file_content2); } GST_END_TEST; GST_START_TEST (test_create_dirs) { GstElement *sink; GstCaps *caps; gchar *tmp_dir = g_strdup ("/tmp/curlfilesink_XXXXXX"); gchar *sub_dir; gchar *sub_sub_dir; gchar *location; gchar *file_name = g_strdup_printf ("curlfilesink_%d", g_random_int ()); const gchar *file_content = "line 1\r\n"; /* create temp dir as base dir (mkdtemp saves dir name in tmp_dir) */ fail_unless (mkdtemp (tmp_dir) != NULL); /* use sub-sub directory as location */ sub_dir = g_strdup_printf ("%s/a", tmp_dir); sub_sub_dir = g_strdup_printf ("%s/b", sub_dir); location = g_strdup_printf ("file://%s/", sub_sub_dir); sink = setup_curlfilesink (); g_object_set (G_OBJECT (sink), "location", location, NULL); g_object_set (G_OBJECT (sink), "file-name", file_name, NULL); g_object_set (G_OBJECT (sink), "create-dirs", TRUE, NULL); /* start playing */ ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC); caps = gst_caps_from_string ("application/x-gst-check"); fail_unless (gst_pad_set_caps (srcpad, caps)); /* setup buffer */ test_set_and_play_buffer (file_content); /* eos */ fail_unless (gst_pad_push_event (srcpad, gst_event_new_eos ())); ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS); gst_caps_unref (caps); cleanup_curlfilesink (sink); /* verify file content in sub-sub dir created by sink */ test_verify_file_data (sub_sub_dir, file_name, file_content); /* remove directories */ fail_unless (g_rmdir (sub_sub_dir) == 0); fail_unless (g_rmdir (sub_dir) == 0); fail_unless (g_rmdir (tmp_dir) == 0); g_free (sub_sub_dir); g_free (sub_dir); g_free (tmp_dir); } GST_END_TEST; GST_START_TEST (test_missing_path) { GstElement *sink; GstCaps *caps; const gchar *location = "file:///missing/path/"; gchar *file_name = g_strdup_printf ("curlfilesink_%d", g_random_int ()); const gchar *file_content = "line 1\r\n"; gchar *res_location = NULL; gchar *res_file_name = NULL; sink = setup_curlfilesink (); g_object_set (G_OBJECT (sink), "location", location, NULL); g_object_set (G_OBJECT (sink), "file-name", file_name, NULL); g_object_get (sink, "location", &res_location, "file-name", &res_file_name, NULL); fail_unless (strncmp (res_location, location, strlen (location)) == 0); fail_unless (strncmp (res_file_name, file_name, strlen (file_name)) == 0); g_free (res_location); g_free (res_file_name); /* start playing */ ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC); caps = gst_caps_from_string ("application/x-gst-check"); fail_unless (gst_pad_set_caps (srcpad, caps)); /* setup & play buffer which should fail due to the missing path */ test_set_and_fail_to_play_buffer (file_content); /* eos */ fail_unless (gst_pad_push_event (srcpad, gst_event_new_eos ())); ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS); gst_caps_unref (caps); cleanup_curlfilesink (sink); } GST_END_TEST; static Suite * curlsink_suite (void) { Suite *s = suite_create ("curlfilesink"); TCase *tc_chain = tcase_create ("general"); suite_add_tcase (s, tc_chain); tcase_set_timeout (tc_chain, 20); tcase_add_test (tc_chain, test_properties); tcase_add_test (tc_chain, test_one_file); tcase_add_test (tc_chain, test_one_big_file); tcase_add_test (tc_chain, test_two_files); tcase_add_test (tc_chain, test_missing_path); tcase_add_test (tc_chain, test_create_dirs); return s; } GST_CHECK_MAIN (curlsink);