selftests/timers: Add set-2038 test from timetest suite
[linux-2.6/btrfs-unstable.git] / tools / testing / selftests / timers / set-2038.c
blobc8a7e14446b19e0550138abd4f8c0405f27ad897
1 /* Time bounds setting test
2 * by: john stultz (johnstul@us.ibm.com)
3 * (C) Copyright IBM 2012
4 * Licensed under the GPLv2
6 * NOTE: This is a meta-test which sets the time to edge cases then
7 * uses other tests to detect problems. Thus this test requires that
8 * the inconsistency-check and nanosleep tests be present in the same
9 * directory it is run from.
11 * To build:
12 * $ gcc set-2038.c -o set-2038 -lrt
14 * This program is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, either version 2 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <time.h>
29 #include <sys/time.h>
30 #ifdef KTEST
31 #include "../kselftest.h"
32 #else
33 static inline int ksft_exit_pass(void)
35 exit(0);
37 static inline int ksft_exit_fail(void)
39 exit(1);
41 #endif
43 #define NSEC_PER_SEC 1000000000LL
45 #define KTIME_MAX ((long long)~((unsigned long long)1 << 63))
46 #define KTIME_SEC_MAX (KTIME_MAX / NSEC_PER_SEC)
48 #define YEAR_1901 (-0x7fffffffL)
49 #define YEAR_1970 1
50 #define YEAR_2038 0x7fffffffL /*overflows 32bit time_t */
51 #define YEAR_2262 KTIME_SEC_MAX /*overflows 64bit ktime_t */
52 #define YEAR_MAX ((long long)((1ULL<<63)-1)) /*overflows 64bit time_t */
54 int is32bits(void)
56 return (sizeof(long) == 4);
59 int settime(long long time)
61 struct timeval now;
62 int ret;
64 now.tv_sec = (time_t)time;
65 now.tv_usec = 0;
67 ret = settimeofday(&now, NULL);
69 printf("Setting time to 0x%lx: %d\n", (long)time, ret);
70 return ret;
73 int do_tests(void)
75 int ret;
77 ret = system("date");
78 ret = system("./inconsistency-check -c 0 -t 20");
79 ret |= system("./nanosleep");
80 ret |= system("./nsleep-lat");
81 return ret;
85 int main(int argc, char *argv[])
87 int ret = 0;
88 int opt, dangerous = 0;
89 time_t start;
91 /* Process arguments */
92 while ((opt = getopt(argc, argv, "d")) != -1) {
93 switch (opt) {
94 case 'd':
95 dangerous = 1;
99 start = time(0);
101 /* First test that crazy values don't work */
102 if (!settime(YEAR_1901)) {
103 ret = -1;
104 goto out;
106 if (!settime(YEAR_MAX)) {
107 ret = -1;
108 goto out;
110 if (!is32bits() && !settime(YEAR_2262)) {
111 ret = -1;
112 goto out;
115 /* Now test behavior near edges */
116 settime(YEAR_1970);
117 ret = do_tests();
118 if (ret)
119 goto out;
121 settime(YEAR_2038 - 600);
122 ret = do_tests();
123 if (ret)
124 goto out;
126 /* The rest of the tests can blowup on 32bit systems */
127 if (is32bits() && !dangerous)
128 goto out;
129 /* Test rollover behavior 32bit edge */
130 settime(YEAR_2038 - 10);
131 ret = do_tests();
132 if (ret)
133 goto out;
135 settime(YEAR_2262 - 600);
136 ret = do_tests();
138 out:
139 /* restore clock */
140 settime(start);
141 if (ret)
142 return ksft_exit_fail();
143 return ksft_exit_pass();