1290001Sglebius#include "config.h"
2290001Sglebius
3290001Sglebius#include "ntp_calendar.h"
4290001Sglebius#include "ntp_stdlib.h"
5290001Sglebius
6290001Sglebius#include "unity.h"
7290001Sglebius#include "test-libntp.h"
8290001Sglebius
9290001Sglebiusvoid setUp(void);
10290001Sglebiusvoid tearDown(void);
11290001Sglebiusvoid test_CurrentYear(void);
12290001Sglebiusvoid test_CurrentYearFuzz(void);
13290001Sglebiusvoid test_TimeZoneOffset(void);
14290001Sglebiusvoid test_WrongYearStart(void);
15290001Sglebiusvoid test_PreviousYear(void);
16290001Sglebiusvoid test_NextYear(void);
17290001Sglebiusvoid test_NoReasonableConversion(void);
18290001Sglebiusint isLE(u_int32 diff,u_int32 actual);
19290001Sglebiusvoid test_AlwaysInLimit(void);
20290001Sglebius
21290001Sglebius
22290001Sglebius/* ---------------------------------------------------------------------
23290001Sglebius * test fixture
24290001Sglebius *
25290001Sglebius * The clocktimeTest uses the NTP calendar feature to use a mockup
26290001Sglebius * function for getting the current system time, so the tests are not
27290001Sglebius * dependent on the actual system time.
28290001Sglebius */
29290001Sglebius
30290001Sglebiusvoid
31290001SglebiussetUp()
32290001Sglebius{
33293896Sglebius	ntpcal_set_timefunc(timefunc);
34293896Sglebius	settime(2000, 1, 1, 0, 0, 0);
35293896Sglebius
36293896Sglebius	return;
37290001Sglebius}
38290001Sglebius
39290001Sglebiusvoid
40290001SglebiustearDown()
41290001Sglebius{
42293896Sglebius	ntpcal_set_timefunc(NULL);
43293896Sglebius
44293896Sglebius	return;
45290001Sglebius}
46290001Sglebius
47290001Sglebius/* ---------------------------------------------------------------------
48290001Sglebius * test cases
49290001Sglebius */
50290001Sglebius
51290001Sglebiusvoid
52293896Sglebiustest_CurrentYear(void)
53293896Sglebius{
54290001Sglebius	/* Timestamp: 2010-06-24 12:50:00Z */
55290001Sglebius	const u_int32 timestamp = 3486372600UL;
56290001Sglebius	const u_int32 expected	= timestamp; /* exactly the same. */
57290001Sglebius
58290001Sglebius	const int yday=175, hour=12, minute=50, second=0, tzoff=0;
59290001Sglebius
60293896Sglebius	u_long yearstart = 0;
61290001Sglebius	u_int32 actual;
62290001Sglebius
63293896Sglebius	TEST_ASSERT_TRUE(clocktime(yday, hour, minute, second, tzoff,
64293896Sglebius				   timestamp, &yearstart, &actual));
65290001Sglebius	TEST_ASSERT_EQUAL(expected, actual);
66293896Sglebius
67293896Sglebius	return;
68290001Sglebius}
69290001Sglebius
70290001Sglebiusvoid
71293896Sglebiustest_CurrentYearFuzz(void)
72293896Sglebius{
73290001Sglebius	/*
74290001Sglebius	 * Timestamp (rec_ui) is: 2010-06-24 12:50:00
75290001Sglebius	 * Time sent into function is 12:00:00.
76290001Sglebius	 *
77290001Sglebius	 * Since the fuzz is rather small, we should get a NTP
78290001Sglebius	 * timestamp for the 12:00:00 time.
79290001Sglebius	 */
80290001Sglebius
81290001Sglebius	const u_int32 timestamp = 3486372600UL; /* 2010-06-24 12:50:00Z */
82290001Sglebius	const u_int32 expected	= 3486369600UL; /* 2010-06-24 12:00:00Z */
83290001Sglebius
84290001Sglebius	const int yday=175, hour=12, minute=0, second=0, tzoff=0;
85290001Sglebius
86290001Sglebius	u_long yearstart=0;
87290001Sglebius	u_int32 actual;
88290001Sglebius
89293896Sglebius	TEST_ASSERT_TRUE(clocktime(yday, hour, minute, second, tzoff,
90293896Sglebius				   timestamp, &yearstart, &actual));
91290001Sglebius	TEST_ASSERT_EQUAL(expected, actual);
92293896Sglebius
93293896Sglebius	return;
94290001Sglebius}
95290001Sglebius
96290001Sglebiusvoid
97293896Sglebiustest_TimeZoneOffset(void)
98293896Sglebius{
99290001Sglebius	/*
100290001Sglebius	 * Timestamp (rec_ui) is: 2010-06-24 12:00:00 +0800
101290001Sglebius	 * (which is 2010-06-24 04:00:00Z)
102290001Sglebius	 *
103290001Sglebius	 * Time sent into function is 04:00:00 +0800
104290001Sglebius	 */
105290001Sglebius	const u_int32 timestamp = 3486369600UL;
106290001Sglebius	const u_int32 expected	= timestamp;
107290001Sglebius
108290001Sglebius	const int yday=175, hour=4, minute=0, second=0, tzoff=8;
109290001Sglebius
110290001Sglebius	u_long yearstart=0;
111290001Sglebius	u_int32 actual;
112290001Sglebius
113290001Sglebius	TEST_ASSERT_TRUE(clocktime(yday, hour, minute, second, tzoff, timestamp,
114290001Sglebius						  &yearstart, &actual));
115290001Sglebius	TEST_ASSERT_EQUAL(expected, actual);
116290001Sglebius}
117290001Sglebius
118290001Sglebiusvoid
119293896Sglebiustest_WrongYearStart(void)
120293896Sglebius{
121290001Sglebius	/*
122290001Sglebius	 * Timestamp (rec_ui) is: 2010-01-02 11:00:00Z
123290001Sglebius	 * Time sent into function is 11:00:00.
124290001Sglebius	 * Yearstart sent into function is the yearstart of 2009!
125290001Sglebius	 */
126290001Sglebius	const u_int32 timestamp = 3471418800UL;
127290001Sglebius	const u_int32 expected	= timestamp;
128290001Sglebius
129290001Sglebius	const int yday=2, hour=11, minute=0, second=0, tzoff=0;
130290001Sglebius
131290001Sglebius	u_long yearstart = 302024100UL; /* Yearstart of 2009. */
132290001Sglebius	u_int32 actual;
133290001Sglebius
134290001Sglebius	TEST_ASSERT_TRUE(clocktime(yday, hour, minute, second, tzoff, timestamp,
135290001Sglebius						  &yearstart, &actual));
136290001Sglebius	TEST_ASSERT_EQUAL(expected, actual);
137290001Sglebius}
138290001Sglebius
139290001Sglebiusvoid
140293896Sglebiustest_PreviousYear(void)
141293896Sglebius{
142290001Sglebius	/*
143290001Sglebius	 * Timestamp is: 2010-01-01 01:00:00Z
144290001Sglebius	 * Time sent into function is 23:00:00
145290001Sglebius	 * (which is meant to be 2009-12-31 23:00:00Z)
146290001Sglebius	 */
147290001Sglebius	const u_int32 timestamp = 3471296400UL;
148290001Sglebius	const u_int32 expected	= 3471289200UL;
149290001Sglebius
150290001Sglebius	const int yday=365, hour=23, minute=0, second=0, tzoff=0;
151290001Sglebius
152290001Sglebius	u_long yearstart = 0;
153290001Sglebius	u_int32 actual;
154290001Sglebius
155290001Sglebius	TEST_ASSERT_TRUE(clocktime(yday, hour, minute, second, tzoff, timestamp,
156290001Sglebius						  &yearstart, &actual));
157290001Sglebius	TEST_ASSERT_EQUAL(expected, actual);
158290001Sglebius}
159290001Sglebius
160290001Sglebiusvoid
161293896Sglebiustest_NextYear(void)
162293896Sglebius{
163290001Sglebius	/*
164290001Sglebius	 * Timestamp is: 2009-12-31 23:00:00Z
165290001Sglebius	 * Time sent into function is 01:00:00
166290001Sglebius	 * (which is meant to be 2010-01-01 01:00:00Z)
167290001Sglebius	 */
168290001Sglebius	const u_int32 timestamp = 3471289200UL;
169290001Sglebius	const u_int32 expected	= 3471296400UL;
170290001Sglebius
171290001Sglebius	const int yday=1, hour=1, minute=0, second=0, tzoff=0;
172290001Sglebius	u_long yearstart = 0;
173290001Sglebius	u_int32 actual;
174290001Sglebius
175293896Sglebius	TEST_ASSERT_TRUE(clocktime(yday, hour, minute, second, tzoff,
176293896Sglebius				   timestamp, &yearstart, &actual));
177290001Sglebius	TEST_ASSERT_EQUAL(expected, actual);
178293896Sglebius
179293896Sglebius	return;
180290001Sglebius}
181290001Sglebius
182290001Sglebiusvoid
183293896Sglebiustest_NoReasonableConversion(void)
184293896Sglebius{
185290001Sglebius	/* Timestamp is: 2010-01-02 11:00:00Z */
186290001Sglebius	const u_int32 timestamp = 3471418800UL;
187293896Sglebius
188290001Sglebius	const int yday=100, hour=12, minute=0, second=0, tzoff=0;
189290001Sglebius	u_long yearstart = 0;
190290001Sglebius	u_int32 actual;
191290001Sglebius
192293896Sglebius	TEST_ASSERT_FALSE(clocktime(yday, hour, minute, second, tzoff,
193293896Sglebius				    timestamp, &yearstart, &actual));
194293896Sglebius
195293896Sglebius	return;
196290001Sglebius}
197290001Sglebius
198290001Sglebius
199290001Sglebiusint/*BOOL*/
200293896SglebiusisLE(u_int32 diff,u_int32 actual)
201293896Sglebius{
202293896Sglebius
203293896Sglebius	if (diff <= actual) {
204290001Sglebius		return TRUE;
205290001Sglebius	}
206290001Sglebius	else return FALSE;
207290001Sglebius}
208290001Sglebius
209290001Sglebius
210290001Sglebiusvoid
211293896Sglebiustest_AlwaysInLimit(void)
212293896Sglebius{
213290001Sglebius	/* Timestamp is: 2010-01-02 11:00:00Z */
214290001Sglebius	const u_int32 timestamp = 3471418800UL;
215290001Sglebius	const u_short prime_incs[] = { 127, 151, 163, 179 };
216290001Sglebius	int	cyc;
217290001Sglebius	int	yday;
218290001Sglebius	u_char	whichprime;
219290001Sglebius	u_short	ydayinc;
220290001Sglebius	int	hour;
221290001Sglebius	int	minute;
222290001Sglebius	u_long	yearstart;
223290001Sglebius	u_int32	actual;
224290001Sglebius	u_int32	diff;
225290001Sglebius
226290001Sglebius	yearstart = 0;
227290001Sglebius	for (cyc = 0; cyc < 5; cyc++) {
228290001Sglebius		settime(1900 + cyc * 65, 1, 1, 0, 0, 0);
229290001Sglebius		for (yday = -26000; yday < 26000; yday += ydayinc) {
230290001Sglebius			whichprime = abs(yday) % COUNTOF(prime_incs);
231290001Sglebius			ydayinc = prime_incs[whichprime];
232290001Sglebius			for (hour = -204; hour < 204; hour += 2) {
233290001Sglebius				for (minute = -60; minute < 60; minute++) {
234290001Sglebius					clocktime(yday, hour, minute, 30, 0,
235293896Sglebius						  timestamp, &yearstart,
236293896Sglebius						  &actual);
237290001Sglebius					diff = actual - timestamp;
238290001Sglebius					if (diff >= 0x80000000UL)
239290001Sglebius						diff = ~diff + 1;
240290001Sglebius					TEST_ASSERT_TRUE(isLE(diff, (183u * SECSPERDAY)));
241290001Sglebius				}
242290001Sglebius			}
243290001Sglebius		}
244290001Sglebius	}
245293896Sglebius	return;
246290001Sglebius}
247