OpenVPN 3 Core Library
Loading...
Searching...
No Matches
test_time.cpp
Go to the documentation of this file.
1#include "test_common.hpp"
2
5
8
9using namespace openvpn;
10using namespace openvpn;
11
12int my_abs(const int value)
13{
14 if (value >= 0)
15 return value;
16 else
17 return -value;
18}
19
20class Mean
21{
22 public:
23 void add(const int value)
24 {
25 sum_ += value;
26 ++count_;
27 }
28
29 int mean() const
30 {
31 return sum_ / count_;
32 }
33
34 void check_mean_range(const std::string &title, const int low, const int hi) const
35 {
36 const int m = mean();
37 ASSERT_TRUE(m > low && m < hi) << title << ' ' << to_string() << " outside of range=(" << low << ',' << hi << ')';
38 }
39
40 int count() const
41 {
42 return count_;
43 }
44
45 std::string to_string() const
46 {
47 return printfmt("[mean=%s count=%s]", mean(), count());
48 }
49
50 private:
51 int count_ = 0;
52 int sum_ = 0;
53};
54
55struct MeanDev
56{
59
60 std::string to_string() const
61 {
62 return mean.to_string() + " dev=" + dev.to_string();
63 }
64};
65
66void test_skew(const Time::Duration &dur,
67 const unsigned int skew_factor,
68 MeanDev &md,
69 const bool verbose,
70 RandomAPI &prng)
71{
72 const Time::Duration after = TimeSkew::skew(dur, skew_factor, prng);
73 md.mean.add(static_cast<int>(after.to_binary_ms()));
74 md.dev.add(my_abs(int(dur.to_binary_ms()) - int(after.to_binary_ms())));
75 if (verbose)
76 OPENVPN_LOG("BEFORE=" << dur.to_binary_ms() << " AFTER=" << after.to_binary_ms());
77}
78
79TEST(time, timeskew)
80{
81 MTRand::Ptr prng(new MTRand());
82 MeanDev md;
83 for (int i = 0; i < 10000; ++i)
84 {
85 test_skew(Time::Duration::seconds(10), TimeSkew::PCT_25, md, false, *prng);
86 }
87 // OPENVPN_LOG(md.to_string());
88 md.mean.check_mean_range("mean", 10100, 10300);
89 md.dev.check_mean_range("dev", 1250, 1350);
90}
91
92TEST(time, test1)
93{
95
96 const Time until = Time::now() + Time::Duration::seconds(1);
97
98 Time::base_type last_sec = 0;
99 Time::type last_frac = 0;
100
101 while (true)
102 {
103 const Time t = Time::now();
104 if (t >= until)
105 break;
106 const Time::base_type sec = t.seconds_since_epoch();
107 const Time::type frac = t.fractional_binary_ms();
108 if (sec != last_sec || frac != last_frac)
109 {
110 // std::cout << sec << ' ' << frac << std::endl;
111 last_sec = sec;
112 last_frac = frac;
113 }
114 }
115}
116
117static void sub(const Time &t1, const Time &t2, bool large)
118{
119 const Time::Duration d = t1 - t2;
120 // std::cout << "T-T " << t1.raw() << " - " << t2.raw() << " = " << d.raw() << std::endl;
121 if (large)
122 ASSERT_GE(d.raw(), 100000u);
123 else
124 ASSERT_EQ(d.raw(), 0u);
125}
126
127static void sub(const Time::Duration &d1, const Time::Duration &d2)
128{
129 const Time::Duration d = d1 - d2;
130 // std::cout << "D-D " << d1.raw() << " - " << d2.raw() << " = " << d.raw() << std::endl;
131 Time::Duration x = d1;
132 x -= d2;
133 ASSERT_EQ(x, d) << "D-D INCONSISTENCY DETECTED";
134}
135
136static void add(const Time &t1, const Time::Duration &d1)
137{
138 const Time t = t1 + d1;
139 // std::cout << "T+D " << t1.raw() << " + " << d1.raw() << " = " << t.raw() << std::endl;
140 Time x = t1;
141 x += d1;
142 ASSERT_EQ(x, t) << "T+D INCONSISTENCY DETECTED";
143}
144
145static void add(const Time::Duration &d1, const Time::Duration &d2)
146{
147 const Time::Duration d = d1 + d2;
148 // std::cout << "D+D " << d1.raw() << " + " << d2.raw() << " = " << d.raw() << std::endl;
149 Time::Duration x = d1;
150 x += d2;
151 ASSERT_EQ(x, d) << "D+D INCONSISTENCY DETECTED";
152}
153
154TEST(time, timeaddsub)
155{
156 {
157 const Time now = Time::now();
158 const Time inf = Time::infinite();
159 sub(now, now, false);
160 sub(inf, now, true);
161 sub(now, inf, false);
162 sub(inf, inf, false);
163 }
164 {
165 const Time::Duration sec = Time::Duration::seconds(1);
166 const Time::Duration inf = Time::Duration::infinite();
167 sub(sec, sec);
168 sub(inf, sec);
169 sub(sec, inf);
170 sub(inf, inf);
171 }
172 {
173 const Time tf = Time::now();
174 const Time ti = Time::infinite();
175 const Time::Duration df = Time::Duration::seconds(1);
176 const Time::Duration di = Time::Duration::infinite();
177 add(tf, df);
178 add(tf, di);
179 add(ti, df);
180 add(ti, di);
181 }
182 {
183 const Time::Duration sec = Time::Duration::seconds(1);
184 const Time::Duration inf = Time::Duration::infinite();
185 add(sec, sec);
186 add(inf, sec);
187 add(sec, inf);
188 add(inf, inf);
189 }
190}
int sum_
Definition test_time.cpp:52
int count() const
Definition test_time.cpp:40
int count_
Definition test_time.cpp:51
void add(const int value)
Definition test_time.cpp:23
int mean() const
Definition test_time.cpp:29
std::string to_string() const
Definition test_time.cpp:45
void check_mean_range(const std::string &title, const int low, const int hi) const
Definition test_time.cpp:34
The smart pointer class.
Definition rc.hpp:119
Abstract base class for random number generators.
Definition randapi.hpp:39
static TimeType infinite()
Definition time.hpp:256
static void reset_base()
Definition time.hpp:425
static TimeType now()
Definition time.hpp:305
base_type seconds_since_epoch() const
Definition time.hpp:292
T fractional_binary_ms() const
Definition time.hpp:300
#define OPENVPN_LOG(args)
std::string printfmt(const std::string &fmt, Args... args)
Definition format.hpp:314
Mean dev
Definition test_time.cpp:58
std::string to_string() const
Definition test_time.cpp:60
Mean mean
Definition test_time.cpp:57
static Time::Duration skew(const Time::Duration &dur, const unsigned int factor, RandomAPI &prng)
Definition skew.hpp:36
static bool verbose
Definition test_ip.cpp:31
TEST(time, timeskew)
Definition test_time.cpp:79
void test_skew(const Time::Duration &dur, const unsigned int skew_factor, MeanDev &md, const bool verbose, RandomAPI &prng)
Definition test_time.cpp:66
int my_abs(const int value)
Definition test_time.cpp:12
static void add(const Time &t1, const Time::Duration &d1)
static void sub(const Time &t1, const Time &t2, bool large)