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 0872C220C0 for ; Tue, 5 Nov 2024 23:45:23 +0100 (CET) Received: (qmail 5158 invoked by uid 550); 5 Nov 2024 22:45:18 -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 5126 invoked from network); 5 Nov 2024 22:45:17 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=boeing.com; s=boeing-s1912; t=1730846709; bh=qbap6TGbopjKvHKYog1LM2+cuZPwE2xSc6jKDcHCnME=; h=From:To:Cc:Subject:Date:From; b=HQV2yG2h4P5zUbl++6BGRxZR3yTed+r83+w8Eg909/nh5AVYTprx93b52adKQGDub Zea4QsPE9aalyF+UxxYPYYlwzYZQE4q47llA0v5NMe61nZLaSc7cfXQbBvX2W+quqY Ku0/BqRTAHsMNmQcg2V3JocGEDV5v2/9Z7MTfCQlvjkfirmOnS3t3Y80kvL5Kbbu+B zotNq/aRZqKFKFzRwWD3iCXRSbJuEVfxiB00OQDfvtcK1qmbDbp/sfMJckIMKroB2j vzC0pP1DorDIOGqrLCwqKc8T5J6wePNNXc1t78c3BjQPmChCThJK3omlexAPQGQ4hu eI7o+Ub3ng54A== From: Ryan Gardner To: musl@lists.openwall.com Cc: Ryan Gardner Date: Tue, 5 Nov 2024 22:44:35 +0000 Message-Id: <20241105224437.67-1-ryan.p.gardner@boeing.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-TM-AS-GCONF: 00 Subject: [musl] [PATCH 1/3 libc-test] functional:time:clock_nanosleep test Testing of musl API against POSIX 2008 standard. Tests added: - EINTR is returned when sleep is interupted by a signal - ENOTSUP is returned when clock_id specifies an unsupported clock - EINVAL is returned when tv_nsec is out of range - EINVAL is returned when clock_id specifies an unknown clock - EINVAL is returned when clokc_id specifies the CPU-time clock of calling thread - rmtp is set to the remaining unslept time when interupted. - time elapses as expected References: - https://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_nanosleep.html Signed-off-by: Ryan Gardner --- src/functional/clock_nanosleep.c | 133 +++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 src/functional/clock_nanosleep.c diff --git a/src/functional/clock_nanosleep.c b/src/functional/clock_nanosleep.c new file mode 100644 index 0000000..071000a --- /dev/null +++ b/src/functional/clock_nanosleep.c @@ -0,0 +1,133 @@ +/* + * clock_nanosleep unit test + */ + +#include "test.h" +#include +#include +#include +#include + +#define MAX_NSEC 1000000000 +#define SLEEP_NANO 500000 +#define TEST(c, ...) ((c) || (t_error(#c " failed: " __VA_ARGS__), 0)) + +static void dummy_signal_handler(int signum) {} + +static void test_time_elapsed(void) +{ + // get start time + struct timespec time1; + if (clock_gettime(CLOCK_MONOTONIC, &time1) == -1) { + t_error("clock_gettime() failed. Errno: %s\n", strerror(errno)); + return; + } + + struct timespec ts = {0, SLEEP_NANO}; + TEST(clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts) == 0, + "clock_nanosleep failed with clock id %d\n", CLOCK_MONOTONIC); + + // get finish time + struct timespec time2; + if (clock_gettime(CLOCK_MONOTONIC, &time2) == -1) { + t_error("clock_gettime() failed. Errno: %s\n", strerror(errno)); + return; + } + + // calculate elapsed time + time_t elapsed = time2.tv_sec > time1.tv_sec + ? time2.tv_nsec + (MAX_NSEC - time1.tv_nsec) + : time2.tv_nsec - time1.tv_nsec; + + TEST(elapsed >= SLEEP_NANO, + "Elapsed time test failed: expected >= %d " + "nanoseconds, got %ld nanoseconds.\n", + SLEEP_NANO, elapsed); +} + +static void test_invalid_inputs(void) +{ + struct timespec ts = {1, 0}; + + // check EINVAL is returned when tv_nsec is too big + ts.tv_nsec = MAX_NSEC; + int retval = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL); + TEST(retval == EINVAL, + "Oversized tv_nsec test failed: Expected %s, got %s\n", + strerror(EINVAL), strerror(retval)); + + // check EINVAL is returned when tv_nsec is too small + ts.tv_nsec = -1; + retval = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL); + TEST(retval == EINVAL, + "Undersized tv_nsec test failed: Expected %s, got %s\n", + strerror(EINVAL), strerror(retval)); + + // check EINVAL is returned when given CPU_time clock of calling thread + retval = clock_nanosleep(CLOCK_THREAD_CPUTIME_ID, 0, &ts, NULL); + TEST(retval == EINVAL, + "Calling threads cpu clock id test failed: Expected %s, got %s\n", + strerror(EINVAL), strerror(retval)); + + const int unknown_clock = 123; + + // check EINVAL is returned when given unknown clock + retval = clock_nanosleep(unknown_clock, 0, &ts, NULL); + TEST(retval == EINVAL, + "Unknown clock id test failed: Expected %s, got %s\n", + strerror(EINVAL), strerror(retval)); + + // check ENOTSUP is returned when given an unsupported clock + retval = clock_nanosleep(CLOCK_MONOTONIC_COARSE, 0, &ts, NULL); + TEST(retval == ENOTSUP, + "Unsupported clock test failed. Expected %s, got %s\n", + strerror(ENOTSUP), strerror(retval)); +} + +static void test_interupted_sleep() +{ + // check EINTR is returned when sleep is interupted by a signal handler + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = dummy_signal_handler; + sigaction(SIGALRM, &sa, NULL); + + timer_t timerid = NULL; + if (timer_create(CLOCK_MONOTONIC, NULL, &timerid) == -1) { + t_error("timer_create() failed. Errno: %s\n", strerror(errno)); + return; + } + + struct itimerspec its = { + .it_value.tv_sec = 0, + .it_value.tv_nsec = SLEEP_NANO, + }; + if (timer_settime(timerid, 0, &its, NULL) == -1) { + t_error("timer_settime() failed. Errno: %s\n", strerror(errno)); + timer_delete(timerid); + return; + } + + struct timespec ts = {2, 0}; + struct timespec rmtp = {0, 0}; + int retval = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &rmtp); + + TEST(retval == EINTR, "Interupted sleep test failed: Expected %s, got %s\n", + strerror(EINTR), strerror(retval)); + + // check that the remaining unslept time is returned into rmtp + TEST(rmtp.tv_sec > 0 || rmtp.tv_nsec > 0, + "rmtp test failed: Expected value > 0, got rmpt.tv_sec = %lu, " + "rmtp.tv_nsec = %lu\n", + rmtp.tv_sec, rmtp.tv_nsec); + + timer_delete(timerid); +} + +int main(void) +{ + test_time_elapsed(); + test_invalid_inputs(); + test_interupted_sleep(); + return t_status; +} -- 2.34.1