1/*
2 * Copyright © 2016 Collabora, Ltd.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial
14 * portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25
26#include <gtest/gtest.h>
27
28#include "util/timespec.h"
29
30TEST(timespec_test, timespec_add)
31{
32   struct timespec a, b, r;
33
34   a.tv_sec = 1;
35   a.tv_nsec = NSEC_PER_SEC - 1;
36   b.tv_sec = 1;
37   b.tv_nsec = 2;
38   timespec_add(&r, &a, &b);
39   EXPECT_EQ(r.tv_sec, 3);
40   EXPECT_EQ(r.tv_nsec, 1);
41}
42
43TEST(timespec_test, timespec_sub)
44{
45   struct timespec a, b, r;
46
47   a.tv_sec = 1;
48   a.tv_nsec = 1;
49   b.tv_sec = 0;
50   b.tv_nsec = 2;
51   timespec_sub(&r, &a, &b);
52   EXPECT_EQ(r.tv_sec, 0);
53   EXPECT_EQ(r.tv_nsec, NSEC_PER_SEC - 1);
54}
55
56TEST(timespec_test, timespec_to_nsec)
57{
58   struct timespec a;
59
60   a.tv_sec = 4;
61   a.tv_nsec = 4;
62   EXPECT_EQ(timespec_to_nsec(&a), (NSEC_PER_SEC * 4ULL) + 4);
63}
64
65TEST(timespec_test, timespec_to_usec)
66{
67   struct timespec a;
68
69   a.tv_sec = 4;
70   a.tv_nsec = 4000;
71   EXPECT_EQ(timespec_to_usec(&a), (4000000ULL) + 4);
72}
73
74TEST(timespec_test, timespec_to_msec)
75{
76   struct timespec a;
77
78   a.tv_sec = 4;
79   a.tv_nsec = 4000000;
80   EXPECT_EQ(timespec_to_msec(&a), (4000ULL) + 4);
81}
82
83TEST(timespec_test, timespec_to_proto)
84{
85   struct timespec a;
86   uint32_t tv_sec_hi;
87   uint32_t tv_sec_lo;
88   uint32_t tv_nsec;
89
90   a.tv_sec = 0;
91   a.tv_nsec = 0;
92   timespec_to_proto(&a, &tv_sec_hi, &tv_sec_lo, &tv_nsec);
93   EXPECT_EQ(0, tv_sec_hi);
94   EXPECT_EQ(0, tv_sec_lo);
95   EXPECT_EQ(0, tv_nsec);
96
97   a.tv_sec = 1234;
98   a.tv_nsec = NSEC_PER_SEC - 1;
99   timespec_to_proto(&a, &tv_sec_hi, &tv_sec_lo, &tv_nsec);
100   EXPECT_EQ(0, tv_sec_hi);
101   EXPECT_EQ(1234, tv_sec_lo);
102   EXPECT_EQ(NSEC_PER_SEC - 1, tv_nsec);
103
104   a.tv_sec = (time_t)0x7000123470005678LL;
105   a.tv_nsec = 1;
106   timespec_to_proto(&a, &tv_sec_hi, &tv_sec_lo, &tv_nsec);
107   EXPECT_EQ((uint64_t)a.tv_sec >> 32, tv_sec_hi);
108   EXPECT_EQ(0x70005678, tv_sec_lo);
109   EXPECT_EQ(1, tv_nsec);
110}
111
112TEST(timespec_test, millihz_to_nsec)
113{
114   EXPECT_EQ(millihz_to_nsec(60000), 16666666);
115}
116
117TEST(timespec_test, timespec_add_nsec)
118{
119   struct timespec a, r;
120
121   a.tv_sec = 0;
122   a.tv_nsec = NSEC_PER_SEC - 1;
123   timespec_add_nsec(&r, &a, 1);
124   EXPECT_EQ(1, r.tv_sec);
125   EXPECT_EQ(0, r.tv_nsec);
126
127   timespec_add_nsec(&r, &a, 2);
128   EXPECT_EQ(1, r.tv_sec);
129   EXPECT_EQ(1, r.tv_nsec);
130
131   timespec_add_nsec(&r, &a, (NSEC_PER_SEC * 2ULL));
132   EXPECT_EQ(2, r.tv_sec);
133   EXPECT_EQ(NSEC_PER_SEC - 1, r.tv_nsec);
134
135   timespec_add_nsec(&r, &a, (NSEC_PER_SEC * 2ULL) + 2);
136   EXPECT_EQ(r.tv_sec, 3);
137   EXPECT_EQ(r.tv_nsec, 1);
138
139   r.tv_sec = 4;
140   r.tv_nsec = 0;
141   timespec_add_nsec(&r, &r, NSEC_PER_SEC + 10ULL);
142   EXPECT_EQ(5, r.tv_sec);
143   EXPECT_EQ(10, r.tv_nsec);
144
145   timespec_add_nsec(&r, &r, (NSEC_PER_SEC * 3ULL) - 9ULL);
146   EXPECT_EQ(8, r.tv_sec);
147   EXPECT_EQ(1, r.tv_nsec);
148
149   timespec_add_nsec(&r, &r, (NSEC_PER_SEC * 7ULL) + (NSEC_PER_SEC - 1ULL));
150   EXPECT_EQ(16, r.tv_sec);
151   EXPECT_EQ(0, r.tv_nsec);
152}
153
154TEST(timespec_test, timespec_add_msec)
155{
156   struct timespec a, r;
157
158   a.tv_sec = 1000;
159   a.tv_nsec = 1;
160   timespec_add_msec(&r, &a, 2002);
161   EXPECT_EQ(1002, r.tv_sec);
162   EXPECT_EQ(2000001, r.tv_nsec);
163}
164
165TEST(timespec_test, timespec_sub_to_nsec)
166{
167   struct timespec a, b;
168
169   a.tv_sec = 1000;
170   a.tv_nsec = 1;
171   b.tv_sec = 1;
172   b.tv_nsec = 2;
173   EXPECT_EQ((999LL * NSEC_PER_SEC) - 1, timespec_sub_to_nsec(&a, &b));
174}
175
176TEST(timespec_test, timespec_sub_to_msec)
177{
178   struct timespec a, b;
179
180   a.tv_sec = 1000;
181   a.tv_nsec = 2000000L;
182   b.tv_sec = 2;
183   b.tv_nsec = 1000000L;
184   EXPECT_EQ((998 * 1000) + 1, timespec_sub_to_msec(&a, &b));
185}
186
187TEST(timespec_test, timespec_from_nsec)
188{
189   struct timespec a;
190
191   timespec_from_nsec(&a, 0);
192   EXPECT_EQ(0, a.tv_sec);
193   EXPECT_EQ(0, a.tv_nsec);
194
195   timespec_from_nsec(&a, NSEC_PER_SEC - 1);
196   EXPECT_EQ(0, a.tv_sec);
197   EXPECT_EQ(NSEC_PER_SEC - 1, a.tv_nsec);
198
199   timespec_from_nsec(&a, NSEC_PER_SEC);
200   EXPECT_EQ(1, a.tv_sec);
201   EXPECT_EQ(0, a.tv_nsec);
202
203   timespec_from_nsec(&a, (5LL * NSEC_PER_SEC) + 1);
204   EXPECT_EQ(5, a.tv_sec);
205   EXPECT_EQ(1, a.tv_nsec);
206
207   timespec_from_nsec(&a, UINT64_MAX);
208   EXPECT_EQ(a.tv_nsec, UINT64_MAX % NSEC_PER_SEC);
209   EXPECT_EQ(a.tv_sec, (time_t)(UINT64_MAX / NSEC_PER_SEC));
210}
211
212TEST(timespec_test, timespec_from_usec)
213{
214   struct timespec a;
215
216   timespec_from_usec(&a, 0);
217   EXPECT_EQ(0, a.tv_sec);
218   EXPECT_EQ(0, a.tv_nsec);
219
220   timespec_from_usec(&a, 999999);
221   EXPECT_EQ(0, a.tv_sec);
222   EXPECT_EQ(999999 * 1000, a.tv_nsec);
223
224   timespec_from_usec(&a, 1000000);
225   EXPECT_EQ(1, a.tv_sec);
226   EXPECT_EQ(0, a.tv_nsec);
227
228   timespec_from_usec(&a, 5000001);
229   EXPECT_EQ(5, a.tv_sec);
230   EXPECT_EQ(1000, a.tv_nsec);
231}
232
233TEST(timespec_test, timespec_from_msec)
234{
235   struct timespec a;
236
237   timespec_from_msec(&a, 0);
238   EXPECT_EQ(0, a.tv_sec);
239   EXPECT_EQ(0, a.tv_nsec);
240
241   timespec_from_msec(&a, 999);
242   EXPECT_EQ(0, a.tv_sec);
243   EXPECT_EQ(999 * 1000000, a.tv_nsec);
244
245   timespec_from_msec(&a, 1000);
246   EXPECT_EQ(1, a.tv_sec);
247   EXPECT_EQ(0, a.tv_nsec);
248
249   timespec_from_msec(&a, 5001);
250   EXPECT_EQ(5, a.tv_sec);
251   EXPECT_EQ(1000000, a.tv_nsec);
252}
253
254TEST(timespec_test, timespec_from_proto)
255{
256   struct timespec a;
257
258   timespec_from_proto(&a, 0, 0, 0);
259   EXPECT_EQ(0, a.tv_sec);
260   EXPECT_EQ(0, a.tv_nsec);
261
262   timespec_from_proto(&a, 0, 1234, 9999);
263   EXPECT_EQ(1234, a.tv_sec);
264   EXPECT_EQ(9999, a.tv_nsec);
265
266   timespec_from_proto(&a, 0x1234, 0x5678, 1);
267   EXPECT_EQ((time_t)0x0000123400005678LL, a.tv_sec);
268   EXPECT_EQ(1, a.tv_nsec);
269}
270
271TEST(timespec_test, timespec_is_zero)
272{
273   struct timespec zero = { 0 };
274   struct timespec non_zero_sec = { .tv_sec = 1, .tv_nsec = 0 };
275   struct timespec non_zero_nsec = { .tv_sec = 0, .tv_nsec = 1 };
276
277   EXPECT_TRUE(timespec_is_zero(&zero));
278   EXPECT_FALSE(timespec_is_zero(&non_zero_nsec));
279   EXPECT_FALSE(timespec_is_zero(&non_zero_sec));
280}
281
282TEST(timespec_test, timespec_eq)
283{
284   struct timespec a = { .tv_sec = 2, .tv_nsec = 1 };
285   struct timespec b = { .tv_sec = -1, .tv_nsec = 2 };
286
287   EXPECT_TRUE(timespec_eq(&a, &a));
288   EXPECT_TRUE(timespec_eq(&b, &b));
289
290   EXPECT_FALSE(timespec_eq(&a, &b));
291   EXPECT_FALSE(timespec_eq(&b, &a));
292}
293