1/* Tests for computing deadlines for timeouts.
2 Copyright (C) 2017-2024 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. */
26static time_t
27time_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
45static int
46do_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, tv: (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, tv: ((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, tv: ((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, tv: (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, tv: (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 tv: (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 tv: (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 tv: (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 tv: (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 (left: (struct deadline) { { 1, 2 } },
161 right: (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 (left: (struct deadline) { { 1, 3 } },
166 right: (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 (left: (struct deadline) { { 1, 2 } },
171 right: (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 (left: (struct deadline) { { 1, 2 } },
176 right: (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 (left: (struct deadline) { { 2, 4 } },
181 right: (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

source code of glibc/inet/tst-deadline.c