]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/ntp/tests/libntp/timespecops.c
Fix ntp multiple vulnerabilities.
[FreeBSD/releng/10.2.git] / contrib / ntp / tests / libntp / timespecops.c
1 #include "config.h"
2
3 #include "ntp_types.h"
4 #include "ntp_fp.h"
5 #include "timespecops.h"
6
7 #include "unity.h"
8
9 #include <math.h>
10 #include <string.h>
11
12
13 #define TEST_ASSERT_EQUAL_timespec(a, b) {                              \
14     TEST_ASSERT_EQUAL_MESSAGE(a.tv_sec, b.tv_sec, "Field tv_sec");      \
15     TEST_ASSERT_EQUAL_MESSAGE(a.tv_nsec, b.tv_nsec, "Field tv_nsec");   \
16 }
17
18
19 #define TEST_ASSERT_EQUAL_l_fp(a, b) {                                  \
20     TEST_ASSERT_EQUAL_MESSAGE(a.l_i, b.l_i, "Field l_i");               \
21     TEST_ASSERT_EQUAL_UINT_MESSAGE(a.l_uf, b.l_uf, "Field l_uf");       \
22 }
23
24
25 static u_int32 my_tick_to_tsf(u_int32 ticks);
26 static u_int32 my_tsf_to_tick(u_int32 tsf);
27
28
29 // that's it...
30 struct lfpfracdata {
31         long    nsec;
32         u_int32 frac;
33 };
34
35
36 void setUp(void);
37 void test_Helpers1(void);
38 void test_Normalise(void);
39 void test_SignNoFrac(void);
40 void test_SignWithFrac(void);
41 void test_CmpFracEQ(void);
42 void test_CmpFracGT(void);
43 void test_CmpFracLT(void);
44 void test_AddFullNorm(void);
45 void test_AddFullOflow1(void);
46 void test_AddNsecNorm(void);
47 void test_AddNsecOflow1(void);
48 void test_SubFullNorm(void);
49 void test_SubFullOflow(void);
50 void test_SubNsecNorm(void);
51 void test_SubNsecOflow(void);
52 void test_Neg(void);
53 void test_AbsNoFrac(void);
54 void test_AbsWithFrac(void);
55 void test_Helpers2(void);
56 void test_ToLFPbittest(void);
57 void test_ToLFPrelPos(void);
58 void test_ToLFPrelNeg(void);
59 void test_ToLFPabs(void);
60 void test_FromLFPbittest(void);
61 void test_FromLFPrelPos(void);
62 void test_FromLFPrelNeg(void);
63 void test_LFProundtrip(void);
64 void test_ToString(void);
65
66 const bool      timespec_isValid(struct timespec V);
67 struct timespec timespec_init(time_t hi, long lo);
68 l_fp            l_fp_init(int32 i, u_int32 f);
69 bool            AssertFpClose(const l_fp m, const l_fp n, const l_fp limit);
70 bool            AssertTimespecClose(const struct timespec m,
71                                     const struct timespec n,
72                                     const struct timespec limit);
73
74
75 //***************************MY CUSTOM FUNCTIONS***************************
76
77
78 void
79 setUp(void)
80 {
81         init_lib();
82
83         return;
84 }
85
86
87 const bool
88 timespec_isValid(struct timespec V)
89 {
90
91         return V.tv_nsec >= 0 && V.tv_nsec < 1000000000;
92 }
93
94
95 struct timespec
96 timespec_init(time_t hi, long lo)
97 {
98         struct timespec V;
99
100         V.tv_sec = hi;
101         V.tv_nsec = lo;
102
103         return V;
104 }
105
106
107 l_fp
108 l_fp_init(int32 i, u_int32 f)
109 {
110         l_fp temp;
111
112         temp.l_i  = i;
113         temp.l_uf = f;
114
115         return temp;
116 }
117
118
119 bool
120 AssertFpClose(const l_fp m, const l_fp n, const l_fp limit)
121 {
122         l_fp diff;
123
124         if (L_ISGEQ(&m, &n)) {
125                 diff = m;
126                 L_SUB(&diff, &n);
127         } else {
128                 diff = n;
129                 L_SUB(&diff, &m);
130         }
131         if (L_ISGEQ(&limit, &diff)) {
132                 return TRUE;
133         }
134         else {
135                 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)); 
136                 return FALSE;
137         }
138 }
139
140
141 bool
142 AssertTimespecClose(const struct timespec m, const struct timespec n,
143         const struct timespec limit)
144 {
145         struct timespec diff;
146
147         diff = abs_tspec(sub_tspec(m, n));
148         if (cmp_tspec(limit, diff) >= 0)
149                 return TRUE;
150         else
151         {
152                 printf("m_expr which is %ld.%lu \nand\nn_expr which is %ld.%lu\nare not close; diff=%ld.%lunsec\n", m.tv_sec, m.tv_nsec, n.tv_sec, n.tv_nsec, diff.tv_sec, diff.tv_nsec); 
153                 return FALSE;
154         }
155 }
156
157 //-----------------------------------------------
158
159 static const struct lfpfracdata fdata[] = {
160         {         0, 0x00000000 }, {   2218896, 0x00916ae6 },
161         {  16408100, 0x0433523d }, { 125000000, 0x20000000 },
162         { 250000000, 0x40000000 }, { 287455871, 0x4996b53d },
163         { 375000000, 0x60000000 }, { 500000000, 0x80000000 },
164         { 518978897, 0x84dbcd0e }, { 563730222, 0x90509fb3 },
165         { 563788007, 0x9054692c }, { 583289882, 0x95527c57 },
166         { 607074509, 0x9b693c2a }, { 625000000, 0xa0000000 },
167         { 645184059, 0xa52ac851 }, { 676497788, 0xad2ef583 },
168         { 678910895, 0xadcd1abb }, { 679569625, 0xadf84663 },
169         { 690926741, 0xb0e0932d }, { 705656483, 0xb4a5e73d },
170         { 723553854, 0xb93ad34c }, { 750000000, 0xc0000000 },
171         { 763550253, 0xc3780785 }, { 775284917, 0xc6791284 },
172         { 826190764, 0xd3813ce8 }, { 875000000, 0xe0000000 },
173         { 956805507, 0xf4f134a9 }, { 982570733, 0xfb89c16c }
174         };
175
176
177 u_int32
178 my_tick_to_tsf(u_int32 ticks)
179 {
180         // convert nanoseconds to l_fp fractional units, using double
181         // precision float calculations or, if available, 64bit integer
182         // arithmetic. This should give the precise fraction, rounded to
183         // the nearest representation.
184
185 #ifdef HAVE_U_INT64
186         return (u_int32)((( ((u_int64)(ticks)) << 32) + 500000000) / 1000000000);
187 #else
188         return (u_int32)((double(ticks)) * 4.294967296 + 0.5);
189 #endif
190         // And before you ask: if ticks >= 1000000000, the result is
191         // truncated nonsense, so don't use it out-of-bounds.
192 }
193
194
195 u_int32
196 my_tsf_to_tick(u_int32 tsf)
197 {
198
199         // Inverse operation: converts fraction to microseconds.
200 #ifdef HAVE_U_INT64
201         return (u_int32)(( ((u_int64)(tsf)) * 1000000000 + 0x80000000) >> 32);
202 #else
203         return (u_int32)(double(tsf) / 4.294967296 + 0.5);
204 #endif
205         // Beware: The result might be 10^9 due to rounding!
206 }
207
208
209
210 // ---------------------------------------------------------------------
211 // test support stuff -- part 1
212 // ---------------------------------------------------------------------
213
214 void
215 test_Helpers1(void)
216 {
217         struct timespec x;
218
219         for (x.tv_sec = -2; x.tv_sec < 3; x.tv_sec++) {
220                 x.tv_nsec = -1;
221                 TEST_ASSERT_FALSE(timespec_isValid(x));
222                 x.tv_nsec = 0;
223                 TEST_ASSERT_TRUE(timespec_isValid(x));
224                 x.tv_nsec = 999999999;
225                 TEST_ASSERT_TRUE(timespec_isValid(x));
226                 x.tv_nsec = 1000000000;
227                 TEST_ASSERT_FALSE(timespec_isValid(x));
228         }
229
230         return;
231 }
232
233
234 //----------------------------------------------------------------------
235 // test normalisation
236 //----------------------------------------------------------------------
237
238 void
239 test_Normalise(void)
240 {
241         long ns;
242
243         for ( ns = -2000000000; ns <= 2000000000; ns += 10000000) {
244                 struct timespec x = timespec_init(0, ns);
245
246                 x = normalize_tspec(x);
247                 TEST_ASSERT_TRUE(timespec_isValid(x));
248         }
249
250         return;
251 }
252
253 //----------------------------------------------------------------------
254 // test classification
255 //----------------------------------------------------------------------
256
257 void
258 test_SignNoFrac(void)
259 {
260         // sign test, no fraction
261         int i;
262
263         for (i = -4; i <= 4; ++i) {
264                 struct timespec a = timespec_init(i, 0);
265                 int E = (i > 0) - (i < 0);
266                 int r = test_tspec(a);
267
268                 TEST_ASSERT_EQUAL(E, r);
269         }
270
271         return;
272 }
273
274
275 void
276 test_SignWithFrac(void)
277 {
278         // sign test, with fraction
279         int i;
280
281         for (i = -4; i <= 4; ++i) {
282                 struct timespec a = timespec_init(i, 10);
283                 int E = (i >= 0) - (i < 0);
284                 int r = test_tspec(a);
285
286                 TEST_ASSERT_EQUAL(E, r);
287         }
288
289         return;
290 }
291
292 //----------------------------------------------------------------------
293 // test compare
294 //----------------------------------------------------------------------
295 void
296 test_CmpFracEQ(void)
297 {
298         // fractions are equal
299         int i, j;
300         for (i = -4; i <= 4; ++i)
301                 for (j = -4; j <= 4; ++j) {
302                         struct timespec a = timespec_init( i , 200);
303                         struct timespec b = timespec_init( j , 200);
304                         int   E = (i > j) - (i < j);
305                         int   r = cmp_tspec_denorm(a, b);
306
307                         TEST_ASSERT_EQUAL(E, r);
308                 }
309
310         return;
311 }
312
313
314 void
315 test_CmpFracGT(void)
316 {
317         // fraction a bigger fraction b
318         int i, j;
319
320         for (i = -4; i <= 4; ++i)
321                 for (j = -4; j <= 4; ++j) {
322                         struct timespec a = timespec_init(i, 999999800);
323                         struct timespec b = timespec_init(j, 200);
324                         int   E = (i >= j) - (i < j);
325                         int   r = cmp_tspec_denorm(a, b);
326
327                         TEST_ASSERT_EQUAL(E, r);
328                 }
329
330         return;
331 }
332
333
334 void
335 test_CmpFracLT(void)
336 {
337         // fraction a less fraction b
338         int i, j;
339
340         for (i = -4; i <= 4; ++i)
341                 for (j = -4; j <= 4; ++j) {
342                         struct timespec a = timespec_init(i, 200);
343                         struct timespec b = timespec_init(j, 999999800);
344                         int   E = (i > j) - (i <= j);
345                         int   r = cmp_tspec_denorm(a, b);
346
347                         TEST_ASSERT_EQUAL(E, r);
348                 }
349
350         return;
351 }
352
353 //----------------------------------------------------------------------
354 // Test addition (sum)
355 //----------------------------------------------------------------------
356
357 void
358 test_AddFullNorm(void)
359 {
360         int i, j;
361
362         for (i = -4; i <= 4; ++i)
363                 for (j = -4; j <= 4; ++j) {
364                         struct timespec a = timespec_init(i, 200);
365                         struct timespec b = timespec_init(j, 400);
366                         struct timespec E = timespec_init(i + j, 200 + 400);
367                         struct timespec c;
368
369                         c = add_tspec(a, b);
370                         TEST_ASSERT_EQUAL_timespec(E, c);
371                 }
372
373         return;
374 }
375
376
377 void
378 test_AddFullOflow1(void)
379 {
380         int i, j;
381
382         for (i = -4; i <= 4; ++i)
383                 for (j = -4; j <= 4; ++j) {
384                         struct timespec a = timespec_init(i, 200);
385                         struct timespec b = timespec_init(j, 999999900);
386                         struct timespec E = timespec_init(i + j + 1, 100);
387                         struct timespec c;
388
389                         c = add_tspec(a, b);
390                         TEST_ASSERT_EQUAL_timespec(E, c);
391                 }
392
393         return;
394 }
395
396
397 void
398 test_AddNsecNorm(void) {
399         int i;
400
401         for (i = -4; i <= 4; ++i) {
402                 struct timespec a = timespec_init(i, 200);
403                 struct timespec E = timespec_init(i, 600);
404                 struct timespec c;
405
406                 c = add_tspec_ns(a, 600 - 200);
407                 TEST_ASSERT_EQUAL_timespec(E, c);
408         }
409
410         return;
411 }
412
413
414 void
415 test_AddNsecOflow1(void)
416 {
417         int i;
418
419         for (i = -4; i <= 4; ++i) {
420                 struct timespec a = timespec_init(i, 200);
421                 struct timespec E = timespec_init(i + 1, 100);
422                 struct timespec c;
423
424                 c = add_tspec_ns(a, NANOSECONDS - 100);
425                 TEST_ASSERT_EQUAL_timespec(E, c);
426         }
427
428         return;
429 }
430
431 //----------------------------------------------------------------------
432 // test subtraction (difference)
433 //----------------------------------------------------------------------
434
435 void
436 test_SubFullNorm(void)
437 {
438         int i, j;
439
440         for (i = -4; i <= 4; ++i)
441                 for (j = -4; j <= 4; ++j) {
442                         struct timespec a = timespec_init( i , 600);
443                         struct timespec b = timespec_init( j , 400);
444                         struct timespec E = timespec_init(i-j, 200);
445                         struct timespec c;
446
447                         c = sub_tspec(a, b);
448                         TEST_ASSERT_EQUAL_timespec(E, c);
449                 }
450
451         return;
452 }
453
454
455 void
456 test_SubFullOflow(void)
457 {
458         int i, j;
459
460         for (i = -4; i <= 4; ++i)
461                 for (j = -4; j <= 4; ++j) {
462                         struct timespec a = timespec_init(i, 100);
463                         struct timespec b = timespec_init(j, 999999900);
464                         struct timespec E = timespec_init(i - j - 1, 200);
465                         struct timespec c;
466
467                         c = sub_tspec(a, b);
468                         TEST_ASSERT_EQUAL_timespec(E, c);
469                 }
470
471         return;
472 }
473
474
475 void
476 test_SubNsecNorm(void)
477 {
478         int i;
479
480         for (i = -4; i <= 4; ++i) {
481                 struct timespec a = timespec_init(i, 600);
482                 struct timespec E = timespec_init(i, 200);
483                 struct timespec c;
484
485                 c = sub_tspec_ns(a, 600 - 200);
486                 TEST_ASSERT_EQUAL_timespec(E, c);
487         }
488
489         return;
490 }
491
492
493 void
494 test_SubNsecOflow(void)
495 {
496         int i;
497
498         for (i = -4; i <= 4; ++i) {
499                 struct timespec a = timespec_init( i , 100);
500                 struct timespec E = timespec_init(i-1, 200);
501                 struct timespec c;
502
503                 c = sub_tspec_ns(a, NANOSECONDS - 100);
504                 TEST_ASSERT_EQUAL_timespec(E, c);
505         }
506
507         return;
508 }
509
510 //----------------------------------------------------------------------
511 // test negation
512 //----------------------------------------------------------------------
513
514
515 void
516 test_Neg(void)
517 {
518         int i;
519
520         for (i = -4; i <= 4; ++i) {
521                 struct timespec a = timespec_init(i, 100);
522                 struct timespec b;
523                 struct timespec c;
524
525                 b = neg_tspec(a);
526                 c = add_tspec(a, b);
527                 TEST_ASSERT_EQUAL(0, test_tspec(c));
528         }
529
530         return;
531 }
532
533 //----------------------------------------------------------------------
534 // test abs value
535 //----------------------------------------------------------------------
536
537 void
538 test_AbsNoFrac(void)
539 {
540         int i;
541
542         for (i = -4; i <= 4; ++i) {
543                 struct timespec a = timespec_init(i , 0);
544                 struct timespec b;
545
546                 b = abs_tspec(a);
547                 TEST_ASSERT_EQUAL((i != 0), test_tspec(b));
548         }
549
550         return;
551 }
552
553
554 void
555 test_AbsWithFrac(void)
556 {
557         int i;
558
559         for (i = -4; i <= 4; ++i) {
560                 struct timespec a = timespec_init(i, 100);
561                 struct timespec b;
562
563                 b = abs_tspec(a);
564                 TEST_ASSERT_EQUAL(1, test_tspec(b));
565         }
566
567         return;
568 }
569
570 // ---------------------------------------------------------------------
571 // test support stuff -- part 2
572 // ---------------------------------------------------------------------
573
574 void
575 test_Helpers2(void)
576 {
577         struct timespec limit = timespec_init(0, 2);
578         struct timespec x, y;
579         long i;
580
581         for (x.tv_sec = -2; x.tv_sec < 3; x.tv_sec++)
582                 for (x.tv_nsec = 1;
583                      x.tv_nsec < 1000000000;
584                      x.tv_nsec += 499999999) {
585                         for (i = -4; i < 5; ++i) {
586                                 y = x;
587                                 y.tv_nsec += i;
588                                 if (i >= -2 && i <= 2) {
589                                         TEST_ASSERT_TRUE(AssertTimespecClose(x, y, limit));
590                                 }
591                                 else
592                                 {
593                                         TEST_ASSERT_FALSE(AssertTimespecClose(x, y, limit));
594                                 }
595                         }
596                 }
597
598         return;
599 }
600
601 //----------------------------------------------------------------------
602 // conversion to l_fp
603 //----------------------------------------------------------------------
604
605 void
606 test_ToLFPbittest(void)
607 {
608         l_fp lfpClose =  l_fp_init(0, 1);
609         u_int32 i;
610
611         for (i = 0; i < 1000000000; i+=1000) {
612                 struct timespec a = timespec_init(1, i);
613                 l_fp E= l_fp_init(1, my_tick_to_tsf(i));
614                 l_fp r;
615
616                 r = tspec_intv_to_lfp(a);
617                 TEST_ASSERT_TRUE(AssertFpClose(E, r, lfpClose));
618         }
619
620         return;
621 }
622
623
624 void
625 test_ToLFPrelPos(void)
626 {
627         int i;
628
629         for (i = 0; i < COUNTOF(fdata); ++i) {
630                 struct timespec a = timespec_init(1, fdata[i].nsec);
631                 l_fp E = l_fp_init(1, fdata[i].frac);
632                 l_fp r;
633
634                 r = tspec_intv_to_lfp(a);
635                 TEST_ASSERT_EQUAL_l_fp(E, r);
636         }
637
638         return;
639 }
640
641
642 void
643 test_ToLFPrelNeg(void)
644 {
645         int i;
646
647         for (i = 0; i < COUNTOF(fdata); ++i) {
648                 struct timespec a = timespec_init(-1, fdata[i].nsec);
649                 l_fp E = l_fp_init(~0, fdata[i].frac);
650                 l_fp r;
651
652                 r = tspec_intv_to_lfp(a);
653                 TEST_ASSERT_EQUAL_l_fp(E, r);
654         }
655
656         return;
657 }
658
659
660 void
661 test_ToLFPabs(void)
662 {
663         int i;
664
665         for (i = 0; i < COUNTOF(fdata); ++i) {
666                 struct timespec a = timespec_init(1, fdata[i].nsec);
667                 l_fp E = l_fp_init(1 + JAN_1970, fdata[i].frac);
668                 l_fp r;
669
670                 r = tspec_stamp_to_lfp(a);
671                 TEST_ASSERT_EQUAL_l_fp(E, r);
672         }
673
674         return;
675 }
676
677 //----------------------------------------------------------------------
678 // conversion from l_fp
679 //----------------------------------------------------------------------
680
681 void
682 test_FromLFPbittest(void)
683 {
684         struct timespec limit = timespec_init(0, 2);
685
686         // Not *exactly* a bittest, because 2**32 tests would take a
687         // really long time even on very fast machines! So we do test
688         // every 1000 fractional units.
689         u_int32 tsf;
690         for (tsf = 0; tsf < ~((u_int32)(1000)); tsf += 1000) {
691                 struct timespec E = timespec_init(1, my_tsf_to_tick(tsf));
692                 l_fp a = l_fp_init(1, tsf);
693                 struct timespec r;
694
695                 r = lfp_intv_to_tspec(a);
696                 // The conversion might be off by one nanosecond when
697                 // comparing to calculated value.
698                 TEST_ASSERT_TRUE(AssertTimespecClose(E, r, limit));
699         }
700
701         return;
702 }
703
704
705 void
706 test_FromLFPrelPos(void)
707 {
708         struct timespec limit = timespec_init(0, 2);
709         int i;
710
711         for (i = 0; i < COUNTOF(fdata); ++i) {
712                 l_fp a = l_fp_init(1, fdata[i].frac);
713                 struct timespec E = timespec_init(1, fdata[i].nsec);
714                 struct timespec r;
715
716                 r = lfp_intv_to_tspec(a);
717                 TEST_ASSERT_TRUE(AssertTimespecClose(E, r, limit));
718         }
719
720         return;
721 }
722
723
724 void
725 test_FromLFPrelNeg(void)
726 {
727         struct timespec limit = timespec_init(0, 2);
728         int i;
729
730         for (i = 0; i < COUNTOF(fdata); ++i) {
731                 l_fp a = l_fp_init(~0, fdata[i].frac);
732                 struct timespec E = timespec_init(-1, fdata[i].nsec);
733                 struct timespec r;
734
735                 r = lfp_intv_to_tspec(a);
736                 TEST_ASSERT_TRUE(AssertTimespecClose(E, r, limit));
737         }
738
739         return;
740 }
741
742
743 // nsec -> frac -> nsec roundtrip, using a prime start and increment
744 void
745 test_LFProundtrip(void)
746 {
747         int32_t t;
748         u_int32 i;
749
750         for (t = -1; t < 2; ++t)
751                 for (i = 4999; i < 1000000000; i += 10007) {
752                         struct timespec E = timespec_init(t, i);
753                         l_fp a;
754                         struct timespec r;
755
756                         a = tspec_intv_to_lfp(E);
757                         r = lfp_intv_to_tspec(a);
758                         TEST_ASSERT_EQUAL_timespec(E, r);
759                 }
760
761         return;
762 }
763
764 //----------------------------------------------------------------------
765 // string formatting
766 //----------------------------------------------------------------------
767
768 void
769 test_ToString(void)
770 {
771         static const struct {
772                 time_t          sec;
773                 long            nsec;
774                 const char *    repr;
775         } data [] = {
776                 { 0, 0,  "0.000000000" },
777                 { 2, 0,  "2.000000000" },
778                 {-2, 0, "-2.000000000" },
779                 { 0, 1,  "0.000000001" },
780                 { 0,-1, "-0.000000001" },
781                 { 1,-1,  "0.999999999" },
782                 {-1, 1, "-0.999999999" },
783                 {-1,-1, "-1.000000001" },
784         };
785         int i;
786
787         for (i = 0; i < COUNTOF(data); ++i) {
788                 struct timespec a = timespec_init(data[i].sec, data[i].nsec);
789                 const char * E = data[i].repr;
790                 const char * r = tspectoa(a);
791                 TEST_ASSERT_EQUAL_STRING(E, r);
792         }
793
794         return;
795 }
796
797 // -*- EOF -*-