blob: a205692d6654743a0b273c2e3749b1f468c18b35 [file] [log] [blame]
Jakub Czapigaa37c8022021-04-15 11:39:13 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <inttypes.h>
4#include <rtc.h>
5#include <string.h>
6#include <tests/test.h>
7
8static void test_rtc_to_tm_from_unix_time(void **state)
9{
10 struct rtc_time tm;
11 int tim;
12
13 /* Zero-day */
14 tim = 0;
15 assert_int_equal(0, rtc_to_tm(tim, &tm));
16 assert_int_equal(1970, tm.year);
17 assert_int_equal(1, tm.mon);
18 assert_int_equal(1, tm.mday);
19 assert_int_equal(0, tm.hour);
20 assert_int_equal(0, tm.min);
21 assert_int_equal(0, tm.sec);
22 assert_int_equal(4, tm.wday); /* Thursday */
23
24 /* One second from time base */
25 tim = 1;
26 assert_int_equal(0, rtc_to_tm(tim, &tm));
27 assert_int_equal(1970, tm.year);
28 assert_int_equal(1, tm.mon);
29 assert_int_equal(1, tm.mday);
30 assert_int_equal(0, tm.hour);
31 assert_int_equal(0, tm.min);
32 assert_int_equal(1, tm.sec);
33 assert_int_equal(4, tm.wday); /* Thursday */
34
35 /* Full time value */
36 tim = INT32_MAX;
37 assert_int_equal(0, rtc_to_tm(tim, &tm));
38 assert_int_equal(2038, tm.year);
39 assert_int_equal(1, tm.mon);
40 assert_int_equal(19, tm.mday);
41 assert_int_equal(3, tm.hour);
42 assert_int_equal(14, tm.min);
43 assert_int_equal(7, tm.sec);
44 assert_int_equal(2, tm.wday); /* Tuesday */
45
46 /* Other common value */
47 tim = 1618484725;
48 assert_int_equal(0, rtc_to_tm(tim, &tm));
49 assert_int_equal(2021, tm.year);
50 assert_int_equal(4, tm.mon);
51 assert_int_equal(15, tm.mday);
52 assert_int_equal(11, tm.hour);
53 assert_int_equal(5, tm.min);
54 assert_int_equal(25, tm.sec);
55 assert_int_equal(4, tm.wday); /* Thursday */
56
57 /* Negative value - expect incorrect output */
58 tim = -1;
59 assert_int_equal(0, rtc_to_tm(tim, &tm));
60 assert_int_equal(1970, tm.year);
61 assert_int_equal(1, tm.mon);
62 assert_int_equal(1, tm.mday);
63 assert_int_equal(0, tm.hour);
64 assert_int_equal(0, tm.min);
65 assert_int_equal(-1, tm.sec);
66 assert_int_equal(4, tm.wday); /* Thursday */
67}
68
69static void test_mktime(void **state)
70{
71 struct rtc_time tm;
72 struct rtc_time tm2;
73 memset(&tm, 0, sizeof(tm));
74 memset(&tm2, 0, sizeof(tm2));
75
76 /* Epoch start */
77 tm = (struct rtc_time){
78 .year = 1970, .mon = 1, .mday = 1, .hour = 0, .min = 0, .sec = 0,
79 };
80 assert_int_equal(0, rtc_mktime(&tm));
81
82 /* Last correct value */
83 tm = (struct rtc_time){
84 .year = 2038, .mon = 1, .mday = 19, .hour = 3, .min = 14, .sec = 7,
85 };
86 assert_int_equal(INT32_MAX, rtc_mktime(&tm));
87
88 /* Common non-leap year */
89 tm = (struct rtc_time){
90 .year = 1999, .mon = 12, .mday = 6, .hour = 16, .min = 13, .sec = 59,
91 };
92 assert_int_equal(944496839, rtc_mktime(&tm));
93
94 /* Ensure that February 29 gives the same result as March 1 in non-leap year */
95 tm = (struct rtc_time){
96 .year = 2017, .mon = 2, .mday = 29, .hour = 1, .min = 2, .sec = 3,
97 };
98 tm2 = (struct rtc_time){
99 .year = 2017, .mon = 3, .mday = 1, .hour = 1, .min = 2, .sec = 3,
100 };
101 assert_int_equal(rtc_mktime(&tm), rtc_mktime(&tm2));
102
103 /* Leap year (only division by 4 rule applies) */
104 tm = (struct rtc_time){
105 .year = 2004, .mon = 8, .mday = 30, .hour = 13, .min = 45, .sec = 33,
106 };
107 assert_int_equal(1093873533, rtc_mktime(&tm));
108 /* Last day of February in leap year */
109 tm.mon = 2;
110 tm.mday = 29;
111 assert_int_equal(1078062333, rtc_mktime(&tm));
Alexander Goncharov893c3ae82023-02-04 15:20:37 +0400112 /* Ensure that February 29 and March 1 have different and correct values
Jakub Czapigaa37c8022021-04-15 11:39:13 +0200113 in leap year */
114 tm = (struct rtc_time){
115 .year = 2004, .mon = 3, .mday = 1, .hour = 7, .min = 7, .sec = 17,
116 };
117 tm2 = (struct rtc_time){
118 .year = 2004, .mon = 2, .mday = 29, .hour = 7, .min = 7, .sec = 17,
119 };
120 /* There should be exactly one day of difference */
121 assert_int_equal(24 * 60 * 60, rtc_mktime(&tm) - rtc_mktime(&tm2));
122
123 /* Leap year (division by 400 rule applies and division by 100 is excluded) */
124 tm = (struct rtc_time){
125 .year = 2000, .mon = 6, .mday = 11, .hour = 21, .min = 3, .sec = 6,
126 };
127 assert_int_equal(960757386, rtc_mktime(&tm));
128 tm.mon = 2;
129 tm.mday = 29;
130 assert_int_equal(951858186, rtc_mktime(&tm));
131
132 tm = (struct rtc_time){
133 .year = 2000, .mon = 3, .mday = 1, .hour = 10, .min = 55, .sec = 21,
134 };
135 tm2 = (struct rtc_time){
136 .year = 2000, .mon = 2, .mday = 29, .hour = 10, .min = 55, .sec = 21,
137 };
138 assert_int_equal(24 * 60 * 60, rtc_mktime(&tm) - rtc_mktime(&tm2));
139}
140
141static void assert_rtc_time_equal(struct rtc_time *tm1, struct rtc_time *tm2)
142{
143 assert_int_equal(tm1->sec, tm2->sec);
144 assert_int_equal(tm1->min, tm2->min);
145 assert_int_equal(tm1->hour, tm2->hour);
146 assert_int_equal(tm1->mday, tm2->mday);
147 assert_int_equal(tm1->mon, tm2->mon);
148 assert_int_equal(tm1->year, tm2->year);
149 assert_int_equal(tm1->wday, tm2->wday);
150}
151
152/* This test check if combination of rtc_to_tm and rtc_mktime gives result equal to input.
153 Week day is ignored by rtc_mktime, but is calculated by rtc_to_tm, so it is included
154 in input. */
155static void test_rtc_mktime_with_rtc_to_tm(void **state)
156{
157 struct rtc_time tm_in;
158 struct rtc_time tm_out;
159 int tim;
160
161 memset(&tm_in, 0, sizeof(tm_in));
162 memset(&tm_out, 0, sizeof(tm_out));
163
164 /* Conversion from rtc_time to timestamp and back to rtc_time */
165 tm_in = (struct rtc_time){
Jakub Czapigac08b6a72022-01-10 13:36:47 +0000166 .year = 1970, .mon = 1, .mday = 1, .hour = 0, .min = 0, .sec = 0, .wday = 4,
Jakub Czapigaa37c8022021-04-15 11:39:13 +0200167 };
168 assert_int_equal(0, rtc_to_tm(rtc_mktime(&tm_in), &tm_out));
169 assert_rtc_time_equal(&tm_in, &tm_out);
170
171 tm_in = (struct rtc_time){
Jakub Czapigac08b6a72022-01-10 13:36:47 +0000172 .year = 2000, .mon = 2, .mday = 29, .hour = 13, .min = 4, .sec = 15, .wday = 2,
Jakub Czapigaa37c8022021-04-15 11:39:13 +0200173 };
174 assert_int_equal(0, rtc_to_tm(rtc_mktime(&tm_in), &tm_out));
175 assert_rtc_time_equal(&tm_in, &tm_out);
176
177 tm_in = (struct rtc_time){
Jakub Czapigac08b6a72022-01-10 13:36:47 +0000178 .year = 2000, .mon = 3, .mday = 1, .hour = 13, .min = 8, .sec = 37, .wday = 3,
Jakub Czapigaa37c8022021-04-15 11:39:13 +0200179 };
180 assert_int_equal(0, rtc_to_tm(rtc_mktime(&tm_in), &tm_out));
181 assert_rtc_time_equal(&tm_in, &tm_out);
182
183 tm_in = (struct rtc_time){
Jakub Czapigac08b6a72022-01-10 13:36:47 +0000184 .year = 2017, .mon = 12, .mday = 7, .hour = 8, .min = 18, .sec = 9, .wday = 4,
Jakub Czapigaa37c8022021-04-15 11:39:13 +0200185 };
186 assert_int_equal(0, rtc_to_tm(rtc_mktime(&tm_in), &tm_out));
187 assert_rtc_time_equal(&tm_in, &tm_out);
188
189 tm_in = (struct rtc_time){
Jakub Czapigac08b6a72022-01-10 13:36:47 +0000190 .year = 2020, .mon = 2, .mday = 29, .hour = 18, .min = 50, .sec = 0, .wday = 6,
Jakub Czapigaa37c8022021-04-15 11:39:13 +0200191 };
192 assert_int_equal(0, rtc_to_tm(rtc_mktime(&tm_in), &tm_out));
193 assert_rtc_time_equal(&tm_in, &tm_out);
194
195 tm_in = (struct rtc_time){
Jakub Czapigac08b6a72022-01-10 13:36:47 +0000196 .year = 2020, .mon = 3, .mday = 1, .hour = 1, .min = 20, .sec = 23, .wday = 0,
Jakub Czapigaa37c8022021-04-15 11:39:13 +0200197 };
198 assert_int_equal(0, rtc_to_tm(rtc_mktime(&tm_in), &tm_out));
199 assert_rtc_time_equal(&tm_in, &tm_out);
200
201
202 /* Conversion from timestamp to rtc_time and back to timestamp */
203 tim = 0;
204 rtc_to_tm(tim, &tm_out);
205 assert_int_equal(tim, rtc_mktime(&tm_out));
206
207 tim = INT32_MAX;
208 rtc_to_tm(tim, &tm_out);
209 assert_int_equal(tim, rtc_mktime(&tm_out));
210
211 /* 2000-02-29 1:23:34 */
212 tim = 951787414;
213 rtc_to_tm(tim, &tm_out);
214 assert_int_equal(tim, rtc_mktime(&tm_out));
215
216 /* 2000-03-01 1:23:34 */
217 tim = 951873814;
218 rtc_to_tm(tim, &tm_out);
219 assert_int_equal(tim, rtc_mktime(&tm_out));
220
221 /* 1999-09-09 9:09:09 */
222 tim = 936868149;
223 rtc_to_tm(tim, &tm_out);
224 assert_int_equal(tim, rtc_mktime(&tm_out));
225
226 /* 2020-02-29 2:29:02 */
227 tim = 1582943342;
228 rtc_to_tm(tim, &tm_out);
229 assert_int_equal(tim, rtc_mktime(&tm_out));
230
231 /* 2020-03-01 3:01:03 */
232 tim = 1583031663;
233 rtc_to_tm(tim, &tm_out);
234 assert_int_equal(tim, rtc_mktime(&tm_out));
235}
236
237static void test_leap_day_secday(void **state)
238{
239 const int secday = 60 * 60 * 24;
240 struct rtc_time tm_in;
241 struct rtc_time tm_out;
242 struct rtc_time tm_expected;
243 int tim;
244
245 memset(&tm_in, 0, sizeof(tm_in));
246 memset(&tm_out, 0, sizeof(tm_out));
247
248 /* Non-leap year */
Jakub Czapigac08b6a72022-01-10 13:36:47 +0000249 tm_in = (struct rtc_time){
250 .year = 1999, .mon = 2, .mday = 28, .hour = 5, .min = 37, .sec = 15, .wday = 0,
Jakub Czapigaa37c8022021-04-15 11:39:13 +0200251 };
252 tim = rtc_mktime(&tm_in) + secday;
Jakub Czapigac08b6a72022-01-10 13:36:47 +0000253 tm_expected = (struct rtc_time){
254 .year = 1999, .mon = 3, .mday = 1, .hour = 5, .min = 37, .sec = 15, .wday = 1,
Jakub Czapigaa37c8022021-04-15 11:39:13 +0200255 };
256 assert_int_equal(0, rtc_to_tm(tim, &tm_out));
257 assert_rtc_time_equal(&tm_out, &tm_expected);
258
259 /* Leap-year February 28 to February 29 */
Jakub Czapigac08b6a72022-01-10 13:36:47 +0000260 tm_in = (struct rtc_time){
Jakub Czapigaa37c8022021-04-15 11:39:13 +0200261 .year = 2000, .mon = 2, .mday = 28, .hour = 0, .min = 33, .sec = 11, .wday = 1,
262 };
263 tim = rtc_mktime(&tm_in) + secday;
Jakub Czapigac08b6a72022-01-10 13:36:47 +0000264 tm_expected = (struct rtc_time){
Jakub Czapigaa37c8022021-04-15 11:39:13 +0200265 .year = 2000, .mon = 2, .mday = 29, .hour = 0, .min = 33, .sec = 11, .wday = 2,
266 };
267 assert_int_equal(0, rtc_to_tm(tim, &tm_out));
268 assert_rtc_time_equal(&tm_out, &tm_expected);
269
Jakub Czapigac08b6a72022-01-10 13:36:47 +0000270 tm_in = (struct rtc_time){
Jakub Czapigaa37c8022021-04-15 11:39:13 +0200271 .year = 2004, .mon = 2, .mday = 28, .hour = 9, .min = 13, .sec = 45, .wday = 6,
272 };
273 tim = rtc_mktime(&tm_in) + secday;
Jakub Czapigac08b6a72022-01-10 13:36:47 +0000274 tm_expected = (struct rtc_time){
Jakub Czapigaa37c8022021-04-15 11:39:13 +0200275 .year = 2004, .mon = 2, .mday = 29, .hour = 9, .min = 13, .sec = 45, .wday = 0,
276 };
277 assert_int_equal(0, rtc_to_tm(tim, &tm_out));
278 assert_rtc_time_equal(&tm_out, &tm_expected);
279
280 /* Leap-year February 29 to March 1 */
Jakub Czapigac08b6a72022-01-10 13:36:47 +0000281 tm_in = (struct rtc_time){
Jakub Czapigaa37c8022021-04-15 11:39:13 +0200282 .year = 2000, .mon = 2, .mday = 29, .hour = 22, .min = 50, .sec = 25, .wday = 2,
283 };
284 tim = rtc_mktime(&tm_in) + secday;
Jakub Czapigac08b6a72022-01-10 13:36:47 +0000285 tm_expected = (struct rtc_time){
Jakub Czapigaa37c8022021-04-15 11:39:13 +0200286 .year = 2000, .mon = 3, .mday = 1, .hour = 22, .min = 50, .sec = 25, .wday = 3,
287 };
288 assert_int_equal(0, rtc_to_tm(tim, &tm_out));
289 assert_rtc_time_equal(&tm_out, &tm_expected);
290
Jakub Czapigac08b6a72022-01-10 13:36:47 +0000291 tm_in = (struct rtc_time){
Jakub Czapigaa37c8022021-04-15 11:39:13 +0200292 .year = 2004, .mon = 2, .mday = 29, .hour = 17, .min = 56, .sec = 27, .wday = 0,
293 };
294 tim = rtc_mktime(&tm_in) + secday;
Jakub Czapigac08b6a72022-01-10 13:36:47 +0000295 tm_expected = (struct rtc_time){
Jakub Czapigaa37c8022021-04-15 11:39:13 +0200296 .year = 2004, .mon = 3, .mday = 1, .hour = 17, .min = 56, .sec = 27, .wday = 1,
297 };
298 assert_int_equal(0, rtc_to_tm(tim, &tm_out));
299 assert_rtc_time_equal(&tm_out, &tm_expected);
300}
301
302int main(void)
303{
304 const struct CMUnitTest tests[] = {
305 cmocka_unit_test(test_rtc_to_tm_from_unix_time),
306 cmocka_unit_test(test_mktime),
307 cmocka_unit_test(test_rtc_mktime_with_rtc_to_tm),
308 cmocka_unit_test(test_leap_day_secday),
309 };
310
Jakub Czapiga7c6081e2021-08-25 16:27:35 +0200311 return cb_run_group_tests(tests, NULL, NULL);
Jakub Czapigaa37c8022021-04-15 11:39:13 +0200312}