Line data Source code
1 : /*
2 : *
3 : * Copyright 2015, Google Inc.
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions are
8 : * met:
9 : *
10 : * * Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : * * Redistributions in binary form must reproduce the above
13 : * copyright notice, this list of conditions and the following disclaimer
14 : * in the documentation and/or other materials provided with the
15 : * distribution.
16 : * * Neither the name of Google Inc. nor the names of its
17 : * contributors may be used to endorse or promote products derived from
18 : * this software without specific prior written permission.
19 : *
20 : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 : * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 : * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 : * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 : * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 : * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 : * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 : *
32 : */
33 :
34 : /* Test of gpr time support. */
35 :
36 : #include <stdio.h>
37 : #include <stdlib.h>
38 : #include <string.h>
39 : #include <limits.h>
40 : #include <grpc/support/log.h>
41 : #include <grpc/support/sync.h>
42 : #include <grpc/support/thd.h>
43 : #include <grpc/support/time.h>
44 : #include "test/core/util/test_config.h"
45 :
46 10 : static void to_fp(void *arg, const char *buf, size_t len) {
47 10 : fwrite(buf, 1, len, (FILE *)arg);
48 10 : }
49 :
50 : /* Convert gpr_uintmax x to ascii base b (2..16), and write with
51 : (*writer)(arg, ...), zero padding to "chars" digits). */
52 6 : static void u_to_s(gpr_uintmax x, unsigned base, int chars,
53 : void (*writer)(void *arg, const char *buf, size_t len),
54 : void *arg) {
55 : char buf[64];
56 6 : char *p = buf + sizeof(buf);
57 : do {
58 88 : *--p = "0123456789abcdef"[x % base];
59 88 : x /= base;
60 88 : chars--;
61 88 : } while (x != 0 || chars > 0);
62 6 : (*writer)(arg, p, (size_t)(buf + sizeof(buf) - p));
63 6 : }
64 :
65 : /* Convert gpr_intmax x to ascii base b (2..16), and write with
66 : (*writer)(arg, ...), zero padding to "chars" digits). */
67 6 : static void i_to_s(gpr_intmax x, unsigned base, int chars,
68 : void (*writer)(void *arg, const char *buf, size_t len),
69 : void *arg) {
70 6 : if (x < 0) {
71 2 : (*writer)(arg, "-", 1);
72 2 : u_to_s((gpr_uintmax)-x, base, chars - 1, writer, arg);
73 : } else {
74 4 : u_to_s((gpr_uintmax)x, base, chars, writer, arg);
75 : }
76 6 : }
77 :
78 : /* Convert ts to ascii, and write with (*writer)(arg, ...). */
79 2 : static void ts_to_s(gpr_timespec t,
80 : void (*writer)(void *arg, const char *buf, size_t len),
81 : void *arg) {
82 2 : if (t.tv_sec < 0 && t.tv_nsec != 0) {
83 0 : t.tv_sec++;
84 0 : t.tv_nsec = GPR_NS_PER_SEC - t.tv_nsec;
85 : }
86 2 : i_to_s(t.tv_sec, 10, 0, writer, arg);
87 2 : (*writer)(arg, ".", 1);
88 2 : i_to_s(t.tv_nsec, 10, 9, writer, arg);
89 2 : }
90 :
91 1 : static void test_values(void) {
92 : int i;
93 :
94 1 : gpr_timespec x = gpr_time_0(GPR_CLOCK_REALTIME);
95 1 : GPR_ASSERT(x.tv_sec == 0 && x.tv_nsec == 0);
96 :
97 1 : x = gpr_inf_future(GPR_CLOCK_REALTIME);
98 1 : fprintf(stderr, "far future ");
99 1 : i_to_s(x.tv_sec, 16, 16, &to_fp, stderr);
100 1 : fprintf(stderr, "\n");
101 1 : GPR_ASSERT(x.tv_sec >= INT_MAX);
102 1 : fprintf(stderr, "far future ");
103 1 : ts_to_s(x, &to_fp, stderr);
104 1 : fprintf(stderr, "\n");
105 :
106 1 : x = gpr_inf_past(GPR_CLOCK_REALTIME);
107 1 : fprintf(stderr, "far past ");
108 1 : i_to_s(x.tv_sec, 16, 16, &to_fp, stderr);
109 1 : fprintf(stderr, "\n");
110 1 : GPR_ASSERT(x.tv_sec <= INT_MIN);
111 1 : fprintf(stderr, "far past ");
112 1 : ts_to_s(x, &to_fp, stderr);
113 1 : fprintf(stderr, "\n");
114 :
115 10 : for (i = 1; i != 1000 * 1000 * 1000; i *= 10) {
116 9 : x = gpr_time_from_micros(i, GPR_TIMESPAN);
117 9 : GPR_ASSERT(x.tv_sec == i / GPR_US_PER_SEC &&
118 : x.tv_nsec == (i % GPR_US_PER_SEC) * GPR_NS_PER_US);
119 9 : x = gpr_time_from_nanos(i, GPR_TIMESPAN);
120 9 : GPR_ASSERT(x.tv_sec == i / GPR_NS_PER_SEC &&
121 : x.tv_nsec == (i % GPR_NS_PER_SEC));
122 9 : x = gpr_time_from_millis(i, GPR_TIMESPAN);
123 9 : GPR_ASSERT(x.tv_sec == i / GPR_MS_PER_SEC &&
124 : x.tv_nsec == (i % GPR_MS_PER_SEC) * GPR_NS_PER_MS);
125 : }
126 :
127 : /* Test possible overflow in conversion of -ve values. */
128 1 : x = gpr_time_from_micros(-(LONG_MAX - 999997), GPR_TIMESPAN);
129 1 : GPR_ASSERT(x.tv_sec < 0);
130 1 : GPR_ASSERT(x.tv_nsec >= 0 && x.tv_nsec < GPR_NS_PER_SEC);
131 :
132 1 : x = gpr_time_from_nanos(-(LONG_MAX - 999999997), GPR_TIMESPAN);
133 1 : GPR_ASSERT(x.tv_sec < 0);
134 1 : GPR_ASSERT(x.tv_nsec >= 0 && x.tv_nsec < GPR_NS_PER_SEC);
135 :
136 1 : x = gpr_time_from_millis(-(LONG_MAX - 997), GPR_TIMESPAN);
137 1 : GPR_ASSERT(x.tv_sec < 0);
138 1 : GPR_ASSERT(x.tv_nsec >= 0 && x.tv_nsec < GPR_NS_PER_SEC);
139 :
140 : /* Test general -ve values. */
141 12 : for (i = -1; i > -1000 * 1000 * 1000; i *= 7) {
142 11 : x = gpr_time_from_micros(i, GPR_TIMESPAN);
143 11 : GPR_ASSERT(x.tv_sec * GPR_US_PER_SEC + x.tv_nsec / GPR_NS_PER_US == i);
144 11 : x = gpr_time_from_nanos(i, GPR_TIMESPAN);
145 11 : GPR_ASSERT(x.tv_sec * GPR_NS_PER_SEC + x.tv_nsec == i);
146 11 : x = gpr_time_from_millis(i, GPR_TIMESPAN);
147 11 : GPR_ASSERT(x.tv_sec * GPR_MS_PER_SEC + x.tv_nsec / GPR_NS_PER_MS == i);
148 : }
149 1 : }
150 :
151 1 : static void test_add_sub(void) {
152 : int i;
153 : int j;
154 : int k;
155 : /* Basic addition and subtraction. */
156 202 : for (i = -100; i <= 100; i++) {
157 40602 : for (j = -100; j <= 100; j++) {
158 363609 : for (k = 1; k <= 10000000; k *= 10) {
159 323208 : int sum = i + j;
160 323208 : int diff = i - j;
161 323208 : gpr_timespec it = gpr_time_from_micros(i * k, GPR_TIMESPAN);
162 323208 : gpr_timespec jt = gpr_time_from_micros(j * k, GPR_TIMESPAN);
163 323208 : gpr_timespec sumt = gpr_time_add(it, jt);
164 323208 : gpr_timespec difft = gpr_time_sub(it, jt);
165 323208 : if (gpr_time_cmp(gpr_time_from_micros(sum * k, GPR_TIMESPAN), sumt) !=
166 : 0) {
167 0 : fprintf(stderr, "i %d j %d sum %d sumt ", i, j, sum);
168 0 : ts_to_s(sumt, &to_fp, stderr);
169 0 : fprintf(stderr, "\n");
170 0 : GPR_ASSERT(0);
171 : }
172 323208 : if (gpr_time_cmp(gpr_time_from_micros(diff * k, GPR_TIMESPAN), difft) !=
173 : 0) {
174 0 : fprintf(stderr, "i %d j %d diff %d diff ", i, j, diff);
175 0 : ts_to_s(sumt, &to_fp, stderr);
176 0 : fprintf(stderr, "\n");
177 0 : GPR_ASSERT(0);
178 : }
179 : }
180 : }
181 : }
182 1 : }
183 :
184 1 : static void test_overflow(void) {
185 : /* overflow */
186 1 : gpr_timespec x = gpr_time_from_micros(1, GPR_TIMESPAN);
187 : do {
188 83 : x = gpr_time_add(x, x);
189 83 : } while (gpr_time_cmp(x, gpr_inf_future(GPR_TIMESPAN)) < 0);
190 1 : GPR_ASSERT(gpr_time_cmp(x, gpr_inf_future(GPR_TIMESPAN)) == 0);
191 1 : x = gpr_time_from_micros(-1, GPR_TIMESPAN);
192 : do {
193 83 : x = gpr_time_add(x, x);
194 83 : } while (gpr_time_cmp(x, gpr_inf_past(GPR_TIMESPAN)) > 0);
195 1 : GPR_ASSERT(gpr_time_cmp(x, gpr_inf_past(GPR_TIMESPAN)) == 0);
196 1 : }
197 :
198 1 : static void test_sticky_infinities(void) {
199 : int i;
200 : int j;
201 : int k;
202 : gpr_timespec infinity[2];
203 : gpr_timespec addend[3];
204 1 : infinity[0] = gpr_inf_future(GPR_TIMESPAN);
205 1 : infinity[1] = gpr_inf_past(GPR_TIMESPAN);
206 1 : addend[0] = gpr_inf_future(GPR_TIMESPAN);
207 1 : addend[1] = gpr_inf_past(GPR_TIMESPAN);
208 1 : addend[2] = gpr_time_0(GPR_TIMESPAN);
209 :
210 : /* Infinities are sticky */
211 3 : for (i = 0; i != sizeof(infinity) / sizeof(infinity[0]); i++) {
212 8 : for (j = 0; j != sizeof(addend) / sizeof(addend[0]); j++) {
213 6 : gpr_timespec x = gpr_time_add(infinity[i], addend[j]);
214 6 : GPR_ASSERT(gpr_time_cmp(x, infinity[i]) == 0);
215 6 : x = gpr_time_sub(infinity[i], addend[j]);
216 6 : GPR_ASSERT(gpr_time_cmp(x, infinity[i]) == 0);
217 : }
218 804 : for (k = -200; k <= 200; k++) {
219 802 : gpr_timespec y = gpr_time_from_micros(k * 100000, GPR_TIMESPAN);
220 802 : gpr_timespec x = gpr_time_add(infinity[i], y);
221 802 : GPR_ASSERT(gpr_time_cmp(x, infinity[i]) == 0);
222 802 : x = gpr_time_sub(infinity[i], y);
223 802 : GPR_ASSERT(gpr_time_cmp(x, infinity[i]) == 0);
224 : }
225 : }
226 1 : }
227 :
228 1 : static void test_similar(void) {
229 1 : GPR_ASSERT(1 == gpr_time_similar(gpr_inf_future(GPR_TIMESPAN),
230 : gpr_inf_future(GPR_TIMESPAN),
231 : gpr_time_0(GPR_TIMESPAN)));
232 1 : GPR_ASSERT(1 == gpr_time_similar(gpr_inf_past(GPR_TIMESPAN),
233 : gpr_inf_past(GPR_TIMESPAN),
234 : gpr_time_0(GPR_TIMESPAN)));
235 1 : GPR_ASSERT(0 == gpr_time_similar(gpr_inf_past(GPR_TIMESPAN),
236 : gpr_inf_future(GPR_TIMESPAN),
237 : gpr_time_0(GPR_TIMESPAN)));
238 1 : GPR_ASSERT(0 == gpr_time_similar(gpr_inf_future(GPR_TIMESPAN),
239 : gpr_inf_past(GPR_TIMESPAN),
240 : gpr_time_0(GPR_TIMESPAN)));
241 1 : GPR_ASSERT(1 == gpr_time_similar(gpr_time_from_micros(10, GPR_TIMESPAN),
242 : gpr_time_from_micros(10, GPR_TIMESPAN),
243 : gpr_time_0(GPR_TIMESPAN)));
244 1 : GPR_ASSERT(1 == gpr_time_similar(gpr_time_from_micros(10, GPR_TIMESPAN),
245 : gpr_time_from_micros(15, GPR_TIMESPAN),
246 : gpr_time_from_micros(10, GPR_TIMESPAN)));
247 1 : GPR_ASSERT(1 == gpr_time_similar(gpr_time_from_micros(15, GPR_TIMESPAN),
248 : gpr_time_from_micros(10, GPR_TIMESPAN),
249 : gpr_time_from_micros(10, GPR_TIMESPAN)));
250 1 : GPR_ASSERT(0 == gpr_time_similar(gpr_time_from_micros(10, GPR_TIMESPAN),
251 : gpr_time_from_micros(25, GPR_TIMESPAN),
252 : gpr_time_from_micros(10, GPR_TIMESPAN)));
253 1 : GPR_ASSERT(0 == gpr_time_similar(gpr_time_from_micros(25, GPR_TIMESPAN),
254 : gpr_time_from_micros(10, GPR_TIMESPAN),
255 : gpr_time_from_micros(10, GPR_TIMESPAN)));
256 1 : }
257 :
258 1 : int main(int argc, char *argv[]) {
259 1 : grpc_test_init(argc, argv);
260 :
261 1 : test_values();
262 1 : test_add_sub();
263 1 : test_overflow();
264 1 : test_sticky_infinities();
265 1 : test_similar();
266 1 : return 0;
267 : }
|