summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2013-09-02 23:07:33 +0200
committerArthur de Jong <arthur@arthurdejong.org>2013-09-02 23:14:48 +0200
commitdb5382ec111ba1080cf7a5b2d6a4c881ec04bc5d (patch)
tree1b89764cca9598f65e06c84c2b499d40b90aa11a /tests
parent7895739cfec05b5edb9eff8c8673803fcdf9ed75 (diff)
Add a test for clock_gettime() supported clocks
This probes the system for available clocks to see if they can be reliably used to get a monotonic-like timer (the test doesn't verify the monotonic part, just usability).
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.am6
-rw-r--r--tests/test_clock.c158
2 files changed, 162 insertions, 2 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 441af73..45f73fc 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -20,7 +20,7 @@
TESTS = test_dict test_set test_tio test_expr test_getpeercred test_cfg \
test_myldap.sh test_common test_nsscmds.sh test_pamcmds.sh \
- test_manpages.sh
+ test_manpages.sh test_clock
if HAVE_PYTHON
TESTS += test_pycompile.sh test_pylint.sh
endif
@@ -31,7 +31,7 @@ endif
AM_TESTS_ENVIRONMENT = PYTHON='@PYTHON@'; export PYTHON;
check_PROGRAMS = test_dict test_set test_tio test_expr test_getpeercred \
- test_cfg test_myldap test_common \
+ test_cfg test_myldap test_common test_clock \
lookup_netgroup lookup_shadow
EXTRA_DIST = nslcd-test.conf usernames.txt in_testenv.sh test_myldap.sh \
@@ -85,6 +85,8 @@ test_myldap_LDADD = ../nslcd/cfg.o $(common_nslcd_LDADD)
test_common_SOURCES = test_common.c ../nslcd/common.h
test_common_LDADD = ../nslcd/cfg.o $(common_nslcd_LDADD)
+test_clock_SOURCES = test_clock.c
+
lookup_netgroup_SOURCES = lookup_netgroup.c
lookup_shadow_SOURCES = lookup_shadow.c
diff --git a/tests/test_clock.c b/tests/test_clock.c
new file mode 100644
index 0000000..8d55f93
--- /dev/null
+++ b/tests/test_clock.c
@@ -0,0 +1,158 @@
+/*
+ test_clock.c - tests for finding usable system clocks
+ This file is part of the nss-pam-ldapd library.
+
+ Copyright (C) 2013 Arthur de Jong
+
+ This library 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 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA
+*/
+
+#include "config.h"
+
+#include <stdio.h>
+#include <assert.h>
+#include <time.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "compat/attrs.h"
+
+/* use clock_gettime() to see if the specified clock is supported */
+static int test_clock_gettime(clockid_t c, const char *cname)
+{
+ struct timespec t1 = {0, 0};
+ struct timespec t2 = {0, 0};
+ struct timespec t3 = {0, 50 * 1000 * 1000}; /* 50 msec */
+ struct timespec t4 = {0, 0};
+ long diff;
+ int result = 0;
+ /* see if we can get resolution (not important so ignore any failures) */
+ errno = 0;
+ if (clock_getres(c, &t1))
+ printf(" clock %s resolution not supported: %s\n", cname, strerror(errno));
+ if ((t1.tv_sec != 0) || (t1.tv_nsec != 0))
+ printf(" clock %s resolution: %ld.%09ld\n", cname, (long)t1.tv_sec, (long)t1.tv_nsec);
+ /* see if we can get the time */
+ errno = 0;
+ if (clock_gettime(c, &t2))
+ {
+ printf("FAIL clock %s get time not supported: %s\n",
+ cname, strerror(errno));
+ if ((t2.tv_sec != 0) || (t2.tv_nsec != 0))
+ printf(" clock %s time: %ld.%09ld\n", cname, (long)t2.tv_sec, (long)t2.tv_nsec);
+ return -1;
+ }
+ else
+ printf("OK clock %s time: %ld.%09ld\n", cname, (long)t2.tv_sec, (long)t2.tv_nsec);
+ /* quick sleep (assume we're not interrupted) */
+ (void)nanosleep(&t3, NULL);
+ /* see if we can get the time again */
+ errno = 0;
+ if (clock_gettime(c, &t4))
+ {
+ printf("FAIL clock %s get time twice not supported: %s\n",
+ cname, strerror(errno));
+ if ((t4.tv_sec != 0) || (t4.tv_nsec != 0))
+ printf(" clock %s time: %ld.%09ld\n", cname, (long)t4.tv_sec, (long)t4.tv_nsec);
+ return -1;
+ }
+ else
+ printf("OK clock %s time: %ld.%09ld\n", cname, (long)t4.tv_sec, (long)t4.tv_nsec);
+ /* calculate difference */
+ diff = ((long)t4.tv_sec - (long)t2.tv_sec - (long)t3.tv_sec) * (long)1000000000 +
+ ((long)t4.tv_nsec - (long)t2.tv_nsec - (long)t3.tv_nsec);
+ if ((diff < (-10 * 1000 * 1000)) || (diff > (20 * 1000 * 1000)))
+ {
+ result = -1;
+ printf("FAIL ");
+ }
+ else
+ printf("OK ");
+ printf("clock %s time diff: %s%ld.%09ld %.1f%%\n", cname, (diff < 0) ? "-" : "",
+ (labs(diff) / 1000000000L), (labs(diff) % 1000000000L),
+ labs(100L * diff) / (float)((long)t3.tv_sec * 1000000000L + (long)t3.tv_nsec));
+ return result;
+}
+
+/* wrapper for test_clock_gettime() that passes the clock name */
+#define TEST_CLOCK_GETTIME(clock) test_clock_gettime(clock, #clock)
+
+int main(int UNUSED(argc), char UNUSED(*argv[]))
+{
+ int found_clocks = 0;
+#ifdef CLOCK_MONOTONIC_RAW
+ if (!TEST_CLOCK_GETTIME(CLOCK_MONOTONIC_RAW))
+ found_clocks++;
+#endif
+#ifdef CLOCK_MONOTONIC_FAST
+ if (!TEST_CLOCK_GETTIME(CLOCK_MONOTONIC_FAST))
+ found_clocks++;
+#endif
+#ifdef CLOCK_MONOTONIC_COARSE
+ if (!TEST_CLOCK_GETTIME(CLOCK_MONOTONIC_COARSE))
+ found_clocks++;
+#endif
+#ifdef CLOCK_MONOTONIC
+ if (!TEST_CLOCK_GETTIME(CLOCK_MONOTONIC))
+ found_clocks++;
+#endif
+#ifdef CLOCK_UPTIME_FAST
+ if (!TEST_CLOCK_GETTIME(CLOCK_UPTIME_FAST))
+ found_clocks++;
+#endif
+#ifdef CLOCK_UPTIME
+ if (!TEST_CLOCK_GETTIME(CLOCK_UPTIME))
+ found_clocks++;
+#endif
+#ifdef CLOCK_BOOTTIME
+ if (!TEST_CLOCK_GETTIME(CLOCK_BOOTTIME))
+ found_clocks++;
+#endif
+#ifdef CLOCK_MONOTONIC_PRECISE
+ if (!TEST_CLOCK_GETTIME(CLOCK_MONOTONIC_PRECISE))
+ found_clocks++;
+#endif
+#ifdef CLOCK_UPTIME_PRECISE
+ if (!TEST_CLOCK_GETTIME(CLOCK_UPTIME_PRECISE))
+ found_clocks++;
+#endif
+#ifdef CLOCK_HIGHRES
+#if CLOCK_HIGHRES == CLOCK_MONOTONIC
+ printf(" CLOCK_HIGHRES == CLOCK_MONOTONIC\n");
+#else
+ /* for Solaris, should be similar to CLOCK_MONOTONIC (it may be an alias) */
+ if (!TEST_CLOCK_GETTIME(CLOCK_HIGHRES))
+ found_clocks++;
+#endif
+#endif
+#ifdef CLOCK_REALTIME_FAST
+ if (!TEST_CLOCK_GETTIME(CLOCK_REALTIME_FAST))
+ found_clocks++;
+#endif
+#ifdef CLOCK_REALTIME_COARSE
+ if (!TEST_CLOCK_GETTIME(CLOCK_REALTIME_COARSE))
+ found_clocks++;
+#endif
+ if (!TEST_CLOCK_GETTIME(CLOCK_REALTIME))
+ found_clocks++;
+#ifdef CLOCK_REALTIME_PRECISE
+ if (!TEST_CLOCK_GETTIME(CLOCK_REALTIME_PRECISE))
+ found_clocks++;
+#endif
+ printf("%d usable clocks found\n", found_clocks);
+ return !(found_clocks > 0);
+}