From d1218d7309475193b53911667911c4f59a1a7752 Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Sat, 21 Nov 2020 22:11:21 -0800 Subject: New NUTS test framework (NNG Unit Test Support). This is based on testutil/acutest, but is cleaner and fixes some short-comings. We will be adding more support for additional common paradigms to better facilitate transport tests. While here we added some more test cases, and fixed a possible symbol collision in the the stats framework (due to Linux use of a macro definition of "si_value" in a standard OS header). Test coverage may regress slightly as we are no longer using some of the legacy APIs. --- src/testing/util.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 src/testing/util.c (limited to 'src/testing/util.c') diff --git a/src/testing/util.c b/src/testing/util.c new file mode 100644 index 00000000..eeb70b4f --- /dev/null +++ b/src/testing/util.c @@ -0,0 +1,164 @@ +// +// Copyright 2020 Staysail Systems, Inc. +// Copyright 2018 Capitar IT Group BV +// +// This software is supplied under the terms of the MIT License, a +// copy of which should be located in the distribution where this +// file was obtained (LICENSE.txt). A copy of the license may also be +// found online at https://opensource.org/licenses/MIT. +// + +#define TEST_NO_MAIN + +#ifdef _WIN32 + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + +#include +#include +// order counts +#include +#define poll WSAPoll +#include +#else +#include +#include +#include +#include +#include +#include +#endif +#include +#include +#include +#include +#include + +#if !defined(_WIN32) && !defined(CLOCK_MONOTONIC) +#include +#endif + +#include "nuts.h" + +uint64_t +nuts_clock(void) +{ +#ifdef _WIN32 + return (GetTickCount64()); +#elif defined(CLOCK_MONTONIC) + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + uint64_t val; + + val = ts.tv_sec; + val *= 1000; + val += ts.tv_nsec / 1000000; + return (val); +#else + static time_t epoch; + struct timeval tv; + + if (epoch == 0) { + epoch = time(NULL); + } + gettimeofday(&tv, NULL); + + if (tv.tv_sec < epoch) { + // Broken clock. + // This will force all other timing tests to fail + return (0); + } + tv.tv_sec -= epoch; + return ( + ((uint64_t)(tv.tv_sec) * 1000) + (uint64_t)(tv.tv_usec / 1000)); +#endif + +#ifdef _WIN32 +#else +#include +#include +#endif +} + +bool +nuts_poll_fd(int fd) +{ +#ifdef _WIN32 + struct pollfd pfd; + pfd.fd = (SOCKET) fd; + pfd.events = POLLRDNORM; + pfd.revents = 0; + + switch (WSAPoll(&pfd, 1, 0)) { + case 0: + return (false); + case 1: + return (true); + } +#else + struct pollfd pfd; + + pfd.fd = fd; + pfd.events = POLLRDNORM; + pfd.revents = 0; + + switch (poll(&pfd, 1, 0)) { + case 0: + return (false); + case 1: + return (true); + } +#endif + return (false); +} + +static bool +is_little_endian(void) +{ + uint16_t num = 0x1; + uint8_t *ptr = (uint8_t *) (void *) (&num); + return (ptr[0] == 1); +} + +uint16_t +nuts_be16(uint16_t in) +{ + if (is_little_endian()) { + in = ((in / 0x100) + ((in % 0x100) * 0x100)); + } + return (in); +} + +uint32_t +nuts_be32(uint32_t in) +{ + if (is_little_endian()) { + in = ((in >> 24u) & 0xffu) | ((in >> 8u) & 0xff00u) | + ((in << 8u) & 0xff0000u) | ((in << 24u) & 0xff000000u); + } + return (in); +} + +void +nuts_sleep(int msec) +{ +#ifdef _WIN32 + Sleep(msec); +#elif defined(CLOCK_MONOTONIC) + struct timespec ts; + + ts.tv_sec = msec / 1000; + ts.tv_nsec = (msec % 1000) * 1000000; + + // Do this in a loop, so that interrupts don't actually wake us. + while (ts.tv_sec || ts.tv_nsec) { + if (nanosleep(&ts, &ts) == 0) { + break; + } + } +#else + poll(NULL, 0, msec); +#endif +} -- cgit v1.2.3-70-g09d2