1 #include "config.h"
2 #include "ntp_stdlib.h"
3 
4 #include "unity.h"
5 #include "unity_fixture.h"
6 
7 #include "ntp_calendar.h"
8 #include "caltime.h"
9 
10 TEST_GROUP(clocktime);
11 
12 // ---------------------------------------------------------------------
13 // test fixture
14 //
15 // The clocktimeTest uses the NTP calendar feature to use a mockup
16 // function for getting the current system time, so the tests are not
17 // dependent on the actual system time.
18 
19 static time_t fixedpivot;
20 
TEST_SETUP(clocktime)21 TEST_SETUP(clocktime) {
22 	fixedpivot = settime(2000, 1, 1, 0, 0, 0);
23 }
24 
TEST_TEAR_DOWN(clocktime)25 TEST_TEAR_DOWN(clocktime) {
26 }
27 
28 // ---------------------------------------------------------------------
29 // test cases
30 
TEST(clocktime,CurrentYear)31 TEST(clocktime, CurrentYear) {
32 	// Timestamp: 2010-06-24 12:50:00Z, no year passed in
33 	const uint32_t timestamp = 3486372600UL;
34 	const uint32_t expected	= timestamp; // exactly the same.
35 
36 	const int year=0, yday=175, hour=12, minute=50, second=0;
37 
38 	uint32_t yearstart=0;
39 	uint32_t actual;
40 
41 	TEST_ASSERT_TRUE(clocktime(year, yday, hour, minute, second,
42 				   fixedpivot, timestamp, &yearstart, &actual));
43 	TEST_ASSERT_EQUAL(expected, actual);
44 	TEST_ASSERT_EQUAL(yearstart, 3471292800);
45 }
46 
TEST(clocktime,CurrentYearExplicit)47 TEST(clocktime, CurrentYearExplicit) {
48 	// Timestamp: 2010-06-24 12:50:00Z, explicit year passed in
49 	const uint32_t timestamp = 3486372600UL;
50 	const uint32_t expected	= timestamp; // exactly the same.
51 
52 	const int year=2010, yday=175, hour=12, minute=50, second=0;
53 
54 	uint32_t yearstart=0;
55 	uint32_t actual;
56 
57 	TEST_ASSERT_TRUE(clocktime(year, yday, hour, minute, second,
58 				   fixedpivot, timestamp, &yearstart, &actual));
59 	/* If this assertion fails with "Expected 3486372600 was
60 	 * 104913720" that's a 32-bit integer overflow and your compiler
61 	 * is failing to cast to int properly inside clocktime.
62 	 * Observed on Mac OS X.
63 	 */
64 	TEST_ASSERT_EQUAL(expected, actual);
65 	TEST_ASSERT_EQUAL(yearstart, 3471292800);
66 }
67 
TEST(clocktime,CurrentYearFuzz)68 TEST(clocktime, CurrentYearFuzz) {
69 	/*
70 	 * Timestamp (rec_ui) is: 2010-06-24 12:50:00
71 	 * Time sent into function is 12:00:00.
72 	 *
73 	 * Since the fuzz is rather small, we should get a NTP
74 	 * timestamp for the 12:00:00 time.
75 	 */
76 
77 	const uint32_t timestamp = 3486372600UL; // 2010-06-24 12:50:00Z
78 	const uint32_t expected	= 3486369600UL; // 2010-06-24 12:00:00Z
79 
80 	const int year=0, yday=175, hour=12, minute=0, second=0;
81 
82 	uint32_t yearstart=0;
83 	uint32_t actual;
84 
85 	TEST_ASSERT_TRUE(clocktime(year, yday, hour, minute, second,
86 				   fixedpivot, timestamp, &yearstart, &actual));
87 	TEST_ASSERT_EQUAL(expected, actual);
88 }
89 
TEST(clocktime,WrongYearStart)90 TEST(clocktime, WrongYearStart) {
91 	/*
92 	 * Timestamp (rec_ui) is: 2010-01-02 11:00:00Z
93 	 * Time sent into function is 11:00:00.
94 	 * Yearstart sent into function is the yearstart of 2009!
95 	 */
96 	const uint32_t timestamp = 3471418800UL;
97 	const uint32_t expected	= timestamp;
98 
99 	const int year=0, yday=2, hour=11, minute=0, second=0;
100 
101 	uint32_t yearstart = 302024100UL; // Yearstart of 2009.
102 	uint32_t actual;
103 
104 	TEST_ASSERT_TRUE(clocktime(year, yday, hour, minute, second,
105 				   fixedpivot, timestamp, &yearstart, &actual));
106 	TEST_ASSERT_EQUAL(expected, actual);
107 }
108 
TEST(clocktime,PreviousYear)109 TEST(clocktime, PreviousYear) {
110 	/*
111 	 * Timestamp is: 2010-01-01 01:00:00Z
112 	 * Time sent into function is 23:00:00
113 	 * (which is meant to be 2009-12-31 23:00:00Z)
114 	 */
115 	const uint32_t timestamp = 3471296400UL;
116 	const uint32_t expected	= 3471289200UL;
117 
118 	const int year=0, yday=365, hour=23, minute=0, second=0;
119 
120 	uint32_t yearstart = 0;
121 	uint32_t actual;
122 
123 	TEST_ASSERT_TRUE(clocktime(year, yday, hour, minute, second,
124 				   fixedpivot, timestamp, &yearstart, &actual));
125 	TEST_ASSERT_EQUAL(expected, actual);
126 }
127 
TEST(clocktime,NextYear)128 TEST(clocktime, NextYear) {
129 	/*
130 	 * Timestamp is: 2009-12-31 23:00:00Z
131 	 * Time sent into function is 01:00:00
132 	 * (which is meant to be 2010-01-01 01:00:00Z)
133 	 */
134 	const uint32_t timestamp = 3471289200UL;
135 	const uint32_t expected	= 3471296400UL;
136 
137 	const int year=0, yday=1, hour=1, minute=0, second=0;
138 	uint32_t yearstart = 0;
139 	uint32_t actual;
140 
141 	TEST_ASSERT_TRUE(clocktime(year, yday, hour, minute, second,
142 				   fixedpivot, timestamp, &yearstart, &actual));
143 	TEST_ASSERT_EQUAL(expected, actual);
144 }
145 
TEST(clocktime,NoReasonableConversion)146 TEST(clocktime, NoReasonableConversion) {
147 	/* Timestamp is: 2010-01-02 11:00:00Z */
148 	const uint32_t timestamp = 3471418800UL;
149 
150 	const int year=0, yday=100, hour=12, minute=0, second=0;
151 	uint32_t yearstart = 0;
152 	uint32_t actual;
153 
154 	TEST_ASSERT_FALSE(clocktime(year, yday, hour, minute, second,
155 				    fixedpivot, timestamp, &yearstart, &actual));
156 }
157 
TEST(clocktime,AlwaysInLimit)158 TEST(clocktime, AlwaysInLimit) {
159 	/* Timestamp is: 2010-01-02 11:00:00Z */
160 	const uint32_t timestamp = 3471418800UL;
161 	const unsigned short prime_incs[] = { 127, 151, 163, 179 };
162 	int		cyc;
163 	int		yday;
164 	unsigned char	whichprime;
165 	unsigned short	ydayinc;
166 	int		hour;
167 	int		minute;
168 	uint32_t	yearstart;
169 	uint32_t	actual;
170 	uint32_t	diff;
171 
172 	yearstart = 0;
173 	for (cyc = 0; cyc < 5; cyc++) {
174 		settime(1900 + cyc * 65, 1, 1, 0, 0, 0);
175 		for (yday = -26000; yday < 26000; yday += ydayinc) {
176 			whichprime = abs(yday) % (int)COUNTOF(prime_incs);
177 			ydayinc = prime_incs[whichprime];
178 			for (hour = -204; hour < 204; hour += 2) {
179 				for (minute = -60; minute < 60; minute++) {
180 				    (void)clocktime(0, yday, hour, minute, 30,
181 						    fixedpivot, timestamp, &yearstart, &actual);
182 					diff = actual - timestamp;
183 					if (diff >= 0x80000000UL) {
184 						diff = ~diff + 1;
185 					}
186 					TEST_ASSERT_TRUE(diff <= (183u * SECSPERDAY));
187 				}
188 			}
189 		}
190 	}
191 }
192 
TEST_GROUP_RUNNER(clocktime)193 TEST_GROUP_RUNNER(clocktime) {
194 	RUN_TEST_CASE(clocktime, CurrentYear);
195 	RUN_TEST_CASE(clocktime, CurrentYearExplicit);
196 	RUN_TEST_CASE(clocktime, CurrentYearFuzz);
197 	RUN_TEST_CASE(clocktime, WrongYearStart);
198 	RUN_TEST_CASE(clocktime, PreviousYear);
199 	RUN_TEST_CASE(clocktime, NextYear);
200 	RUN_TEST_CASE(clocktime, NoReasonableConversion);
201 	RUN_TEST_CASE(clocktime, AlwaysInLimit);
202 }
203