aboutsummaryrefslogtreecommitdiff
path: root/tests/libntp/g_timestructs.h
blob: 7bc4ffdcf8caada13fc23288abf706a2c1dcef67 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/*
 * timestructs.h -- test bed adaptors for time structs.
 *
 * Written by Juergen Perlinger (perlinger@ntp.org) for the NTP project.
 * The contents of 'html/copyright.html' apply.
 *
 * Some wrapper classes and a closeness predicate that are used to
 * bridge the gap between the goggletest framework and the structs used
 * for representing time stamps (l_fp, struct timeval, struct timespec).
 *
 * Some ostream conversion operators are provided to give diagnostic
 * output on errors. The normal string conversion functions will give
 * HRVs (human readable values) but we might also be interested in the
 * machine representation for diagnostic purposes.
 */
#ifndef TIMESTRUCTS_H
#define TIMESTRUCTS_H

extern "C" {
#include "ntp_fp.h"
}

namespace timeStruct {

// wrap a l_fp struct with common operations
class l_fp_wrap {
  public:
	l_fp V;
	
	l_fp_wrap()
		{ ZERO(V); }
	l_fp_wrap(u_int32 hi, u_int32 lo)
		{ V.l_ui = hi; V.l_uf = lo; }
	l_fp_wrap(const l_fp &rhs)
		{ V = rhs; }
	bool operator == (const l_fp_wrap& rhs) const
		{ return L_ISEQU(&V, &rhs.V); }
	operator l_fp* () 
		{ return &V; }
	operator l_fp& ()
		{ return V; }
	l_fp_wrap & operator = (const l_fp_wrap& rhs)
		{ V = rhs.V; return *this; }
	l_fp_wrap& operator = (const l_fp& rhs)
		{ V = rhs; return *this; }
	};
	
// wrap a 'struct timeval' with common operations
class timeval_wrap {
public:
	struct timeval V;

	timeval_wrap()
		{ ZERO(V); }
	timeval_wrap(time_t hi, long lo)
		{ V.tv_sec = hi; V.tv_usec = lo; }
	timeval_wrap(const struct timeval & rhs)
		{ V = rhs; }
	timeval_wrap(const timeval_wrap & rhs)
		{ V = rhs.V; }
	bool operator == (const timeval_wrap& rhs) const
		{ return V.tv_sec == rhs.V.tv_sec &&
			 V.tv_usec == rhs.V.tv_usec ; }
	bool valid() const
		{ return V.tv_usec >= 0 && V.tv_usec < 1000000; }
	operator struct timeval* () 
		{ return &V; }
	operator struct timeval& ()
		{ return V; }
	timeval_wrap& operator = (const timeval_wrap& rhs)
		{ V = rhs.V; return *this; }
	timeval_wrap& operator = (const struct timeval& rhs)
		{ V = rhs; return *this; }
};

// wrap a 'struct timespec' with common operations
class timespec_wrap {
public:
	struct timespec V;

	timespec_wrap()
		{ ZERO(V); }
	timespec_wrap(time_t hi, long lo)
		{ V.tv_sec = hi; V.tv_nsec = lo; }
	timespec_wrap(const struct timespec & rhs)
		{ V = rhs; }
	timespec_wrap(const timespec_wrap & rhs)
		{ V = rhs.V; }
	bool operator == (const timespec_wrap& rhs) const
		{ return V.tv_sec == rhs.V.tv_sec &&
			 V.tv_nsec == rhs.V.tv_nsec ; }
	bool valid() const
		{ return V.tv_nsec >= 0 && V.tv_nsec < 1000000000; }
	operator struct timespec* () 
		{ return &V; }
	operator struct timespec& ()
		{ return V;	}
	timespec_wrap& operator = (const timespec_wrap& rhs)
		{ V = rhs.V; return *this; }
	timespec_wrap& operator = (const struct timespec& rhs)
		{ V = rhs; return *this; }
};

// l_fp closeness testing predicate
//
// This predicate is used for the closeness ('near') testing of l_fp
// values. Once constructed with a limit, it can be used to check the
// absolute difference of two l_fp structs against that limit; if the
// difference is less or equal to this limit, the test passes.
class AssertFpClose {
private:
	l_fp limit;

public:
	AssertFpClose(u_int32 hi, u_int32 lo);

	::testing::AssertionResult
	operator()(const char* m_expr, const char* n_expr,
		   const l_fp & m, const l_fp & n);
};


// timeval closeness testing predicate
//
// CAVEAT: This class uses the timevalops functions
// - sub_tval
// - abs_tval
// - cmp_tval
//
// This creates a dependency loop of sorts. The loop is defused by the
// fact that these basic operations can be tested by exact value tests,
// so once the basic timeval operations passed it's safe to use this
// predicate.
class AssertTimevalClose {
private:
	struct timeval limit;

public:
	// note: (hi,lo) should be a positive normalised timeval;
	// the constructor does not normalise the values!
	AssertTimevalClose(time_t hi, int32 lo);

	::testing::AssertionResult
	operator()(const char* m_expr, const char* n_expr,
		   const struct timeval & m, const struct timeval & n);
};


// timespec closeness testing predicate
//
// CAVEAT: This class uses the timespecops functions
// - sub_tspec
// - abs_tspec
// - cmp_tspec
//
// See the equivalent timeval helper.
class AssertTimespecClose {
private:
	struct timespec limit;

public:
	// note: (hi,lo) should be a positive normalised timespec;
	// the constructor does not normalise the values!
	AssertTimespecClose(time_t hi, int32 lo);

	::testing::AssertionResult
	operator()(const char* m_expr, const char* n_expr,
		   const struct timespec & m, const struct timespec & n);
};


// since googletest wants to string format items, we declare the
// necessary operators. Since all adaptors have only public members
// there is need for friend declarations anywhere.

extern std::ostream& operator << (std::ostream& os,
				  const timeStruct::l_fp_wrap& val);
extern std::ostream& operator << (std::ostream& os,
				  const timeStruct::timeval_wrap& val);
extern std::ostream& operator << (std::ostream& os,
				  const timeStruct::timespec_wrap& val);

} // namespace timeStruct

#endif // TIMESTRUCTS_H