ConvTest.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. /*
  2. * Copyright 2017-present Facebook, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <folly/chrono/Conv.h>
  17. #include <folly/portability/GTest.h>
  18. using namespace folly;
  19. using namespace std::chrono;
  20. using namespace std::chrono_literals;
  21. namespace {
  22. /**
  23. * A helper function to create a time_point even if the input duration type has
  24. * finer resolution than the clock duration type.
  25. */
  26. template <typename Clock, typename Duration>
  27. typename Clock::time_point createTimePoint(const Duration& d) {
  28. return typename Clock::time_point(
  29. std::chrono::duration_cast<typename Clock::duration>(d));
  30. }
  31. } // namespace
  32. TEST(Conv, timespecToStdChrono) {
  33. struct timespec ts;
  34. ts.tv_sec = 0;
  35. ts.tv_nsec = 10;
  36. EXPECT_EQ(10ns, to<nanoseconds>(ts));
  37. EXPECT_EQ(0us, to<microseconds>(ts));
  38. EXPECT_EQ(0ms, to<milliseconds>(ts));
  39. EXPECT_EQ(0s, to<seconds>(ts));
  40. ts.tv_sec = 1;
  41. ts.tv_nsec = 10;
  42. EXPECT_EQ(1000000010ns, to<nanoseconds>(ts));
  43. EXPECT_EQ(1000000us, to<microseconds>(ts));
  44. EXPECT_EQ(1000ms, to<milliseconds>(ts));
  45. EXPECT_EQ(1s, to<seconds>(ts));
  46. EXPECT_EQ(
  47. createTimePoint<system_clock>(1000000010ns),
  48. to<system_clock::time_point>(ts));
  49. EXPECT_EQ(
  50. createTimePoint<steady_clock>(1000000010ns),
  51. to<steady_clock::time_point>(ts));
  52. // Test a non-canonical value with tv_nsec larger than 1 second
  53. ts.tv_sec = 5;
  54. ts.tv_nsec = 3219876543;
  55. // Beware about using std::chrono_literals suffixes with very literals:
  56. // older versions of GCC are buggy and would truncate these to 32-bits.
  57. EXPECT_EQ(8219876543LL, to<nanoseconds>(ts).count());
  58. EXPECT_EQ(8219876us, to<microseconds>(ts));
  59. EXPECT_EQ(8219ms, to<milliseconds>(ts));
  60. EXPECT_EQ(8s, to<seconds>(ts));
  61. EXPECT_EQ(
  62. createTimePoint<system_clock>(nanoseconds(8219876543LL)),
  63. to<system_clock::time_point>(ts));
  64. EXPECT_EQ(
  65. createTimePoint<steady_clock>(nanoseconds(8219876543LL)),
  66. to<steady_clock::time_point>(ts));
  67. // Test negative values
  68. // When going to coarser grained types these should be rounded up towards 0.
  69. ts.tv_sec = -5;
  70. ts.tv_nsec = 123456;
  71. EXPECT_EQ(-4999876544, to<nanoseconds>(ts).count());
  72. EXPECT_EQ(-4999876544, duration_cast<nanoseconds>(-5s + 123456ns).count());
  73. EXPECT_EQ(-4999876, to<microseconds>(ts).count());
  74. EXPECT_EQ(-4999876, duration_cast<microseconds>(-5s + 123456ns).count());
  75. EXPECT_EQ(-4999, to<milliseconds>(ts).count());
  76. EXPECT_EQ(-4999, duration_cast<milliseconds>(-5s + 123456ns).count());
  77. EXPECT_EQ(-4s, to<seconds>(ts));
  78. EXPECT_EQ(-4, duration_cast<seconds>(-5s + 123456ns).count());
  79. ts.tv_sec = -7200;
  80. ts.tv_nsec = 123456;
  81. EXPECT_EQ(-1h, to<hours>(ts));
  82. EXPECT_EQ(
  83. -1,
  84. duration_cast<hours>(seconds{ts.tv_sec} + nanoseconds{ts.tv_nsec})
  85. .count());
  86. ts.tv_sec = -7000;
  87. ts.tv_nsec = 123456;
  88. EXPECT_EQ(-1h, to<hours>(ts));
  89. EXPECT_EQ(
  90. -1,
  91. duration_cast<hours>(seconds{ts.tv_sec} + nanoseconds{ts.tv_nsec})
  92. .count());
  93. ts.tv_sec = -7201;
  94. ts.tv_nsec = 123456;
  95. EXPECT_EQ(-2h, to<hours>(ts));
  96. EXPECT_EQ(
  97. -2,
  98. duration_cast<hours>(seconds{ts.tv_sec} + nanoseconds{ts.tv_nsec})
  99. .count());
  100. // Test converions to floating point durations
  101. ts.tv_sec = 1;
  102. ts.tv_nsec = 500000000;
  103. EXPECT_EQ(1.5, to<duration<double>>(ts).count());
  104. ts.tv_sec = -1;
  105. ts.tv_nsec = 500000000;
  106. EXPECT_EQ(-0.5, to<duration<double>>(ts).count());
  107. ts.tv_sec = -1;
  108. ts.tv_nsec = -500000000;
  109. EXPECT_EQ(-1.5, to<duration<double>>(ts).count());
  110. ts.tv_sec = 1;
  111. ts.tv_nsec = 500000000;
  112. auto doubleNanos = to<duration<double, std::nano>>(ts);
  113. EXPECT_EQ(1500000000, doubleNanos.count());
  114. ts.tv_sec = 90;
  115. ts.tv_nsec = 0;
  116. auto doubleMinutes = to<duration<double, std::ratio<60>>>(ts);
  117. EXPECT_EQ(1.5, doubleMinutes.count());
  118. // Test with unusual durations where neither the numerator nor denominator
  119. // are 1.
  120. using five_sevenths = std::chrono::duration<int64_t, std::ratio<5, 7>>;
  121. ts.tv_sec = 1;
  122. ts.tv_nsec = 0;
  123. EXPECT_EQ(1, to<five_sevenths>(ts).count());
  124. ts.tv_sec = 1;
  125. ts.tv_nsec = 428571500;
  126. EXPECT_EQ(2, to<five_sevenths>(ts).count());
  127. using thirteen_thirds = std::chrono::duration<double, std::ratio<13, 3>>;
  128. ts.tv_sec = 39;
  129. ts.tv_nsec = 0;
  130. EXPECT_NEAR(9.0, to<thirteen_thirds>(ts).count(), 0.000000001);
  131. ts.tv_sec = 1;
  132. ts.tv_nsec = 0;
  133. EXPECT_NEAR(0.230769230, to<thirteen_thirds>(ts).count(), 0.000000001);
  134. }
  135. TEST(Conv, timespecToStdChronoOverflow) {
  136. struct timespec ts;
  137. // All of our boundary conditions below assume time_t is int64_t.
  138. // This is true on most modern platforms.
  139. if (!std::is_same<decltype(ts.tv_sec), int64_t>::value) {
  140. LOG(INFO) << "skipping most overflow tests: time_t is not int64_t";
  141. } else {
  142. // Test the upper boundary of conversion to uint64_t nanoseconds
  143. using nsec_u64 = std::chrono::duration<uint64_t, std::nano>;
  144. ts.tv_sec = 18446744073;
  145. ts.tv_nsec = 709551615;
  146. EXPECT_EQ(std::numeric_limits<uint64_t>::max(), to<nsec_u64>(ts).count());
  147. ts.tv_nsec += 1;
  148. EXPECT_THROW(to<nsec_u64>(ts), std::range_error);
  149. // Test the lower boundary of conversion to uint64_t nanoseconds
  150. ts.tv_sec = 0;
  151. ts.tv_nsec = 0;
  152. EXPECT_EQ(0, to<nsec_u64>(ts).count());
  153. ts.tv_sec = -1;
  154. ts.tv_nsec = 0;
  155. EXPECT_THROW(to<nsec_u64>(ts), std::range_error);
  156. // Test the upper boundary of conversion to int64_t microseconds
  157. using usec_i64 = std::chrono::duration<int64_t, std::micro>;
  158. ts.tv_sec = 9223372036854LL;
  159. ts.tv_nsec = 775807000;
  160. EXPECT_EQ(std::numeric_limits<int64_t>::max(), to<usec_i64>(ts).count());
  161. ts.tv_nsec += 1;
  162. EXPECT_THROW(to<usec_i64>(ts), std::range_error);
  163. // Test the lower boundary of conversion to int64_t microseconds
  164. ts.tv_sec = -9223372036855LL;
  165. ts.tv_nsec = 224192000;
  166. EXPECT_EQ(std::numeric_limits<int64_t>::min(), to<usec_i64>(ts).count());
  167. ts.tv_nsec -= 1;
  168. EXPECT_THROW(to<usec_i64>(ts), std::range_error);
  169. // Test the boundaries of conversion to int32_t seconds
  170. using sec_i32 = std::chrono::duration<int32_t>;
  171. ts.tv_sec = 2147483647;
  172. ts.tv_nsec = 0;
  173. EXPECT_EQ(std::numeric_limits<int32_t>::max(), to<sec_i32>(ts).count());
  174. ts.tv_nsec = 1000000000;
  175. EXPECT_THROW(to<sec_i32>(ts), std::range_error);
  176. ts.tv_sec = -2147483648;
  177. ts.tv_nsec = 0;
  178. EXPECT_EQ(std::numeric_limits<int32_t>::min(), to<sec_i32>(ts).count());
  179. ts.tv_sec = -2147483649;
  180. ts.tv_nsec = 999999999;
  181. EXPECT_THROW(to<sec_i32>(ts), std::range_error);
  182. ts.tv_sec = -2147483649;
  183. ts.tv_nsec = 0;
  184. EXPECT_THROW(to<sec_i32>(ts), std::range_error);
  185. ts.tv_sec = -2147483650;
  186. ts.tv_nsec = 0;
  187. EXPECT_THROW(to<sec_i32>(ts), std::range_error);
  188. // Test the upper boundary of conversion to uint32_t hours
  189. using hours_u32 = std::chrono::duration<uint32_t, std::ratio<3600>>;
  190. ts.tv_sec = 15461882262000LL;
  191. ts.tv_nsec = 0;
  192. EXPECT_EQ(std::numeric_limits<uint32_t>::max(), to<hours_u32>(ts).count());
  193. ts.tv_sec = 15461882265599LL;
  194. EXPECT_EQ(std::numeric_limits<uint32_t>::max(), to<hours_u32>(ts).count());
  195. ts.tv_sec = 15461882265600LL;
  196. EXPECT_THROW(to<hours_u32>(ts), std::range_error);
  197. using nsec_i64 = std::chrono::duration<int64_t, std::nano>;
  198. ts.tv_sec = std::numeric_limits<int64_t>::max();
  199. ts.tv_nsec = std::numeric_limits<int64_t>::max();
  200. EXPECT_THROW(to<nsec_i64>(ts), std::range_error);
  201. ts.tv_sec = std::numeric_limits<int64_t>::min();
  202. ts.tv_nsec = std::numeric_limits<int64_t>::min();
  203. EXPECT_THROW(to<nsec_i64>(ts), std::range_error);
  204. // Test some non-normal inputs near the int64_t limit
  205. ts.tv_sec = 0;
  206. ts.tv_nsec = std::numeric_limits<int64_t>::min();
  207. EXPECT_EQ(std::numeric_limits<int64_t>::min(), to<nsec_i64>(ts).count());
  208. ts.tv_sec = -1;
  209. ts.tv_nsec = std::numeric_limits<int64_t>::min() + std::nano::den;
  210. EXPECT_EQ(std::numeric_limits<int64_t>::min(), to<nsec_i64>(ts).count());
  211. ts.tv_sec = -1;
  212. ts.tv_nsec = std::numeric_limits<int64_t>::min() + std::nano::den - 1;
  213. EXPECT_THROW(to<nsec_i64>(ts), std::range_error);
  214. ts.tv_sec = 0;
  215. ts.tv_nsec = std::numeric_limits<int64_t>::max();
  216. EXPECT_EQ(std::numeric_limits<int64_t>::max(), to<nsec_i64>(ts).count());
  217. ts.tv_sec = 1;
  218. ts.tv_nsec = std::numeric_limits<int64_t>::max() - std::nano::den;
  219. EXPECT_EQ(std::numeric_limits<int64_t>::max(), to<nsec_i64>(ts).count());
  220. ts.tv_sec = 1;
  221. ts.tv_nsec = std::numeric_limits<int64_t>::max() - std::nano::den + 1;
  222. EXPECT_THROW(to<nsec_i64>(ts), std::range_error);
  223. }
  224. // Theoretically conversion is representable in the output type,
  225. // but we normalize the input first, and normalization would trigger an
  226. // overflow.
  227. using hours_u64 = std::chrono::duration<uint64_t, std::ratio<3600>>;
  228. ts.tv_sec = std::numeric_limits<decltype(ts.tv_sec)>::max();
  229. ts.tv_nsec = 1000000000;
  230. EXPECT_THROW(to<hours_u64>(ts), std::range_error);
  231. // If we drop it back down to the normal range it should succeed
  232. ts.tv_nsec = 999999999;
  233. EXPECT_EQ(
  234. std::numeric_limits<decltype(ts.tv_sec)>::max() / 3600,
  235. to<hours_u64>(ts).count());
  236. // Test overflow with an unusual duration where neither the numerator nor
  237. // denominator are 1.
  238. using unusual_time = std::chrono::duration<int16_t, std::ratio<13, 3>>;
  239. ts.tv_sec = 141994;
  240. ts.tv_nsec = 666666666;
  241. EXPECT_EQ(32767, to<unusual_time>(ts).count());
  242. ts.tv_nsec = 666666667;
  243. EXPECT_THROW(to<unusual_time>(ts), std::range_error);
  244. ts.tv_sec = -141998;
  245. ts.tv_nsec = 999999999;
  246. EXPECT_EQ(-32768, to<unusual_time>(ts).count());
  247. ts.tv_sec = -141999;
  248. ts.tv_nsec = 0;
  249. EXPECT_THROW(to<unusual_time>(ts), std::range_error);
  250. }
  251. TEST(Conv, timevalToStdChrono) {
  252. struct timeval tv;
  253. tv.tv_sec = 0;
  254. tv.tv_usec = 10;
  255. EXPECT_EQ(10000ns, to<nanoseconds>(tv));
  256. EXPECT_EQ(10us, to<microseconds>(tv));
  257. EXPECT_EQ(0ms, to<milliseconds>(tv));
  258. EXPECT_EQ(0s, to<seconds>(tv));
  259. tv.tv_sec = 1;
  260. tv.tv_usec = 10;
  261. EXPECT_EQ(1000010000ns, to<nanoseconds>(tv));
  262. EXPECT_EQ(1000010us, to<microseconds>(tv));
  263. EXPECT_EQ(1000ms, to<milliseconds>(tv));
  264. EXPECT_EQ(1s, to<seconds>(tv));
  265. EXPECT_EQ(
  266. createTimePoint<system_clock>(1000010000ns),
  267. to<system_clock::time_point>(tv));
  268. EXPECT_EQ(
  269. createTimePoint<steady_clock>(1000010000ns),
  270. to<steady_clock::time_point>(tv));
  271. // Test a non-canonical value with tv_usec larger than 1 second
  272. tv.tv_sec = 5;
  273. tv.tv_usec = 3219876;
  274. EXPECT_EQ(8219876000LL, to<nanoseconds>(tv).count());
  275. EXPECT_EQ(8219876us, to<microseconds>(tv));
  276. EXPECT_EQ(8219ms, to<milliseconds>(tv));
  277. EXPECT_EQ(8s, to<seconds>(tv));
  278. EXPECT_EQ(
  279. createTimePoint<system_clock>(nanoseconds(8219876000LL)),
  280. to<system_clock::time_point>(tv));
  281. EXPECT_EQ(
  282. createTimePoint<steady_clock>(nanoseconds(8219876000LL)),
  283. to<steady_clock::time_point>(tv));
  284. // Test for overflow.
  285. if (std::numeric_limits<decltype(tv.tv_sec)>::max() >=
  286. std::numeric_limits<int64_t>::max()) {
  287. // Use our own type alias here rather than std::chrono::nanoseconds
  288. // to ensure we have 64-bit rep type.
  289. using nsec_i64 = std::chrono::duration<int64_t, std::nano>;
  290. tv.tv_sec = std::numeric_limits<decltype(tv.tv_sec)>::max();
  291. tv.tv_usec = std::numeric_limits<decltype(tv.tv_usec)>::max();
  292. EXPECT_THROW(to<nsec_i64>(tv), std::range_error);
  293. tv.tv_sec = std::numeric_limits<decltype(tv.tv_sec)>::min();
  294. tv.tv_usec = std::numeric_limits<decltype(tv.tv_usec)>::max();
  295. EXPECT_THROW(to<nsec_i64>(tv), std::range_error);
  296. }
  297. }
  298. TEST(Conv, stdChronoToTimespec) {
  299. auto ts = to<struct timespec>(10ns);
  300. EXPECT_EQ(0, ts.tv_sec);
  301. EXPECT_EQ(10, ts.tv_nsec);
  302. // We don't use std::chrono_literals suffixes here since older
  303. // gcc versions silently truncate the literals to 32-bits.
  304. ts = to<struct timespec>(nanoseconds(987654321012LL));
  305. EXPECT_EQ(987, ts.tv_sec);
  306. EXPECT_EQ(654321012, ts.tv_nsec);
  307. ts = to<struct timespec>(nanoseconds(-987654321012LL));
  308. EXPECT_EQ(-988, ts.tv_sec);
  309. EXPECT_EQ(345678988, ts.tv_nsec);
  310. ts = to<struct timespec>(microseconds(987654321012LL));
  311. EXPECT_EQ(987654, ts.tv_sec);
  312. EXPECT_EQ(321012000, ts.tv_nsec);
  313. ts = to<struct timespec>(milliseconds(987654321012LL));
  314. EXPECT_EQ(987654321, ts.tv_sec);
  315. EXPECT_EQ(12000000, ts.tv_nsec);
  316. ts = to<struct timespec>(seconds(987654321012LL));
  317. EXPECT_EQ(987654321012, ts.tv_sec);
  318. EXPECT_EQ(0, ts.tv_nsec);
  319. ts = to<struct timespec>(10h);
  320. EXPECT_EQ(36000, ts.tv_sec);
  321. EXPECT_EQ(0, ts.tv_nsec);
  322. ts = to<struct timespec>(createTimePoint<steady_clock>(123ns));
  323. EXPECT_EQ(0, ts.tv_sec);
  324. EXPECT_EQ(123, ts.tv_nsec);
  325. ts = to<struct timespec>(createTimePoint<system_clock>(123ns));
  326. EXPECT_EQ(0, ts.tv_sec);
  327. EXPECT_EQ(123, ts.tv_nsec);
  328. // Test with some unusual durations where neither the numerator nor
  329. // denominator are 1.
  330. using five_sevenths = std::chrono::duration<int64_t, std::ratio<5, 7>>;
  331. ts = to<struct timespec>(five_sevenths(7));
  332. EXPECT_EQ(5, ts.tv_sec);
  333. EXPECT_EQ(0, ts.tv_nsec);
  334. ts = to<struct timespec>(five_sevenths(19));
  335. EXPECT_EQ(13, ts.tv_sec);
  336. EXPECT_EQ(571428571, ts.tv_nsec);
  337. using seven_fifths = std::chrono::duration<int64_t, std::ratio<7, 5>>;
  338. ts = to<struct timespec>(seven_fifths(5));
  339. EXPECT_EQ(7, ts.tv_sec);
  340. EXPECT_EQ(0, ts.tv_nsec);
  341. }
  342. TEST(Conv, stdChronoToTimespecOverflow) {
  343. EXPECT_THROW(to<uint8_t>(1234), std::range_error);
  344. struct timespec ts;
  345. if (!std::is_same<decltype(ts.tv_sec), int64_t>::value) {
  346. LOG(INFO) << "skipping most overflow tests: time_t is not int64_t";
  347. } else {
  348. // Check for overflow converting from uint64_t seconds to time_t
  349. using sec_u64 = duration<uint64_t>;
  350. ts = to<struct timespec>(sec_u64(9223372036854775807ULL));
  351. EXPECT_EQ(ts.tv_sec, 9223372036854775807ULL);
  352. EXPECT_EQ(ts.tv_nsec, 0);
  353. EXPECT_THROW(
  354. to<struct timespec>(sec_u64(9223372036854775808ULL)), std::range_error);
  355. // Check for overflow converting from int64_t hours to time_t
  356. using hours_i64 = duration<int64_t, std::ratio<3600>>;
  357. ts = to<struct timespec>(hours_i64(2562047788015215LL));
  358. EXPECT_EQ(ts.tv_sec, 9223372036854774000LL);
  359. EXPECT_EQ(ts.tv_nsec, 0);
  360. EXPECT_THROW(
  361. to<struct timespec>(hours_i64(2562047788015216LL)), std::range_error);
  362. // Test overflows from an unusual duration where neither the numerator nor
  363. // denominator are 1.
  364. using three_halves = std::chrono::duration<uint64_t, std::ratio<3, 2>>;
  365. EXPECT_THROW(
  366. to<struct timespec>(three_halves(6148914691236517206ULL)),
  367. std::range_error);
  368. }
  369. // Test for overflow.
  370. // Use a custom hours type using time_t as the underlying storage type to
  371. // guarantee that we can overflow.
  372. using hours_timet = std::chrono::duration<time_t, std::ratio<3600>>;
  373. EXPECT_THROW(
  374. to<struct timespec>(hours_timet(std::numeric_limits<time_t>::max())),
  375. std::range_error);
  376. }
  377. TEST(Conv, stdChronoToTimeval) {
  378. auto tv = to<struct timeval>(10ns);
  379. EXPECT_EQ(0, tv.tv_sec);
  380. EXPECT_EQ(0, tv.tv_usec);
  381. tv = to<struct timeval>(10us);
  382. EXPECT_EQ(0, tv.tv_sec);
  383. EXPECT_EQ(10, tv.tv_usec);
  384. tv = to<struct timeval>(nanoseconds(987654321012LL));
  385. EXPECT_EQ(987, tv.tv_sec);
  386. EXPECT_EQ(654321, tv.tv_usec);
  387. tv = to<struct timeval>(nanoseconds(-987654321012LL));
  388. EXPECT_EQ(-988, tv.tv_sec);
  389. EXPECT_EQ(345679, tv.tv_usec);
  390. tv = to<struct timeval>(microseconds(987654321012LL));
  391. EXPECT_EQ(987654, tv.tv_sec);
  392. EXPECT_EQ(321012, tv.tv_usec);
  393. tv = to<struct timeval>(milliseconds(987654321012LL));
  394. EXPECT_EQ(987654321, tv.tv_sec);
  395. EXPECT_EQ(12000, tv.tv_usec);
  396. tv = to<struct timeval>(seconds(987654321012LL));
  397. EXPECT_EQ(987654321012, tv.tv_sec);
  398. EXPECT_EQ(0, tv.tv_usec);
  399. // Try converting fractional seconds
  400. tv = to<struct timeval>(duration<double>{3.456789});
  401. EXPECT_EQ(3, tv.tv_sec);
  402. EXPECT_EQ(456789, tv.tv_usec);
  403. tv = to<struct timeval>(duration<double>{-3.456789});
  404. EXPECT_EQ(-4, tv.tv_sec);
  405. EXPECT_EQ(543211, tv.tv_usec);
  406. // Try converting fractional hours
  407. tv = to<struct timeval>(duration<double, std::ratio<3600>>{3.456789});
  408. EXPECT_EQ(12444, tv.tv_sec);
  409. // The usec field is generally off-by-one due to
  410. // floating point rounding error
  411. EXPECT_NEAR(440400, tv.tv_usec, 1);
  412. tv = to<struct timeval>(duration<double, std::ratio<3600>>{-3.456789});
  413. EXPECT_EQ(-12445, tv.tv_sec);
  414. EXPECT_NEAR(559600, tv.tv_usec, 1);
  415. // Try converting fractional milliseconds
  416. tv = to<struct timeval>(duration<double, std::milli>{9123.456789});
  417. EXPECT_EQ(9, tv.tv_sec);
  418. EXPECT_EQ(123456, tv.tv_usec);
  419. tv = to<struct timeval>(duration<double, std::milli>{-9123.456789});
  420. EXPECT_EQ(-10, tv.tv_sec);
  421. EXPECT_NEAR(876544, tv.tv_usec, 1);
  422. tv = to<struct timeval>(duration<uint32_t, std::ratio<3600>>{3});
  423. EXPECT_EQ(10800, tv.tv_sec);
  424. EXPECT_EQ(0, tv.tv_usec);
  425. tv = to<struct timeval>(duration<uint32_t, std::nano>{3123});
  426. EXPECT_EQ(0, tv.tv_sec);
  427. EXPECT_EQ(3, tv.tv_usec);
  428. tv = to<struct timeval>(duration<int32_t, std::nano>{-3123});
  429. EXPECT_EQ(-1, tv.tv_sec);
  430. EXPECT_EQ(999997, tv.tv_usec);
  431. tv = to<struct timeval>(createTimePoint<steady_clock>(123us));
  432. EXPECT_EQ(0, tv.tv_sec);
  433. EXPECT_EQ(123, tv.tv_usec);
  434. tv = to<struct timeval>(createTimePoint<system_clock>(123us));
  435. EXPECT_EQ(0, tv.tv_sec);
  436. EXPECT_EQ(123, tv.tv_usec);
  437. }