1 /* Test for support_timespec_check_in_range function.
2    Copyright (C) 2020-2022 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 #include <support/timespec.h>
20 #include <support/check.h>
21 #include <limits.h>
22 #include <intprops.h>
23 
24 #define TIMESPEC_HZ 1000000000
25 
26 struct timespec_ns_test_case
27 {
28   struct timespec time;
29   time_t time_ns;
30 };
31 
32 struct timespec_norm_test_case
33 {
34   struct timespec time;
35   struct timespec norm;
36 };
37 
38 struct timespec_test_case
39 {
40   struct timespec expected;
41   struct timespec observed;
42   double upper_bound;
43   double lower_bound;
44   int result;
45 };
46 
47 #define TIME_T_MIN TYPE_MINIMUM (time_t)
48 #define TIME_T_MAX TYPE_MAXIMUM (time_t)
49 
50 /* Test cases for timespec_ns */
51 struct timespec_ns_test_case ns_cases[] = {
52   {.time = {.tv_sec = 0, .tv_nsec = 0},
53    .time_ns = 0,
54   },
55   {.time = {.tv_sec = 0, .tv_nsec = 1},
56    .time_ns = 1,
57   },
58   {.time = {.tv_sec = 1, .tv_nsec = 0},
59    .time_ns = TIMESPEC_HZ,
60   },
61   {.time = {.tv_sec = 1, .tv_nsec = 1},
62    .time_ns = TIMESPEC_HZ + 1,
63   },
64   {.time = {.tv_sec = 0, .tv_nsec = -1},
65    .time_ns = -1,
66   },
67   {.time = {.tv_sec = -1, .tv_nsec = 0},
68    .time_ns = -TIMESPEC_HZ,
69   },
70   {.time = {.tv_sec = -1, .tv_nsec = -1},
71    .time_ns = -TIMESPEC_HZ - 1,
72   },
73   {.time = {.tv_sec = 1, .tv_nsec = -1},
74    .time_ns = TIMESPEC_HZ - 1,
75   },
76   {.time = {.tv_sec = -1, .tv_nsec = 1},
77    .time_ns = -TIMESPEC_HZ + 1,
78   },
79   /* Overflow bondary by 2  */
80   {.time = {.tv_sec = TIME_T_MAX / TIMESPEC_HZ,
81 	    .tv_nsec = TIME_T_MAX % TIMESPEC_HZ - 1},
82    .time_ns = TIME_T_MAX - 1,
83   },
84   /* Overflow bondary  */
85   {.time = {.tv_sec = TIME_T_MAX / TIMESPEC_HZ,
86 	    .tv_nsec = TIME_T_MAX % TIMESPEC_HZ},
87    .time_ns = TIME_T_MAX,
88   },
89   /* Underflow bondary by 1  */
90   {.time = {.tv_sec = TIME_T_MIN / TIMESPEC_HZ,
91 	    .tv_nsec = TIME_T_MIN % TIMESPEC_HZ + 1},
92    .time_ns = TIME_T_MIN + 1,
93   },
94   /* Underflow bondary  */
95   {.time = {.tv_sec = TIME_T_MIN / TIMESPEC_HZ,
96 	    .tv_nsec = TIME_T_MIN % TIMESPEC_HZ},
97    .time_ns = TIME_T_MIN,
98   },
99   /* Multiplication overflow  */
100   {.time = {.tv_sec = TIME_T_MAX / TIMESPEC_HZ + 1, .tv_nsec = 1},
101    .time_ns = TIME_T_MAX,
102   },
103   /* Multiplication underflow  */
104   {.time = {.tv_sec = TIME_T_MIN / TIMESPEC_HZ - 1, .tv_nsec = -1},
105    .time_ns = TIME_T_MIN,
106   },
107   /* Sum overflows  */
108   {.time = {.tv_sec = TIME_T_MAX / TIMESPEC_HZ,
109 	    .tv_nsec = TIME_T_MAX % TIMESPEC_HZ + 1},
110    .time_ns = TIME_T_MAX,
111   },
112   /* Sum underflow  */
113   {.time = {.tv_sec = TIME_T_MIN / TIMESPEC_HZ,
114 	    .tv_nsec = TIME_T_MIN % TIMESPEC_HZ - 1},
115    .time_ns = TIME_T_MIN,
116   }
117 };
118 
119 /* Test cases for timespec_norm */
120 struct timespec_norm_test_case norm_cases[] = {
121   /* Positive cases  */
122   {.time = {.tv_sec = 0, .tv_nsec = 0},
123    .norm = {.tv_sec = 0, .tv_nsec = 0}
124   },
125   {.time = {.tv_sec = 1, .tv_nsec = 0},
126    .norm = {.tv_sec = 1, .tv_nsec = 0}
127   },
128   {.time = {.tv_sec = 0, .tv_nsec = 1},
129    .norm = {.tv_sec = 0, .tv_nsec = 1}
130   },
131   {.time = {.tv_sec = 0, .tv_nsec = TIMESPEC_HZ},
132    .norm = {.tv_sec = 1, .tv_nsec = 0}
133   },
134   {.time = {.tv_sec = 0, .tv_nsec = TIMESPEC_HZ + 1},
135    .norm = {.tv_sec = 1, .tv_nsec = 1}
136   },
137   {.time = {.tv_sec = 1, .tv_nsec = TIMESPEC_HZ},
138    .norm = {.tv_sec = 2, .tv_nsec = 0}
139   },
140   {.time = {.tv_sec = 1, .tv_nsec = TIMESPEC_HZ + 1},
141    .norm = {.tv_sec = 2, .tv_nsec = 1}
142   },
143   /* Negative cases  */
144   {.time = {.tv_sec = 0, .tv_nsec = -TIMESPEC_HZ},
145    .norm = {.tv_sec = -1, .tv_nsec = 0}
146   },
147   {.time = {.tv_sec = 0, .tv_nsec = -TIMESPEC_HZ - 1},
148    .norm = {.tv_sec = -1, .tv_nsec = -1}
149   },
150   {.time = {.tv_sec = -1, .tv_nsec = -TIMESPEC_HZ},
151    .norm = {.tv_sec = -2, .tv_nsec = 0}
152   },
153   {.time = {.tv_sec = -1, .tv_nsec = -TIMESPEC_HZ - 1},
154    .norm = {.tv_sec = -2, .tv_nsec = -1}
155   },
156   /* Overflow bondary by 2  */
157   {.time = {.tv_sec = TIME_T_MAX - 2, .tv_nsec = TIMESPEC_HZ + 1},
158    .norm = {.tv_sec = TIME_T_MAX - 1, 1},
159   },
160   /* Overflow bondary by 1  */
161   {.time = {.tv_sec = TIME_T_MAX - 1, .tv_nsec = TIMESPEC_HZ + 1},
162    .norm = {.tv_sec = TIME_T_MAX, .tv_nsec = 1},
163   },
164   /* Underflow bondary by 2  */
165   {.time = {.tv_sec = TIME_T_MIN + 2, .tv_nsec = -TIMESPEC_HZ - 1},
166    .norm = {.tv_sec = TIME_T_MIN + 1, -1},
167   },
168   /* Underflow bondary by 1  */
169   {.time = {.tv_sec = TIME_T_MIN + 1, .tv_nsec = -TIMESPEC_HZ - 1},
170    .norm = {.tv_sec = TIME_T_MIN, .tv_nsec = -1},
171   },
172   /* SUM overflow  */
173   {.time = {.tv_sec = TIME_T_MAX, .tv_nsec = TIMESPEC_HZ},
174    .norm = {.tv_sec = TIME_T_MAX, .tv_nsec = TIMESPEC_HZ - 1},
175   },
176   /* SUM underflow  */
177   {.time = {.tv_sec = TIME_T_MIN, .tv_nsec = -TIMESPEC_HZ},
178    .norm = {.tv_sec = TIME_T_MIN, .tv_nsec = -1 * (TIMESPEC_HZ - 1)},
179   }
180 };
181 
182 /* Test cases for timespec_check_in_range  */
183 struct timespec_test_case check_cases[] = {
184   /* 0 - In range  */
185   {.expected = {.tv_sec = 1, .tv_nsec = 0},
186    .observed = {.tv_sec = 1, .tv_nsec = 0},
187    .upper_bound = 1, .lower_bound = 1, .result = 1,
188   },
189   /* 1 - Out of range  */
190   {.expected = {.tv_sec = 1, .tv_nsec = 0},
191    .observed = {.tv_sec = 2, .tv_nsec = 0},
192    .upper_bound = 1, .lower_bound = 1, .result = 0,
193   },
194   /* 2 - Upper Bound  */
195   {.expected = {.tv_sec = 1, .tv_nsec = 0},
196    .observed = {.tv_sec = 2, .tv_nsec = 0},
197    .upper_bound = 2, .lower_bound = 1, .result = 1,
198   },
199   /* 3 - Lower Bound  */
200   {.expected = {.tv_sec = 1, .tv_nsec = 0},
201    .observed = {.tv_sec = 0, .tv_nsec = 0},
202    .upper_bound = 1, .lower_bound = 0, .result = 1,
203   },
204   /* 4 - Out of range by nanosecs  */
205   {.expected = {.tv_sec = 1, .tv_nsec = 0},
206    .observed = {.tv_sec = 1, .tv_nsec = 500},
207    .upper_bound = 1, .lower_bound = 1, .result = 0,
208   },
209   /* 5 - In range by nanosecs  */
210   {.expected = {.tv_sec = 1, .tv_nsec = 0},
211    .observed = {.tv_sec = 1, .tv_nsec = 50000},
212    .upper_bound = 1.3, .lower_bound = 1, .result = 1,
213   },
214   /* 6 - Big nanosecs  */
215   {.expected = {.tv_sec = 1, .tv_nsec = 0},
216    .observed = {.tv_sec = 0, .tv_nsec = 4000000},
217    .upper_bound = 1, .lower_bound = .001, .result = 1,
218   },
219   /* 7 - In range Negative values  */
220   {.expected = {.tv_sec = -1, .tv_nsec = 0},
221    .observed = {.tv_sec = -1, .tv_nsec = 0},
222    .upper_bound = 1, .lower_bound = 1, .result = 1,
223   },
224   /* 8 - Out of range Negative values  */
225   {.expected = {.tv_sec = -1, .tv_nsec = 0},
226    .observed = {.tv_sec = -1, .tv_nsec = 0},
227    .upper_bound = -1, .lower_bound = -1, .result = 0,
228   },
229   /* 9 - Negative values with negative nanosecs  */
230   {.expected = {.tv_sec = -1, .tv_nsec = 0},
231    .observed = {.tv_sec = -1, .tv_nsec = -2000},
232    .upper_bound = 1, .lower_bound = 1, .result = 0,
233   },
234   /* 10 - Strict bounds  */
235   {.expected = {.tv_sec = -1, .tv_nsec = 0},
236    .observed = {.tv_sec = -1, .tv_nsec = -20000},
237    .upper_bound = 1.00002, .lower_bound = 1.0000191, .result = 1,
238   },
239   /* 11 - Strict bounds with loose upper bound  */
240   {.expected = {.tv_sec = 1, .tv_nsec = 20000},
241    .observed = {.tv_sec = 1, .tv_nsec = 30000},
242    .upper_bound = 1.0000100000, .lower_bound = 1.0000099998, .result = 1,
243   },
244   /* 12 - Strict bounds with loose lower bound  */
245   {.expected = {.tv_sec = 1, .tv_nsec = 20000},
246    .observed = {.tv_sec = 1, .tv_nsec = 30000},
247    .upper_bound = 1.0000099999, .lower_bound = 1.00000999979, .result = 1,
248   },
249   /* 13 - Strict bounds highest precision  */
250   {.expected = {.tv_sec = 1, .tv_nsec = 20000},
251    .observed = {.tv_sec = 1, .tv_nsec = 30000},
252    .upper_bound = 1.00000999980001, .lower_bound = 1.00000999979999, .result = 1,
253   },
254   /* Maximum/Minimum long values  */
255   /* 14  */
256   {.expected = {.tv_sec = TIME_T_MAX, .tv_nsec = TIMESPEC_HZ - 1},
257    .observed = {.tv_sec = TIME_T_MAX, .tv_nsec = TIMESPEC_HZ - 2},
258    .upper_bound = 1, .lower_bound = .9, .result = 1,
259   },
260   /* 15 - support_timespec_ns overflow  */
261   {.expected = {.tv_sec = TIME_T_MAX, .tv_nsec = TIMESPEC_HZ},
262    .observed = {.tv_sec = TIME_T_MAX, .tv_nsec = TIMESPEC_HZ},
263    .upper_bound = 1, .lower_bound = 1, .result = 1,
264   },
265   /* 16 - support_timespec_ns overflow + underflow  */
266   {.expected = {.tv_sec = TIME_T_MAX, .tv_nsec = TIMESPEC_HZ},
267    .observed = {.tv_sec = TIME_T_MIN, .tv_nsec = -TIMESPEC_HZ},
268    .upper_bound = 1, .lower_bound = 1, .result = 0,
269   },
270   /* 17 - support_timespec_ns underflow  */
271   {.expected = {.tv_sec = TIME_T_MIN, .tv_nsec = -TIMESPEC_HZ},
272    .observed = {.tv_sec = TIME_T_MIN, .tv_nsec = -TIMESPEC_HZ},
273    .upper_bound = 1, .lower_bound = 1, .result = 1,
274   },
275   /* 18 - support_timespec_ns underflow + overflow  */
276   {.expected = {.tv_sec = TIME_T_MIN, .tv_nsec = -TIMESPEC_HZ},
277    .observed = {.tv_sec = TIME_T_MAX, .tv_nsec = TIMESPEC_HZ},
278    .upper_bound = 1, .lower_bound = 1, .result = 0,
279   },
280   /* 19 - Biggest division  */
281   {.expected = {.tv_sec = TIME_T_MAX / TIMESPEC_HZ,
282 		.tv_nsec = TIMESPEC_HZ - 1},
283    .observed = {.tv_sec = 0, .tv_nsec = 1},
284    .upper_bound = 1, .lower_bound = 1.0842021724855044e-19, .result = 1,
285   },
286   /* 20 - Lowest division  */
287   {.expected = {.tv_sec = 0, .tv_nsec = 1},
288    .observed = {.tv_sec = TIME_T_MAX / TIMESPEC_HZ,
289 		.tv_nsec = TIMESPEC_HZ - 1},
290    .upper_bound = TIME_T_MAX, .lower_bound = 1, .result = 1,
291   },
292 };
293 
294 static int
do_test(void)295 do_test (void)
296 {
297   int i = 0;
298   int ntests = sizeof (ns_cases) / sizeof (ns_cases[0]);
299 
300   printf("Testing support_timespec_ns\n");
301   for (i = 0; i < ntests; i++)
302     {
303       printf("Test case %d\n", i);
304       TEST_COMPARE (support_timespec_ns (ns_cases[i].time),
305 		    ns_cases[i].time_ns);
306     }
307 
308   ntests = sizeof (norm_cases) / sizeof (norm_cases[0]);
309   struct timespec result;
310   printf("Testing support_timespec_normalize\n");
311   for (i = 0; i < ntests; i++)
312     {
313       printf("Test case %d\n", i);
314       result = support_timespec_normalize (norm_cases[i].time);
315       TEST_COMPARE (norm_cases[i].norm.tv_sec, result.tv_sec);
316       TEST_COMPARE (norm_cases[i].norm.tv_nsec, result.tv_nsec);
317     }
318 
319   ntests = sizeof (check_cases) / sizeof (check_cases[0]);
320   printf("Testing support_timespec_check_in_range\n");
321   for (i = 0; i < ntests; i++)
322     {
323       /* Its hard to find which test failed with just the TEST_COMPARE report.
324          So here we print every running testcase as well.  */
325       printf("Test case %d\n", i);
326       TEST_COMPARE (support_timespec_check_in_range
327 		    (check_cases[i].expected, check_cases[i].observed,
328 		     check_cases[i].lower_bound,
329 		     check_cases[i].upper_bound), check_cases[i].result);
330     }
331   return 0;
332 }
333 
334 #include <support/test-driver.c>
335