From be6231988793c4e981a40448a0b88d009dac5e5b Mon Sep 17 00:00:00 2001 From: Marvin Scholz Date: Fri, 13 Mar 2020 19:45:37 +0100 Subject: [PATCH] compat: add test for clock_nanosleep on darwin --- compat/Makefile.am | 10 ++- compat/test/clock_nanosleep.c | 121 ++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 compat/test/clock_nanosleep.c diff --git a/compat/Makefile.am b/compat/Makefile.am index fb33c17e00..43cff74a9e 100644 --- a/compat/Makefile.am +++ b/compat/Makefile.am @@ -14,10 +14,18 @@ check_PROGRAMS = \ test_heap \ test_strnstr -TESTS = $(check_PROGRAMS) AM_TESTS_ENVIRONMENT = ASAN_OPTIONS="allocator_may_return_null=1" test_heap_SOURCES = test/heap.c test_heap_LDADD = libcompat.la test_strnstr_SOURCES = test/strnstr.c test_strnstr_LDADD = libcompat.la + +if HAVE_DARWIN +check_PROGRAMS += test_clock_nanosleep + +test_clock_nanosleep_SOURCES = test/clock_nanosleep.c +test_clock_nanosleep_LDADD = libcompat.la +endif + +TESTS = $(check_PROGRAMS) diff --git a/compat/test/clock_nanosleep.c b/compat/test/clock_nanosleep.c new file mode 100644 index 0000000000..9c94f4b7ae --- /dev/null +++ b/compat/test/clock_nanosleep.c @@ -0,0 +1,121 @@ +/***************************************************************************** + * clock_nanosleep.c: Test for clock_nanosleep implementation + ***************************************************************************** + * Copyright © 2020 VideoLAN & VLC authors + * + * Authors: Marvin Scholz + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +#include "config.h" + +#include +#include +#undef NDEBUG +#include +#include +#include +#include + +#define VLC_NSEC_PER_SEC 1000000000ull + +#define VLC_TEST(id, flags, tp, eret, eerr) \ +do { \ + assert( clock_nanosleep(id, flags, tp, NULL) == eret ); \ + if (eret != 0) assert( eerr == errno ); \ +} while (0) + +// Thread entry function for cancellation test +static void *waiting_thread_entry(void *unused) +{ + (void)unused; + + struct timespec ts = { 5, 0 }; + assert(clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL) == 0); + assert(0); + return NULL; +} + +int main(void) +{ + alarm(1); + + // Invalid timespec (negative) + { + struct timespec inv_ts = { -1, -1 }; + VLC_TEST(CLOCK_MONOTONIC, 0, &inv_ts, -1, EINVAL); + VLC_TEST(CLOCK_MONOTONIC, TIMER_ABSTIME, &inv_ts, -1, EINVAL); + VLC_TEST(CLOCK_REALTIME, 0, &inv_ts, -1, EINVAL); + VLC_TEST(CLOCK_REALTIME, TIMER_ABSTIME, &inv_ts, -1, EINVAL); + } + + // Invalid timespec (nsec out of range) + { + struct timespec inv_ts = { -1, VLC_NSEC_PER_SEC }; + VLC_TEST(CLOCK_MONOTONIC, 0, &inv_ts, -1, EINVAL); + VLC_TEST(CLOCK_MONOTONIC, TIMER_ABSTIME, &inv_ts, -1, EINVAL); + VLC_TEST(CLOCK_REALTIME, 0, &inv_ts, -1, EINVAL); + VLC_TEST(CLOCK_REALTIME, TIMER_ABSTIME, &inv_ts, -1, EINVAL); + } + + // Valid timespec (0 sec, 0 nsec) + { + struct timespec ts = { 0, 0 }; + VLC_TEST(CLOCK_MONOTONIC, 0, &ts, 0, 0); + VLC_TEST(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, 0, 0); + VLC_TEST(CLOCK_REALTIME, 0, &ts, 0, 0); + VLC_TEST(CLOCK_REALTIME, TIMER_ABSTIME, &ts, 0, 0); + } + + // Valid timespec (wait for nearly one second each) + { + alarm(3); + struct timespec ts = { 0, VLC_NSEC_PER_SEC - 1 }; + VLC_TEST(CLOCK_MONOTONIC, 0, &ts, 0, 0); + VLC_TEST(CLOCK_REALTIME, 0, &ts, 0, 0); + } + + // Absolute monotonic clock waiting (wait for one second) + { + alarm(3); + struct timespec ts, ts_now; + + clock_gettime(CLOCK_MONOTONIC, &ts); + ts.tv_sec += 1; + + VLC_TEST(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, 0, 0); + + clock_gettime(CLOCK_MONOTONIC, &ts_now); + assert(ts.tv_sec <= ts_now.tv_sec); + } + + // Absolute realtime clock in the past + { + alarm(1); + struct timespec ts = { 10, 10 }; + VLC_TEST(CLOCK_REALTIME, TIMER_ABSTIME, &ts, 0, 0); + } + + // Test thread cancellation + { + alarm(1); + pthread_t th; + pthread_create(&th, NULL, waiting_thread_entry, NULL); + pthread_cancel(th); + pthread_join(th, NULL); + } + +}