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