1 | //===-- Unittests for gmtime ----------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "src/__support/CPP/limits.h" // INT_MAX, INT_MIN |
10 | #include "src/errno/libc_errno.h" |
11 | #include "src/time/gmtime.h" |
12 | #include "src/time/time_utils.h" |
13 | #include "test/UnitTest/ErrnoSetterMatcher.h" |
14 | #include "test/UnitTest/Test.h" |
15 | #include "test/src/time/TmMatcher.h" |
16 | |
17 | using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails; |
18 | using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds; |
19 | using LIBC_NAMESPACE::time_utils::TimeConstants; |
20 | |
21 | TEST(LlvmLibcGmTime, OutOfRange) { |
22 | if (sizeof(time_t) < sizeof(int64_t)) |
23 | return; |
24 | time_t seconds = |
25 | 1 + INT_MAX * static_cast<int64_t>( |
26 | TimeConstants::NUMBER_OF_SECONDS_IN_LEAP_YEAR); |
27 | struct tm *tm_data = LIBC_NAMESPACE::gmtime(timer: &seconds); |
28 | EXPECT_TRUE(tm_data == nullptr); |
29 | ASSERT_ERRNO_EQ(EOVERFLOW); |
30 | |
31 | LIBC_NAMESPACE::libc_errno = 0; |
32 | seconds = INT_MIN * static_cast<int64_t>( |
33 | TimeConstants::NUMBER_OF_SECONDS_IN_LEAP_YEAR) - |
34 | 1; |
35 | tm_data = LIBC_NAMESPACE::gmtime(timer: &seconds); |
36 | EXPECT_TRUE(tm_data == nullptr); |
37 | ASSERT_ERRNO_EQ(EOVERFLOW); |
38 | } |
39 | |
40 | TEST(LlvmLibcGmTime, InvalidSeconds) { |
41 | time_t seconds = 0; |
42 | struct tm *tm_data = nullptr; |
43 | // -1 second from 1970-01-01 00:00:00 returns 1969-12-31 23:59:59. |
44 | seconds = -1; |
45 | tm_data = LIBC_NAMESPACE::gmtime(timer: &seconds); |
46 | EXPECT_TM_EQ((tm{59, // sec |
47 | 59, // min |
48 | 23, // hr |
49 | 31, // day |
50 | 12 - 1, // tm_mon starts with 0 for Jan |
51 | 1969 - TimeConstants::TIME_YEAR_BASE, // year |
52 | 3, // wday |
53 | 364, // yday |
54 | 0}), |
55 | *tm_data); |
56 | // 60 seconds from 1970-01-01 00:00:00 returns 1970-01-01 00:01:00. |
57 | seconds = 60; |
58 | tm_data = LIBC_NAMESPACE::gmtime(timer: &seconds); |
59 | EXPECT_TM_EQ((tm{0, // sec |
60 | 1, // min |
61 | 0, // hr |
62 | 1, // day |
63 | 0, // tm_mon starts with 0 for Jan |
64 | 1970 - TimeConstants::TIME_YEAR_BASE, // year |
65 | 4, // wday |
66 | 0, // yday |
67 | 0}), |
68 | *tm_data); |
69 | } |
70 | |
71 | TEST(LlvmLibcGmTime, InvalidMinutes) { |
72 | time_t seconds = 0; |
73 | struct tm *tm_data = nullptr; |
74 | // -1 minute from 1970-01-01 00:00:00 returns 1969-12-31 23:59:00. |
75 | seconds = -TimeConstants::SECONDS_PER_MIN; |
76 | tm_data = LIBC_NAMESPACE::gmtime(timer: &seconds); |
77 | EXPECT_TM_EQ((tm{0, // sec |
78 | 59, // min |
79 | 23, // hr |
80 | 31, // day |
81 | 11, // tm_mon starts with 0 for Jan |
82 | 1969 - TimeConstants::TIME_YEAR_BASE, // year |
83 | 3, // wday |
84 | 0, // yday |
85 | 0}), |
86 | *tm_data); |
87 | // 60 minutes from 1970-01-01 00:00:00 returns 1970-01-01 01:00:00. |
88 | seconds = 60 * TimeConstants::SECONDS_PER_MIN; |
89 | tm_data = LIBC_NAMESPACE::gmtime(timer: &seconds); |
90 | EXPECT_TM_EQ((tm{0, // sec |
91 | 0, // min |
92 | 1, // hr |
93 | 1, // day |
94 | 0, // tm_mon starts with 0 for Jan |
95 | 1970 - TimeConstants::TIME_YEAR_BASE, // year |
96 | 4, // wday |
97 | 0, // yday |
98 | 0}), |
99 | *tm_data); |
100 | } |
101 | |
102 | TEST(LlvmLibcGmTime, InvalidHours) { |
103 | time_t seconds = 0; |
104 | struct tm *tm_data = nullptr; |
105 | // -1 hour from 1970-01-01 00:00:00 returns 1969-12-31 23:00:00. |
106 | seconds = -TimeConstants::SECONDS_PER_HOUR; |
107 | tm_data = LIBC_NAMESPACE::gmtime(timer: &seconds); |
108 | EXPECT_TM_EQ((tm{0, // sec |
109 | 0, // min |
110 | 23, // hr |
111 | 31, // day |
112 | 11, // tm_mon starts with 0 for Jan |
113 | 1969 - TimeConstants::TIME_YEAR_BASE, // year |
114 | 3, // wday |
115 | 0, // yday |
116 | 0}), |
117 | *tm_data); |
118 | // 24 hours from 1970-01-01 00:00:00 returns 1970-01-02 00:00:00. |
119 | seconds = 24 * TimeConstants::SECONDS_PER_HOUR; |
120 | tm_data = LIBC_NAMESPACE::gmtime(timer: &seconds); |
121 | EXPECT_TM_EQ((tm{0, // sec |
122 | 0, // min |
123 | 0, // hr |
124 | 2, // day |
125 | 0, // tm_mon starts with 0 for Jan |
126 | 1970 - TimeConstants::TIME_YEAR_BASE, // year |
127 | 5, // wday |
128 | 0, // yday |
129 | 0}), |
130 | *tm_data); |
131 | } |
132 | |
133 | TEST(LlvmLibcGmTime, InvalidYear) { |
134 | // -1 year from 1970-01-01 00:00:00 returns 1969-01-01 00:00:00. |
135 | time_t seconds = |
136 | -TimeConstants::DAYS_PER_NON_LEAP_YEAR * TimeConstants::SECONDS_PER_DAY; |
137 | struct tm *tm_data = LIBC_NAMESPACE::gmtime(timer: &seconds); |
138 | EXPECT_TM_EQ((tm{0, // sec |
139 | 0, // min |
140 | 0, // hr |
141 | 1, // day |
142 | 0, // tm_mon starts with 0 for Jan |
143 | 1969 - TimeConstants::TIME_YEAR_BASE, // year |
144 | 3, // wday |
145 | 0, // yday |
146 | 0}), |
147 | *tm_data); |
148 | } |
149 | |
150 | TEST(LlvmLibcGmTime, InvalidMonths) { |
151 | time_t seconds = 0; |
152 | struct tm *tm_data = nullptr; |
153 | // -1 month from 1970-01-01 00:00:00 returns 1969-12-01 00:00:00. |
154 | seconds = -31 * TimeConstants::SECONDS_PER_DAY; |
155 | tm_data = LIBC_NAMESPACE::gmtime(timer: &seconds); |
156 | EXPECT_TM_EQ((tm{0, // sec |
157 | 0, // min |
158 | 0, // hr |
159 | 1, // day |
160 | 12 - 1, // tm_mon starts with 0 for Jan |
161 | 1969 - TimeConstants::TIME_YEAR_BASE, // year |
162 | 1, // wday |
163 | 0, // yday |
164 | 0}), |
165 | *tm_data); |
166 | // 1970-13-01 00:00:00 returns 1971-01-01 00:00:00. |
167 | seconds = |
168 | TimeConstants::DAYS_PER_NON_LEAP_YEAR * TimeConstants::SECONDS_PER_DAY; |
169 | tm_data = LIBC_NAMESPACE::gmtime(timer: &seconds); |
170 | EXPECT_TM_EQ((tm{0, // sec |
171 | 0, // min |
172 | 0, // hr |
173 | 1, // day |
174 | 0, // tm_mon starts with 0 for Jan |
175 | 1971 - TimeConstants::TIME_YEAR_BASE, // year |
176 | 5, // wday |
177 | 0, // yday |
178 | 0}), |
179 | *tm_data); |
180 | } |
181 | |
182 | TEST(LlvmLibcGmTime, InvalidDays) { |
183 | time_t seconds = 0; |
184 | struct tm *tm_data = nullptr; |
185 | // -1 day from 1970-01-01 00:00:00 returns 1969-12-31 00:00:00. |
186 | seconds = -1 * TimeConstants::SECONDS_PER_DAY; |
187 | tm_data = LIBC_NAMESPACE::gmtime(timer: &seconds); |
188 | EXPECT_TM_EQ((tm{0, // sec |
189 | 0, // min |
190 | 0, // hr |
191 | 31, // day |
192 | 11, // tm_mon starts with 0 for Jan |
193 | 1969 - TimeConstants::TIME_YEAR_BASE, // year |
194 | 3, // wday |
195 | 0, // yday |
196 | 0}), |
197 | *tm_data); |
198 | |
199 | // 1970-01-32 00:00:00 returns 1970-02-01 00:00:00. |
200 | seconds = 31 * TimeConstants::SECONDS_PER_DAY; |
201 | tm_data = LIBC_NAMESPACE::gmtime(timer: &seconds); |
202 | EXPECT_TM_EQ((tm{0, // sec |
203 | 0, // min |
204 | 0, // hr |
205 | 1, // day |
206 | 0, // tm_mon starts with 0 for Jan |
207 | 1970 - TimeConstants::TIME_YEAR_BASE, // year |
208 | 0, // wday |
209 | 0, // yday |
210 | 0}), |
211 | *tm_data); |
212 | |
213 | // 1970-02-29 00:00:00 returns 1970-03-01 00:00:00. |
214 | seconds = 59 * TimeConstants::SECONDS_PER_DAY; |
215 | tm_data = LIBC_NAMESPACE::gmtime(timer: &seconds); |
216 | EXPECT_TM_EQ((tm{0, // sec |
217 | 0, // min |
218 | 0, // hr |
219 | 1, // day |
220 | 2, // tm_mon starts with 0 for Jan |
221 | 1970 - TimeConstants::TIME_YEAR_BASE, // year |
222 | 0, // wday |
223 | 0, // yday |
224 | 0}), |
225 | *tm_data); |
226 | |
227 | // 1972-02-30 00:00:00 returns 1972-03-01 00:00:00. |
228 | seconds = ((2 * TimeConstants::DAYS_PER_NON_LEAP_YEAR) + 60) * |
229 | TimeConstants::SECONDS_PER_DAY; |
230 | tm_data = LIBC_NAMESPACE::gmtime(timer: &seconds); |
231 | EXPECT_TM_EQ((tm{0, // sec |
232 | 0, // min |
233 | 0, // hr |
234 | 1, // day |
235 | 2, // tm_mon starts with 0 for Jan |
236 | 1972 - TimeConstants::TIME_YEAR_BASE, // year |
237 | 3, // wday |
238 | 0, // yday |
239 | 0}), |
240 | *tm_data); |
241 | } |
242 | |
243 | TEST(LlvmLibcGmTime, EndOf32BitEpochYear) { |
244 | // Test for maximum value of a signed 32-bit integer. |
245 | // Test implementation can encode time for Tue 19 January 2038 03:14:07 UTC. |
246 | time_t seconds = 0x7FFFFFFF; |
247 | struct tm *tm_data = LIBC_NAMESPACE::gmtime(timer: &seconds); |
248 | EXPECT_TM_EQ((tm{7, // sec |
249 | 14, // min |
250 | 3, // hr |
251 | 19, // day |
252 | 0, // tm_mon starts with 0 for Jan |
253 | 2038 - TimeConstants::TIME_YEAR_BASE, // year |
254 | 2, // wday |
255 | 7, // yday |
256 | 0}), |
257 | *tm_data); |
258 | } |
259 | |
260 | TEST(LlvmLibcGmTime, Max64BitYear) { |
261 | if (sizeof(time_t) == 4) |
262 | return; |
263 | // Mon Jan 1 12:50:50 2170 (200 years from 1970), |
264 | time_t seconds = 6311479850; |
265 | struct tm *tm_data = LIBC_NAMESPACE::gmtime(timer: &seconds); |
266 | EXPECT_TM_EQ((tm{50, // sec |
267 | 50, // min |
268 | 12, // hr |
269 | 1, // day |
270 | 0, // tm_mon starts with 0 for Jan |
271 | 2170 - TimeConstants::TIME_YEAR_BASE, // year |
272 | 1, // wday |
273 | 50, // yday |
274 | 0}), |
275 | *tm_data); |
276 | |
277 | // Test for Tue Jan 1 12:50:50 in 2,147,483,647th year. |
278 | seconds = 67767976202043050; |
279 | tm_data = LIBC_NAMESPACE::gmtime(timer: &seconds); |
280 | EXPECT_TM_EQ((tm{50, // sec |
281 | 50, // min |
282 | 12, // hr |
283 | 1, // day |
284 | 0, // tm_mon starts with 0 for Jan |
285 | 2147483647 - TimeConstants::TIME_YEAR_BASE, // year |
286 | 2, // wday |
287 | 50, // yday |
288 | 0}), |
289 | *tm_data); |
290 | } |
291 | |