blob: 1641a920126764ca0978ceeda20ca9711d336a47 [file] [log] [blame]
Brian Silvermandcaa3f72015-11-29 05:32:08 +00001#include "aos/common/util/phased_loop.h"
2
3#include "gtest/gtest.h"
4
Brian Silvermanf5f8d8e2015-12-06 18:39:12 -05005#include "aos/testing/test_logging.h"
Brian Silvermandcaa3f72015-11-29 05:32:08 +00006
7namespace aos {
8namespace time {
9namespace testing {
10
11class PhasedLoopTest : public ::testing::Test {
12 protected:
13 PhasedLoopTest() {
Brian Silvermanf5f8d8e2015-12-06 18:39:12 -050014 ::aos::testing::EnableTestLogging();
Brian Silvermandcaa3f72015-11-29 05:32:08 +000015 }
16};
17
18typedef PhasedLoopTest PhasedLoopDeathTest;
19
20TEST_F(PhasedLoopTest, Reset) {
21 {
22 PhasedLoop loop(Time::InMS(100), Time::kZero);
23
24 loop.Reset(Time::kZero);
25 EXPECT_EQ(Time::InMS(0), loop.sleep_time());
26 EXPECT_EQ(1, loop.Iterate(Time::kZero));
27 EXPECT_EQ(Time::InMS(100), loop.sleep_time());
28
29 loop.Reset(Time::InMS(99));
30 EXPECT_EQ(Time::InMS(0), loop.sleep_time());
31 EXPECT_EQ(1, loop.Iterate(Time::InMS(99)));
32 EXPECT_EQ(Time::InMS(100), loop.sleep_time());
33
34 loop.Reset(Time::InMS(100));
35 EXPECT_EQ(Time::InMS(100), loop.sleep_time());
36 EXPECT_EQ(1, loop.Iterate(Time::InMS(199)));
37 EXPECT_EQ(Time::InMS(200), loop.sleep_time());
38
39 loop.Reset(Time::InMS(101));
40 EXPECT_EQ(Time::InMS(100), loop.sleep_time());
41 EXPECT_EQ(1, loop.Iterate(Time::InMS(101)));
42 EXPECT_EQ(Time::InMS(200), loop.sleep_time());
43 }
44 {
45 PhasedLoop loop(Time::InMS(100), Time::InMS(1));
46 loop.Reset(Time::kZero);
47 EXPECT_EQ(Time::InMS(-99), loop.sleep_time());
48 EXPECT_EQ(1, loop.Iterate(Time::kZero));
49 EXPECT_EQ(Time::InMS(1), loop.sleep_time());
50 }
51 {
52 PhasedLoop loop(Time::InMS(100), Time::InMS(99));
53
54 loop.Reset(Time::kZero);
55 EXPECT_EQ(Time::InMS(-1), loop.sleep_time());
56 EXPECT_EQ(1, loop.Iterate(Time::kZero));
57 EXPECT_EQ(Time::InMS(99), loop.sleep_time());
58
59 loop.Reset(Time::InMS(98));
60 EXPECT_EQ(Time::InMS(-1), loop.sleep_time());
61 EXPECT_EQ(1, loop.Iterate(Time::InMS(98)));
62 EXPECT_EQ(Time::InMS(99), loop.sleep_time());
63
64 loop.Reset(Time::InMS(99));
65 EXPECT_EQ(Time::InMS(99), loop.sleep_time());
66 EXPECT_EQ(1, loop.Iterate(Time::InMS(99)));
67 EXPECT_EQ(Time::InMS(199), loop.sleep_time());
68
69 loop.Reset(Time::InMS(100));
70 EXPECT_EQ(Time::InMS(99), loop.sleep_time());
71 EXPECT_EQ(1, loop.Iterate(Time::InMS(100)));
72 EXPECT_EQ(Time::InMS(199), loop.sleep_time());
73 }
74}
75
76TEST_F(PhasedLoopTest, Iterate) {
77 {
78 PhasedLoop loop(Time::InMS(100), Time::InMS(99));
79 loop.Reset(Time::kZero);
80 EXPECT_EQ(1, loop.Iterate(Time::kZero));
81 EXPECT_EQ(Time::InMS(99), loop.sleep_time());
82 EXPECT_EQ(1, loop.Iterate(Time::InMS(100)));
83 EXPECT_EQ(Time::InMS(199), loop.sleep_time());
84 EXPECT_EQ(0, loop.Iterate(Time::InMS(100)));
85 EXPECT_EQ(Time::InMS(199), loop.sleep_time());
86 EXPECT_EQ(0, loop.Iterate(Time::InMS(101)));
87 EXPECT_EQ(Time::InMS(199), loop.sleep_time());
88 EXPECT_EQ(0, loop.Iterate(Time::InMS(198)));
89 EXPECT_EQ(Time::InMS(199), loop.sleep_time());
90 EXPECT_EQ(1, loop.Iterate(Time::InMS(199)));
91 EXPECT_EQ(Time::InMS(299), loop.sleep_time());
92 EXPECT_EQ(1, loop.Iterate(Time::InMS(300)));
93 EXPECT_EQ(Time::InMS(399), loop.sleep_time());
94 EXPECT_EQ(3, loop.Iterate(Time::InMS(600)));
95 EXPECT_EQ(Time::InMS(699), loop.sleep_time());
96 }
97 {
98 PhasedLoop loop(Time::InMS(100), Time::InMS(1));
99 loop.Reset(Time::kZero);
100 EXPECT_EQ(1, loop.Iterate(Time::kZero));
101 EXPECT_EQ(Time::InMS(1), loop.sleep_time());
102 EXPECT_EQ(1, loop.Iterate(Time::InMS(100)));
103 EXPECT_EQ(Time::InMS(101), loop.sleep_time());
104 EXPECT_EQ(0, loop.Iterate(Time::InMS(100)));
105 EXPECT_EQ(Time::InMS(101), loop.sleep_time());
106 EXPECT_EQ(1, loop.Iterate(Time::InMS(103)));
107 EXPECT_EQ(Time::InMS(201), loop.sleep_time());
108 EXPECT_EQ(0, loop.Iterate(Time::InMS(198)));
109 EXPECT_EQ(Time::InMS(201), loop.sleep_time());
110 EXPECT_EQ(0, loop.Iterate(Time::InMS(200)));
111 EXPECT_EQ(Time::InMS(201), loop.sleep_time());
112 EXPECT_EQ(1, loop.Iterate(Time::InMS(201)));
113 EXPECT_EQ(Time::InMS(301), loop.sleep_time());
114 EXPECT_EQ(3, loop.Iterate(Time::InMS(600)));
115 EXPECT_EQ(Time::InMS(601), loop.sleep_time());
116 }
117}
118
119// Makes sure that everything works correctly when crossing zero.
120// This seems like a rare case at first, but starting from zero needs to
121// work, which means negatives should too.
122TEST_F(PhasedLoopTest, CrossingZero) {
123 PhasedLoop loop(Time::InMS(100), Time::InMS(1));
124 loop.Reset(Time::InMS(-1000));
125 EXPECT_EQ(Time::InMS(-1099), loop.sleep_time());
126 EXPECT_EQ(9, loop.Iterate(Time::InMS(-250)));
127 EXPECT_EQ(Time::InMS(-199), loop.sleep_time());
128 EXPECT_EQ(1, loop.Iterate(Time::InMS(-199)));
129 EXPECT_EQ(Time::InMS(-99), loop.sleep_time());
130 EXPECT_EQ(1, loop.Iterate(Time::InMS(-90)));
131 EXPECT_EQ(Time::InMS(1), loop.sleep_time());
132 EXPECT_EQ(0, loop.Iterate(Time::InMS(0)));
133 EXPECT_EQ(Time::InMS(1), loop.sleep_time());
134 EXPECT_EQ(1, loop.Iterate(Time::InMS(1)));
135 EXPECT_EQ(Time::InMS(101), loop.sleep_time());
136
137 EXPECT_EQ(0, loop.Iterate(Time::InMS(2)));
138 EXPECT_EQ(Time::InMS(101), loop.sleep_time());
139
140 EXPECT_EQ(-2, loop.Iterate(Time::InMS(-101)));
141 EXPECT_EQ(Time::InMS(-99), loop.sleep_time());
142 EXPECT_EQ(1, loop.Iterate(Time::InMS(-99)));
143 EXPECT_EQ(Time::InMS(1), loop.sleep_time());
144
145 EXPECT_EQ(0, loop.Iterate(Time::InMS(-99)));
146 EXPECT_EQ(Time::InMS(1), loop.sleep_time());
147}
148
149// Tests that passing invalid values to the constructor dies correctly.
150TEST_F(PhasedLoopDeathTest, InvalidValues) {
151 EXPECT_DEATH(PhasedLoop(Time::InMS(1), Time::InMS(2)), ".*offset<interval.*");
152 EXPECT_DEATH(PhasedLoop(Time::InMS(1), Time::InMS(1)), ".*offset<interval.*");
153 EXPECT_DEATH(PhasedLoop(Time::InMS(1), Time::InMS(-1)),
154 ".*offset>=Time::kZero.*");
155 EXPECT_DEATH(PhasedLoop(Time::InMS(0), Time::InMS(0)),
156 ".*interval>Time::kZero.*");
157}
158
159} // namespace testing
160} // namespace time
161} // namespace aos