1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <stdio.h>
17#include <stdlib.h>
18#include <time.h>
19
20#include <limits.h>
21#include "gtest/gtest.h"
22#include "log.h"
23
24using namespace testing::ext;
25time_t g_time = 18880;
26size_t g_zero = 0;
27class TimeUtilsTest : public testing::Test {
28};
29
30/**
31* @tc.number     SUB_KERNEL_TIME_API_ASCTIME_0100
32* @tc.name       test asctime api
33* @tc.desc       [C- SOFTWARE -0200]
34*/
35HWTEST_F(TimeUtilsTest, testAscTime, Function | MediumTest | Level1)
36{
37    struct tm timeptr = {0};
38    timeptr.tm_sec = 0;
39    timeptr.tm_min = 10;
40    timeptr.tm_hour = 10;
41    timeptr.tm_mday = 9;
42    timeptr.tm_mon = 7;
43    timeptr.tm_year = 120;
44    timeptr.tm_wday = 7;
45
46    char * returnStr = asctime(&timeptr);
47    LOG("    asctime &timeptr:='{timeptr.tm_year=%d timeptr.tm_mon=%d timeptr.tm_mday=%d}'   "
48        "--> returnStr:='%s'\n", timeptr.tm_year, timeptr.tm_mon, timeptr.tm_mday, returnStr);
49    EXPECT_STREQ("Sun Aug  9 10:10:00 2020\n", returnStr)
50        << "ErrInfo: asctime &timeptr:='{timeptr.tm_year=" << timeptr.tm_year
51        << " timeptr.tm_mon=" << timeptr.tm_mon << "' timeptr.tm_mday=" << timeptr.tm_mday
52        << "}'   --> returnStr:='" << returnStr << "'";
53}
54
55/**
56* @tc.number     SUB_KERNEL_TIME_API_ASCTIMER_0100
57* @tc.name       test asctimer api
58* @tc.desc       [C- SOFTWARE -0200]
59*/
60HWTEST_F(TimeUtilsTest, testAscTimeR, Function | MediumTest | Level1)
61{
62    struct tm timeptr = {0};
63    timeptr.tm_sec = 0;
64    timeptr.tm_min = 10;
65    timeptr.tm_hour = 10;
66    timeptr.tm_mday = 9;
67    timeptr.tm_mon = 7;
68    timeptr.tm_year = 120;
69    timeptr.tm_wday = 7;
70
71    char str[26];
72    char *returnStr = asctime_r(&timeptr, str);
73    EXPECT_STREQ("Sun Aug  9 10:10:00 2020\n", returnStr) << "asctime_r return error!";
74    EXPECT_STREQ(returnStr, str) << "asctime_r buf return error!";
75}
76
77/**
78* @tc.number     SUB_KERNEL_TIME_API_CTIME_0100
79* @tc.name       test ctime api
80* @tc.desc       [C- SOFTWARE -0200]
81*/
82HWTEST_F(TimeUtilsTest, testCtime, Function | MediumTest | Level2)
83{
84    time_t curClock;
85    time(&curClock);
86    char* returnStr = ctime(&curClock);
87    LOG("returnStr = %s\n", returnStr);
88    EXPECT_STRNE(returnStr, "") << "ctime return error!";
89
90    returnStr = ctime(&g_time);
91    EXPECT_STREQ(returnStr, "Thu Jan  1 05:14:40 1970\n") << "ctime return error!";
92}
93
94/**
95* @tc.number     SUB_KERNEL_TIME_API_CTIME_R_0100
96* @tc.name       test ctime_r api
97* @tc.desc       [C- SOFTWARE -0200]
98*/
99HWTEST_F(TimeUtilsTest, testCtimeR, Function | MediumTest | Level3)
100{
101    time_t curClock;
102    time(&curClock);
103    char str[26];
104    char *returnStr = ctime_r(&curClock, str);
105    LOG("str = %s", str);
106    EXPECT_STRNE(returnStr, "") << "ctime_r return error!";
107    EXPECT_STREQ(returnStr, str) << "ctime_r returns not equal";
108
109    returnStr = ctime_r(&g_time, str);
110    EXPECT_STREQ(returnStr, "Thu Jan  1 05:14:40 1970\n") << "ctime_r return error!";
111    EXPECT_STREQ(returnStr, str) << "ctime_r returns not equal";
112}
113
114/**
115* @tc.number     SUB_KERNEL_NDKAPI_TIME_DIFFTIME_0100
116* @tc.name       test difftime api
117* @tc.desc       [C- SOFTWARE -0200]
118*/
119HWTEST_F(TimeUtilsTest, testDifftime, Function | MediumTest | Level2)
120{
121    time_t timeStart, timeEnd;
122    double returnVal;
123    time(&timeStart);
124    sleep(1);
125    time(&timeEnd);
126    returnVal = difftime(timeEnd, timeStart);
127    LOG("    difftime timeEnd:='%lld' timeStart:='%lld'   "
128        "--> returnVal:='%f'\n", timeEnd, timeStart, returnVal);
129    LOG("    sizeof timeEnd:='%d'   sizeof timeStart:='%d'\n", sizeof(timeEnd), sizeof(timeStart));
130    EXPECT_GE(returnVal, 0)
131        << "ErrInfo: difftime timeEnd:='" << timeEnd << "' timeStart:='"
132        << timeStart << "'   --> returnVal:='" << returnVal << "'";
133    EXPECT_LE(returnVal, 2)
134        << "ErrInfo: difftime timeEnd:='" << timeEnd << "' timeStart:='"
135        << timeStart << "'   --> returnVal:='" << returnVal << "'";
136}
137
138/**
139* @tc.number     SUB_KERNEL_NDKAPI_TIME_TIMEGM_0100
140* @tc.name       test timegm api
141* @tc.desc       [C- SOFTWARE -0200]
142*/
143HWTEST_F(TimeUtilsTest, testTimegm, Function | MediumTest | Level3)
144{
145    struct tm timeptr = {0};
146    time_t timeThis;
147    timeptr.tm_sec = 0;
148    timeptr.tm_min = 10;
149    timeptr.tm_hour = 10;
150    timeptr.tm_mday = 9;
151    timeptr.tm_mon = 7;
152    timeptr.tm_year = 120;
153    timeptr.tm_wday = 5;
154
155    timeThis = timegm(&timeptr);
156    LOG("    timegm &timeptr:='{timeptr.tm_year=%d timeptr.tm_mon=%d timeptr.tm_mday=%d}'   "
157        "--> return timeThis:='%lld'\n", timeptr.tm_year, timeptr.tm_mon, timeptr.tm_mday, timeThis);
158    EXPECT_GE(timeThis, 1)
159        << "ErrInfo: timegm &timeptr:='{timeptr.tm_year=" << timeptr.tm_year
160        << " timeptr.tm_mon=" << timeptr.tm_mon << " timeptr.tm_mday="
161        << timeptr.tm_mday << "}'   --> return timeThis:='" << timeThis << "'";
162
163    struct tm *stm2 = gmtime(&g_time);
164    time_t timep = timegm(stm2);
165    LOG("stm = %s;mktime:%ld\n", asctime(stm2), (long)timep);
166    EXPECT_EQ(timep, g_time) << "timegm return error!";
167}
168
169/**
170* @tc.number     SUB_KERNEL_TIME_API_GMTIME_0100
171* @tc.name       test gmtime api
172* @tc.desc       [C- SOFTWARE -0200]
173*/
174HWTEST_F(TimeUtilsTest, testGmtime, Function | MediumTest | Level3)
175{
176    time_t time1 = 18880;
177    struct tm *stm = gmtime(&time1);
178    ASSERT_NE(nullptr, stm);
179    EXPECT_EQ(stm->tm_hour, 05) << "gmtime return error!";
180    EXPECT_STREQ(asctime(stm), "Thu Jan  1 05:14:40 1970\n") << "gmtime return error!";
181
182    time1 = LONG_MAX;
183    stm = gmtime(&time1);
184    ASSERT_NE(nullptr, stm);
185    EXPECT_STREQ(asctime(stm), "Tue Jan 19 03:14:07 2038\n") << "gmtime return error!";
186
187    time1 = 253402300799;
188    stm = gmtime(&time1);
189    ASSERT_NE(nullptr, stm);
190    EXPECT_STREQ(asctime(stm), "Fri Dec 31 23:59:59 9999\n") << "gmtime return error!";
191
192    time1 = LONG_MIN;
193    stm = gmtime(&time1);
194    ASSERT_NE(nullptr, stm);
195    EXPECT_STREQ(asctime(stm), "Fri Dec 13 20:45:52 1901\n") << "gmtime return error!";
196}
197
198/**
199* @tc.number     SUB_KERNEL_TIME_API_GMTIMER_0100
200* @tc.name       test gmtime_r api
201* @tc.desc       [C- SOFTWARE -0200]
202*/
203HWTEST_F(TimeUtilsTest, testGmtimeR, Function | MediumTest | Level3)
204{
205    struct tm res = {0};
206    struct tm *stm = gmtime_r(&g_time, &res);
207    ASSERT_NE(nullptr, stm);
208    EXPECT_EQ(stm->tm_hour, 05) << "gmtime_r return error!";
209    EXPECT_STREQ(asctime(stm), "Thu Jan  1 05:14:40 1970\n") << "gmtime_r return error!";
210    EXPECT_TRUE(stm == &res) << "gmtime_r returns not equal";
211
212    time_t timeNow;
213    time(&timeNow);
214    stm = gmtime_r(&timeNow, &res);
215    ASSERT_NE(nullptr, stm);
216    EXPECT_EQ(stm->tm_year, 70) << "gmtime_r return error!";
217    EXPECT_STRNE(asctime(stm), "") << "gmtime_r return error!";
218    EXPECT_TRUE(stm == &res) << "gmtime_r returns not equal";
219}
220
221/**
222* @tc.number     SUB_KERNEL_TIME_API_MKTIME_0100
223* @tc.name       test mktime api
224* @tc.desc       [C- SOFTWARE -0200]
225*/
226HWTEST_F(TimeUtilsTest, testMktime, Function | MediumTest | Level2)
227{
228    struct tm *localTime;
229    struct tm timeptr = {0};
230    timeptr.tm_sec = 0;
231    timeptr.tm_min = 10;
232    timeptr.tm_hour = 10;
233    timeptr.tm_mday = 9;
234    timeptr.tm_mon = 7;
235    timeptr.tm_year = 120;
236    timeptr.tm_wday = 7;
237    EXPECT_EQ(mktime(&timeptr), 1596967800) << "mktime return error!";
238
239    localTime = localtime(&g_time);
240    ASSERT_NE(nullptr, localTime);
241    time_t timep = mktime(localTime);
242    EXPECT_EQ(timep, 18880) << "mktime return error!";
243}
244
245/**
246* @tc.number     SUB_KERNEL_TIME_API_STRFTIME_0100
247* @tc.name       test strftime api
248* @tc.desc       [C- SOFTWARE -0200]
249*/
250HWTEST_F(TimeUtilsTest, testStrftime, Function | MediumTest | Level3)
251{
252    size_t strftimeBytes = 19;
253    char buffer[80] = {0};
254    time_t mtime = 18880;
255    struct tm *localTime = localtime(&mtime);
256    if (localTime == nullptr) {
257        LOG("localtime errno ");
258        ADD_FAILURE();
259    }
260    size_t ftime = strftime(buffer, sizeof(buffer) - 1, "%Ex %EX %A", localTime);
261    EXPECT_GT(ftime, g_zero) << "strftime return error!";
262    EXPECT_STREQ(buffer, "01/01/70 05:14:40 Thursday") << "buffer return error!";
263
264    mtime = LONG_MAX;
265    localTime = localtime(&mtime);
266    ASSERT_NE(nullptr, localTime);
267    ftime = strftime(buffer, sizeof(buffer) - 1, "%y-%m-%d %H:%M:%S", localTime);
268    EXPECT_STREQ(buffer, "38-01-19 03:14:07") << "buffer return error!";
269
270    mtime = 253402300799;
271    localTime = localtime(&mtime);
272    ASSERT_NE(nullptr, localTime);
273    ftime = strftime(buffer, sizeof(buffer) - 1, "%Y-%m-%d %H:%M:%S", localTime);
274    EXPECT_STREQ(buffer, "9999-12-31 23:59:59") << "buffer return error!";
275
276    mtime = LONG_MIN;
277    localTime = localtime(&mtime);
278    ASSERT_NE(nullptr, localTime);
279    ftime = strftime(buffer, sizeof(buffer) - 1, "%x %X", localTime);
280    EXPECT_STREQ(buffer, "12/13/01 20:45:52") << "buffer return error!";
281
282    ftime = strftime(buffer, sizeof(buffer) - 1, "%Y-%m-%d %H:%M:%S", localTime);
283    EXPECT_EQ(ftime, strftimeBytes) << "strftime return error!";
284    EXPECT_STREQ(buffer, "1901-12-13 20:45:52") << "buffer return error!";
285}
286
287/**
288* @tc.number     SUB_KERNEL_TIME_API_STRFTIMEL_0100
289* @tc.name       test strftime_l api
290* @tc.desc       [C- SOFTWARE -0200]
291*/
292HWTEST_F(TimeUtilsTest, testStrftimeL, Function | MediumTest | Level2)
293{
294    struct tm *tm1;
295    char buffer[80] = {0};
296
297    tm1 = localtime(&g_time);
298    ASSERT_NE(nullptr, tm1);
299    size_t ftime = strftime_l(buffer, sizeof(buffer) - 1, "%F %T %Z", tm1, nullptr);
300    EXPECT_GT(ftime, g_zero) << "strftime return error!";
301    EXPECT_STREQ(buffer, "1970-01-01 05:14:40 UTC") << "buffer return error!";
302}
303
304/**
305* @tc.number     SUB_KERNEL_TIME_API_WCSFTIME_0100
306* @tc.name       test wcsftime api
307* @tc.desc       [C- SOFTWARE -0200]
308*/
309HWTEST_F(TimeUtilsTest, testWcsftime, Function | MediumTest | Level2)
310{
311    size_t wcsftimeBytes = 33;
312    wchar_t buff[48] = {0};
313    struct tm *localTime = localtime(&g_time);
314    ASSERT_NE(nullptr, localTime);
315    size_t len = wcsftime(buff, sizeof(buff) - 1, L"%A %c", localTime);
316    LOG("buff = %ls, len = %ld\n", buff, (long)len);
317    EXPECT_EQ(len, wcsftimeBytes) << "wcsftime return error!";
318    EXPECT_STREQ(buff, L"Thursday Thu Jan  1 05:14:40 1970") << "buff return error!";
319
320    localTime = localtime(&g_time);
321    ASSERT_NE(nullptr, localTime);
322    len = wcsftime(buff, sizeof(buff) - 1, L"%A %c", localTime);
323    LOG("buff = %ls, len = %ld\n", buff, (long)len);
324    EXPECT_EQ(len, wcsftimeBytes) << "wcsftime return error!";
325    EXPECT_STREQ(buff, L"Thursday Thu Jan  1 05:14:40 1970") << "buff return error!";
326}
327