1 /*	$NetBSD: clocktime.c,v 1.2 2020/05/25 20:47:36 christos Exp $	*/
2 
3 #include "config.h"
4 
5 #include "ntp_calendar.h"
6 #include "ntp_stdlib.h"
7 
8 #include "unity.h"
9 #include "test-libntp.h"
10 
11 void setUp(void);
12 void tearDown(void);
13 void test_CurrentYear(void);
14 void test_CurrentYearFuzz(void);
15 void test_TimeZoneOffset(void);
16 void test_WrongYearStart(void);
17 void test_PreviousYear(void);
18 void test_NextYear(void);
19 void test_NoReasonableConversion(void);
20 int isLE(u_int32 diff,u_int32 actual);
21 void test_AlwaysInLimit(void);
22 
23 
24 /* ---------------------------------------------------------------------
25  * test fixture
26  *
27  * The clocktimeTest uses the NTP calendar feature to use a mockup
28  * function for getting the current system time, so the tests are not
29  * dependent on the actual system time.
30  */
31 
32 void
setUp()33 setUp()
34 {
35 	ntpcal_set_timefunc(timefunc);
36 	settime(2000, 1, 1, 0, 0, 0);
37 
38 	return;
39 }
40 
41 void
tearDown()42 tearDown()
43 {
44 	ntpcal_set_timefunc(NULL);
45 
46 	return;
47 }
48 
49 /* ---------------------------------------------------------------------
50  * test cases
51  */
52 
53 void
test_CurrentYear(void)54 test_CurrentYear(void)
55 {
56 	/* Timestamp: 2010-06-24 12:50:00Z */
57 	const u_int32 timestamp = 3486372600UL;
58 	const u_int32 expected	= timestamp; /* exactly the same. */
59 
60 	const int yday=175, hour=12, minute=50, second=0, tzoff=0;
61 
62 	u_long yearstart = 0;
63 	u_int32 actual;
64 
65 	TEST_ASSERT_TRUE(clocktime(yday, hour, minute, second, tzoff,
66 				   timestamp, &yearstart, &actual));
67 	TEST_ASSERT_EQUAL(expected, actual);
68 
69 	return;
70 }
71 
72 void
test_CurrentYearFuzz(void)73 test_CurrentYearFuzz(void)
74 {
75 	/*
76 	 * Timestamp (rec_ui) is: 2010-06-24 12:50:00
77 	 * Time sent into function is 12:00:00.
78 	 *
79 	 * Since the fuzz is rather small, we should get a NTP
80 	 * timestamp for the 12:00:00 time.
81 	 */
82 
83 	const u_int32 timestamp = 3486372600UL; /* 2010-06-24 12:50:00Z */
84 	const u_int32 expected	= 3486369600UL; /* 2010-06-24 12:00:00Z */
85 
86 	const int yday=175, hour=12, minute=0, second=0, tzoff=0;
87 
88 	u_long yearstart=0;
89 	u_int32 actual;
90 
91 	TEST_ASSERT_TRUE(clocktime(yday, hour, minute, second, tzoff,
92 				   timestamp, &yearstart, &actual));
93 	TEST_ASSERT_EQUAL(expected, actual);
94 
95 	return;
96 }
97 
98 void
test_TimeZoneOffset(void)99 test_TimeZoneOffset(void)
100 {
101 	/*
102 	 * Timestamp (rec_ui) is: 2010-06-24 12:00:00 +0800
103 	 * (which is 2010-06-24 04:00:00Z)
104 	 *
105 	 * Time sent into function is 04:00:00 +0800
106 	 */
107 	const u_int32 timestamp = 3486369600UL;
108 	const u_int32 expected	= timestamp;
109 
110 	const int yday=175, hour=4, minute=0, second=0, tzoff=8;
111 
112 	u_long yearstart=0;
113 	u_int32 actual;
114 
115 	TEST_ASSERT_TRUE(clocktime(yday, hour, minute, second, tzoff, timestamp,
116 						  &yearstart, &actual));
117 	TEST_ASSERT_EQUAL(expected, actual);
118 }
119 
120 void
test_WrongYearStart(void)121 test_WrongYearStart(void)
122 {
123 	/*
124 	 * Timestamp (rec_ui) is: 2010-01-02 11:00:00Z
125 	 * Time sent into function is 11:00:00.
126 	 * Yearstart sent into function is the yearstart of 2009!
127 	 */
128 	const u_int32 timestamp = 3471418800UL;
129 	const u_int32 expected	= timestamp;
130 
131 	const int yday=2, hour=11, minute=0, second=0, tzoff=0;
132 
133 	u_long yearstart = 302024100UL; /* Yearstart of 2009. */
134 	u_int32 actual;
135 
136 	TEST_ASSERT_TRUE(clocktime(yday, hour, minute, second, tzoff, timestamp,
137 						  &yearstart, &actual));
138 	TEST_ASSERT_EQUAL(expected, actual);
139 }
140 
141 void
test_PreviousYear(void)142 test_PreviousYear(void)
143 {
144 	/*
145 	 * Timestamp is: 2010-01-01 01:00:00Z
146 	 * Time sent into function is 23:00:00
147 	 * (which is meant to be 2009-12-31 23:00:00Z)
148 	 */
149 	const u_int32 timestamp = 3471296400UL;
150 	const u_int32 expected	= 3471289200UL;
151 
152 	const int yday=365, hour=23, minute=0, second=0, tzoff=0;
153 
154 	u_long yearstart = 0;
155 	u_int32 actual;
156 
157 	TEST_ASSERT_TRUE(clocktime(yday, hour, minute, second, tzoff, timestamp,
158 						  &yearstart, &actual));
159 	TEST_ASSERT_EQUAL(expected, actual);
160 }
161 
162 void
test_NextYear(void)163 test_NextYear(void)
164 {
165 	/*
166 	 * Timestamp is: 2009-12-31 23:00:00Z
167 	 * Time sent into function is 01:00:00
168 	 * (which is meant to be 2010-01-01 01:00:00Z)
169 	 */
170 	const u_int32 timestamp = 3471289200UL;
171 	const u_int32 expected	= 3471296400UL;
172 
173 	const int yday=1, hour=1, minute=0, second=0, tzoff=0;
174 	u_long yearstart = 0;
175 	u_int32 actual;
176 
177 	TEST_ASSERT_TRUE(clocktime(yday, hour, minute, second, tzoff,
178 				   timestamp, &yearstart, &actual));
179 	TEST_ASSERT_EQUAL(expected, actual);
180 
181 	return;
182 }
183 
184 void
test_NoReasonableConversion(void)185 test_NoReasonableConversion(void)
186 {
187 	/* Timestamp is: 2010-01-02 11:00:00Z */
188 	const u_int32 timestamp = 3471418800UL;
189 
190 	const int yday=100, hour=12, minute=0, second=0, tzoff=0;
191 	u_long yearstart = 0;
192 	u_int32 actual;
193 
194 	TEST_ASSERT_FALSE(clocktime(yday, hour, minute, second, tzoff,
195 				    timestamp, &yearstart, &actual));
196 
197 	return;
198 }
199 
200 
201 int/*BOOL*/
isLE(u_int32 diff,u_int32 actual)202 isLE(u_int32 diff,u_int32 actual)
203 {
204 
205 	if (diff <= actual) {
206 		return TRUE;
207 	}
208 	else return FALSE;
209 }
210 
211 
212 void
test_AlwaysInLimit(void)213 test_AlwaysInLimit(void)
214 {
215 	/* Timestamp is: 2010-01-02 11:00:00Z */
216 	const u_int32 timestamp = 3471418800UL;
217 	const u_short prime_incs[] = { 127, 151, 163, 179 };
218 	int	cyc;
219 	int	yday;
220 	u_char	whichprime;
221 	u_short	ydayinc;
222 	int	hour;
223 	int	minute;
224 	u_long	yearstart;
225 	u_int32	actual;
226 	u_int32	diff;
227 
228 	yearstart = 0;
229 	for (cyc = 0; cyc < 5; cyc++) {
230 		settime(1900 + cyc * 65, 1, 1, 0, 0, 0);
231 		for (yday = -26000; yday < 26000; yday += ydayinc) {
232 			whichprime = abs(yday) % COUNTOF(prime_incs);
233 			ydayinc = prime_incs[whichprime];
234 			for (hour = -204; hour < 204; hour += 2) {
235 				for (minute = -60; minute < 60; minute++) {
236 					clocktime(yday, hour, minute, 30, 0,
237 						  timestamp, &yearstart,
238 						  &actual);
239 					diff = actual - timestamp;
240 					if (diff >= 0x80000000UL)
241 						diff = ~diff + 1;
242 					TEST_ASSERT_TRUE(isLE(diff, (183u * SECSPERDAY)));
243 				}
244 			}
245 		}
246 	}
247 	return;
248 }
249