blob: eb97859a23375b8e8792761b4bd17545799f4cc6 [file] [log] [blame]
John Park33858a32018-09-28 23:05:48 -07001#include "aos/time/time.h"
brians343bc112013-02-10 01:53:46 +00002
Stephan Pleinescd3701f2024-05-30 10:56:04 -07003#include <sys/time.h>
Austin Schuh793d6b92016-05-01 13:28:14 -07004
Stephan Pleinescd3701f2024-05-30 10:56:04 -07005#include <memory>
6
Austin Schuh60e77942022-05-16 17:48:24 -07007#include "gtest/gtest.h"
brians343bc112013-02-10 01:53:46 +00008
Stephan Pleinesf63bde82024-01-13 15:59:33 -08009namespace aos::time::testing {
brians343bc112013-02-10 01:53:46 +000010
Austin Schuhe92f7e62019-12-25 13:54:41 -080011namespace chrono = std::chrono;
12
13TEST(TimeTest, FromRate) { EXPECT_EQ(chrono::milliseconds(10), FromRate(100)); }
Brian Silvermandcaa3f72015-11-29 05:32:08 +000014
Austin Schuh793d6b92016-05-01 13:28:14 -070015// Test the monotonic_clock and sleep_until functions.
16TEST(TimeTest, MonotonicClockSleepAndNow) {
17 monotonic_clock::time_point start = monotonic_clock::now();
Austin Schuhe92f7e62019-12-25 13:54:41 -080018 const auto kSleepTime = chrono::milliseconds(500);
Austin Schuh793d6b92016-05-01 13:28:14 -070019 ::std::this_thread::sleep_until(start + kSleepTime);
20 monotonic_clock::time_point end = monotonic_clock::now();
21 EXPECT_GE(end - start, kSleepTime);
Austin Schuhe92f7e62019-12-25 13:54:41 -080022 EXPECT_LT(end - start, kSleepTime + chrono::milliseconds(200));
Austin Schuh793d6b92016-05-01 13:28:14 -070023}
24
Neil Balch229001a2018-01-07 18:22:52 -080025// Test to_timespec for a duration.
26TEST(TimeTest, DurationToTimespec) {
Austin Schuhe92f7e62019-12-25 13:54:41 -080027 struct timespec pos_time = to_timespec(chrono::milliseconds(56262));
Neil Balch229001a2018-01-07 18:22:52 -080028 EXPECT_EQ(pos_time.tv_sec, 56);
29 EXPECT_EQ(pos_time.tv_nsec, 262000000);
30
Austin Schuhe92f7e62019-12-25 13:54:41 -080031 struct timespec neg_time = to_timespec(chrono::milliseconds(-56262));
Neil Balch229001a2018-01-07 18:22:52 -080032 EXPECT_EQ(neg_time.tv_sec, -56);
33 EXPECT_EQ(neg_time.tv_nsec, -262000000);
34}
35
36// Test to_timespec for a time_point.
37TEST(TimeTest, TimePointToTimespec) {
Austin Schuhe92f7e62019-12-25 13:54:41 -080038 struct timespec pos_time =
39 to_timespec(::aos::monotonic_clock::epoch() + chrono::seconds(1432423));
Neil Balch229001a2018-01-07 18:22:52 -080040 EXPECT_EQ(pos_time.tv_sec, 1432423);
41 EXPECT_EQ(pos_time.tv_nsec, 0);
42
Austin Schuhe92f7e62019-12-25 13:54:41 -080043 struct timespec neg_time =
44 to_timespec(::aos::monotonic_clock::epoch() - chrono::seconds(1432423));
Neil Balch229001a2018-01-07 18:22:52 -080045 EXPECT_EQ(neg_time.tv_sec, -1432423);
46 EXPECT_EQ(neg_time.tv_nsec, 0);
47}
48
Brian Silverman967e5df2020-02-09 16:43:34 -080049// Tests from_timeval.
50TEST(TimeTest, TimevalToTimePoint) {
51 struct timeval pos_time;
52 pos_time.tv_sec = 1432423;
53 pos_time.tv_usec = 0;
54 EXPECT_EQ(::aos::monotonic_clock::epoch() + chrono::seconds(1432423),
55 from_timeval(pos_time));
56
57 struct timeval neg_time;
58 neg_time.tv_sec = -1432423;
59 neg_time.tv_usec = 0;
60 EXPECT_EQ(::aos::monotonic_clock::epoch() - chrono::seconds(1432423),
61 from_timeval(neg_time));
62}
63
Austin Schuhe92f7e62019-12-25 13:54:41 -080064// Test that << works with numbers with leading 0's.
65TEST(TimeTest, OperatorStream) {
66 const monotonic_clock::time_point t = monotonic_clock::epoch() +
67 chrono::seconds(1432423) +
68 chrono::milliseconds(15);
69
70 // And confirm that the stream's settings are restored by adding a random
71 // number afterwords.
72 std::stringstream s;
73 s << t << " and number " << 123;
74
75 EXPECT_EQ(s.str(), "1432423.015000000sec and number 123");
76}
77
78// Test that << works with negative numbers.
79TEST(TimeTest, OperatorStreamNegative) {
80 {
81 const monotonic_clock::time_point t = monotonic_clock::epoch() -
82 chrono::seconds(14) +
83 chrono::milliseconds(915);
84
85 std::stringstream s;
86 s << t;
87
88 EXPECT_EQ(s.str(), "-13.085000000sec");
Austin Schuh3ce0a922020-07-21 21:08:54 -070089 EXPECT_EQ(monotonic_clock::FromString(s.str()).value(), t);
Austin Schuhe92f7e62019-12-25 13:54:41 -080090 }
91 {
92 const monotonic_clock::time_point t =
93 monotonic_clock::epoch() - chrono::nanoseconds(1);
94
95 std::stringstream s;
96 s << t;
97
98 EXPECT_EQ(s.str(), "-0.000000001sec");
Austin Schuh3ce0a922020-07-21 21:08:54 -070099 EXPECT_EQ(monotonic_clock::FromString(s.str()).value(), t);
Austin Schuhe92f7e62019-12-25 13:54:41 -0800100 }
101 {
102 const monotonic_clock::time_point t =
103 monotonic_clock::epoch() - chrono::seconds(1) - chrono::nanoseconds(1);
104
105 std::stringstream s;
106 s << t;
107
108 EXPECT_EQ(s.str(), "-1.000000001sec");
Austin Schuh3ce0a922020-07-21 21:08:54 -0700109 EXPECT_EQ(monotonic_clock::FromString(s.str()).value(), t);
Austin Schuhe92f7e62019-12-25 13:54:41 -0800110 }
111 {
112 const monotonic_clock::time_point t =
113 monotonic_clock::epoch() - chrono::seconds(2) - chrono::nanoseconds(1);
114
115 std::stringstream s;
116 s << t;
117
118 EXPECT_EQ(s.str(), "-2.000000001sec");
Austin Schuh3ce0a922020-07-21 21:08:54 -0700119 EXPECT_EQ(monotonic_clock::FromString(s.str()).value(), t);
Austin Schuhe92f7e62019-12-25 13:54:41 -0800120 }
121}
122
123// Test that << works with min_time.
124TEST(TimeTest, OperatorStreamMinTime) {
125 const monotonic_clock::time_point t = monotonic_clock::min_time;
126
127 std::stringstream s;
128 s << t;
129
130 EXPECT_EQ(s.str(), "-9223372036.854775808sec");
Austin Schuh3ce0a922020-07-21 21:08:54 -0700131 EXPECT_EQ(monotonic_clock::FromString(s.str()).value(), t);
Austin Schuhe92f7e62019-12-25 13:54:41 -0800132}
133
Austin Schuh40102d22019-12-27 23:30:06 -0800134// Test that << works with the epoch on the realtime clock.
135TEST(TimeTest, OperatorStreamRealtimeEpoch) {
136 const realtime_clock::time_point t = realtime_clock::epoch();
137
138 std::stringstream s;
139 s << t;
140
141 EXPECT_EQ(s.str(), "1970-01-01_00-00-00.000000000");
Austin Schuh3ce0a922020-07-21 21:08:54 -0700142 EXPECT_EQ(realtime_clock::FromString(s.str()).value(), t);
Austin Schuh40102d22019-12-27 23:30:06 -0800143}
144
145// Test that << works with positive time on the realtime clock.
146TEST(TimeTest, OperatorStreamRealtimePositive) {
147 const realtime_clock::time_point t =
148 realtime_clock::epoch() + std::chrono::hours(5 * 24) +
149 std::chrono::seconds(11) + std::chrono::milliseconds(5);
150
151 std::stringstream s;
152 s << t;
153
154 EXPECT_EQ(s.str(), "1970-01-06_00-00-11.005000000");
Austin Schuh3ce0a922020-07-21 21:08:54 -0700155 EXPECT_EQ(realtime_clock::FromString(s.str()).value(), t);
Austin Schuh40102d22019-12-27 23:30:06 -0800156}
157
158// Test that << works with negative time on the realtime clock.
159TEST(TimeTest, OperatorStreamRealtimeNegative) {
160 {
161 const realtime_clock::time_point t =
162 realtime_clock::epoch() - std::chrono::nanoseconds(1);
163
164 std::stringstream s;
165 s << t;
166
167 EXPECT_EQ(s.str(), "1969-12-31_23-59-59.999999999");
Austin Schuh3ce0a922020-07-21 21:08:54 -0700168 EXPECT_EQ(realtime_clock::FromString(s.str()).value(), t);
Austin Schuh40102d22019-12-27 23:30:06 -0800169 }
170 {
171 const realtime_clock::time_point t =
172 realtime_clock::epoch() - std::chrono::nanoseconds(999999999);
173
174 std::stringstream s;
175 s << t;
176
177 EXPECT_EQ(s.str(), "1969-12-31_23-59-59.000000001");
Austin Schuh3ce0a922020-07-21 21:08:54 -0700178 EXPECT_EQ(realtime_clock::FromString(s.str()).value(), t);
Austin Schuh40102d22019-12-27 23:30:06 -0800179 }
180 {
181 const realtime_clock::time_point t = realtime_clock::epoch() -
182 std::chrono::seconds(1) -
183 std::chrono::nanoseconds(999999999);
184
185 std::stringstream s;
186 s << t;
187
188 EXPECT_EQ(s.str(), "1969-12-31_23-59-58.000000001");
Austin Schuh3ce0a922020-07-21 21:08:54 -0700189 EXPECT_EQ(realtime_clock::FromString(s.str()).value(), t);
Austin Schuh40102d22019-12-27 23:30:06 -0800190 }
191 {
192 const realtime_clock::time_point t =
193 realtime_clock::epoch() - std::chrono::hours(5 * 24) +
194 std::chrono::seconds(11) - std::chrono::milliseconds(5);
195
196 std::stringstream s;
197 s << t;
198
199 EXPECT_EQ(s.str(), "1969-12-27_00-00-10.995000000");
Austin Schuh3ce0a922020-07-21 21:08:54 -0700200 EXPECT_EQ(realtime_clock::FromString(s.str()).value(), t);
Austin Schuh40102d22019-12-27 23:30:06 -0800201 }
Austin Schuhb2ac0562021-09-13 23:23:33 -0700202
203 {
204 const realtime_clock::time_point t = realtime_clock::min_time;
205
206 std::stringstream s;
207 s << t;
208
Philipp Schraderd0d264d2023-12-20 11:11:35 -0800209 // min_time happens to be unrepresentable because of rounding and signed
210 // integer overflow.
211 EXPECT_EQ(s.str(), "(unrepresentable realtime -9223372036854775808)");
Austin Schuhb2ac0562021-09-13 23:23:33 -0700212 }
213
214 {
215 const realtime_clock::time_point t =
216 realtime_clock::min_time + std::chrono::nanoseconds(999999999);
217
218 std::stringstream s;
219 s << t;
220
221 EXPECT_EQ(s.str(), "1677-09-21_00-12-44.145224191");
222 EXPECT_EQ(realtime_clock::FromString(s.str()).value(), t);
223 }
Austin Schuh40102d22019-12-27 23:30:06 -0800224}
225
Eric Schmiedeberg42273f42023-12-14 13:48:45 -0700226// Test that ToString works for monotonic and realtime time points.
227TEST(TimeTest, ToStringTimePoints) {
228 EXPECT_EQ(ToString(realtime_clock::epoch() + std::chrono::hours(5 * 24) +
229 std::chrono::seconds(11) + std::chrono::milliseconds(5)),
230 "1970-01-06_00-00-11.005000000");
231 EXPECT_EQ(ToString(monotonic_clock::min_time), "-9223372036.854775808sec");
232}
233
Stephan Pleinesf63bde82024-01-13 15:59:33 -0800234} // namespace aos::time::testing