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 "c11/time.h" 29#include "util/timespec.h" 30 31#include <limits> 32 33TEST(timespec_test, timespec_add) 34{ 35 struct timespec a, b, r; 36 37 a.tv_sec = 1; 38 a.tv_nsec = NSEC_PER_SEC - 1; 39 b.tv_sec = 1; 40 b.tv_nsec = 2; 41 timespec_add(&r, &a, &b); 42 EXPECT_EQ(r.tv_sec, 3); 43 EXPECT_EQ(r.tv_nsec, 1); 44} 45 46TEST(timespec_test, timespec_sub) 47{ 48 struct timespec a, b, r; 49 50 a.tv_sec = 1; 51 a.tv_nsec = 1; 52 b.tv_sec = 0; 53 b.tv_nsec = 2; 54 timespec_sub(&r, &a, &b); 55 EXPECT_EQ(r.tv_sec, 0); 56 EXPECT_EQ(r.tv_nsec, NSEC_PER_SEC - 1); 57} 58 59TEST(timespec_test, timespec_to_nsec) 60{ 61 struct timespec a; 62 63 a.tv_sec = 4; 64 a.tv_nsec = 4; 65 EXPECT_EQ(timespec_to_nsec(&a), (NSEC_PER_SEC * 4ULL) + 4); 66} 67 68TEST(timespec_test, timespec_to_usec) 69{ 70 struct timespec a; 71 72 a.tv_sec = 4; 73 a.tv_nsec = 4000; 74 EXPECT_EQ(timespec_to_usec(&a), (4000000ULL) + 4); 75} 76 77TEST(timespec_test, timespec_to_msec) 78{ 79 struct timespec a; 80 81 a.tv_sec = 4; 82 a.tv_nsec = 4000000; 83 EXPECT_EQ(timespec_to_msec(&a), (4000ULL) + 4); 84} 85 86TEST(timespec_test, timespec_to_proto) 87{ 88 struct timespec a; 89 uint32_t tv_sec_hi; 90 uint32_t tv_sec_lo; 91 uint32_t tv_nsec; 92 93 a.tv_sec = 0; 94 a.tv_nsec = 0; 95 timespec_to_proto(&a, &tv_sec_hi, &tv_sec_lo, &tv_nsec); 96 EXPECT_EQ(0, tv_sec_hi); 97 EXPECT_EQ(0, tv_sec_lo); 98 EXPECT_EQ(0, tv_nsec); 99 100 a.tv_sec = 1234; 101 a.tv_nsec = NSEC_PER_SEC - 1; 102 timespec_to_proto(&a, &tv_sec_hi, &tv_sec_lo, &tv_nsec); 103 EXPECT_EQ(0, tv_sec_hi); 104 EXPECT_EQ(1234, tv_sec_lo); 105 EXPECT_EQ(NSEC_PER_SEC - 1, tv_nsec); 106 107 a.tv_sec = (time_t)0x7000123470005678LL; 108 a.tv_nsec = 1; 109 timespec_to_proto(&a, &tv_sec_hi, &tv_sec_lo, &tv_nsec); 110 EXPECT_EQ((uint64_t)a.tv_sec >> 32, tv_sec_hi); 111 EXPECT_EQ(0x70005678, tv_sec_lo); 112 EXPECT_EQ(1, tv_nsec); 113} 114 115TEST(timespec_test, millihz_to_nsec) 116{ 117 EXPECT_EQ(millihz_to_nsec(60000), 16666666); 118} 119 120TEST(timespec_test, time_t_max) 121{ 122 /* The TIME_T_MAX macro assumes it's no more than 64 bits */ 123 EXPECT_LE(sizeof(time_t), sizeof(uint64_t)); 124 125 time_t t = TIME_T_MAX; 126 EXPECT_EQ((uint64_t)t, (uint64_t)TIME_T_MAX); 127 128 /* Since the tests are C++ code, we have std::numeric_limits */ 129 EXPECT_EQ(std::numeric_limits<time_t>::max(), TIME_T_MAX); 130} 131 132TEST(timespec_test, timespec_add_nsec) 133{ 134 struct timespec a, r; 135 136 a.tv_sec = 0; 137 a.tv_nsec = NSEC_PER_SEC - 1; 138 EXPECT_FALSE(timespec_add_nsec(&r, &a, 1)); 139 EXPECT_EQ(1, r.tv_sec); 140 EXPECT_EQ(0, r.tv_nsec); 141 142 EXPECT_FALSE(timespec_add_nsec(&r, &a, 2)); 143 EXPECT_EQ(1, r.tv_sec); 144 EXPECT_EQ(1, r.tv_nsec); 145 146 EXPECT_FALSE(timespec_add_nsec(&r, &a, (NSEC_PER_SEC * 2ULL))); 147 EXPECT_EQ(2, r.tv_sec); 148 EXPECT_EQ(NSEC_PER_SEC - 1, r.tv_nsec); 149 150 EXPECT_FALSE(timespec_add_nsec(&r, &a, (NSEC_PER_SEC * 2ULL) + 2)); 151 EXPECT_EQ(r.tv_sec, 3); 152 EXPECT_EQ(r.tv_nsec, 1); 153 154 r.tv_sec = 4; 155 r.tv_nsec = 0; 156 EXPECT_FALSE(timespec_add_nsec(&r, &r, NSEC_PER_SEC + 10ULL)); 157 EXPECT_EQ(5, r.tv_sec); 158 EXPECT_EQ(10, r.tv_nsec); 159 160 EXPECT_FALSE(timespec_add_nsec(&r, &r, (NSEC_PER_SEC * 3ULL) - 9ULL)); 161 EXPECT_EQ(8, r.tv_sec); 162 EXPECT_EQ(1, r.tv_nsec); 163 164 EXPECT_FALSE(timespec_add_nsec(&r, &r, (NSEC_PER_SEC * 7ULL) + 165 (NSEC_PER_SEC - 1ULL))); 166 EXPECT_EQ(16, r.tv_sec); 167 EXPECT_EQ(0, r.tv_nsec); 168 169 a.tv_sec = TIME_T_MAX; 170 a.tv_nsec = 0; 171 EXPECT_TRUE(timespec_add_nsec(&r, &a, UINT64_MAX)); 172 173 a.tv_sec = TIME_T_MAX; 174 a.tv_nsec = 0; 175 EXPECT_TRUE(timespec_add_nsec(&r, &a, NSEC_PER_SEC)); 176 177 a.tv_sec = TIME_T_MAX; 178 a.tv_nsec = NSEC_PER_SEC / 2; 179 EXPECT_TRUE(timespec_add_nsec(&r, &a, NSEC_PER_SEC / 2)); 180} 181 182TEST(timespec_test, timespec_add_msec) 183{ 184 struct timespec a, r; 185 186 a.tv_sec = 1000; 187 a.tv_nsec = 1; 188 timespec_add_msec(&r, &a, 2002); 189 EXPECT_EQ(1002, r.tv_sec); 190 EXPECT_EQ(2000001, r.tv_nsec); 191} 192 193TEST(timespec_test, timespec_sub_to_nsec) 194{ 195 struct timespec a, b; 196 197 a.tv_sec = 1000; 198 a.tv_nsec = 1; 199 b.tv_sec = 1; 200 b.tv_nsec = 2; 201 EXPECT_EQ((999LL * NSEC_PER_SEC) - 1, timespec_sub_to_nsec(&a, &b)); 202} 203 204TEST(timespec_test, timespec_sub_to_msec) 205{ 206 struct timespec a, b; 207 208 a.tv_sec = 1000; 209 a.tv_nsec = 2000000L; 210 b.tv_sec = 2; 211 b.tv_nsec = 1000000L; 212 EXPECT_EQ((998 * 1000) + 1, timespec_sub_to_msec(&a, &b)); 213} 214 215TEST(timespec_test, timespec_from_nsec) 216{ 217 struct timespec a; 218 219 timespec_from_nsec(&a, 0); 220 EXPECT_EQ(0, a.tv_sec); 221 EXPECT_EQ(0, a.tv_nsec); 222 223 timespec_from_nsec(&a, NSEC_PER_SEC - 1); 224 EXPECT_EQ(0, a.tv_sec); 225 EXPECT_EQ(NSEC_PER_SEC - 1, a.tv_nsec); 226 227 timespec_from_nsec(&a, NSEC_PER_SEC); 228 EXPECT_EQ(1, a.tv_sec); 229 EXPECT_EQ(0, a.tv_nsec); 230 231 timespec_from_nsec(&a, (5LL * NSEC_PER_SEC) + 1); 232 EXPECT_EQ(5, a.tv_sec); 233 EXPECT_EQ(1, a.tv_nsec); 234 235 timespec_from_nsec(&a, UINT64_MAX); 236 EXPECT_EQ(a.tv_nsec, UINT64_MAX % NSEC_PER_SEC); 237 EXPECT_EQ(a.tv_sec, (time_t)(UINT64_MAX / NSEC_PER_SEC)); 238} 239 240TEST(timespec_test, timespec_from_usec) 241{ 242 struct timespec a; 243 244 timespec_from_usec(&a, 0); 245 EXPECT_EQ(0, a.tv_sec); 246 EXPECT_EQ(0, a.tv_nsec); 247 248 timespec_from_usec(&a, 999999); 249 EXPECT_EQ(0, a.tv_sec); 250 EXPECT_EQ(999999 * 1000, a.tv_nsec); 251 252 timespec_from_usec(&a, 1000000); 253 EXPECT_EQ(1, a.tv_sec); 254 EXPECT_EQ(0, a.tv_nsec); 255 256 timespec_from_usec(&a, 5000001); 257 EXPECT_EQ(5, a.tv_sec); 258 EXPECT_EQ(1000, a.tv_nsec); 259} 260 261TEST(timespec_test, timespec_from_msec) 262{ 263 struct timespec a; 264 265 timespec_from_msec(&a, 0); 266 EXPECT_EQ(0, a.tv_sec); 267 EXPECT_EQ(0, a.tv_nsec); 268 269 timespec_from_msec(&a, 999); 270 EXPECT_EQ(0, a.tv_sec); 271 EXPECT_EQ(999 * 1000000, a.tv_nsec); 272 273 timespec_from_msec(&a, 1000); 274 EXPECT_EQ(1, a.tv_sec); 275 EXPECT_EQ(0, a.tv_nsec); 276 277 timespec_from_msec(&a, 5001); 278 EXPECT_EQ(5, a.tv_sec); 279 EXPECT_EQ(1000000, a.tv_nsec); 280} 281 282TEST(timespec_test, timespec_from_proto) 283{ 284 struct timespec a; 285 286 timespec_from_proto(&a, 0, 0, 0); 287 EXPECT_EQ(0, a.tv_sec); 288 EXPECT_EQ(0, a.tv_nsec); 289 290 timespec_from_proto(&a, 0, 1234, 9999); 291 EXPECT_EQ(1234, a.tv_sec); 292 EXPECT_EQ(9999, a.tv_nsec); 293 294 timespec_from_proto(&a, 0x1234, 0x5678, 1); 295 EXPECT_EQ((time_t)0x0000123400005678LL, a.tv_sec); 296 EXPECT_EQ(1, a.tv_nsec); 297} 298 299TEST(timespec_test, timespec_is_zero) 300{ 301 struct timespec zero = { 0 }; 302 struct timespec non_zero_sec = { 1, 0 }; 303 struct timespec non_zero_nsec = { 0, 1 }; 304 305 EXPECT_TRUE(timespec_is_zero(&zero)); 306 EXPECT_FALSE(timespec_is_zero(&non_zero_nsec)); 307 EXPECT_FALSE(timespec_is_zero(&non_zero_sec)); 308} 309 310TEST(timespec_test, timespec_eq) 311{ 312 struct timespec a = { 2, 1 }; 313 struct timespec b = { -1, 2 }; 314 315 EXPECT_TRUE(timespec_eq(&a, &a)); 316 EXPECT_TRUE(timespec_eq(&b, &b)); 317 318 EXPECT_FALSE(timespec_eq(&a, &b)); 319 EXPECT_FALSE(timespec_eq(&b, &a)); 320} 321 322TEST(timespec_test, timespec_get) 323{ 324 struct timespec a; 325 struct timespec b; 326 time_t t; 327 timespec_get(&a, TIME_UTC); 328 time(&t); 329 timespec_get(&b, TIME_UTC); 330 /* `t + 1` and `t - 1` are used intentionally for avoid flakes */ 331 EXPECT_LE(a.tv_sec, t + 1); 332 EXPECT_LE(t - 1, b.tv_sec); 333} 334