summaryrefslogtreecommitdiff
path: root/tests/libntp/timestructs.h
diff options
context:
space:
mode:
Diffstat (limited to 'tests/libntp/timestructs.h')
-rw-r--r--tests/libntp/timestructs.h185
1 files changed, 185 insertions, 0 deletions
diff --git a/tests/libntp/timestructs.h b/tests/libntp/timestructs.h
new file mode 100644
index 0000000..7bc4ffd
--- /dev/null
+++ b/tests/libntp/timestructs.h
@@ -0,0 +1,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