From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL autolearn=ham autolearn_force=no version=3.4.4 Received: from second.openwall.net (second.openwall.net [193.110.157.125]) by inbox.vuxu.org (Postfix) with SMTP id 52B95222B8 for ; Tue, 5 Nov 2024 23:45:41 +0100 (CET) Received: (qmail 7391 invoked by uid 550); 5 Nov 2024 22:45:30 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com x-ms-reactions: disallow Received: (qmail 7317 invoked from network); 5 Nov 2024 22:45:30 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=boeing.com; s=boeing-s1912; t=1730846722; bh=d5oU2d/YCbHYJnByNV74pmXIs0VO1Sp2KQaU9qlZ0Ss=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qXV/QB2e+lVIpGNkJxT4+XzOD6eLysxcT3QAtWOJrChpbVwx4qop2+ZKDcl7iahBc Ls3hNiKk9UWqpoexBMKmQdbk/f7+Pyl/RNbBkqmt1zllY+RS0sSCzjBte9P4JF8ZsH GASm3UZubE54EytPLbR7hIFCHCW/KDCWw4pCQOz4DMlAroqUiKze/v/o/pfiUN3Fht aZd6Poz9Kx4VV0o1DHqV6nFiyeUfUQRzq6jXu9O4gVW9J0xFpHKnr/Xrj4K2zqdiFM O/4pUfbd6Go5iD87WfwjK/3BGeSf5kYlBF5ZuP6NBs2bde/PQ2IOM8J/hA+22fBt3p /85MNSZ+e+xiw== From: Ryan Gardner To: musl@lists.openwall.com Cc: Ryan Gardner Date: Tue, 5 Nov 2024 22:44:37 +0000 Message-Id: <20241105224437.67-3-ryan.p.gardner@boeing.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241105224437.67-1-ryan.p.gardner@boeing.com> References: <20241105224437.67-1-ryan.p.gardner@boeing.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-TM-AS-GCONF: 00 Subject: [musl] [PATCH 3/3 libc-test] functional:time:timer_settime test Testing of musl API against POSIX 2008 standard. Tests added: - EINVAL is returned when value value struct is invalid - setting an already armed timer results in a reset - setting an already armed timer with it_value = 0 results in the timer being disarmed - timer expires repeatedly when given non-zero interval value - ovalue is set correctly References: - https://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_settime.html Signed-off-by: Ryan Gardner --- src/functional/timer_settime.c | 212 +++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 src/functional/timer_settime.c diff --git a/src/functional/timer_settime.c b/src/functional/timer_settime.c new file mode 100644 index 0000000..d5597fb --- /dev/null +++ b/src/functional/timer_settime.c @@ -0,0 +1,212 @@ +/* + * timer_settime unit test + */ + +#include "test.h" +#include +#include +#include +#include + +#define TEST(c, ...) ((c) || (t_error(#c " failed: " __VA_ARGS__), 0)) +#define TIME_NANO 500000 +#define OVERSIZED_NANOSECONDS 1000000001 +#define NUM_REPEATS 5 + +volatile int timeout_count = 0; +static void timeout_signal_counter(int signum) { timeout_count++; } + +static void test_settime(void) +{ + timer_t timerid = NULL; + if (timer_create(CLOCK_REALTIME, NULL, &timerid) == -1) { + t_error("Failed to create timer. Errno: %s\n", strerror(errno)); + return; + } + + struct itimerspec its = { + .it_value = {1, TIME_NANO}, + .it_interval = {1, TIME_NANO}, + }; + + // test timer_settime() returns 0 when successful + TEST(timer_settime(timerid, 0, &its, NULL) == 0, + "Failed to set timer. Errno: %s\n", strerror(errno)); + + struct itimerspec res; + if (timer_gettime(timerid, &res) == -1) { + t_error("Failed to get timer time. Errno: %s\n", strerror(errno)); + timer_delete(timerid); + return; + } + + // test values from timer_settime() are set properly + TEST(res.it_value.tv_sec == 1 && res.it_value.tv_nsec != 0 && + res.it_interval.tv_sec == 1 && + res.it_interval.tv_nsec == TIME_NANO, + "Failed to set correct timer values\n"); + + timer_delete(timerid); +} + +static void test_periodic_timer(void) +{ + // setup signal handler + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = timeout_signal_counter; + sigaction(SIGALRM, &sa, NULL); + + timer_t timerid = NULL; + if (timer_create(CLOCK_REALTIME, NULL, &timerid) == -1) { + t_error("Failed to create timer. Errno: %s\n", strerror(errno)); + return; + } + + struct itimerspec its = { + .it_value = {0, TIME_NANO}, + .it_interval = {0, TIME_NANO}, + }; + + TEST(timer_settime(timerid, 0, &its, NULL) == 0, + "Failed to set timer. Errno: %s\n", strerror(errno)); + + struct timespec sleep_time = { + .tv_sec = 1, + .tv_nsec = 0, + }; + + // sleep for 1 second or until 5 timer timeouts have occured + while ( + clock_nanosleep(CLOCK_REALTIME, 0, &sleep_time, &sleep_time) == EINTR && + timeout_count < NUM_REPEATS) { + continue; + }; + + // test that the timer repeats after timeout + TEST(timeout_count >= NUM_REPEATS, + "Failed periodic timer test. Expected timeout_count value >= 5, got " + "%d\n", + timeout_count); + + timer_delete(timerid); +} + +static void test_invalid_inputs(void) +{ + timer_t timerid = NULL; + if (timer_create(CLOCK_REALTIME, NULL, &timerid) == -1) { + t_error("Failed to create timer. Errno: %s\n", strerror(errno)); + return; + } + + struct itimerspec its = { + .it_value = {0, OVERSIZED_NANOSECONDS}, + .it_interval = {0, 0}, + }; + + TEST(timer_settime(timerid, 0, &its, NULL) == -1 && errno == EINVAL, + "Oversized nanoseconds test failed, expected %s,got %s\n", + strerror(EINVAL), strerror(errno)); + + errno = 0; + its.it_value.tv_nsec = -1; + + TEST(timer_settime(timerid, 0, &its, NULL) == -1 && errno == EINVAL, + "Undersized nanoseconds test failed, expected %s,got %s\n", + strerror(EINVAL), strerror(errno)); + + timer_delete(timerid); +} + +static void test_timer_resets(void) +{ + timer_t timerid = NULL; + if (timer_create(CLOCK_REALTIME, NULL, &timerid) == -1) { + t_error("Failed to create timer. Errno: %s\n", strerror(errno)); + return; + } + + struct itimerspec its = { + .it_value = {0, TIME_NANO}, + .it_interval = {0, 0}, + }; + + TEST(timer_settime(timerid, 0, &its, NULL) == 0, + "Failed to set time. Errno: %s\n", strerror(errno)); + + its.it_value.tv_sec = 1; + its.it_value.tv_nsec = 0; + + struct itimerspec ovalue = {.it_value.tv_nsec = 0}; + + TEST(timer_settime(timerid, 0, &its, &ovalue) == 0, + "Failed to set time. Errno: %s\n", strerror(errno)); + + struct itimerspec res; + if (timer_gettime(timerid, &res) == -1) { + t_error("Failed to get timer time. Errno: %s\n", strerror(errno)); + timer_delete(timerid); + return; + } + + // check that it_value has been overwritten + TEST(res.it_value.tv_nsec > TIME_NANO, + "Timer reset test failed, expected time until expiry > %d, got %ld\n", + TIME_NANO, res.it_value.tv_nsec); + + // check ovalue is set correctly + TEST(ovalue.it_value.tv_nsec != 0, + "timer_settime() failed to set ovalue correctly\n"); + + timer_delete(timerid); +} + +static void test_disarm_timer(void) +{ + timer_t timerid = NULL; + if (timer_create(CLOCK_REALTIME, NULL, &timerid) == -1) { + t_error("Failed to create timer. Errno: %s\n", strerror(errno)); + return; + } + + struct itimerspec its = { + .it_value = {0, TIME_NANO}, + .it_interval = {0, 0}, + }; + + TEST(timer_settime(timerid, 0, &its, NULL) == 0, + "Failed to set time. Errno: %s\n", strerror(errno)); + + its.it_value.tv_nsec = 0; + + TEST(timer_settime(timerid, 0, &its, NULL) == 0, + "Failed to set time. Errno: %s\n", strerror(errno)); + + struct itimerspec res; + + if (timer_gettime(timerid, &res) == -1) { + t_error("Failed to get timer time. Errno: %s\n", strerror(errno)); + timer_delete(timerid); + return; + } + + // setting the it_value of an armed timer to 0 should result in the timer + // being disarmed + TEST(res.it_value.tv_sec == 0 && res.it_value.tv_nsec == 0, + "Disarm timer test failed, expected it_value.tv_sec = 0, got %ld, " + "expected it_value.tv_nsec = 0, got %ld\n", + res.it_value.tv_sec, res.it_value.tv_nsec); + + timer_delete(timerid); +} + +int main(void) +{ + test_settime(); + test_periodic_timer(); + test_invalid_inputs(); + test_timer_resets(); + test_disarm_timer(); + return t_status; +} -- 2.34.1