xref: /netbsd-src/external/bsd/ntp/dist/tests/libntp/timevalops.c (revision 200d779b75dbeafa7bc01fd0f60bc61185f6967b)
1 /*	$NetBSD: timevalops.c,v 1.1.1.2 2015/07/10 13:11:14 christos Exp $	*/
2 
3 #include "config.h"
4 
5 //some unused features are still in the wrapper, unconverted
6 
7 #include "ntp_types.h"
8 #include "ntp_fp.h"
9 
10 #include <math.h>
11 #include "timevalops.h"
12 
13 #include "unity.h"
14 
15 
16 //in unity_helper.h :
17 #define TEST_ASSERT_EQUAL_timeval(a, b) { \
18     TEST_ASSERT_EQUAL_MESSAGE(a.tv_sec, b.tv_sec, "Field tv_sec"); \
19     TEST_ASSERT_EQUAL_MESSAGE(a.tv_usec, b.tv_usec, "Field tv_usec");	\
20 }
21 
22 //timeval has time_t, long, and time_t is basically uint
23 
24 static u_int32 my_tick_to_tsf(u_int32 ticks);
25 static u_int32 my_tsf_to_tick(u_int32 tsf);
26 
27 // that's it...
28 typedef struct {
29 	long	usec;
30 	u_int32	frac;
31 } lfpfracdata ;
32 
33 
34 //******************************************MY CUSTOM FUNCTIONS*******************************
35 
36 typedef int bool; //TRUE and FALSE are already defined somewhere, so I can't do typedef enum { FALSE, TRUE } boolean;
37 
38 struct timeval timeval_init( time_t hi, long lo){
39 	struct timeval V;
40 	V.tv_sec = hi;
41 	V.tv_usec = lo;
42 	return V;
43 }
44 
45 const bool timeval_isValid(struct timeval V)
46 	{ return V.tv_usec >= 0 && V.tv_usec < 1000000; }
47 
48 //taken from lfpfunc.c -> maybe remove this from timevalops.c and lfpfunc. and put in c_timstructs.h ????!!!!!
49 l_fp l_fp_init(int32 i, u_int32 f)
50 {
51 	l_fp temp;
52 	temp.l_i  = i;
53 	temp.l_uf = f;
54 
55 	return temp;
56 }
57 
58 bool AssertTimevalClose(const struct timeval m, const struct timeval n, const struct timeval limit)
59 {
60 	struct timeval diff;
61 
62 	diff = abs_tval(sub_tval(m, n));
63 	if (cmp_tval(limit, diff) >= 0)
64 		return TRUE;
65 
66 	else
67 	{
68 		//printf("");
69 		//<< m_expr << " which is " << timeval_wrap(m)
70 		//<< "\nand\n"
71 		//<< n_expr << " which is " << timeval_wrap(n)
72 		//<< "\nare not close; diff=" << timeval_wrap(diff);
73 		return FALSE;
74 	}
75 }
76 
77 bool AssertFpClose(const l_fp m,const l_fp n, const l_fp limit)
78 {
79 	l_fp diff;
80 
81 	if (L_ISGEQ(&m, &n)) {
82 		diff = m;
83 		L_SUB(&diff, &n);
84 	} else {
85 		diff = n;
86 		L_SUB(&diff, &m);
87 	}
88 	if (L_ISGEQ(&limit, &diff)){
89 		return TRUE;
90 	}
91 	else {
92 		//<< m_expr << " which is " << l_fp_wrap(m)
93 		//<< "\nand\n"
94 		//<< n_expr << " which is " << l_fp_wrap(n)
95 		//<< "\nare not close; diff=" << l_fp_wrap(diff);
96 		return FALSE;
97 	}
98 }
99 
100 
101 //---------------------------------------------------
102 
103 static const lfpfracdata fdata[] = {
104 	{      0, 0x00000000 }, {   7478, 0x01ea1405 },
105 	{  22077, 0x05a6d699 }, { 125000, 0x20000000 },
106 	{ 180326, 0x2e29d841 }, { 207979, 0x353e1c9b },
107 	{ 250000, 0x40000000 }, { 269509, 0x44fe8ab5 },
108 	{ 330441, 0x5497c808 }, { 333038, 0x5541fa76 },
109 	{ 375000, 0x60000000 }, { 394734, 0x650d4995 },
110 	{ 446327, 0x72427c7c }, { 500000, 0x80000000 },
111 	{ 517139, 0x846338b4 }, { 571953, 0x926b8306 },
112 	{ 587353, 0x965cc426 }, { 625000, 0xa0000000 },
113 	{ 692136, 0xb12fd32c }, { 750000, 0xc0000000 },
114 	{ 834068, 0xd5857aff }, { 848454, 0xd9344806 },
115 	{ 854222, 0xdaae4b02 }, { 861465, 0xdc88f862 },
116 	{ 875000, 0xe0000000 }, { 910661, 0xe921144d },
117 	{ 922162, 0xec12cf10 }, { 942190, 0xf1335d25 }
118 };
119 
120 
121 u_int32 my_tick_to_tsf(u_int32 ticks)
122 {
123 	// convert microseconds to l_fp fractional units, using double
124 	// precision float calculations or, if available, 64bit integer
125 	// arithmetic. This should give the precise fraction, rounded to
126 	// the nearest representation.
127 #ifdef HAVE_U_INT64
128 	return (u_int32)((( ((u_int64)(ticks)) << 32) + 500000) / 1000000); //I put too much () when casting just to be safe
129 #else
130 	return (u_int32)( ((double)(ticks)) * 4294.967296 + 0.5);
131 #endif
132 	// And before you ask: if ticks >= 1000000, the result is
133 	// truncated nonsense, so don't use it out-of-bounds.
134 }
135 
136 u_int32 my_tsf_to_tick(u_int32 tsf)
137 {
138 	// Inverse operation: converts fraction to microseconds.
139 #ifdef HAVE_U_INT64
140 	return (u_int32)( ((u_int64)(tsf) * 1000000 + 0x80000000) >> 32); //CHECK ME!!!
141 #else
142 	return (u_int32)(double(tsf) / 4294.967296 + 0.5);
143 #endif
144 	// Beware: The result might be 10^6 due to rounding!
145 }
146 
147 
148 //***************************************END OF CUSTOM FUNCTIONS*****************************
149 
150 
151 // ---------------------------------------------------------------------
152 // test support stuff - part1
153 // ---------------------------------------------------------------------
154 
155 void test_Helpers1() {
156 	struct timeval x;
157 
158 	for (x.tv_sec = -2; x.tv_sec < 3; x.tv_sec++) {
159 		x.tv_usec = -1;
160 		TEST_ASSERT_FALSE(timeval_isValid(x));
161 		x.tv_usec = 0;
162 		TEST_ASSERT_TRUE(timeval_isValid(x));
163 		x.tv_usec = 999999;
164 		TEST_ASSERT_TRUE(timeval_isValid(x));
165 		x.tv_usec = 1000000;
166 		TEST_ASSERT_FALSE(timeval_isValid(x));
167 	}
168 }
169 
170 
171 //----------------------------------------------------------------------
172 // test normalisation
173 //----------------------------------------------------------------------
174 
175 void test_Normalise() {
176 	long ns;
177 	for (ns = -2000000000; ns <= 2000000000; ns += 10000000) {
178 		struct timeval x = timeval_init(0, ns);
179 
180 		x = normalize_tval(x);
181 		TEST_ASSERT_TRUE(timeval_isValid(x));
182 	}
183 }
184 
185 //----------------------------------------------------------------------
186 // test classification
187 //----------------------------------------------------------------------
188 
189 void test_SignNoFrac() {
190 	int i;
191 	// sign test, no fraction
192 	for (i = -4; i <= 4; ++i) {
193 		struct timeval a = timeval_init(i, 0);
194 		int	     E = (i > 0) - (i < 0);
195 		int	     r = test_tval(a);
196 
197 		TEST_ASSERT_EQUAL(E, r);
198 	}
199 }
200 
201 void test_SignWithFrac() {
202 	// sign test, with fraction
203 	int i;
204 	for (i = -4; i <= 4; ++i) {
205 		struct timeval a = timeval_init(i, 10);
206 		int	     E = (i >= 0) - (i < 0);
207 		int	     r = test_tval(a);
208 
209 		TEST_ASSERT_EQUAL(E, r);
210 	}
211 }
212 
213 //----------------------------------------------------------------------
214 // test compare
215 //----------------------------------------------------------------------
216 void test_CmpFracEQ() {
217 	int i,j;
218 	// fractions are equal
219 	for (i = -4; i <= 4; ++i)
220 		for (j = -4; j <= 4; ++j) {
221 			struct timeval a = timeval_init(i, 200);
222 			struct timeval b = timeval_init(j, 200);
223 			int	     E = (i > j) - (i < j);
224 			int	     r = cmp_tval_denorm(a, b);
225 
226 			TEST_ASSERT_EQUAL(E, r);
227 		}
228 }
229 
230 void test_CmpFracGT() {
231 	// fraction a bigger fraction b
232 	int i,j;
233 	for (i = -4; i <= 4; ++i)
234 		for (j = -4; j <= 4; ++j) {
235 			struct timeval a = timeval_init( i , 999800);
236 			struct timeval b = timeval_init( j , 200);
237 			int	     E = (i >= j) - (i < j);
238 			int	     r = cmp_tval_denorm(a, b);
239 
240 			TEST_ASSERT_EQUAL(E, r);
241 		}
242 }
243 
244 void test_CmpFracLT() {
245 	// fraction a less fraction b
246 	int i,j;
247 	for (i = -4; i <= 4; ++i)
248 		for (j = -4; j <= 4; ++j) {
249 			struct timeval a = timeval_init(i, 200);
250 			struct timeval b = timeval_init(j, 999800);
251 			int	     E = (i > j) - (i <= j);
252 			int	     r = cmp_tval_denorm(a, b);
253 
254 			TEST_ASSERT_EQUAL(E, r);
255 		}
256 }
257 
258 //----------------------------------------------------------------------
259 // Test addition (sum)
260 //----------------------------------------------------------------------
261 
262 void test_AddFullNorm() {
263 	int i,j;
264 	for (i = -4; i <= 4; ++i)
265 		for (j = -4; j <= 4; ++j) {
266 			struct timeval a = timeval_init(i, 200);
267 			struct timeval b = timeval_init(j, 400);
268 			struct timeval E = timeval_init(i + j, 200 + 400);
269 			struct timeval c;
270 
271 			c = add_tval(a, b);
272 			TEST_ASSERT_EQUAL_timeval(E, c);
273 		}
274 }
275 
276 void test_AddFullOflow1() {
277 	int i,j;
278 	for (i = -4; i <= 4; ++i)
279 		for (j = -4; j <= 4; ++j) {
280 			struct timeval a = timeval_init(i, 200);
281 			struct timeval b = timeval_init(j, 999900);
282 			struct timeval E = timeval_init(i + j + 1, 100);
283 			struct timeval c;
284 
285 			c = add_tval(a, b);
286 			TEST_ASSERT_EQUAL_timeval(E, c);
287 		}
288 }
289 
290 void test_AddUsecNorm() {
291 	int i;
292 	for (i = -4; i <= 4; ++i) {
293 		struct timeval a = timeval_init(i, 200);
294 		struct timeval E = timeval_init(i, 600);
295 		struct timeval c;
296 
297 		c = add_tval_us(a, 600 - 200);
298 		TEST_ASSERT_EQUAL_timeval(E, c);
299 	}
300 }
301 
302 void test_AddUsecOflow1() {
303 	int i;
304 	for (i = -4; i <= 4; ++i) {
305 		struct timeval a = timeval_init(i, 200);
306 		struct timeval E = timeval_init(i + 1, 100);
307 		struct timeval c;
308 
309 		c = add_tval_us(a, MICROSECONDS - 100);
310 		TEST_ASSERT_EQUAL_timeval(E, c);
311 	}
312 }
313 
314 //----------------------------------------------------------------------
315 // test subtraction (difference)
316 //----------------------------------------------------------------------
317 
318 void test_SubFullNorm() {
319 	int i,j;
320 	for (i = -4; i <= 4; ++i)
321 		for (j = -4; j <= 4; ++j) {
322 			struct timeval a = timeval_init(i, 600);
323 			struct timeval b = timeval_init(j, 400);
324 			struct timeval E = timeval_init(i - j, 600 - 400);
325 			struct timeval c;
326 
327 			c = sub_tval(a, b);
328 			TEST_ASSERT_EQUAL_timeval(E, c);
329 		}
330 }
331 
332 void test_SubFullOflow() {
333 	int i,j;
334 	for (i = -4; i <= 4; ++i)
335 		for (j = -4; j <= 4; ++j) {
336 			struct timeval a = timeval_init(i, 100);
337 			struct timeval b = timeval_init(j, 999900);
338 			struct timeval E = timeval_init(i - j - 1, 200);
339 			struct timeval c;
340 
341 			c = sub_tval(a, b);
342 			TEST_ASSERT_EQUAL_timeval(E, c);
343 		}
344 }
345 
346 void test_SubUsecNorm() {
347 	int i = -4;
348 	for (i = -4; i <= 4; ++i) {
349 		struct timeval a = timeval_init(i, 600);
350 		struct timeval E = timeval_init(i, 200);
351 		struct timeval c;
352 
353 		c = sub_tval_us(a, 600 - 200);
354 		TEST_ASSERT_EQUAL_timeval(E, c);
355 	}
356 }
357 
358 void test_SubUsecOflow() {
359 	int i = -4;
360 	for (i = -4; i <= 4; ++i) {
361 		struct timeval a = timeval_init(i, 100);
362 		struct timeval E = timeval_init(i - 1, 200);
363 		struct timeval c;
364 
365 		c = sub_tval_us(a, MICROSECONDS - 100);
366 		TEST_ASSERT_EQUAL_timeval(E, c);
367 	}
368 }
369 
370 //----------------------------------------------------------------------
371 // test negation
372 //----------------------------------------------------------------------
373 
374 void test_Neg() {
375 	int i = -4;
376 	for (i = -4; i <= 4; ++i) {
377 		struct timeval a = timeval_init(i, 100);
378 		struct timeval b;
379 		struct timeval c;
380 
381 		b = neg_tval(a);
382 		c = add_tval(a, b);
383 		TEST_ASSERT_EQUAL(0, test_tval(c));
384 	}
385 }
386 
387 //----------------------------------------------------------------------
388 // test abs value
389 //----------------------------------------------------------------------
390 
391 void test_AbsNoFrac() {
392 	int i = -4;
393 	for (i = -4; i <= 4; ++i) {
394 		struct timeval a = timeval_init(i, 0);
395 		struct timeval b;
396 
397 		b = abs_tval(a);
398 		TEST_ASSERT_EQUAL((i != 0), test_tval(b));
399 	}
400 }
401 
402 void test_AbsWithFrac() {
403 	int i = -4;
404 	for (i = -4; i <= 4; ++i) {
405 		struct timeval a = timeval_init(i, 100);
406 		struct timeval b;
407 
408 		b = abs_tval(a);
409 		TEST_ASSERT_EQUAL(1, test_tval(b));
410 	}
411 }
412 
413 // ---------------------------------------------------------------------
414 // test support stuff -- part 2
415 // ---------------------------------------------------------------------
416 
417 
418 void test_Helpers2() {
419 	//struct AssertTimevalClose isClose = AssertTimevalClose_init(0, 2);
420 	struct timeval limit = timeval_init(0, 2);
421 	struct timeval x, y;
422 	long i;
423 
424 	for (x.tv_sec = -2; x.tv_sec < 3; x.tv_sec++){
425 		for (x.tv_usec = 1;
426 		     x.tv_usec < 1000000;
427 		     x.tv_usec += 499999) {
428 			for (i = -4; i < 5; i++) {
429 				y = x;
430 				y.tv_usec += i;
431 				if (i >= -2 && i <= 2){
432 					TEST_ASSERT_TRUE(AssertTimevalClose(x,y,limit));//ASSERT_PRED_FORMAT2(isClose, x, y);
433 				}
434 				else {
435 					TEST_ASSERT_FALSE(AssertTimevalClose(x,y,limit));//ASSERT_PRED_FORMAT2(!isClose, x, y);
436 				}
437 			}
438 		}
439 	}
440 }
441 
442 // and the global predicate instances we're using here
443 
444 //static l_fp lfpClose =  l_fp_init(0,1); //static AssertFpClose FpClose(0, 1);
445 //static struct timeval timevalClose = timeval_init(0,1); //static AssertTimevalClose TimevalClose(0, 1);
446 
447 //----------------------------------------------------------------------
448 // conversion to l_fp
449 //----------------------------------------------------------------------
450 
451 void test_ToLFPbittest() {
452 	l_fp lfpClose =  l_fp_init(0,1);
453 
454 	u_int32 i = 0;
455 	for (i = 0; i < 1000000; i++) {
456 		struct timeval a = timeval_init(1, i);
457 		l_fp E = l_fp_init(1,my_tick_to_tsf(i));
458 		l_fp r;
459 
460 		r = tval_intv_to_lfp(a);
461 		TEST_ASSERT_TRUE(AssertFpClose(E,r,lfpClose));	//ASSERT_PRED_FORMAT2(FpClose, E, r);
462 	}
463 }
464 
465 
466 void test_ToLFPrelPos() {
467 	l_fp lfpClose =  l_fp_init(0,1);
468 
469 	int i = 0;
470 	for (i = 0; i < COUNTOF(fdata); i++) {
471 		struct timeval a = timeval_init(1, fdata[i].usec);
472 		l_fp E = l_fp_init(1, fdata[i].frac);
473 		l_fp r;
474 
475 		r = tval_intv_to_lfp(a);
476 		TEST_ASSERT_TRUE(AssertFpClose(E,r,lfpClose)); //ASSERT_PRED_FORMAT2(FpClose, E, r);
477 	}
478 }
479 
480 void test_ToLFPrelNeg() {
481 	l_fp lfpClose =  l_fp_init(0,1);
482 	int i = 0;
483 	for (i = 0; i < COUNTOF(fdata); i++) {
484 		struct timeval a = timeval_init(-1, fdata[i].usec);
485 		l_fp E = l_fp_init(~0, fdata[i].frac);
486 		l_fp    r;
487 
488 		r = tval_intv_to_lfp(a);
489 		TEST_ASSERT_TRUE(AssertFpClose(E,r,lfpClose)); //ASSERT_PRED_FORMAT2(FpClose,E, r);
490 	}
491 }
492 
493 void test_ToLFPabs() {
494 	l_fp lfpClose =  l_fp_init(0,1);
495 
496 	int i = 0;
497 	for (i = 0; i < COUNTOF(fdata); i++) {
498 		struct timeval a = timeval_init(1, fdata[i].usec);
499 		l_fp E = l_fp_init(1 + JAN_1970, fdata[i].frac);
500 		l_fp    r;
501 
502 		r = tval_stamp_to_lfp(a);
503 		TEST_ASSERT_TRUE(AssertFpClose(E,r,lfpClose)); //ASSERT_PRED_FORMAT2(FpClose, E, r);
504 	}
505 }
506 
507 //----------------------------------------------------------------------
508 // conversion from l_fp
509 //----------------------------------------------------------------------
510 
511 void test_FromLFPbittest() {
512 	struct timeval timevalClose = timeval_init(0,1);
513 	// Not *exactly* a bittest, because 2**32 tests would take a
514 	// really long time even on very fast machines! So we do test
515 	// every 1000 fractional units.
516 	u_int32 tsf = 0;
517 	for (tsf = 0; tsf < ~((u_int32)(1000)); tsf += 1000) {
518 		struct timeval E = timeval_init(1, my_tsf_to_tick(tsf));
519 		l_fp a = l_fp_init(1, tsf);
520 		struct timeval r;
521 
522 		r = lfp_intv_to_tval(a);
523 		// The conversion might be off by one microsecond when
524 		// comparing to calculated value.
525 		TEST_ASSERT_TRUE(AssertTimevalClose(E,r,timevalClose)); //ASSERT_PRED_FORMAT2(TimevalClose, E, r);
526 	}
527 }
528 
529 void test_FromLFPrelPos() {
530 	struct timeval timevalClose = timeval_init(0,1);
531 	int i = 0;
532 	for (i = 0; i < COUNTOF(fdata); i++) {
533 		l_fp a = l_fp_init(1, fdata[i].frac);
534 		struct timeval E = timeval_init(1, fdata[i].usec);
535 		struct timeval r;
536 
537 		r = lfp_intv_to_tval(a);
538 		TEST_ASSERT_TRUE(AssertTimevalClose(E,r,timevalClose)); //ASSERT_PRED_FORMAT2(TimevalClose, E, r);
539 	}
540 }
541 
542 void test_FromLFPrelNeg() {
543 	struct timeval timevalClose = timeval_init(0,1);
544 	int i = 0;
545 	for (i = 0; i < COUNTOF(fdata); i++) {
546 		l_fp a = l_fp_init(~0, fdata[i].frac);
547 		struct timeval E = timeval_init(-1, fdata[i].usec);
548 		struct timeval r;
549 
550 		r = lfp_intv_to_tval(a);
551 		TEST_ASSERT_TRUE(AssertTimevalClose(E,r,timevalClose)); //ASSERT_PRED_FORMAT2(TimevalClose, E, r);
552 	}
553 }
554 
555 // usec -> frac -> usec roundtrip, using a prime start and increment
556 void test_LFProundtrip() {
557 	int32_t t = -1;
558 	u_int32 i = 5;
559 	for (t = -1; t < 2; ++t)
560 		for (i = 5; i < 1000000; i+=11) {
561 			struct timeval E = timeval_init(t, i);
562 			l_fp a;
563 			struct timeval r;
564 
565 			a = tval_intv_to_lfp(E);
566 			r = lfp_intv_to_tval(a);
567 			TEST_ASSERT_EQUAL_timeval(E, r);
568 		}
569 }
570 
571 //----------------------------------------------------------------------
572 // string formatting
573 //----------------------------------------------------------------------
574 
575 void test_ToString() {
576 	static const struct {
577 		time_t	     sec;
578 		long	     usec;
579 		const char * repr;
580 	} data [] = {
581 		{ 0, 0,	 "0.000000" },
582 		{ 2, 0,	 "2.000000" },
583 		{-2, 0, "-2.000000" },
584 		{ 0, 1,	 "0.000001" },
585 		{ 0,-1,	"-0.000001" },
586 		{ 1,-1,	 "0.999999" },
587 		{-1, 1, "-0.999999" },
588 		{-1,-1, "-1.000001" },
589 	};
590 	int i;
591 	for (i = 0; i < COUNTOF(data); ++i) {
592 		struct timeval a = timeval_init(data[i].sec, data[i].usec);
593 		const char *  E = data[i].repr; //??
594 		const char *  r = tvaltoa(a);
595 
596 		TEST_ASSERT_EQUAL_STRING(E, r);
597 	}
598 }
599 
600 // -*- EOF -*-
601