1 /* Tests for computing deadlines for timeouts.
2    Copyright (C) 2017-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 <inet/net-internal.h>
20 #include <limits.h>
21 #include <stdbool.h>
22 #include <stdint.h>
23 #include <support/check.h>
24 
25 /* Find the maximum value which can be represented in a time_t.  */
26 static time_t
time_t_max(void)27 time_t_max (void)
28 {
29   _Static_assert (0 > (time_t) -1, "time_t is signed");
30   uintmax_t current = 1;
31   while (true)
32     {
33       uintmax_t next = current * 2;
34       /* This cannot happen because time_t is signed.  */
35       TEST_VERIFY_EXIT (next > current);
36       ++next;
37       if ((time_t) next < 0 || next != (uintmax_t) (time_t) next)
38         /* Value cannot be represented in time_t.  Return the previous
39            value. */
40         return current;
41       current = next;
42     }
43 }
44 
45 static int
do_test(void)46 do_test (void)
47 {
48   {
49     struct deadline_current_time current_time = __deadline_current_time ();
50     TEST_VERIFY (current_time.current.tv_sec >= 0);
51     current_time = __deadline_current_time ();
52     /* Due to CLOCK_MONOTONIC, either seconds or nanoseconds are
53        greater than zero.  This is also true for the gettimeofday
54        fallback.  */
55     TEST_VERIFY (current_time.current.tv_sec >= 0);
56     TEST_VERIFY (current_time.current.tv_sec > 0
57                  || current_time.current.tv_nsec > 0);
58   }
59 
60   /* Check basic computations of deadlines.  */
61   struct deadline_current_time current_time = { { 1, 123456789 } };
62   struct deadline deadline = __deadline_from_timeval
63     (current_time, (struct timeval) { 0, 1 });
64   TEST_VERIFY (deadline.absolute.tv_sec == 1);
65   TEST_VERIFY (deadline.absolute.tv_nsec == 123457789);
66   TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1);
67 
68   deadline = __deadline_from_timeval
69     (current_time, ((struct timeval) { 0, 2 }));
70   TEST_VERIFY (deadline.absolute.tv_sec == 1);
71   TEST_VERIFY (deadline.absolute.tv_nsec == 123458789);
72   TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1);
73 
74   deadline = __deadline_from_timeval
75     (current_time, ((struct timeval) { 1, 0 }));
76   TEST_VERIFY (deadline.absolute.tv_sec == 2);
77   TEST_VERIFY (deadline.absolute.tv_nsec == 123456789);
78   TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000);
79 
80   /* Check if timeouts are correctly rounded up to the next
81      millisecond.  */
82   for (int i = 0; i < 999999; ++i)
83     {
84       ++current_time.current.tv_nsec;
85       TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000);
86     }
87 
88   /* A full millisecond has elapsed, so the time to the deadline is
89      now less than 1000.  */
90   ++current_time.current.tv_nsec;
91   TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 999);
92 
93   /* Check __deadline_to_ms carry-over.  */
94   current_time = (struct deadline_current_time) { { 9, 123456789 } };
95   deadline = (struct deadline) { { 10, 122456789 } };
96   TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 999);
97   deadline = (struct deadline) { { 10, 122456790 } };
98   TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000);
99   deadline = (struct deadline) { { 10, 123456788 } };
100   TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000);
101   deadline = (struct deadline) { { 10, 123456789 } };
102   TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000);
103 
104   /* Check __deadline_to_ms overflow.  */
105   deadline = (struct deadline) { { INT_MAX - 1, 1 } };
106   TEST_VERIFY (__deadline_to_ms (current_time, deadline) == INT_MAX);
107 
108   /* Check __deadline_to_ms for elapsed deadlines.  */
109   current_time = (struct deadline_current_time) { { 9, 123456789 } };
110   deadline.absolute = current_time.current;
111   TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0);
112   current_time = (struct deadline_current_time) { { 9, 123456790 } };
113   TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0);
114   current_time = (struct deadline_current_time) { { 10, 0 } };
115   TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0);
116   current_time = (struct deadline_current_time) { { 10, 123456788 } };
117   TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0);
118   current_time = (struct deadline_current_time) { { 10, 123456789 } };
119   TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0);
120 
121   /* Check carry-over in __deadline_from_timeval.  */
122   current_time = (struct deadline_current_time) { { 9, 998000001 } };
123   for (int i = 0; i < 2000; ++i)
124     {
125       deadline = __deadline_from_timeval
126         (current_time, (struct timeval) { 1, i });
127       TEST_VERIFY (deadline.absolute.tv_sec == 10);
128       TEST_VERIFY (deadline.absolute.tv_nsec == 998000001 + i * 1000);
129     }
130   for (int i = 2000; i < 3000; ++i)
131     {
132       deadline = __deadline_from_timeval
133         (current_time, (struct timeval) { 2, i });
134       TEST_VERIFY (deadline.absolute.tv_sec == 12);
135       TEST_VERIFY (deadline.absolute.tv_nsec == 1 + (i - 2000) * 1000);
136     }
137 
138   /* Check infinite deadlines.  */
139   deadline = __deadline_from_timeval
140     ((struct deadline_current_time) { { 0, 1000 * 1000 * 1000 - 1000 } },
141      (struct timeval) { time_t_max (), 1 });
142   TEST_VERIFY (__deadline_is_infinite (deadline));
143   deadline = __deadline_from_timeval
144     ((struct deadline_current_time) { { 0, 1000 * 1000 * 1000 - 1001 } },
145      (struct timeval) { time_t_max (), 1 });
146   TEST_VERIFY (!__deadline_is_infinite (deadline));
147   deadline = __deadline_from_timeval
148     ((struct deadline_current_time)
149        { { time_t_max (), 1000 * 1000 * 1000 - 1000 } },
150      (struct timeval) { 0, 1 });
151   TEST_VERIFY (__deadline_is_infinite (deadline));
152   deadline = __deadline_from_timeval
153     ((struct deadline_current_time)
154        { { time_t_max () / 2 + 1, 0 } },
155      (struct timeval) { time_t_max () / 2 + 1, 0 });
156   TEST_VERIFY (__deadline_is_infinite (deadline));
157 
158   /* Check __deadline_first behavior.  */
159   deadline = __deadline_first
160     ((struct deadline) { { 1, 2 } },
161      (struct deadline) { { 1, 3 } });
162   TEST_VERIFY (deadline.absolute.tv_sec == 1);
163   TEST_VERIFY (deadline.absolute.tv_nsec == 2);
164   deadline = __deadline_first
165     ((struct deadline) { { 1, 3 } },
166      (struct deadline) { { 1, 2 } });
167   TEST_VERIFY (deadline.absolute.tv_sec == 1);
168   TEST_VERIFY (deadline.absolute.tv_nsec == 2);
169   deadline = __deadline_first
170     ((struct deadline) { { 1, 2 } },
171      (struct deadline) { { 2, 1 } });
172   TEST_VERIFY (deadline.absolute.tv_sec == 1);
173   TEST_VERIFY (deadline.absolute.tv_nsec == 2);
174   deadline = __deadline_first
175     ((struct deadline) { { 1, 2 } },
176      (struct deadline) { { 2, 4 } });
177   TEST_VERIFY (deadline.absolute.tv_sec == 1);
178   TEST_VERIFY (deadline.absolute.tv_nsec == 2);
179   deadline = __deadline_first
180     ((struct deadline) { { 2, 4 } },
181      (struct deadline) { { 1, 2 } });
182   TEST_VERIFY (deadline.absolute.tv_sec == 1);
183   TEST_VERIFY (deadline.absolute.tv_nsec == 2);
184 
185   return 0;
186 }
187 
188 #include <support/test-driver.c>
189