diff --git a/ChangeLog b/ChangeLog index 4bd49ce44a..03d578c023 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2004-12-21 Thomas Vander Stichele + + * check/Makefile.am: + * check/gst-libs/.cvsignore: + * check/gst-libs/gdp.c: + * libs/gst/dataprotocol/Makefile.am: + * libs/gst/dataprotocol/dataprotocol-test.c: + Change dataprotocol test to new check + 2004-12-20 Wim Taymans * gst/elements/gstfakesink.c: (gst_fakesink_event): diff --git a/check/Makefile.am b/check/Makefile.am index f250242481..1f5f29a4ff 100644 --- a/check/Makefile.am +++ b/check/Makefile.am @@ -1,6 +1,12 @@ -TESTS = gst/gstobject +TESTS = gst/gstobject gst-libs/gdp check_PROGRAMS = $(TESTS) AM_CFLAGS = $(GST_OBJ_CFLAGS) $(CHECK_CFLAGS) LDADD = $(GST_OBJ_LIBS) $(CHECK_LIBS) + +gst_libs_gdp_SOURCES = \ + gst-libs/gdp.c \ + $(top_srcdir)/libs/gst/dataprotocol/dataprotocol.c +# remove GST_ENABLE_NEW when dataprotocol has been declared API-stable +gst_libs_gdp_CFLAGS = $(AM_CFLAGS) -DGST_ENABLE_NEW diff --git a/check/gst-libs/.gitignore b/check/gst-libs/.gitignore new file mode 100644 index 0000000000..5ad589e106 --- /dev/null +++ b/check/gst-libs/.gitignore @@ -0,0 +1 @@ +gdp diff --git a/check/gst-libs/gdp.c b/check/gst-libs/gdp.c new file mode 100644 index 0000000000..dbcbb620a8 --- /dev/null +++ b/check/gst-libs/gdp.c @@ -0,0 +1,313 @@ +/* GStreamer + * + * unit test for data protocol + * + * Copyright (C) <2004> Thomas Vander Stichele + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include /* memcmp */ + +#include + +#include +#include + +#include "libs/gst/dataprotocol/dp-private.h" /* private header */ + + +/* FIXME: externalize */ +/* logging function for tests + * a test uses g_message() to log a debug line + * a gst unit test can be run with GST_TEST_DEBUG env var set to see the + * messages + */ +gboolean _gst_test_debug = FALSE; + +gboolean _gst_test_threads_running = FALSE; + +void gst_test_log_func + (const gchar * log_domain, GLogLevelFlags log_level, + const gchar * message, gpointer user_data) +{ + // g_print ("HANDLER CALLED\n"); + if (_gst_test_debug) { + g_print (message); + } +} + +/* initialize GStreamer testing */ +void +gst_test_init (void) +{ + if (g_getenv ("GST_TEST_DEBUG")) + _gst_test_debug = TRUE; + + g_log_set_handler (NULL, G_LOG_LEVEL_MESSAGE, gst_test_log_func, NULL); +} + + +/* test our method of reading and writing headers using TO/FROM_BE */ +START_TEST (test_conversion) +{ + guint8 array[9]; + guint8 write_array[9]; + guint16 read_two, expect_two; + guint32 read_four, expect_four; + guint64 read_eight, expect_eight; + int i; + + for (i = 0; i < 9; ++i) { + array[i] = i * 0x10; + } + + /* read 8 16 bits */ + for (i = 0; i < 8; ++i) { + read_two = GST_READ_UINT16_BE (array + i); + expect_two = array[i] * (1 << 8) + array[i + 1]; + fail_unless (read_two == expect_two, + "GST_READ_UINT16_BE %d: read %d != %d\n", i, read_two, expect_two); + } + + /* write 8 16 bits */ + for (i = 0; i < 8; ++i) { + GST_WRITE_UINT16_BE (&write_array[i], read_two); + fail_unless (memcmp (array + 7, write_array + i, 2) == 0, + "GST_WRITE_UINT16_BE %d: memcmp failed", i); + } + + /* read 5 32 bits */ + for (i = 0; i < 5; ++i) { + read_four = GST_READ_UINT32_BE (array + i); + expect_four = array[i] * (1 << 24) + array[i + 1] * (1 << 16) + + array[i + 2] * (1 << 8) + array[i + 3]; + fail_unless (read_four == expect_four, + "GST_READ_UINT32_BE %d: read %d != %d\n", i, read_four, expect_four); + } + + /* read 2 64 bits */ + for (i = 0; i < 2; ++i) { + read_eight = GST_READ_UINT64_BE (array + i); + expect_eight = array[i] * (1LL << 56) + array[i + 1] * (1LL << 48) + + array[i + 2] * (1LL << 40) + array[i + 3] * (1LL << 32) + + array[i + 4] * (1 << 24) + array[i + 5] * (1 << 16) + + array[i + 6] * (1 << 8) + array[i + 7]; + fail_unless (read_eight == expect_eight, + "GST_READ_UINT64_BE %d: read %" G_GUINT64_FORMAT + " != %" G_GUINT64_FORMAT "\n", i, read_eight, expect_eight); + } + + /* write 1 64 bit */ + GST_WRITE_UINT64_BE (&write_array[0], read_eight); + fail_unless (memcmp (array + 1, write_array, 8) == 0, + "GST_WRITE_UINT64_BE: memcmp failed"); +} + +END_TEST +/* test creation of header from buffer and back again */ +START_TEST (test_buffer) +{ + GstBuffer *buffer; + GstBuffer *newbuffer; + + guint header_length; + guint8 *header; + + /* create buffer */ + g_message ("Creating a new 8-byte buffer with ts 0.5 sec, dur 1 sec\n"); + buffer = gst_buffer_new_and_alloc (8); + GST_BUFFER_TIMESTAMP (buffer) = (GstClockTime) (GST_SECOND * 0.5); + GST_BUFFER_DURATION (buffer) = (GstClockTime) GST_SECOND; + GST_BUFFER_OFFSET (buffer) = (guint64) 10; + GST_BUFFER_OFFSET_END (buffer) = (guint64) 19; + GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_IN_CAPS); + GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_SUBBUFFER); + memmove (GST_BUFFER_DATA (buffer), "a buffer", 8); + + /* create a buffer with CRC checking */ + fail_unless (gst_dp_header_from_buffer (buffer, GST_DP_HEADER_FLAG_CRC, + &header_length, &header), "Could not create header from buffer."); + + /* validate the header */ + fail_unless (gst_dp_validate_header (header_length, header), + "Could not validate header"); + /* create a new, empty buffer with the right size */ + newbuffer = gst_dp_buffer_from_header (header_length, header); + fail_unless (newbuffer != NULL, "Could not create a new buffer from header"); + fail_unless (GST_IS_BUFFER (newbuffer), "Created buffer is not a GstBuffer"); + /* read/copy the data */ + memmove (GST_BUFFER_DATA (newbuffer), GST_BUFFER_DATA (buffer), + GST_BUFFER_SIZE (buffer)); + /* validate the buffer */ + fail_unless (gst_dp_validate_payload (header_length, header, + GST_BUFFER_DATA (newbuffer)), "Could not validate payload"); + + g_message ("new buffer timestamp: %" GST_TIME_FORMAT "\n", + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (newbuffer))); + g_message ("new buffer duration: %" GST_TIME_FORMAT "\n", + GST_TIME_ARGS (GST_BUFFER_DURATION (newbuffer))); + g_message ("new buffer offset: %" G_GUINT64_FORMAT "\n", + GST_BUFFER_OFFSET (newbuffer)); + g_message ("new buffer offset_end: %" G_GUINT64_FORMAT "\n", + GST_BUFFER_OFFSET_END (newbuffer)); + fail_unless (GST_BUFFER_TIMESTAMP (newbuffer) == + GST_BUFFER_TIMESTAMP (buffer), "Timestamps don't match !"); + fail_unless (GST_BUFFER_DURATION (newbuffer) == GST_BUFFER_DURATION (buffer), + "Durations don't match !"); + fail_unless (GST_BUFFER_OFFSET (newbuffer) == GST_BUFFER_OFFSET (buffer), + "Offsets don't match !"); + fail_unless (GST_BUFFER_OFFSET_END (newbuffer) == + GST_BUFFER_OFFSET_END (buffer), "Offset ends don't match !"); + fail_if (GST_BUFFER_FLAG_IS_SET (newbuffer, GST_BUFFER_SUBBUFFER), + "GST_BUFFER_SUBBUFFER flag should not have been copied !"); + fail_unless (GST_BUFFER_FLAG_IS_SET (newbuffer, GST_BUFFER_IN_CAPS), + "GST_BUFFER_IN_CAPS flag should have been copied !"); + + g_free (header); +} + +END_TEST +START_TEST (test_caps) +{ + gchar *string, *newstring; + GstCaps *caps, *newcaps; + + guint header_length; + guint8 *header, *payload; + + caps = gst_caps_from_string ("audio/x-raw-float, " + "rate = (int) [ 11025, 48000 ], " + "channels = (int) [ 1, 2 ], " "endianness = (int) BYTE_ORDER, " + "width = (int) 32, " "buffer-frames = (int) 0"); + string = gst_caps_to_string (caps); + g_message ("Created caps: %s\n", string); + fail_unless (gst_dp_packet_from_caps (caps, 0, &header_length, &header, + &payload), "Could not create packet from caps."); + + /* validate the packet */ + fail_unless (gst_dp_validate_packet (header_length, header, payload), + "Could not validate packet"); + newcaps = gst_dp_caps_from_packet (header_length, header, payload); + fail_unless (newcaps != NULL, "Could not create caps from packet"); + //g_return_val_if_fail (GST_IS_CAPS (newcaps), -1); + newstring = gst_caps_to_string (newcaps); + g_message ("Received caps: %s\n", newstring); + fail_unless (strcmp (string, newstring) == 0, + "Created caps do not match original caps"); + g_free (string); + g_free (newstring); +} + +END_TEST +START_TEST (test_event) +{ + GstEvent *send; + GstEvent *receive; + guint header_length; + guint8 *header, *payload; + + g_message ("Testing EOS event at 1s\n"); + send = gst_event_new (GST_EVENT_EOS); + GST_EVENT_TIMESTAMP (send) = GST_SECOND; + fail_unless (gst_dp_packet_from_event (send, GST_DP_HEADER_FLAG_CRC, + &header_length, &header, &payload), + "Could not create packet from eos event"); + + receive = gst_dp_event_from_packet (header_length, header, payload); + + g_message ("EOS, timestamp %" GST_TIME_FORMAT "\n", + GST_TIME_ARGS (GST_EVENT_TIMESTAMP (receive))); + fail_unless (GST_EVENT_TYPE (receive) == GST_EVENT_EOS, + "Received event is not EOS"); + fail_unless (GST_EVENT_TIMESTAMP (receive) == GST_SECOND, + "EOS timestamp is not 1.0 sec"); + gst_event_unref (send); + gst_event_unref (receive); + + g_message ("Testing FLUSH event at 2s\n"); + send = gst_event_new (GST_EVENT_FLUSH); + GST_EVENT_TIMESTAMP (send) = GST_SECOND * 2; + fail_unless (gst_dp_packet_from_event (send, GST_DP_HEADER_FLAG_CRC, + &header_length, &header, &payload), + "Could not create packet from flush event"); + + receive = gst_dp_event_from_packet (header_length, header, payload); + + g_message ("Flush, timestamp %" GST_TIME_FORMAT "\n", + GST_TIME_ARGS (GST_EVENT_TIMESTAMP (receive))); + fail_unless (GST_EVENT_TYPE (receive) == GST_EVENT_FLUSH, + "Received event is not flush"); + fail_unless (GST_EVENT_TIMESTAMP (receive) == GST_SECOND * 2, + "Flush timestamp is not 2.0 sec"); + gst_event_unref (send); + gst_event_unref (receive); + + g_message ("Testing SEEK event with 1 second at 3 seconds\n"); + send = gst_event_new_seek (GST_FORMAT_TIME, GST_SECOND); + GST_EVENT_TIMESTAMP (send) = GST_SECOND * 3; + fail_unless (gst_dp_packet_from_event (send, GST_DP_HEADER_FLAG_CRC, + &header_length, &header, &payload), + "Could not create packet from seek event"); + + receive = gst_dp_event_from_packet (header_length, header, payload); + + g_message ("Seek, timestamp %" GST_TIME_FORMAT ", to %" GST_TIME_FORMAT "\n", + GST_TIME_ARGS (GST_EVENT_TIMESTAMP (receive)), + GST_TIME_ARGS (GST_EVENT_SEEK_OFFSET (receive))); + fail_unless (GST_EVENT_TYPE (receive) == GST_EVENT_SEEK, + "Returned event is not seek"); + fail_unless (GST_EVENT_TIMESTAMP (receive) == GST_SECOND * 3, + "Seek timestamp is not 3.0 sec"); + fail_unless (GST_EVENT_SEEK_FORMAT (receive) == GST_FORMAT_TIME, + "Seek format is not time"); + fail_unless (GST_EVENT_SEEK_OFFSET (receive) == GST_SECOND, + "Seek offset is not 1.0 sec"); + gst_event_unref (send); + gst_event_unref (receive); +} +END_TEST Suite * gst_object_suite (void) +{ + Suite *s = suite_create ("data protocol"); + TCase *tc_chain = tcase_create ("general"); + + suite_add_tcase (s, tc_chain); + tcase_add_test (tc_chain, test_conversion); + tcase_add_test (tc_chain, test_buffer); + tcase_add_test (tc_chain, test_caps); + tcase_add_test (tc_chain, test_event); + + return s; +} + +int +main (int argc, char **argv) +{ + int nf; + + Suite *s = gst_object_suite (); + SRunner *sr = srunner_create (s); + + gst_init (&argc, &argv); + gst_test_init (); + gst_dp_init (); + + srunner_run_all (sr, CK_NORMAL); + nf = srunner_ntests_failed (sr); + srunner_free (sr); + + return nf; +} diff --git a/libs/gst/dataprotocol/Makefile.am b/libs/gst/dataprotocol/Makefile.am index c4077eb10d..85a8a69653 100644 --- a/libs/gst/dataprotocol/Makefile.am +++ b/libs/gst/dataprotocol/Makefile.am @@ -22,11 +22,3 @@ install-data-local: as-libtool-install-data-local uninstall-local: as-libtool-uninstall-local include $(top_srcdir)/common/as-libtool.mak - -# regression test -check_PROGRAMS = dataprotocol-test -dataprotocol_test_SOURCES = dataprotocol-test.c dataprotocol.c -dataprotocol_test_CFLAGS = $(GST_LIB_CFLAGS) -I$(top_srcdir)/libs -DGST_ENABLE_NEW -dataprotocol_test_LDADD = $(GST_OBJ_LIBS) - -TESTS = $(check_PROGRAMS) diff --git a/libs/gst/dataprotocol/dataprotocol-test.c b/libs/gst/dataprotocol/dataprotocol-test.c deleted file mode 100644 index 9e408136ab..0000000000 --- a/libs/gst/dataprotocol/dataprotocol-test.c +++ /dev/null @@ -1,309 +0,0 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen - * Copyright (C) <2004> Thomas Vander Stichele - * - * dataprotocol-test.c: Test functions for GStreamer Data Protocol - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include -#include -#include "dp-private.h" - -#include /* memcmp */ - -/* test our method of reading and writing headers using TO/FROM_BE */ -static int -conversion_test () -{ - guint8 array[9]; - guint8 write_array[9]; - guint16 read_two, expect_two; - guint32 read_four, expect_four; - guint64 read_eight, expect_eight; - int i; - - for (i = 0; i < 9; ++i) { - array[i] = i * 0x10; - } - - /* read 8 16 bits */ - for (i = 0; i < 8; ++i) { - read_two = GST_READ_UINT16_BE (array + i); - expect_two = array[i] * (1 << 8) + array[i + 1]; - if (read_two != expect_two) { - g_print ("GST_READ_UINT16_BE %d: read %d != %d\n", i, read_two, - expect_two); - return -1; - } - } - - /* write 8 16 bit */ - for (i = 0; i < 8; ++i) { - GST_WRITE_UINT16_BE (&write_array[i], read_two); - if (memcmp (array + 7, write_array + i, 2) != 0) { - gst_dp_dump_byte_array (write_array + i, 2); - gst_dp_dump_byte_array (array + 7, 2); - return -1; - } - } - - /* read 5 32 bits */ - for (i = 0; i < 5; ++i) { - read_four = GST_READ_UINT32_BE (array + i); - expect_four = array[i] * (1 << 24) + array[i + 1] * (1 << 16) - + array[i + 2] * (1 << 8) + array[i + 3]; - if (read_four != expect_four) { - g_print ("GST_READ_UINT32_BE %d: read %d != %d\n", i, read_four, - expect_four); - return -1; - } - } - - /* read 2 64 bits */ - for (i = 0; i < 2; ++i) { - read_eight = GST_READ_UINT64_BE (array + i); - expect_eight = array[i] * (1LL << 56) + array[i + 1] * (1LL << 48) - + array[i + 2] * (1LL << 40) + array[i + 3] * (1LL << 32) - + array[i + 4] * (1 << 24) + array[i + 5] * (1 << 16) - + array[i + 6] * (1 << 8) + array[i + 7]; - ; - if (read_eight != expect_eight) { - g_print ("GST_READ_UINT64_BE %d: read %" G_GUINT64_FORMAT - " != %" G_GUINT64_FORMAT "\n", i, read_eight, expect_eight); - return -1; - } - } - - /* write 1 64 bit */ - GST_WRITE_UINT64_BE (&write_array[0], read_eight); - if (memcmp (array + 1, write_array, 8) != 0) { - gst_dp_dump_byte_array (write_array, 8); - gst_dp_dump_byte_array (array + 1, 8); - return -1; - } - - return 0; -} - -/* test creation of header from buffer and back again */ -static int -buffer_test () -{ - GstBuffer *buffer; - GstBuffer *newbuffer; - - guint header_length; - guint8 *header; - - /* create buffer */ - g_print ("Creating a new 8-byte buffer with ts 0.5 sec, dur 1 sec\n"); - buffer = gst_buffer_new_and_alloc (8); - GST_BUFFER_TIMESTAMP (buffer) = (GstClockTime) (GST_SECOND * 0.5); - GST_BUFFER_DURATION (buffer) = (GstClockTime) GST_SECOND; - GST_BUFFER_OFFSET (buffer) = (guint64) 10; - GST_BUFFER_OFFSET_END (buffer) = (guint64) 19; - GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_IN_CAPS); - GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_SUBBUFFER); - memmove (GST_BUFFER_DATA (buffer), "a buffer", 8); - - /* create a buffer with CRC checking */ - if (!gst_dp_header_from_buffer (buffer, GST_DP_HEADER_FLAG_CRC, - &header_length, &header)) { - g_print ("Could not create header from buffer."); - exit (1); - } - - /* validate the header */ - g_return_val_if_fail (gst_dp_validate_header (header_length, header), -1); - /* create a new, empty buffer with the right size */ - newbuffer = gst_dp_buffer_from_header (header_length, header); - /* read/copy the data */ - memmove (GST_BUFFER_DATA (newbuffer), GST_BUFFER_DATA (buffer), - GST_BUFFER_SIZE (buffer)); - /* validate the buffer */ - g_return_val_if_fail (gst_dp_validate_payload (header_length, header, - GST_BUFFER_DATA (newbuffer)), -1); - - g_return_val_if_fail (newbuffer, -1); - g_return_val_if_fail (GST_IS_BUFFER (newbuffer), -1); - g_print ("new buffer timestamp: %" GST_TIME_FORMAT "\n", - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (newbuffer))); - g_print ("new buffer duration: %" GST_TIME_FORMAT "\n", - GST_TIME_ARGS (GST_BUFFER_DURATION (newbuffer))); - g_print ("new buffer offset: %" G_GUINT64_FORMAT "\n", - GST_BUFFER_OFFSET (newbuffer)); - g_print ("new buffer offset_end: %" G_GUINT64_FORMAT "\n", - GST_BUFFER_OFFSET_END (newbuffer)); - if (GST_BUFFER_TIMESTAMP (newbuffer) != GST_BUFFER_TIMESTAMP (buffer)) { - g_error ("Timestamps don't match !"); - } - if (GST_BUFFER_DURATION (newbuffer) != GST_BUFFER_DURATION (buffer)) { - g_error ("Durations don't match !"); - } - if (GST_BUFFER_OFFSET (newbuffer) != GST_BUFFER_OFFSET (buffer)) { - g_error ("Offsets don't match !"); - } - if (GST_BUFFER_OFFSET_END (newbuffer) != GST_BUFFER_OFFSET_END (buffer)) { - g_error ("Offset ends don't match !"); - } - if (GST_BUFFER_FLAG_IS_SET (newbuffer, GST_BUFFER_SUBBUFFER)) { - g_error ("GST_BUFFER_SUBBUFFER flag should not have been copied !"); - } - if (!GST_BUFFER_FLAG_IS_SET (newbuffer, GST_BUFFER_IN_CAPS)) { - g_error ("GST_BUFFER_IN_CAPS flag should have been copied !"); - } - g_free (header); - - return 0; -} - -static int -caps_test () -{ - gchar *string, *newstring; - GstCaps *caps, *newcaps; - - guint header_length; - guint8 *header, *payload; - - caps = gst_caps_from_string ("audio/x-raw-float, " - "rate = (int) [ 11025, 48000 ], " - "channels = (int) [ 1, 2 ], " "endianness = (int) BYTE_ORDER, " - "width = (int) 32, " "buffer-frames = (int) 0"); - string = gst_caps_to_string (caps); - g_print ("Created caps: %s\n", string); - //g_assert (GST_IS_CAPS (caps)); - if (!gst_dp_packet_from_caps (caps, 0, &header_length, &header, &payload)) { - g_print ("Could not create packet from caps."); - exit (1); - } - - /* validate the packet */ - g_return_val_if_fail (gst_dp_validate_packet (header_length, header, payload), - FALSE); - newcaps = gst_dp_caps_from_packet (header_length, header, payload); - g_return_val_if_fail (newcaps, -1); - //g_return_val_if_fail (GST_IS_CAPS (newcaps), -1); - newstring = gst_caps_to_string (newcaps); - g_print ("Received caps: %s\n", newstring); - if (strcmp (string, newstring) != 0) - return -1; - g_free (string); - g_free (newstring); - - return 0; -} - -static int -event_test () -{ - GstEvent *send; - GstEvent *receive; - guint header_length; - guint8 *header, *payload; - - g_print ("Testing EOS event at 1s\n"); - send = gst_event_new (GST_EVENT_EOS); - GST_EVENT_TIMESTAMP (send) = GST_SECOND; - if (!gst_dp_packet_from_event (send, GST_DP_HEADER_FLAG_CRC, &header_length, - &header, &payload)) { - g_warning ("Could not create packet from eos event"); - return 1; - } - receive = gst_dp_event_from_packet (header_length, header, payload); - - g_print ("EOS, timestamp %" GST_TIME_FORMAT "\n", - GST_TIME_ARGS (GST_EVENT_TIMESTAMP (receive))); - g_assert (GST_EVENT_TYPE (receive) == GST_EVENT_EOS); - g_assert (GST_EVENT_TIMESTAMP (receive) == GST_SECOND); - gst_event_unref (send); - gst_event_unref (receive); - - g_print ("Testing FLUSH event at 2s\n"); - send = gst_event_new (GST_EVENT_FLUSH); - GST_EVENT_TIMESTAMP (send) = GST_SECOND * 2; - if (!gst_dp_packet_from_event (send, GST_DP_HEADER_FLAG_CRC, &header_length, - &header, &payload)) { - g_warning ("Could not create packet from flush event"); - return 1; - } - receive = gst_dp_event_from_packet (header_length, header, payload); - - g_print ("Flush, timestamp %" GST_TIME_FORMAT "\n", - GST_TIME_ARGS (GST_EVENT_TIMESTAMP (receive))); - g_assert (GST_EVENT_TYPE (receive) == GST_EVENT_FLUSH); - g_assert (GST_EVENT_TIMESTAMP (receive) == GST_SECOND * 2); - gst_event_unref (send); - gst_event_unref (receive); - - g_print ("Testing SEEK event with 1 second at 3 seconds\n"); - send = gst_event_new_seek (GST_FORMAT_TIME, GST_SECOND); - GST_EVENT_TIMESTAMP (send) = GST_SECOND * 3; - if (!gst_dp_packet_from_event (send, GST_DP_HEADER_FLAG_CRC, &header_length, - &header, &payload)) { - g_warning ("Could not create packet from seek event"); - return 1; - } - receive = gst_dp_event_from_packet (header_length, header, payload); - - g_print ("Seek, timestamp %" GST_TIME_FORMAT ", to %" GST_TIME_FORMAT "\n", - GST_TIME_ARGS (GST_EVENT_TIMESTAMP (receive)), - GST_TIME_ARGS (GST_EVENT_SEEK_OFFSET (receive))); - g_assert (GST_EVENT_TYPE (receive) == GST_EVENT_SEEK); - g_assert (GST_EVENT_TIMESTAMP (receive) == GST_SECOND * 3); - g_assert (GST_EVENT_SEEK_FORMAT (receive) == GST_FORMAT_TIME); - g_assert (GST_EVENT_SEEK_OFFSET (receive) == GST_SECOND); - gst_event_unref (send); - gst_event_unref (receive); - - - return 0; -} - -int -main (int argc, char *argv[]) -{ - int ret; - - gst_init (&argc, &argv); - gst_dp_init (); - - g_print ("\nconversion test\n\n"); - ret = conversion_test (); - if (ret != 0) - return ret; - - g_print ("\nbuffer test\n\n"); - ret = buffer_test (); - if (ret != 0) - return ret; - - g_print ("\ncaps test\n\n"); - ret = caps_test (); - if (ret != 0) - return ret; - - g_print ("\nevent test\n\n"); - ret = event_test (); - if (ret != 0) - return ret; - - - g_print ("\nall tests worked.\n\n"); - return 0; -} diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index f250242481..1f5f29a4ff 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -1,6 +1,12 @@ -TESTS = gst/gstobject +TESTS = gst/gstobject gst-libs/gdp check_PROGRAMS = $(TESTS) AM_CFLAGS = $(GST_OBJ_CFLAGS) $(CHECK_CFLAGS) LDADD = $(GST_OBJ_LIBS) $(CHECK_LIBS) + +gst_libs_gdp_SOURCES = \ + gst-libs/gdp.c \ + $(top_srcdir)/libs/gst/dataprotocol/dataprotocol.c +# remove GST_ENABLE_NEW when dataprotocol has been declared API-stable +gst_libs_gdp_CFLAGS = $(AM_CFLAGS) -DGST_ENABLE_NEW diff --git a/tests/check/libs/.gitignore b/tests/check/libs/.gitignore new file mode 100644 index 0000000000..5ad589e106 --- /dev/null +++ b/tests/check/libs/.gitignore @@ -0,0 +1 @@ +gdp diff --git a/tests/check/libs/gdp.c b/tests/check/libs/gdp.c new file mode 100644 index 0000000000..dbcbb620a8 --- /dev/null +++ b/tests/check/libs/gdp.c @@ -0,0 +1,313 @@ +/* GStreamer + * + * unit test for data protocol + * + * Copyright (C) <2004> Thomas Vander Stichele + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include /* memcmp */ + +#include + +#include +#include + +#include "libs/gst/dataprotocol/dp-private.h" /* private header */ + + +/* FIXME: externalize */ +/* logging function for tests + * a test uses g_message() to log a debug line + * a gst unit test can be run with GST_TEST_DEBUG env var set to see the + * messages + */ +gboolean _gst_test_debug = FALSE; + +gboolean _gst_test_threads_running = FALSE; + +void gst_test_log_func + (const gchar * log_domain, GLogLevelFlags log_level, + const gchar * message, gpointer user_data) +{ + // g_print ("HANDLER CALLED\n"); + if (_gst_test_debug) { + g_print (message); + } +} + +/* initialize GStreamer testing */ +void +gst_test_init (void) +{ + if (g_getenv ("GST_TEST_DEBUG")) + _gst_test_debug = TRUE; + + g_log_set_handler (NULL, G_LOG_LEVEL_MESSAGE, gst_test_log_func, NULL); +} + + +/* test our method of reading and writing headers using TO/FROM_BE */ +START_TEST (test_conversion) +{ + guint8 array[9]; + guint8 write_array[9]; + guint16 read_two, expect_two; + guint32 read_four, expect_four; + guint64 read_eight, expect_eight; + int i; + + for (i = 0; i < 9; ++i) { + array[i] = i * 0x10; + } + + /* read 8 16 bits */ + for (i = 0; i < 8; ++i) { + read_two = GST_READ_UINT16_BE (array + i); + expect_two = array[i] * (1 << 8) + array[i + 1]; + fail_unless (read_two == expect_two, + "GST_READ_UINT16_BE %d: read %d != %d\n", i, read_two, expect_two); + } + + /* write 8 16 bits */ + for (i = 0; i < 8; ++i) { + GST_WRITE_UINT16_BE (&write_array[i], read_two); + fail_unless (memcmp (array + 7, write_array + i, 2) == 0, + "GST_WRITE_UINT16_BE %d: memcmp failed", i); + } + + /* read 5 32 bits */ + for (i = 0; i < 5; ++i) { + read_four = GST_READ_UINT32_BE (array + i); + expect_four = array[i] * (1 << 24) + array[i + 1] * (1 << 16) + + array[i + 2] * (1 << 8) + array[i + 3]; + fail_unless (read_four == expect_four, + "GST_READ_UINT32_BE %d: read %d != %d\n", i, read_four, expect_four); + } + + /* read 2 64 bits */ + for (i = 0; i < 2; ++i) { + read_eight = GST_READ_UINT64_BE (array + i); + expect_eight = array[i] * (1LL << 56) + array[i + 1] * (1LL << 48) + + array[i + 2] * (1LL << 40) + array[i + 3] * (1LL << 32) + + array[i + 4] * (1 << 24) + array[i + 5] * (1 << 16) + + array[i + 6] * (1 << 8) + array[i + 7]; + fail_unless (read_eight == expect_eight, + "GST_READ_UINT64_BE %d: read %" G_GUINT64_FORMAT + " != %" G_GUINT64_FORMAT "\n", i, read_eight, expect_eight); + } + + /* write 1 64 bit */ + GST_WRITE_UINT64_BE (&write_array[0], read_eight); + fail_unless (memcmp (array + 1, write_array, 8) == 0, + "GST_WRITE_UINT64_BE: memcmp failed"); +} + +END_TEST +/* test creation of header from buffer and back again */ +START_TEST (test_buffer) +{ + GstBuffer *buffer; + GstBuffer *newbuffer; + + guint header_length; + guint8 *header; + + /* create buffer */ + g_message ("Creating a new 8-byte buffer with ts 0.5 sec, dur 1 sec\n"); + buffer = gst_buffer_new_and_alloc (8); + GST_BUFFER_TIMESTAMP (buffer) = (GstClockTime) (GST_SECOND * 0.5); + GST_BUFFER_DURATION (buffer) = (GstClockTime) GST_SECOND; + GST_BUFFER_OFFSET (buffer) = (guint64) 10; + GST_BUFFER_OFFSET_END (buffer) = (guint64) 19; + GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_IN_CAPS); + GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_SUBBUFFER); + memmove (GST_BUFFER_DATA (buffer), "a buffer", 8); + + /* create a buffer with CRC checking */ + fail_unless (gst_dp_header_from_buffer (buffer, GST_DP_HEADER_FLAG_CRC, + &header_length, &header), "Could not create header from buffer."); + + /* validate the header */ + fail_unless (gst_dp_validate_header (header_length, header), + "Could not validate header"); + /* create a new, empty buffer with the right size */ + newbuffer = gst_dp_buffer_from_header (header_length, header); + fail_unless (newbuffer != NULL, "Could not create a new buffer from header"); + fail_unless (GST_IS_BUFFER (newbuffer), "Created buffer is not a GstBuffer"); + /* read/copy the data */ + memmove (GST_BUFFER_DATA (newbuffer), GST_BUFFER_DATA (buffer), + GST_BUFFER_SIZE (buffer)); + /* validate the buffer */ + fail_unless (gst_dp_validate_payload (header_length, header, + GST_BUFFER_DATA (newbuffer)), "Could not validate payload"); + + g_message ("new buffer timestamp: %" GST_TIME_FORMAT "\n", + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (newbuffer))); + g_message ("new buffer duration: %" GST_TIME_FORMAT "\n", + GST_TIME_ARGS (GST_BUFFER_DURATION (newbuffer))); + g_message ("new buffer offset: %" G_GUINT64_FORMAT "\n", + GST_BUFFER_OFFSET (newbuffer)); + g_message ("new buffer offset_end: %" G_GUINT64_FORMAT "\n", + GST_BUFFER_OFFSET_END (newbuffer)); + fail_unless (GST_BUFFER_TIMESTAMP (newbuffer) == + GST_BUFFER_TIMESTAMP (buffer), "Timestamps don't match !"); + fail_unless (GST_BUFFER_DURATION (newbuffer) == GST_BUFFER_DURATION (buffer), + "Durations don't match !"); + fail_unless (GST_BUFFER_OFFSET (newbuffer) == GST_BUFFER_OFFSET (buffer), + "Offsets don't match !"); + fail_unless (GST_BUFFER_OFFSET_END (newbuffer) == + GST_BUFFER_OFFSET_END (buffer), "Offset ends don't match !"); + fail_if (GST_BUFFER_FLAG_IS_SET (newbuffer, GST_BUFFER_SUBBUFFER), + "GST_BUFFER_SUBBUFFER flag should not have been copied !"); + fail_unless (GST_BUFFER_FLAG_IS_SET (newbuffer, GST_BUFFER_IN_CAPS), + "GST_BUFFER_IN_CAPS flag should have been copied !"); + + g_free (header); +} + +END_TEST +START_TEST (test_caps) +{ + gchar *string, *newstring; + GstCaps *caps, *newcaps; + + guint header_length; + guint8 *header, *payload; + + caps = gst_caps_from_string ("audio/x-raw-float, " + "rate = (int) [ 11025, 48000 ], " + "channels = (int) [ 1, 2 ], " "endianness = (int) BYTE_ORDER, " + "width = (int) 32, " "buffer-frames = (int) 0"); + string = gst_caps_to_string (caps); + g_message ("Created caps: %s\n", string); + fail_unless (gst_dp_packet_from_caps (caps, 0, &header_length, &header, + &payload), "Could not create packet from caps."); + + /* validate the packet */ + fail_unless (gst_dp_validate_packet (header_length, header, payload), + "Could not validate packet"); + newcaps = gst_dp_caps_from_packet (header_length, header, payload); + fail_unless (newcaps != NULL, "Could not create caps from packet"); + //g_return_val_if_fail (GST_IS_CAPS (newcaps), -1); + newstring = gst_caps_to_string (newcaps); + g_message ("Received caps: %s\n", newstring); + fail_unless (strcmp (string, newstring) == 0, + "Created caps do not match original caps"); + g_free (string); + g_free (newstring); +} + +END_TEST +START_TEST (test_event) +{ + GstEvent *send; + GstEvent *receive; + guint header_length; + guint8 *header, *payload; + + g_message ("Testing EOS event at 1s\n"); + send = gst_event_new (GST_EVENT_EOS); + GST_EVENT_TIMESTAMP (send) = GST_SECOND; + fail_unless (gst_dp_packet_from_event (send, GST_DP_HEADER_FLAG_CRC, + &header_length, &header, &payload), + "Could not create packet from eos event"); + + receive = gst_dp_event_from_packet (header_length, header, payload); + + g_message ("EOS, timestamp %" GST_TIME_FORMAT "\n", + GST_TIME_ARGS (GST_EVENT_TIMESTAMP (receive))); + fail_unless (GST_EVENT_TYPE (receive) == GST_EVENT_EOS, + "Received event is not EOS"); + fail_unless (GST_EVENT_TIMESTAMP (receive) == GST_SECOND, + "EOS timestamp is not 1.0 sec"); + gst_event_unref (send); + gst_event_unref (receive); + + g_message ("Testing FLUSH event at 2s\n"); + send = gst_event_new (GST_EVENT_FLUSH); + GST_EVENT_TIMESTAMP (send) = GST_SECOND * 2; + fail_unless (gst_dp_packet_from_event (send, GST_DP_HEADER_FLAG_CRC, + &header_length, &header, &payload), + "Could not create packet from flush event"); + + receive = gst_dp_event_from_packet (header_length, header, payload); + + g_message ("Flush, timestamp %" GST_TIME_FORMAT "\n", + GST_TIME_ARGS (GST_EVENT_TIMESTAMP (receive))); + fail_unless (GST_EVENT_TYPE (receive) == GST_EVENT_FLUSH, + "Received event is not flush"); + fail_unless (GST_EVENT_TIMESTAMP (receive) == GST_SECOND * 2, + "Flush timestamp is not 2.0 sec"); + gst_event_unref (send); + gst_event_unref (receive); + + g_message ("Testing SEEK event with 1 second at 3 seconds\n"); + send = gst_event_new_seek (GST_FORMAT_TIME, GST_SECOND); + GST_EVENT_TIMESTAMP (send) = GST_SECOND * 3; + fail_unless (gst_dp_packet_from_event (send, GST_DP_HEADER_FLAG_CRC, + &header_length, &header, &payload), + "Could not create packet from seek event"); + + receive = gst_dp_event_from_packet (header_length, header, payload); + + g_message ("Seek, timestamp %" GST_TIME_FORMAT ", to %" GST_TIME_FORMAT "\n", + GST_TIME_ARGS (GST_EVENT_TIMESTAMP (receive)), + GST_TIME_ARGS (GST_EVENT_SEEK_OFFSET (receive))); + fail_unless (GST_EVENT_TYPE (receive) == GST_EVENT_SEEK, + "Returned event is not seek"); + fail_unless (GST_EVENT_TIMESTAMP (receive) == GST_SECOND * 3, + "Seek timestamp is not 3.0 sec"); + fail_unless (GST_EVENT_SEEK_FORMAT (receive) == GST_FORMAT_TIME, + "Seek format is not time"); + fail_unless (GST_EVENT_SEEK_OFFSET (receive) == GST_SECOND, + "Seek offset is not 1.0 sec"); + gst_event_unref (send); + gst_event_unref (receive); +} +END_TEST Suite * gst_object_suite (void) +{ + Suite *s = suite_create ("data protocol"); + TCase *tc_chain = tcase_create ("general"); + + suite_add_tcase (s, tc_chain); + tcase_add_test (tc_chain, test_conversion); + tcase_add_test (tc_chain, test_buffer); + tcase_add_test (tc_chain, test_caps); + tcase_add_test (tc_chain, test_event); + + return s; +} + +int +main (int argc, char **argv) +{ + int nf; + + Suite *s = gst_object_suite (); + SRunner *sr = srunner_create (s); + + gst_init (&argc, &argv); + gst_test_init (); + gst_dp_init (); + + srunner_run_all (sr, CK_NORMAL); + nf = srunner_ntests_failed (sr); + srunner_free (sr); + + return nf; +}