| /* GStreamer |
| * |
| * unit test for GstPoll |
| * |
| * Copyright (C) <2007> Peter Kjellerstedt <pkj@axis.com> |
| * |
| * 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., 51 Franklin St, Fifth Floor, |
| * Boston, MA 02110-1301, USA. |
| */ |
| #ifdef HAVE_CONFIG_H |
| #include "config.h" |
| #endif |
| |
| #include <gst/check/gstcheck.h> |
| |
| #ifdef G_OS_WIN32 |
| #include <winsock2.h> |
| #include <fcntl.h> |
| #else |
| #include <unistd.h> |
| #include <sys/socket.h> |
| #endif |
| |
| GST_START_TEST (test_poll_wait) |
| { |
| GstPoll *set; |
| GstPollFD rfd = GST_POLL_FD_INIT; |
| GstPollFD wfd = GST_POLL_FD_INIT; |
| gint socks[2]; |
| guchar c = 'A'; |
| |
| set = gst_poll_new (FALSE); |
| fail_if (set == NULL, "Failed to create a GstPoll"); |
| |
| #ifdef G_OS_WIN32 |
| fail_if (_pipe (socks, 4096, _O_BINARY) < 0, "Could not create a pipe"); |
| #else |
| fail_if (socketpair (PF_UNIX, SOCK_STREAM, 0, socks) < 0, |
| "Could not create a pipe"); |
| #endif |
| rfd.fd = socks[0]; |
| wfd.fd = socks[1]; |
| |
| fail_unless (gst_poll_add_fd (set, &rfd), "Could not add read descriptor"); |
| fail_unless (gst_poll_fd_ctl_read (set, &rfd, TRUE), |
| "Could not mark the descriptor as readable"); |
| |
| fail_unless (write (wfd.fd, &c, 1) == 1, "write() failed"); |
| |
| fail_unless (gst_poll_wait (set, GST_CLOCK_TIME_NONE) == 1, |
| "One descriptor should be available"); |
| fail_unless (gst_poll_fd_can_read (set, &rfd), |
| "Read descriptor should be readable"); |
| fail_if (gst_poll_fd_can_write (set, &rfd), |
| "Read descriptor should not be writeable"); |
| |
| fail_unless (gst_poll_add_fd (set, &wfd), "Could not add write descriptor"); |
| fail_unless (gst_poll_fd_ctl_write (set, &wfd, TRUE), |
| "Could not mark the descriptor as writeable"); |
| |
| fail_unless (gst_poll_wait (set, GST_CLOCK_TIME_NONE) == 2, |
| "Two descriptors should be available"); |
| fail_unless (gst_poll_fd_can_read (set, &rfd), |
| "Read descriptor should be readable"); |
| fail_if (gst_poll_fd_can_write (set, &rfd), |
| "Read descriptor should not be writeable"); |
| fail_if (gst_poll_fd_can_read (set, &wfd), |
| "Write descriptor should not be readable"); |
| fail_unless (gst_poll_fd_can_write (set, &wfd), |
| "Write descriptor should be writeable"); |
| |
| fail_unless (read (rfd.fd, &c, 1) == 1, "read() failed"); |
| |
| fail_unless (gst_poll_wait (set, GST_CLOCK_TIME_NONE) == 1, |
| "One descriptor should be available"); |
| fail_if (gst_poll_fd_can_read (set, &rfd), |
| "Read descriptor should not be readable"); |
| fail_if (gst_poll_fd_can_write (set, &rfd), |
| "Read descriptor should not be writeable"); |
| fail_if (gst_poll_fd_can_read (set, &wfd), |
| "Write descriptor should not be readable"); |
| fail_unless (gst_poll_fd_can_write (set, &wfd), |
| "Write descriptor should be writeable"); |
| |
| gst_poll_free (set); |
| close (socks[0]); |
| close (socks[1]); |
| } |
| |
| GST_END_TEST; |
| |
| GST_START_TEST (test_poll_basic) |
| { |
| GstPoll *set; |
| GstPollFD fd = GST_POLL_FD_INIT; |
| |
| fd.fd = 1; |
| |
| set = gst_poll_new (FALSE); |
| fail_if (set == NULL, "Failed to create a GstPoll"); |
| |
| fail_unless (gst_poll_add_fd (set, &fd), "Could not add descriptor"); |
| fail_unless (gst_poll_fd_ctl_write (set, &fd, TRUE), |
| "Could not mark the descriptor as writeable"); |
| fail_unless (gst_poll_fd_ctl_read (set, &fd, TRUE), |
| "Could not mark the descriptor as readable"); |
| fail_if (gst_poll_fd_has_closed (set, &fd), |
| "Descriptor should not be closed"); |
| fail_if (gst_poll_fd_has_error (set, &fd), |
| "Descriptor should not have an error"); |
| fail_if (gst_poll_fd_can_write (set, &fd), |
| "Descriptor should not be writeable"); |
| fail_if (gst_poll_fd_can_read (set, &fd), |
| "Descriptor should not be readable"); |
| fail_unless (gst_poll_remove_fd (set, &fd), "Could not remove descriptor"); |
| |
| fail_if (gst_poll_remove_fd (set, &fd), |
| "Could remove already removed descriptor"); |
| |
| fail_unless (gst_poll_wait (set, 50 * GST_MSECOND) == 0, |
| "Waiting did not timeout"); |
| |
| gst_poll_free (set); |
| |
| set = gst_poll_new (TRUE); |
| fail_if (set == NULL, "Failed to create a GstPoll"); |
| gst_poll_set_flushing (set, TRUE); |
| gst_poll_free (set); |
| } |
| |
| GST_END_TEST; |
| |
| static gpointer |
| delayed_stop (gpointer data) |
| { |
| GstPoll *set = data; |
| |
| THREAD_START (); |
| |
| g_usleep (500000); |
| |
| gst_poll_set_flushing (set, TRUE); |
| |
| return NULL; |
| } |
| |
| GST_START_TEST (test_poll_wait_stop) |
| { |
| GstPoll *set; |
| |
| set = gst_poll_new (TRUE); |
| fail_if (set == NULL, "Failed to create a GstPoll"); |
| |
| MAIN_START_THREADS (1, delayed_stop, set); |
| |
| fail_unless (gst_poll_wait (set, GST_SECOND) != 0, "Waiting timed out"); |
| |
| MAIN_STOP_THREADS (); |
| |
| gst_poll_free (set); |
| } |
| |
| GST_END_TEST; |
| |
| static gpointer |
| delayed_restart (gpointer data) |
| { |
| GstPoll *set = data; |
| GstPollFD fd = GST_POLL_FD_INIT; |
| |
| fd.fd = 1; |
| |
| THREAD_START (); |
| |
| g_usleep (500000); |
| |
| gst_poll_add_fd (set, &fd); |
| gst_poll_fd_ctl_write (set, &fd, TRUE); |
| gst_poll_restart (set); |
| |
| return NULL; |
| } |
| |
| GST_START_TEST (test_poll_wait_restart) |
| { |
| GstPoll *set; |
| GstPollFD fd = GST_POLL_FD_INIT; |
| |
| fd.fd = 1; |
| |
| set = gst_poll_new (TRUE); |
| fail_if (set == NULL, "Failed to create a GstPoll"); |
| |
| MAIN_START_THREADS (1, delayed_restart, set); |
| |
| fail_unless (gst_poll_wait (set, GST_SECOND) > 0, "Waiting was interrupted"); |
| fail_unless (gst_poll_fd_can_write (set, &fd), |
| "Write descriptor should be writeable"); |
| |
| MAIN_STOP_THREADS (); |
| |
| gst_poll_free (set); |
| } |
| |
| GST_END_TEST; |
| |
| static gpointer |
| delayed_flush (gpointer data) |
| { |
| GstPoll *set = data; |
| |
| THREAD_START (); |
| |
| g_usleep (500000); |
| gst_poll_set_flushing (set, TRUE); |
| |
| return NULL; |
| } |
| |
| GST_START_TEST (test_poll_wait_flush) |
| { |
| GstPoll *set; |
| |
| set = gst_poll_new (TRUE); |
| fail_if (set == NULL, "Failed to create a GstPoll"); |
| |
| gst_poll_set_flushing (set, TRUE); |
| fail_unless (gst_poll_wait (set, GST_SECOND) == -1 && errno == EBUSY, |
| "Waiting was not flushed"); |
| fail_unless (gst_poll_wait (set, GST_SECOND) == -1 && errno == EBUSY, |
| "Waiting was not flushed"); |
| |
| gst_poll_set_flushing (set, FALSE); |
| fail_unless (gst_poll_wait (set, GST_SECOND) == 0, "Waiting did not timeout"); |
| |
| MAIN_START_THREADS (1, delayed_flush, set); |
| |
| fail_unless (gst_poll_wait (set, GST_SECOND) == -1 && errno == EBUSY, |
| "Waiting was not flushed"); |
| fail_unless (gst_poll_wait (set, GST_SECOND) == -1 && errno == EBUSY, |
| "Waiting was not flushed"); |
| |
| gst_poll_set_flushing (set, FALSE); |
| fail_unless (gst_poll_wait (set, GST_SECOND) == 0, "Waiting did not timeout"); |
| |
| MAIN_STOP_THREADS (); |
| |
| gst_poll_free (set); |
| } |
| |
| GST_END_TEST; |
| |
| static gpointer |
| delayed_control (gpointer data) |
| { |
| GstPoll *set = data; |
| GstPollFD fd = GST_POLL_FD_INIT; |
| |
| fd.fd = 1; |
| |
| THREAD_START (); |
| |
| g_usleep (500000); |
| |
| gst_poll_add_fd (set, &fd); |
| gst_poll_fd_ctl_write (set, &fd, TRUE); |
| gst_poll_restart (set); |
| |
| g_mutex_lock (&mutex); |
| THREAD_SYNCHRONIZE (); |
| |
| g_usleep (500000); |
| |
| gst_poll_add_fd (set, &fd); |
| gst_poll_fd_ctl_write (set, &fd, TRUE); |
| gst_poll_restart (set); |
| |
| return NULL; |
| } |
| |
| GST_START_TEST (test_poll_controllable) |
| { |
| GstPoll *set; |
| GstPollFD fd = GST_POLL_FD_INIT; |
| |
| fd.fd = 1; |
| |
| set = gst_poll_new (FALSE); |
| fail_if (set == NULL, "Failed to create a GstPoll"); |
| |
| MAIN_START_THREADS (1, delayed_control, set); |
| |
| fail_unless (gst_poll_wait (set, GST_SECOND) == 0, "Waiting did not timeout"); |
| |
| fail_unless (gst_poll_remove_fd (set, &fd), "Could not remove descriptor"); |
| fail_unless (gst_poll_set_controllable (set, TRUE), |
| "Could not make the set controllable"); |
| |
| MAIN_SYNCHRONIZE (); |
| |
| fail_unless (gst_poll_wait (set, GST_SECOND) > 0, "Waiting was interrupted"); |
| fail_unless (gst_poll_fd_can_write (set, &fd), |
| "Write descriptor should be writeable"); |
| |
| MAIN_STOP_THREADS (); |
| |
| gst_poll_free (set); |
| } |
| |
| GST_END_TEST; |
| |
| static Suite * |
| gst_poll_suite (void) |
| { |
| Suite *s = suite_create ("GstPoll"); |
| TCase *tc_chain = tcase_create ("general"); |
| |
| /* turn off timeout */ |
| tcase_set_timeout (tc_chain, 60); |
| |
| suite_add_tcase (s, tc_chain); |
| |
| #ifndef G_OS_WIN32 |
| tcase_add_test (tc_chain, test_poll_basic); |
| tcase_add_test (tc_chain, test_poll_wait); |
| tcase_add_test (tc_chain, test_poll_wait_stop); |
| tcase_add_test (tc_chain, test_poll_wait_restart); |
| tcase_add_test (tc_chain, test_poll_wait_flush); |
| tcase_add_test (tc_chain, test_poll_controllable); |
| #else |
| tcase_skip_broken_test (tc_chain, test_poll_basic); |
| tcase_skip_broken_test (tc_chain, test_poll_wait); |
| tcase_skip_broken_test (tc_chain, test_poll_wait_stop); |
| tcase_skip_broken_test (tc_chain, test_poll_wait_restart); |
| tcase_skip_broken_test (tc_chain, test_poll_wait_flush); |
| tcase_skip_broken_test (tc_chain, test_poll_controllable); |
| #endif |
| |
| return s; |
| } |
| |
| GST_CHECK_MAIN (gst_poll); |