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