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