1284990Scy#include "config.h"
2284990Scy
3284990Scy#include "ntp_types.h"
4284990Scy#include "ntp_fp.h"
5284990Scy#include "timespecops.h"
6284990Scy
7284990Scy#include "unity.h"
8284990Scy
9290000Sglebius#include <math.h>
10284990Scy#include <string.h>
11284990Scy
12290000Sglebius
13293894Sglebius#define TEST_ASSERT_EQUAL_timespec(a, b) {				\
14293894Sglebius    TEST_ASSERT_EQUAL_MESSAGE(a.tv_sec, b.tv_sec, "Field tv_sec");	\
15284990Scy    TEST_ASSERT_EQUAL_MESSAGE(a.tv_nsec, b.tv_nsec, "Field tv_nsec");	\
16284990Scy}
17284990Scy
18290000Sglebius
19293894Sglebius#define TEST_ASSERT_EQUAL_l_fp(a, b) {					\
20293894Sglebius    TEST_ASSERT_EQUAL_MESSAGE(a.l_i, b.l_i, "Field l_i");		\
21284990Scy    TEST_ASSERT_EQUAL_UINT_MESSAGE(a.l_uf, b.l_uf, "Field l_uf");	\
22284990Scy}
23284990Scy
24284990Scy
25284990Scystatic u_int32 my_tick_to_tsf(u_int32 ticks);
26284990Scystatic u_int32 my_tsf_to_tick(u_int32 tsf);
27284990Scy
28290000Sglebius
29284990Scy// that's it...
30284990Scystruct lfpfracdata {
31284990Scy	long	nsec;
32284990Scy	u_int32 frac;
33284990Scy};
34284990Scy
35290000Sglebius
36293894Sglebiusvoid setUp(void);
37290000Sglebiusvoid test_Helpers1(void);
38290000Sglebiusvoid test_Normalise(void);
39290000Sglebiusvoid test_SignNoFrac(void);
40290000Sglebiusvoid test_SignWithFrac(void);
41290000Sglebiusvoid test_CmpFracEQ(void);
42290000Sglebiusvoid test_CmpFracGT(void);
43290000Sglebiusvoid test_CmpFracLT(void);
44290000Sglebiusvoid test_AddFullNorm(void);
45290000Sglebiusvoid test_AddFullOflow1(void);
46290000Sglebiusvoid test_AddNsecNorm(void);
47290000Sglebiusvoid test_AddNsecOflow1(void);
48290000Sglebiusvoid test_SubFullNorm(void);
49290000Sglebiusvoid test_SubFullOflow(void);
50290000Sglebiusvoid test_SubNsecNorm(void);
51290000Sglebiusvoid test_SubNsecOflow(void);
52290000Sglebiusvoid test_Neg(void);
53290000Sglebiusvoid test_AbsNoFrac(void);
54290000Sglebiusvoid test_AbsWithFrac(void);
55290000Sglebiusvoid test_Helpers2(void);
56290000Sglebiusvoid test_ToLFPbittest(void);
57290000Sglebiusvoid test_ToLFPrelPos(void);
58290000Sglebiusvoid test_ToLFPrelNeg(void);
59290000Sglebiusvoid test_ToLFPabs(void);
60290000Sglebiusvoid test_FromLFPbittest(void);
61290000Sglebiusvoid test_FromLFPrelPos(void);
62290000Sglebiusvoid test_FromLFPrelNeg(void);
63290000Sglebiusvoid test_LFProundtrip(void);
64290000Sglebiusvoid test_ToString(void);
65290000Sglebius
66293894Sglebiusconst bool	timespec_isValid(struct timespec V);
67290000Sglebiusstruct timespec timespec_init(time_t hi, long lo);
68293894Sglebiusl_fp		l_fp_init(int32 i, u_int32 f);
69293894Sglebiusbool		AssertFpClose(const l_fp m, const l_fp n, const l_fp limit);
70293894Sglebiusbool		AssertTimespecClose(const struct timespec m,
71293894Sglebius				    const struct timespec n,
72293894Sglebius				    const struct timespec limit);
73290000Sglebius
74290000Sglebius
75293894Sglebius//***************************MY CUSTOM FUNCTIONS***************************
76284990Scy
77284990Scy
78293894Sglebiusvoid
79293894SglebiussetUp(void)
80293894Sglebius{
81293894Sglebius	init_lib();
82284990Scy
83293894Sglebius	return;
84293894Sglebius}
85293894Sglebius
86293894Sglebius
87290000Sglebiusconst bool
88293894Sglebiustimespec_isValid(struct timespec V)
89293894Sglebius{
90293894Sglebius
91290000Sglebius	return V.tv_nsec >= 0 && V.tv_nsec < 1000000000;
92290000Sglebius}
93290000Sglebius
94290000Sglebius
95290000Sglebiusstruct timespec
96293894Sglebiustimespec_init(time_t hi, long lo)
97293894Sglebius{
98293894Sglebius	struct timespec V;
99293894Sglebius
100284990Scy	V.tv_sec = hi;
101284990Scy	V.tv_nsec = lo;
102293894Sglebius
103284990Scy	return V;
104284990Scy}
105284990Scy
106290000Sglebius
107290000Sglebiusl_fp
108293894Sglebiusl_fp_init(int32 i, u_int32 f)
109293894Sglebius{
110284990Scy	l_fp temp;
111293894Sglebius
112284990Scy	temp.l_i  = i;
113284990Scy	temp.l_uf = f;
114284990Scy
115284990Scy	return temp;
116284990Scy}
117284990Scy
118290000Sglebius
119290000Sglebiusbool
120293894SglebiusAssertFpClose(const l_fp m, const l_fp n, const l_fp limit)
121293894Sglebius{
122284990Scy	l_fp diff;
123284990Scy
124284990Scy	if (L_ISGEQ(&m, &n)) {
125284990Scy		diff = m;
126284990Scy		L_SUB(&diff, &n);
127284990Scy	} else {
128284990Scy		diff = n;
129284990Scy		L_SUB(&diff, &m);
130284990Scy	}
131293894Sglebius	if (L_ISGEQ(&limit, &diff)) {
132284990Scy		return TRUE;
133284990Scy	}
134284990Scy	else {
135290000Sglebius		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));
136284990Scy		return FALSE;
137284990Scy	}
138284990Scy}
139284990Scy
140284990Scy
141290000Sglebiusbool
142293894SglebiusAssertTimespecClose(const struct timespec m, const struct timespec n,
143293894Sglebius	const struct timespec limit)
144293894Sglebius{
145284990Scy	struct timespec diff;
146284990Scy
147284990Scy	diff = abs_tspec(sub_tspec(m, n));
148284990Scy	if (cmp_tspec(limit, diff) >= 0)
149284990Scy		return TRUE;
150284990Scy	else
151284990Scy	{
152290000Sglebius		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);
153284990Scy		return FALSE;
154284990Scy	}
155284990Scy}
156284990Scy
157284990Scy//-----------------------------------------------
158284990Scy
159284990Scystatic const struct lfpfracdata fdata[] = {
160284990Scy	{	  0, 0x00000000 }, {   2218896, 0x00916ae6 },
161284990Scy	{  16408100, 0x0433523d }, { 125000000, 0x20000000 },
162284990Scy	{ 250000000, 0x40000000 }, { 287455871, 0x4996b53d },
163284990Scy	{ 375000000, 0x60000000 }, { 500000000, 0x80000000 },
164284990Scy	{ 518978897, 0x84dbcd0e }, { 563730222, 0x90509fb3 },
165284990Scy	{ 563788007, 0x9054692c }, { 583289882, 0x95527c57 },
166284990Scy	{ 607074509, 0x9b693c2a }, { 625000000, 0xa0000000 },
167284990Scy	{ 645184059, 0xa52ac851 }, { 676497788, 0xad2ef583 },
168284990Scy	{ 678910895, 0xadcd1abb }, { 679569625, 0xadf84663 },
169284990Scy	{ 690926741, 0xb0e0932d }, { 705656483, 0xb4a5e73d },
170284990Scy	{ 723553854, 0xb93ad34c }, { 750000000, 0xc0000000 },
171284990Scy	{ 763550253, 0xc3780785 }, { 775284917, 0xc6791284 },
172284990Scy	{ 826190764, 0xd3813ce8 }, { 875000000, 0xe0000000 },
173284990Scy	{ 956805507, 0xf4f134a9 }, { 982570733, 0xfb89c16c }
174284990Scy	};
175284990Scy
176284990Scy
177290000Sglebiusu_int32
178293894Sglebiusmy_tick_to_tsf(u_int32 ticks)
179293894Sglebius{
180284990Scy	// convert nanoseconds to l_fp fractional units, using double
181284990Scy	// precision float calculations or, if available, 64bit integer
182284990Scy	// arithmetic. This should give the precise fraction, rounded to
183284990Scy	// the nearest representation.
184293894Sglebius
185284990Scy#ifdef HAVE_U_INT64
186284990Scy	return (u_int32)((( ((u_int64)(ticks)) << 32) + 500000000) / 1000000000);
187284990Scy#else
188284990Scy	return (u_int32)((double(ticks)) * 4.294967296 + 0.5);
189284990Scy#endif
190284990Scy	// And before you ask: if ticks >= 1000000000, the result is
191284990Scy	// truncated nonsense, so don't use it out-of-bounds.
192284990Scy}
193284990Scy
194290000Sglebius
195290000Sglebiusu_int32
196293894Sglebiusmy_tsf_to_tick(u_int32 tsf)
197293894Sglebius{
198293894Sglebius
199284990Scy	// Inverse operation: converts fraction to microseconds.
200284990Scy#ifdef HAVE_U_INT64
201284990Scy	return (u_int32)(( ((u_int64)(tsf)) * 1000000000 + 0x80000000) >> 32);
202284990Scy#else
203284990Scy	return (u_int32)(double(tsf) / 4.294967296 + 0.5);
204284990Scy#endif
205284990Scy	// Beware: The result might be 10^9 due to rounding!
206284990Scy}
207284990Scy
208284990Scy
209284990Scy
210284990Scy// ---------------------------------------------------------------------
211284990Scy// test support stuff -- part 1
212284990Scy// ---------------------------------------------------------------------
213284990Scy
214290000Sglebiusvoid
215293894Sglebiustest_Helpers1(void)
216293894Sglebius{
217284990Scy	struct timespec x;
218284990Scy
219284990Scy	for (x.tv_sec = -2; x.tv_sec < 3; x.tv_sec++) {
220284990Scy		x.tv_nsec = -1;
221284990Scy		TEST_ASSERT_FALSE(timespec_isValid(x));
222284990Scy		x.tv_nsec = 0;
223284990Scy		TEST_ASSERT_TRUE(timespec_isValid(x));
224284990Scy		x.tv_nsec = 999999999;
225284990Scy		TEST_ASSERT_TRUE(timespec_isValid(x));
226284990Scy		x.tv_nsec = 1000000000;
227284990Scy		TEST_ASSERT_FALSE(timespec_isValid(x));
228284990Scy	}
229293894Sglebius
230293894Sglebius	return;
231284990Scy}
232284990Scy
233284990Scy
234284990Scy//----------------------------------------------------------------------
235284990Scy// test normalisation
236284990Scy//----------------------------------------------------------------------
237284990Scy
238290000Sglebiusvoid
239293894Sglebiustest_Normalise(void)
240293894Sglebius{
241284990Scy	long ns;
242293894Sglebius
243284990Scy	for ( ns = -2000000000; ns <= 2000000000; ns += 10000000) {
244284990Scy		struct timespec x = timespec_init(0, ns);
245284990Scy
246284990Scy		x = normalize_tspec(x);
247284990Scy		TEST_ASSERT_TRUE(timespec_isValid(x));
248284990Scy	}
249293894Sglebius
250293894Sglebius	return;
251284990Scy}
252284990Scy
253284990Scy//----------------------------------------------------------------------
254284990Scy// test classification
255284990Scy//----------------------------------------------------------------------
256284990Scy
257290000Sglebiusvoid
258293894Sglebiustest_SignNoFrac(void)
259293894Sglebius{
260284990Scy	// sign test, no fraction
261284990Scy	int i;
262293894Sglebius
263284990Scy	for (i = -4; i <= 4; ++i) {
264284990Scy		struct timespec a = timespec_init(i, 0);
265284990Scy		int E = (i > 0) - (i < 0);
266284990Scy		int r = test_tspec(a);
267284990Scy
268284990Scy		TEST_ASSERT_EQUAL(E, r);
269284990Scy	}
270293894Sglebius
271293894Sglebius	return;
272284990Scy}
273284990Scy
274290000Sglebius
275290000Sglebiusvoid
276293894Sglebiustest_SignWithFrac(void)
277293894Sglebius{
278284990Scy	// sign test, with fraction
279284990Scy	int i;
280293894Sglebius
281284990Scy	for (i = -4; i <= 4; ++i) {
282284990Scy		struct timespec a = timespec_init(i, 10);
283284990Scy		int E = (i >= 0) - (i < 0);
284284990Scy		int r = test_tspec(a);
285293894Sglebius
286284990Scy		TEST_ASSERT_EQUAL(E, r);
287284990Scy	}
288293894Sglebius
289293894Sglebius	return;
290284990Scy}
291284990Scy
292284990Scy//----------------------------------------------------------------------
293284990Scy// test compare
294284990Scy//----------------------------------------------------------------------
295290000Sglebiusvoid
296293894Sglebiustest_CmpFracEQ(void)
297293894Sglebius{
298284990Scy	// fractions are equal
299290000Sglebius	int i, j;
300284990Scy	for (i = -4; i <= 4; ++i)
301284990Scy		for (j = -4; j <= 4; ++j) {
302284990Scy			struct timespec a = timespec_init( i , 200);
303284990Scy			struct timespec b = timespec_init( j , 200);
304284990Scy			int   E = (i > j) - (i < j);
305284990Scy			int   r = cmp_tspec_denorm(a, b);
306293894Sglebius
307284990Scy			TEST_ASSERT_EQUAL(E, r);
308284990Scy		}
309293894Sglebius
310293894Sglebius	return;
311284990Scy}
312284990Scy
313290000Sglebius
314290000Sglebiusvoid
315293894Sglebiustest_CmpFracGT(void)
316293894Sglebius{
317284990Scy	// fraction a bigger fraction b
318290000Sglebius	int i, j;
319293894Sglebius
320284990Scy	for (i = -4; i <= 4; ++i)
321284990Scy		for (j = -4; j <= 4; ++j) {
322284990Scy			struct timespec a = timespec_init(i, 999999800);
323284990Scy			struct timespec b = timespec_init(j, 200);
324284990Scy			int   E = (i >= j) - (i < j);
325284990Scy			int   r = cmp_tspec_denorm(a, b);
326293894Sglebius
327284990Scy			TEST_ASSERT_EQUAL(E, r);
328284990Scy		}
329293894Sglebius
330293894Sglebius	return;
331284990Scy}
332284990Scy
333290000Sglebius
334290000Sglebiusvoid
335293894Sglebiustest_CmpFracLT(void)
336293894Sglebius{
337284990Scy	// fraction a less fraction b
338290000Sglebius	int i, j;
339293894Sglebius
340284990Scy	for (i = -4; i <= 4; ++i)
341284990Scy		for (j = -4; j <= 4; ++j) {
342284990Scy			struct timespec a = timespec_init(i, 200);
343284990Scy			struct timespec b = timespec_init(j, 999999800);
344284990Scy			int   E = (i > j) - (i <= j);
345284990Scy			int   r = cmp_tspec_denorm(a, b);
346293894Sglebius
347284990Scy			TEST_ASSERT_EQUAL(E, r);
348284990Scy		}
349293894Sglebius
350293894Sglebius	return;
351284990Scy}
352284990Scy
353284990Scy//----------------------------------------------------------------------
354284990Scy// Test addition (sum)
355284990Scy//----------------------------------------------------------------------
356284990Scy
357290000Sglebiusvoid
358293894Sglebiustest_AddFullNorm(void)
359293894Sglebius{
360290000Sglebius	int i, j;
361293894Sglebius
362284990Scy	for (i = -4; i <= 4; ++i)
363284990Scy		for (j = -4; j <= 4; ++j) {
364284990Scy			struct timespec a = timespec_init(i, 200);
365284990Scy			struct timespec b = timespec_init(j, 400);
366284990Scy			struct timespec E = timespec_init(i + j, 200 + 400);
367284990Scy			struct timespec c;
368284990Scy
369284990Scy			c = add_tspec(a, b);
370284990Scy			TEST_ASSERT_EQUAL_timespec(E, c);
371284990Scy		}
372293894Sglebius
373293894Sglebius	return;
374284990Scy}
375284990Scy
376290000Sglebius
377290000Sglebiusvoid
378293894Sglebiustest_AddFullOflow1(void)
379293894Sglebius{
380290000Sglebius	int i, j;
381293894Sglebius
382284990Scy	for (i = -4; i <= 4; ++i)
383284990Scy		for (j = -4; j <= 4; ++j) {
384284990Scy			struct timespec a = timespec_init(i, 200);
385284990Scy			struct timespec b = timespec_init(j, 999999900);
386284990Scy			struct timespec E = timespec_init(i + j + 1, 100);
387284990Scy			struct timespec c;
388284990Scy
389284990Scy			c = add_tspec(a, b);
390284990Scy			TEST_ASSERT_EQUAL_timespec(E, c);
391284990Scy		}
392293894Sglebius
393293894Sglebius	return;
394284990Scy}
395284990Scy
396290000Sglebius
397290000Sglebiusvoid
398290000Sglebiustest_AddNsecNorm(void) {
399284990Scy	int i;
400293894Sglebius
401284990Scy	for (i = -4; i <= 4; ++i) {
402284990Scy		struct timespec a = timespec_init(i, 200);
403284990Scy		struct timespec E = timespec_init(i, 600);
404284990Scy		struct timespec c;
405284990Scy
406284990Scy		c = add_tspec_ns(a, 600 - 200);
407284990Scy		TEST_ASSERT_EQUAL_timespec(E, c);
408284990Scy	}
409293894Sglebius
410293894Sglebius	return;
411284990Scy}
412284990Scy
413290000Sglebius
414290000Sglebiusvoid
415293894Sglebiustest_AddNsecOflow1(void)
416293894Sglebius{
417284990Scy	int i;
418293894Sglebius
419284990Scy	for (i = -4; i <= 4; ++i) {
420284990Scy		struct timespec a = timespec_init(i, 200);
421284990Scy		struct timespec E = timespec_init(i + 1, 100);
422284990Scy		struct timespec c;
423284990Scy
424284990Scy		c = add_tspec_ns(a, NANOSECONDS - 100);
425284990Scy		TEST_ASSERT_EQUAL_timespec(E, c);
426284990Scy	}
427293894Sglebius
428293894Sglebius	return;
429284990Scy}
430284990Scy
431284990Scy//----------------------------------------------------------------------
432284990Scy// test subtraction (difference)
433284990Scy//----------------------------------------------------------------------
434284990Scy
435290000Sglebiusvoid
436293894Sglebiustest_SubFullNorm(void)
437293894Sglebius{
438290000Sglebius	int i, j;
439293894Sglebius
440284990Scy	for (i = -4; i <= 4; ++i)
441284990Scy		for (j = -4; j <= 4; ++j) {
442284990Scy			struct timespec a = timespec_init( i , 600);
443284990Scy			struct timespec b = timespec_init( j , 400);
444284990Scy			struct timespec E = timespec_init(i-j, 200);
445284990Scy			struct timespec c;
446284990Scy
447284990Scy			c = sub_tspec(a, b);
448284990Scy			TEST_ASSERT_EQUAL_timespec(E, c);
449284990Scy		}
450293894Sglebius
451293894Sglebius	return;
452284990Scy}
453284990Scy
454290000Sglebius
455290000Sglebiusvoid
456293894Sglebiustest_SubFullOflow(void)
457293894Sglebius{
458290000Sglebius	int i, j;
459293894Sglebius
460284990Scy	for (i = -4; i <= 4; ++i)
461284990Scy		for (j = -4; j <= 4; ++j) {
462290000Sglebius			struct timespec a = timespec_init(i, 100);
463290000Sglebius			struct timespec b = timespec_init(j, 999999900);
464290000Sglebius			struct timespec E = timespec_init(i - j - 1, 200);
465284990Scy			struct timespec c;
466284990Scy
467284990Scy			c = sub_tspec(a, b);
468284990Scy			TEST_ASSERT_EQUAL_timespec(E, c);
469284990Scy		}
470293894Sglebius
471293894Sglebius	return;
472284990Scy}
473284990Scy
474290000Sglebius
475290000Sglebiusvoid
476293894Sglebiustest_SubNsecNorm(void)
477293894Sglebius{
478284990Scy	int i;
479293894Sglebius
480284990Scy	for (i = -4; i <= 4; ++i) {
481284990Scy		struct timespec a = timespec_init(i, 600);
482284990Scy		struct timespec E = timespec_init(i, 200);
483284990Scy		struct timespec c;
484284990Scy
485284990Scy		c = sub_tspec_ns(a, 600 - 200);
486284990Scy		TEST_ASSERT_EQUAL_timespec(E, c);
487284990Scy	}
488293894Sglebius
489293894Sglebius	return;
490284990Scy}
491284990Scy
492290000Sglebius
493290000Sglebiusvoid
494293894Sglebiustest_SubNsecOflow(void)
495293894Sglebius{
496284990Scy	int i;
497293894Sglebius
498284990Scy	for (i = -4; i <= 4; ++i) {
499284990Scy		struct timespec a = timespec_init( i , 100);
500284990Scy		struct timespec E = timespec_init(i-1, 200);
501284990Scy		struct timespec c;
502284990Scy
503284990Scy		c = sub_tspec_ns(a, NANOSECONDS - 100);
504284990Scy		TEST_ASSERT_EQUAL_timespec(E, c);
505284990Scy	}
506293894Sglebius
507293894Sglebius	return;
508284990Scy}
509284990Scy
510284990Scy//----------------------------------------------------------------------
511284990Scy// test negation
512284990Scy//----------------------------------------------------------------------
513284990Scy
514290000Sglebius
515290000Sglebiusvoid
516293894Sglebiustest_Neg(void)
517293894Sglebius{
518284990Scy	int i;
519293894Sglebius
520284990Scy	for (i = -4; i <= 4; ++i) {
521284990Scy		struct timespec a = timespec_init(i, 100);
522284990Scy		struct timespec b;
523284990Scy		struct timespec c;
524284990Scy
525284990Scy		b = neg_tspec(a);
526284990Scy		c = add_tspec(a, b);
527284990Scy		TEST_ASSERT_EQUAL(0, test_tspec(c));
528284990Scy	}
529293894Sglebius
530293894Sglebius	return;
531284990Scy}
532284990Scy
533284990Scy//----------------------------------------------------------------------
534284990Scy// test abs value
535284990Scy//----------------------------------------------------------------------
536284990Scy
537290000Sglebiusvoid
538293894Sglebiustest_AbsNoFrac(void)
539293894Sglebius{
540284990Scy	int i;
541293894Sglebius
542284990Scy	for (i = -4; i <= 4; ++i) {
543284990Scy		struct timespec a = timespec_init(i , 0);
544284990Scy		struct timespec b;
545284990Scy
546284990Scy		b = abs_tspec(a);
547284990Scy		TEST_ASSERT_EQUAL((i != 0), test_tspec(b));
548284990Scy	}
549293894Sglebius
550293894Sglebius	return;
551284990Scy}
552284990Scy
553290000Sglebius
554290000Sglebiusvoid
555293894Sglebiustest_AbsWithFrac(void)
556293894Sglebius{
557284990Scy	int i;
558293894Sglebius
559284990Scy	for (i = -4; i <= 4; ++i) {
560284990Scy		struct timespec a = timespec_init(i, 100);
561284990Scy		struct timespec b;
562284990Scy
563284990Scy		b = abs_tspec(a);
564284990Scy		TEST_ASSERT_EQUAL(1, test_tspec(b));
565284990Scy	}
566293894Sglebius
567293894Sglebius	return;
568284990Scy}
569284990Scy
570284990Scy// ---------------------------------------------------------------------
571284990Scy// test support stuff -- part 2
572284990Scy// ---------------------------------------------------------------------
573284990Scy
574290000Sglebiusvoid
575293894Sglebiustest_Helpers2(void)
576293894Sglebius{
577290000Sglebius	struct timespec limit = timespec_init(0, 2);
578284990Scy	struct timespec x, y;
579284990Scy	long i;
580284990Scy
581284990Scy	for (x.tv_sec = -2; x.tv_sec < 3; x.tv_sec++)
582284990Scy		for (x.tv_nsec = 1;
583284990Scy		     x.tv_nsec < 1000000000;
584284990Scy		     x.tv_nsec += 499999999) {
585290000Sglebius			for (i = -4; i < 5; ++i) {
586284990Scy				y = x;
587284990Scy				y.tv_nsec += i;
588293894Sglebius				if (i >= -2 && i <= 2) {
589290000Sglebius					TEST_ASSERT_TRUE(AssertTimespecClose(x, y, limit));
590284990Scy				}
591284990Scy				else
592284990Scy				{
593290000Sglebius					TEST_ASSERT_FALSE(AssertTimespecClose(x, y, limit));
594284990Scy				}
595284990Scy			}
596284990Scy		}
597293894Sglebius
598293894Sglebius	return;
599284990Scy}
600284990Scy
601284990Scy//----------------------------------------------------------------------
602284990Scy// conversion to l_fp
603284990Scy//----------------------------------------------------------------------
604284990Scy
605290000Sglebiusvoid
606293894Sglebiustest_ToLFPbittest(void)
607293894Sglebius{
608290000Sglebius	l_fp lfpClose =  l_fp_init(0, 1);
609284990Scy	u_int32 i;
610293894Sglebius
611284990Scy	for (i = 0; i < 1000000000; i+=1000) {
612284990Scy		struct timespec a = timespec_init(1, i);
613284990Scy		l_fp E= l_fp_init(1, my_tick_to_tsf(i));
614284990Scy		l_fp r;
615284990Scy
616284990Scy		r = tspec_intv_to_lfp(a);
617290000Sglebius		TEST_ASSERT_TRUE(AssertFpClose(E, r, lfpClose));
618284990Scy	}
619293894Sglebius
620293894Sglebius	return;
621284990Scy}
622284990Scy
623290000Sglebius
624290000Sglebiusvoid
625293894Sglebiustest_ToLFPrelPos(void)
626293894Sglebius{
627284990Scy	int i;
628293894Sglebius
629290000Sglebius	for (i = 0; i < COUNTOF(fdata); ++i) {
630284990Scy		struct timespec a = timespec_init(1, fdata[i].nsec);
631284990Scy		l_fp E = l_fp_init(1, fdata[i].frac);
632284990Scy		l_fp r;
633284990Scy
634284990Scy		r = tspec_intv_to_lfp(a);
635284990Scy		TEST_ASSERT_EQUAL_l_fp(E, r);
636284990Scy	}
637293894Sglebius
638293894Sglebius	return;
639284990Scy}
640284990Scy
641290000Sglebius
642290000Sglebiusvoid
643293894Sglebiustest_ToLFPrelNeg(void)
644293894Sglebius{
645284990Scy	int i;
646293894Sglebius
647290000Sglebius	for (i = 0; i < COUNTOF(fdata); ++i) {
648284990Scy		struct timespec a = timespec_init(-1, fdata[i].nsec);
649284990Scy		l_fp E = l_fp_init(~0, fdata[i].frac);
650284990Scy		l_fp r;
651284990Scy
652284990Scy		r = tspec_intv_to_lfp(a);
653284990Scy		TEST_ASSERT_EQUAL_l_fp(E, r);
654284990Scy	}
655293894Sglebius
656293894Sglebius	return;
657284990Scy}
658284990Scy
659290000Sglebius
660290000Sglebiusvoid
661293894Sglebiustest_ToLFPabs(void)
662293894Sglebius{
663284990Scy	int i;
664293894Sglebius
665290000Sglebius	for (i = 0; i < COUNTOF(fdata); ++i) {
666284990Scy		struct timespec a = timespec_init(1, fdata[i].nsec);
667284990Scy		l_fp E = l_fp_init(1 + JAN_1970, fdata[i].frac);
668284990Scy		l_fp r;
669284990Scy
670284990Scy		r = tspec_stamp_to_lfp(a);
671284990Scy		TEST_ASSERT_EQUAL_l_fp(E, r);
672284990Scy	}
673293894Sglebius
674293894Sglebius	return;
675284990Scy}
676284990Scy
677284990Scy//----------------------------------------------------------------------
678284990Scy// conversion from l_fp
679284990Scy//----------------------------------------------------------------------
680284990Scy
681290000Sglebiusvoid
682293894Sglebiustest_FromLFPbittest(void)
683293894Sglebius{
684290000Sglebius	struct timespec limit = timespec_init(0, 2);
685290000Sglebius
686284990Scy	// Not *exactly* a bittest, because 2**32 tests would take a
687284990Scy	// really long time even on very fast machines! So we do test
688284990Scy	// every 1000 fractional units.
689284990Scy	u_int32 tsf;
690284990Scy	for (tsf = 0; tsf < ~((u_int32)(1000)); tsf += 1000) {
691284990Scy		struct timespec E = timespec_init(1, my_tsf_to_tick(tsf));
692284990Scy		l_fp a = l_fp_init(1, tsf);
693284990Scy		struct timespec r;
694284990Scy
695284990Scy		r = lfp_intv_to_tspec(a);
696284990Scy		// The conversion might be off by one nanosecond when
697284990Scy		// comparing to calculated value.
698290000Sglebius		TEST_ASSERT_TRUE(AssertTimespecClose(E, r, limit));
699284990Scy	}
700293894Sglebius
701293894Sglebius	return;
702284990Scy}
703284990Scy
704290000Sglebius
705290000Sglebiusvoid
706293894Sglebiustest_FromLFPrelPos(void)
707293894Sglebius{
708290000Sglebius	struct timespec limit = timespec_init(0, 2);
709284990Scy	int i;
710293894Sglebius
711290000Sglebius	for (i = 0; i < COUNTOF(fdata); ++i) {
712284990Scy		l_fp a = l_fp_init(1, fdata[i].frac);
713284990Scy		struct timespec E = timespec_init(1, fdata[i].nsec);
714284990Scy		struct timespec r;
715284990Scy
716284990Scy		r = lfp_intv_to_tspec(a);
717290000Sglebius		TEST_ASSERT_TRUE(AssertTimespecClose(E, r, limit));
718284990Scy	}
719293894Sglebius
720293894Sglebius	return;
721284990Scy}
722284990Scy
723290000Sglebius
724290000Sglebiusvoid
725293894Sglebiustest_FromLFPrelNeg(void)
726293894Sglebius{
727290000Sglebius	struct timespec limit = timespec_init(0, 2);
728284990Scy	int i;
729293894Sglebius
730290000Sglebius	for (i = 0; i < COUNTOF(fdata); ++i) {
731284990Scy		l_fp a = l_fp_init(~0, fdata[i].frac);
732284990Scy		struct timespec E = timespec_init(-1, fdata[i].nsec);
733284990Scy		struct timespec r;
734284990Scy
735284990Scy		r = lfp_intv_to_tspec(a);
736290000Sglebius		TEST_ASSERT_TRUE(AssertTimespecClose(E, r, limit));
737284990Scy	}
738293894Sglebius
739293894Sglebius	return;
740284990Scy}
741284990Scy
742284990Scy
743284990Scy// nsec -> frac -> nsec roundtrip, using a prime start and increment
744290000Sglebiusvoid
745293894Sglebiustest_LFProundtrip(void)
746293894Sglebius{
747284990Scy	int32_t t;
748284990Scy	u_int32 i;
749293894Sglebius
750284990Scy	for (t = -1; t < 2; ++t)
751290000Sglebius		for (i = 4999; i < 1000000000; i += 10007) {
752284990Scy			struct timespec E = timespec_init(t, i);
753284990Scy			l_fp a;
754284990Scy			struct timespec r;
755284990Scy
756284990Scy			a = tspec_intv_to_lfp(E);
757284990Scy			r = lfp_intv_to_tspec(a);
758284990Scy			TEST_ASSERT_EQUAL_timespec(E, r);
759284990Scy		}
760293894Sglebius
761293894Sglebius	return;
762284990Scy}
763284990Scy
764284990Scy//----------------------------------------------------------------------
765284990Scy// string formatting
766284990Scy//----------------------------------------------------------------------
767284990Scy
768290000Sglebiusvoid
769293894Sglebiustest_ToString(void)
770293894Sglebius{
771284990Scy	static const struct {
772284990Scy		time_t		sec;
773284990Scy		long		nsec;
774284990Scy		const char *	repr;
775284990Scy	} data [] = {
776284990Scy		{ 0, 0,	 "0.000000000" },
777284990Scy		{ 2, 0,	 "2.000000000" },
778284990Scy		{-2, 0, "-2.000000000" },
779284990Scy		{ 0, 1,	 "0.000000001" },
780284990Scy		{ 0,-1,	"-0.000000001" },
781284990Scy		{ 1,-1,	 "0.999999999" },
782284990Scy		{-1, 1, "-0.999999999" },
783284990Scy		{-1,-1, "-1.000000001" },
784284990Scy	};
785284990Scy	int i;
786293894Sglebius
787290000Sglebius	for (i = 0; i < COUNTOF(data); ++i) {
788284990Scy		struct timespec a = timespec_init(data[i].sec, data[i].nsec);
789284990Scy		const char * E = data[i].repr;
790284990Scy		const char * r = tspectoa(a);
791284990Scy		TEST_ASSERT_EQUAL_STRING(E, r);
792284990Scy	}
793293894Sglebius
794293894Sglebius	return;
795284990Scy}
796284990Scy
797284990Scy// -*- EOF -*-
798