1a72499e4SRaman Tenneti //===-- Unittests for asctime ---------------------------------------------===//
2a72499e4SRaman Tenneti //
3a72499e4SRaman Tenneti // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4a72499e4SRaman Tenneti // See https://llvm.org/LICENSE.txt for license information.
5a72499e4SRaman Tenneti // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a72499e4SRaman Tenneti //
7a72499e4SRaman Tenneti //===----------------------------------------------------------------------===//
8a72499e4SRaman Tenneti
9b98c1906SRaman Tenneti #include "src/errno/libc_errno.h"
10a72499e4SRaman Tenneti #include "src/time/asctime.h"
11af1315c2SSiva Chandra Reddy #include "test/UnitTest/Test.h"
12a72499e4SRaman Tenneti #include "test/src/time/TmHelper.h"
13a72499e4SRaman Tenneti
call_asctime(struct tm * tm_data,int year,int month,int mday,int hour,int min,int sec,int wday,int yday)14a72499e4SRaman Tenneti static inline char *call_asctime(struct tm *tm_data, int year, int month,
15a72499e4SRaman Tenneti int mday, int hour, int min, int sec, int wday,
16a72499e4SRaman Tenneti int yday) {
17b6bc9d72SGuillaume Chatelet LIBC_NAMESPACE::tmhelper::testing::initialize_tm_data(
1825226f3eSMichael Jones tm_data, year, month, mday, hour, min, sec, wday, yday);
19b6bc9d72SGuillaume Chatelet return LIBC_NAMESPACE::asctime(tm_data);
20a72499e4SRaman Tenneti }
21a72499e4SRaman Tenneti
TEST(LlvmLibcAsctime,Nullptr)22a72499e4SRaman Tenneti TEST(LlvmLibcAsctime, Nullptr) {
23a72499e4SRaman Tenneti char *result;
24b6bc9d72SGuillaume Chatelet result = LIBC_NAMESPACE::asctime(nullptr);
25*28699e38Slntue ASSERT_ERRNO_EQ(EINVAL);
26a72499e4SRaman Tenneti ASSERT_STREQ(nullptr, result);
27a72499e4SRaman Tenneti }
28a72499e4SRaman Tenneti
29a72499e4SRaman Tenneti // Weekdays are in the range 0 to 6. Test passing invalid value in wday.
TEST(LlvmLibcAsctime,InvalidWday)30a72499e4SRaman Tenneti TEST(LlvmLibcAsctime, InvalidWday) {
31a72499e4SRaman Tenneti struct tm tm_data;
32a72499e4SRaman Tenneti
33a72499e4SRaman Tenneti // Test with wday = -1.
342e4ef9b6SSiva Chandra Reddy call_asctime(&tm_data,
35a72499e4SRaman Tenneti 1970, // year
36a72499e4SRaman Tenneti 1, // month
37a72499e4SRaman Tenneti 1, // day
38a72499e4SRaman Tenneti 0, // hr
39a72499e4SRaman Tenneti 0, // min
40a72499e4SRaman Tenneti 0, // sec
41a72499e4SRaman Tenneti -1, // wday
42a72499e4SRaman Tenneti 0); // yday
43*28699e38Slntue ASSERT_ERRNO_EQ(EINVAL);
44a72499e4SRaman Tenneti
45a72499e4SRaman Tenneti // Test with wday = 7.
462e4ef9b6SSiva Chandra Reddy call_asctime(&tm_data,
47a72499e4SRaman Tenneti 1970, // year
48a72499e4SRaman Tenneti 1, // month
49a72499e4SRaman Tenneti 1, // day
50a72499e4SRaman Tenneti 0, // hr
51a72499e4SRaman Tenneti 0, // min
52a72499e4SRaman Tenneti 0, // sec
53a72499e4SRaman Tenneti 7, // wday
54a72499e4SRaman Tenneti 0); // yday
55*28699e38Slntue ASSERT_ERRNO_EQ(EINVAL);
56a72499e4SRaman Tenneti }
57a72499e4SRaman Tenneti
58a72499e4SRaman Tenneti // Months are from January to December. Test passing invalid value in month.
TEST(LlvmLibcAsctime,InvalidMonth)59a72499e4SRaman Tenneti TEST(LlvmLibcAsctime, InvalidMonth) {
60a72499e4SRaman Tenneti struct tm tm_data;
61a72499e4SRaman Tenneti
62a72499e4SRaman Tenneti // Test with month = 0.
632e4ef9b6SSiva Chandra Reddy call_asctime(&tm_data,
64a72499e4SRaman Tenneti 1970, // year
65a72499e4SRaman Tenneti 0, // month
66a72499e4SRaman Tenneti 1, // day
67a72499e4SRaman Tenneti 0, // hr
68a72499e4SRaman Tenneti 0, // min
69a72499e4SRaman Tenneti 0, // sec
70a72499e4SRaman Tenneti 4, // wday
71a72499e4SRaman Tenneti 0); // yday
72*28699e38Slntue ASSERT_ERRNO_EQ(EINVAL);
73a72499e4SRaman Tenneti
74a72499e4SRaman Tenneti // Test with month = 13.
752e4ef9b6SSiva Chandra Reddy call_asctime(&tm_data,
76a72499e4SRaman Tenneti 1970, // year
77a72499e4SRaman Tenneti 13, // month
78a72499e4SRaman Tenneti 1, // day
79a72499e4SRaman Tenneti 0, // hr
80a72499e4SRaman Tenneti 0, // min
81a72499e4SRaman Tenneti 0, // sec
82a72499e4SRaman Tenneti 4, // wday
83a72499e4SRaman Tenneti 0); // yday
84*28699e38Slntue ASSERT_ERRNO_EQ(EINVAL);
85a72499e4SRaman Tenneti }
86a72499e4SRaman Tenneti
TEST(LlvmLibcAsctime,ValidWeekdays)87a72499e4SRaman Tenneti TEST(LlvmLibcAsctime, ValidWeekdays) {
88a72499e4SRaman Tenneti struct tm tm_data;
89a72499e4SRaman Tenneti char *result;
90a72499e4SRaman Tenneti // 1970-01-01 00:00:00.
91a72499e4SRaman Tenneti result = call_asctime(&tm_data,
92a72499e4SRaman Tenneti 1970, // year
93a72499e4SRaman Tenneti 1, // month
94a72499e4SRaman Tenneti 1, // day
95a72499e4SRaman Tenneti 0, // hr
96a72499e4SRaman Tenneti 0, // min
97a72499e4SRaman Tenneti 0, // sec
98a72499e4SRaman Tenneti 4, // wday
99a72499e4SRaman Tenneti 0); // yday
100a72499e4SRaman Tenneti ASSERT_STREQ("Thu Jan 1 00:00:00 1970\n", result);
101a72499e4SRaman Tenneti
102a72499e4SRaman Tenneti // 1970-01-03 00:00:00.
103a72499e4SRaman Tenneti result = call_asctime(&tm_data,
104a72499e4SRaman Tenneti 1970, // year
105a72499e4SRaman Tenneti 1, // month
106a72499e4SRaman Tenneti 3, // day
107a72499e4SRaman Tenneti 0, // hr
108a72499e4SRaman Tenneti 0, // min
109a72499e4SRaman Tenneti 0, // sec
110a72499e4SRaman Tenneti 6, // wday
111a72499e4SRaman Tenneti 0); // yday
112a72499e4SRaman Tenneti ASSERT_STREQ("Sat Jan 3 00:00:00 1970\n", result);
113a72499e4SRaman Tenneti
114a72499e4SRaman Tenneti // 1970-01-04 00:00:00.
115a72499e4SRaman Tenneti result = call_asctime(&tm_data,
116a72499e4SRaman Tenneti 1970, // year
117a72499e4SRaman Tenneti 1, // month
118a72499e4SRaman Tenneti 4, // day
119a72499e4SRaman Tenneti 0, // hr
120a72499e4SRaman Tenneti 0, // min
121a72499e4SRaman Tenneti 0, // sec
122a72499e4SRaman Tenneti 0, // wday
123a72499e4SRaman Tenneti 0); // yday
124a72499e4SRaman Tenneti ASSERT_STREQ("Sun Jan 4 00:00:00 1970\n", result);
125a72499e4SRaman Tenneti }
126a72499e4SRaman Tenneti
TEST(LlvmLibcAsctime,ValidMonths)127a72499e4SRaman Tenneti TEST(LlvmLibcAsctime, ValidMonths) {
128a72499e4SRaman Tenneti struct tm tm_data;
129a72499e4SRaman Tenneti char *result;
130a72499e4SRaman Tenneti // 1970-01-01 00:00:00.
131a72499e4SRaman Tenneti result = call_asctime(&tm_data,
132a72499e4SRaman Tenneti 1970, // year
133a72499e4SRaman Tenneti 1, // month
134a72499e4SRaman Tenneti 1, // day
135a72499e4SRaman Tenneti 0, // hr
136a72499e4SRaman Tenneti 0, // min
137a72499e4SRaman Tenneti 0, // sec
138a72499e4SRaman Tenneti 4, // wday
139a72499e4SRaman Tenneti 0); // yday
140a72499e4SRaman Tenneti ASSERT_STREQ("Thu Jan 1 00:00:00 1970\n", result);
141a72499e4SRaman Tenneti
142a72499e4SRaman Tenneti // 1970-02-01 00:00:00.
143a72499e4SRaman Tenneti result = call_asctime(&tm_data,
144a72499e4SRaman Tenneti 1970, // year
145a72499e4SRaman Tenneti 2, // month
146a72499e4SRaman Tenneti 1, // day
147a72499e4SRaman Tenneti 0, // hr
148a72499e4SRaman Tenneti 0, // min
149a72499e4SRaman Tenneti 0, // sec
150a72499e4SRaman Tenneti 0, // wday
151a72499e4SRaman Tenneti 0); // yday
152a72499e4SRaman Tenneti ASSERT_STREQ("Sun Feb 1 00:00:00 1970\n", result);
153a72499e4SRaman Tenneti
154a72499e4SRaman Tenneti // 1970-12-31 23:59:59.
155a72499e4SRaman Tenneti result = call_asctime(&tm_data,
156a72499e4SRaman Tenneti 1970, // year
157a72499e4SRaman Tenneti 12, // month
158a72499e4SRaman Tenneti 31, // day
159a72499e4SRaman Tenneti 23, // hr
160a72499e4SRaman Tenneti 59, // min
161a72499e4SRaman Tenneti 59, // sec
162a72499e4SRaman Tenneti 4, // wday
163a72499e4SRaman Tenneti 0); // yday
164a72499e4SRaman Tenneti ASSERT_STREQ("Thu Dec 31 23:59:59 1970\n", result);
165a72499e4SRaman Tenneti }
166a72499e4SRaman Tenneti
TEST(LlvmLibcAsctime,EndOf32BitEpochYear)167a72499e4SRaman Tenneti TEST(LlvmLibcAsctime, EndOf32BitEpochYear) {
168a72499e4SRaman Tenneti struct tm tm_data;
169a72499e4SRaman Tenneti char *result;
170a72499e4SRaman Tenneti // Test for maximum value of a signed 32-bit integer.
171a72499e4SRaman Tenneti // Test implementation can encode time for Tue 19 January 2038 03:14:07 UTC.
172a72499e4SRaman Tenneti result = call_asctime(&tm_data,
173a72499e4SRaman Tenneti 2038, // year
174a72499e4SRaman Tenneti 1, // month
175a72499e4SRaman Tenneti 19, // day
176a72499e4SRaman Tenneti 3, // hr
177a72499e4SRaman Tenneti 14, // min
178a72499e4SRaman Tenneti 7, // sec
179a72499e4SRaman Tenneti 2, // wday
180a72499e4SRaman Tenneti 7); // yday
181a72499e4SRaman Tenneti ASSERT_STREQ("Tue Jan 19 03:14:07 2038\n", result);
182a72499e4SRaman Tenneti }
183a72499e4SRaman Tenneti
TEST(LlvmLibcAsctime,Max64BitYear)184a72499e4SRaman Tenneti TEST(LlvmLibcAsctime, Max64BitYear) {
185a72499e4SRaman Tenneti if (sizeof(time_t) == 4)
186a72499e4SRaman Tenneti return;
187a72499e4SRaman Tenneti // Mon Jan 1 12:50:50 2170 (200 years from 1970),
188a72499e4SRaman Tenneti struct tm tm_data;
189a72499e4SRaman Tenneti char *result;
190a72499e4SRaman Tenneti result = call_asctime(&tm_data,
191a72499e4SRaman Tenneti 2170, // year
192a72499e4SRaman Tenneti 1, // month
193a72499e4SRaman Tenneti 1, // day
194a72499e4SRaman Tenneti 12, // hr
195a72499e4SRaman Tenneti 50, // min
196a72499e4SRaman Tenneti 50, // sec
197a72499e4SRaman Tenneti 1, // wday
198a72499e4SRaman Tenneti 50); // yday
199a72499e4SRaman Tenneti ASSERT_STREQ("Mon Jan 1 12:50:50 2170\n", result);
200a72499e4SRaman Tenneti
201a72499e4SRaman Tenneti // Test for Tue Jan 1 12:50:50 in 2,147,483,647th year.
202a72499e4SRaman Tenneti // This test would cause buffer overflow and thus asctime returns nullptr.
203a72499e4SRaman Tenneti result = call_asctime(&tm_data,
204a72499e4SRaman Tenneti 2147483647, // year
205a72499e4SRaman Tenneti 1, // month
206a72499e4SRaman Tenneti 1, // day
207a72499e4SRaman Tenneti 12, // hr
208a72499e4SRaman Tenneti 50, // min
209a72499e4SRaman Tenneti 50, // sec
210a72499e4SRaman Tenneti 2, // wday
211a72499e4SRaman Tenneti 50); // yday
212*28699e38Slntue ASSERT_ERRNO_EQ(EOVERFLOW);
213a72499e4SRaman Tenneti ASSERT_STREQ(nullptr, result);
214a72499e4SRaman Tenneti }
215