37763ab46b211e3a8bc24a9a4edc755d24306750
[ccan] / ccan / time / test / run-check.c
1 #define DEBUG
2 #include <ccan/time/time.h>
3 #include <ccan/time/time.c>
4 #include <ccan/tap/tap.h>
5 #include <unistd.h>
6 #include <stdlib.h>
7 #include <signal.h>
8 #include <sys/types.h>
9 #include <sys/wait.h>
10
11 /* If we really abort, we don't get coverage info! */
12 void abort(void)
13 {
14         exit(7);
15 }
16
17 int main(void)
18 {
19         struct timespec t1, t2, t3, zero = { 0, 0 };
20         int fds[2];
21
22         plan_tests(62);
23
24         /* Test time_now */
25         t1 = time_now();
26         t2 = time_now();
27
28         /* Test time_sub. */
29         t3 = time_sub(t2, t1);
30         ok1(t3.tv_sec > 0 || t3.tv_nsec >= 0);
31         t3 = time_sub(t2, t2);
32         ok1(t3.tv_sec == 0 && t3.tv_nsec == 0);
33         t3 = time_sub(t1, t1);
34         ok1(t3.tv_sec == 0 && t3.tv_nsec == 0);
35
36         /* Test time_eq */
37         ok1(time_eq(t1, t1));
38         ok1(time_eq(t2, t2));
39         ok1(!time_eq(t1, t3));
40         ok1(!time_eq(t2, t3));
41
42         /* Make sure t2 > t1. */
43         t3.tv_sec = 0;
44         t3.tv_nsec = 1;
45         t2 = time_add(t2, t3);
46
47         /* Test time_less and time_greater. */
48         ok1(!time_eq(t1, t2));
49         ok1(!time_greater(t1, t2));
50         ok1(time_less(t1, t2));
51         ok1(time_greater(t2, t1));
52         ok1(!time_less(t2, t1));
53         t3.tv_sec = 0;
54         t3.tv_nsec = 999999999;
55         t2 = time_add(t2, t3);
56         ok1(!time_eq(t1, t2));
57         ok1(!time_greater(t1, t2));
58         ok1(time_less(t1, t2));
59         ok1(time_greater(t2, t1));
60         ok1(!time_less(t2, t1));
61
62         t3 = time_sub(t2, zero);
63         ok1(time_eq(t3, t2));
64         t3 = time_sub(t2, t2);
65         ok1(time_eq(t3, zero));
66
67         /* time_from_msec / time_to_msec */
68         t3 = time_from_msec(500);
69         ok1(t3.tv_sec == 0);
70         ok1(t3.tv_nsec == 500000000);
71         ok1(time_to_msec(t3) == 500);
72
73         t3 = time_from_msec(1000);
74         ok1(t3.tv_sec == 1);
75         ok1(t3.tv_nsec == 0);
76         ok1(time_to_msec(t3) == 1000);
77
78         t3 = time_from_msec(1500);
79         ok1(t3.tv_sec == 1);
80         ok1(t3.tv_nsec == 500000000);
81         ok1(time_to_msec(t3) == 1500);
82
83         /* time_from_usec */
84         t3 = time_from_usec(500000);
85         ok1(t3.tv_sec == 0);
86         ok1(t3.tv_nsec == 500000000);
87         ok1(time_to_usec(t3) == 500000);
88
89         t3 = time_from_usec(1000000);
90         ok1(t3.tv_sec == 1);
91         ok1(t3.tv_nsec == 0);
92         ok1(time_to_usec(t3) == 1000000);
93
94         t3 = time_from_usec(1500000);
95         ok1(t3.tv_sec == 1);
96         ok1(t3.tv_nsec == 500000000);
97         ok1(time_to_usec(t3) == 1500000);
98
99         /* time_from_nsec */
100         t3 = time_from_nsec(500000000);
101         ok1(t3.tv_sec == 0);
102         ok1(t3.tv_nsec == 500000000);
103         ok1(time_to_nsec(t3) == 500000000);
104
105         t3 = time_from_nsec(1000000000);
106         ok1(t3.tv_sec == 1);
107         ok1(t3.tv_nsec == 0);
108         ok1(time_to_nsec(t3) == 1000000000);
109
110         t3 = time_from_nsec(1500000000);
111         ok1(t3.tv_sec == 1);
112         ok1(t3.tv_nsec == 500000000);
113         ok1(time_to_nsec(t3) == 1500000000);
114
115         /* Test wrapunder */
116         t3 = time_sub(time_sub(t2, time_from_msec(500)), time_from_msec(500));
117         ok1(t3.tv_sec == t2.tv_sec - 1);
118         ok1(t3.tv_nsec == t2.tv_nsec);
119
120         /* time_divide and time_multiply */
121         t1.tv_nsec = 100;
122         t1.tv_sec = 100;
123
124         t3 = time_divide(t1, 2);
125         ok1(t3.tv_sec == 50);
126         ok1(t3.tv_nsec == 50);
127
128         t3 = time_divide(t1, 100);
129         ok1(t3.tv_sec == 1);
130         ok1(t3.tv_nsec == 1);
131
132         t3 = time_multiply(t3, 100);
133         ok1(time_eq(t3, t1));
134
135         t3 = time_divide(t1, 200);
136         ok1(t3.tv_sec == 0);
137         ok1(t3.tv_nsec == 500000000);
138
139         /* Divide by huge number. */
140         t1.tv_sec = (1U << 31) - 1;
141         t1.tv_nsec = 999999999;
142         t2 = time_divide(t1, 1 << 30);
143         /* Allow us to round either way. */
144         ok1((t2.tv_sec == 2 && t2.tv_nsec == 0)
145             || (t2.tv_sec == 1 && t2.tv_nsec == 999999999));
146
147         /* Multiply by huge number. */
148         t1.tv_sec = 0;
149         t1.tv_nsec = 1;
150         t2 = time_multiply(t1, 1UL << 31);
151         ok1(t2.tv_sec == 2);
152         ok1(t2.tv_nsec == 147483648);
153
154         pipe(fds);
155
156         fflush(stdout);
157         switch (fork()) {
158         case 0:
159                 close(fds[0]);
160                 dup2(fds[1], 1);
161                 dup2(fds[1], 2);
162                 t1.tv_sec = 7;
163                 t1.tv_nsec = 1000000001;
164                 t2 = time_check(t1, NULL);
165                 if (t2.tv_sec != 8 || t2.tv_nsec != 1)
166                         exit(1);
167                 t1.tv_sec = -1;
168                 t1.tv_nsec = 5;
169                 t2 = time_check(t1, NULL);
170                 if (t2.tv_sec != 0 || t2.tv_nsec != 5)
171                         exit(1);
172                 t1.tv_sec = 8;
173                 t1.tv_nsec = 1000000002;
174                 /* We expect this to abort! */
175                 t2 = time_check(t1, "abortstr");
176                 exit(1);
177                 
178         default: {
179                 char readbuf[1024];
180                 int r, len = 0;
181
182                 close(fds[1]);
183                 while ((r = read(fds[0], readbuf + len, 1023 - len)) > 0)
184                         len += r;
185                 readbuf[len] = '\0';
186                 ok1(strcmp(readbuf,
187                            "WARNING: malformed time"
188                            " 7 seconds 1000000001 ns converted to 8.000000001.\n"
189                            "WARNING: malformed time"
190                            " -1 seconds 5 ns converted to 0.000000005.\n"
191                            "abortstr: malformed time 8.1000000002\n") == 0);
192                 ok1(wait(&r) != -1);
193                 ok1(WIFEXITED(r));
194                 ok1(WEXITSTATUS(r) == 7);
195         }
196         }
197
198         return exit_status();
199 }