blob: 8eeca6ea0e039e69b1a28296543d172e702187e9 [file] [log] [blame]
brians343bc112013-02-10 01:53:46 +00001#include <unistd.h>
2
Austin Schuhf2a50ba2016-12-24 16:16:26 -08003#include <chrono>
brians343bc112013-02-10 01:53:46 +00004#include <memory>
5
6#include "gtest/gtest.h"
Brian Silvermanf5f8d8e2015-12-06 18:39:12 -05007
John Park33858a32018-09-28 23:05:48 -07008#include "aos/die.h"
9#include "aos/test_queue.q.h"
10#include "aos/util/thread.h"
Brian Silvermanf5f8d8e2015-12-06 18:39:12 -050011#include "aos/testing/test_shm.h"
brians343bc112013-02-10 01:53:46 +000012
brians343bc112013-02-10 01:53:46 +000013namespace aos {
14namespace common {
brians343bc112013-02-10 01:53:46 +000015namespace testing {
16
Austin Schuhf2a50ba2016-12-24 16:16:26 -080017namespace chrono = ::std::chrono;
18
brians343bc112013-02-10 01:53:46 +000019class QueueTest : public ::testing::Test {
20 protected:
Brian Silverman8d2e56e2013-09-23 17:55:03 -070021 void SetUp() override {
22 SetDieTestMode(true);
23 }
24
Brian Silvermanf5f8d8e2015-12-06 18:39:12 -050025 ::aos::testing::TestSharedMemory my_shm_;
brians343bc112013-02-10 01:53:46 +000026 // Create a new instance of the test queue so that it invalidates the queue
27 // that it points to. Otherwise, we will have a pointer to shared memory that
28 // is no longer valid.
29 ::aos::Queue<TestingMessage> my_test_queue;
30
31 QueueTest() : my_test_queue(".aos.common.testing.test_queue") {}
32};
33
Brian Silverman798c7782013-03-28 16:48:02 -070034class MyThread : public util::Thread {
brians343bc112013-02-10 01:53:46 +000035 public:
36 MyThread() : threaded_test_queue(".aos.common.testing.test_queue") {}
37
38 virtual void Run() {
Brian Silverman428de562014-04-10 15:59:19 -070039 threaded_test_queue.FetchNextBlocking();
brians343bc112013-02-10 01:53:46 +000040 EXPECT_TRUE(threaded_test_queue->test_bool);
41 EXPECT_EQ(0x971, threaded_test_queue->test_int);
42 }
43
44 ::aos::Queue<TestingMessage> threaded_test_queue;
45 private:
46 DISALLOW_COPY_AND_ASSIGN(MyThread);
47};
48
49
50// Tests that we can send a message to another thread and it blocking receives
51// it at the correct time.
52TEST_F(QueueTest, FetchBlocking) {
53 MyThread t;
54 t.Start();
55 usleep(50000);
56 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
57 t.Join();
Austin Schuhf2a50ba2016-12-24 16:16:26 -080058 EXPECT_LE(t.threaded_test_queue.Age(), chrono::milliseconds(57));
brians343bc112013-02-10 01:53:46 +000059}
60
61// Tests that we can send a message with the message pointer and get it back.
62TEST_F(QueueTest, SendMessage) {
63 ScopedMessagePtr<TestingMessage> msg = my_test_queue.MakeMessage();
64 msg->test_bool = true;
65 msg->test_int = 0x971;
66 msg.Send();
67
68 ASSERT_TRUE(my_test_queue.FetchLatest());
69 EXPECT_TRUE(my_test_queue->test_bool);
70 EXPECT_EQ(0x971, my_test_queue->test_int);
71}
72
brians343bc112013-02-10 01:53:46 +000073// Tests that we can send a message with the builder and get it back.
74TEST_F(QueueTest, SendWithBuilder) {
75 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
76
77 ASSERT_TRUE(my_test_queue.FetchLatest());
78 EXPECT_EQ(true, my_test_queue->test_bool);
79 EXPECT_EQ(0x971, my_test_queue->test_int);
Austin Schuhf2a50ba2016-12-24 16:16:26 -080080 EXPECT_EQ(true, my_test_queue.IsNewerThan(chrono::milliseconds(10000)));
brians343bc112013-02-10 01:53:46 +000081}
82
Brian Silverman89c609d2015-04-03 16:14:15 -040083// Tests that multiple queue instances don't break each other.
84TEST_F(QueueTest, MultipleQueues) {
85 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
86 ASSERT_TRUE(my_test_queue.FetchLatest());
87 EXPECT_TRUE(my_test_queue.get());
88
89 {
90 ::aos::Queue<TestingMessage> my_other_test_queue(
91 ".aos.common.testing.queue_name");
92 my_other_test_queue.MakeMessage();
93 EXPECT_FALSE(my_other_test_queue.FetchLatest());
94 EXPECT_FALSE(my_test_queue.FetchLatest());
95 }
96
97 EXPECT_TRUE(my_test_queue.get());
98}
99
100// Tests that using a queue from multiple threads works correctly.
101TEST_F(QueueTest, MultipleThreads) {
102 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
103 ASSERT_TRUE(my_test_queue.FetchLatest());
104 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x254).Send();
105 EXPECT_EQ(0x971, my_test_queue->test_int);
106
107 ::aos::util::FunctionThread::RunInOtherThread([this]() {
108 ASSERT_TRUE(my_test_queue.FetchLatest());
109 EXPECT_EQ(0x254, my_test_queue->test_int);
110 });
111 EXPECT_EQ(0x254, my_test_queue->test_int);
112}
113
Brian Silverman42456d82014-08-19 12:43:59 -0400114// Makes sure that MakeWithBuilder zeros the message initially.
115// This might randomly succeed sometimes, but it will fail with asan if it
116// doesn't.
117TEST_F(QueueTest, BuilderZero) {
118 my_test_queue.MakeWithBuilder().Send();
119
120 ASSERT_TRUE(my_test_queue.FetchLatest());
121 EXPECT_FALSE(my_test_queue->test_bool);
122 EXPECT_EQ(0, my_test_queue->test_int);
123}
124
brians343bc112013-02-10 01:53:46 +0000125// Tests that various pointer deref functions at least seem to work.
126TEST_F(QueueTest, PointerDeref) {
127 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
128
129 ASSERT_TRUE(my_test_queue.FetchLatest());
130 const TestingMessage *msg_ptr = my_test_queue.get();
131 ASSERT_NE(static_cast<TestingMessage*>(NULL), msg_ptr);
132 EXPECT_EQ(0x971, msg_ptr->test_int);
133 EXPECT_EQ(msg_ptr, &(*my_test_queue));
134}
135
136// Tests that FetchNext doesn't miss any messages.
137TEST_F(QueueTest, FetchNext) {
138 for (int i = 0; i < 10; ++i) {
139 my_test_queue.MakeWithBuilder().test_bool(true).test_int(i).Send();
140 }
141
142 for (int i = 0; i < 10; ++i) {
143 ASSERT_TRUE(my_test_queue.FetchNext());
144 EXPECT_EQ(i, my_test_queue->test_int);
145 }
146}
147
148// Tests that FetchLatest skips a missing message.
149TEST_F(QueueTest, FetchLatest) {
150 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x254).Send();
151 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
152
153 ASSERT_TRUE(my_test_queue.FetchLatest());
154 EXPECT_EQ(0x971, my_test_queue->test_int);
155}
156
157// Tests that FetchLatest works with multiple readers.
158TEST_F(QueueTest, FetchLatestMultiple) {
159 ::aos::Queue<TestingMessage> my_second_test_queue(
160 ".aos.common.testing.test_queue");
161 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x254).Send();
162 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
163
164 ASSERT_TRUE(my_test_queue.FetchLatest());
165 EXPECT_EQ(0x971, my_test_queue->test_int);
166 ASSERT_TRUE(my_second_test_queue.FetchLatest());
167 ASSERT_TRUE(my_second_test_queue.get() != NULL);
168 EXPECT_EQ(0x971, my_second_test_queue->test_int);
169}
170
171
172// Tests that fetching without a new message returns false.
173TEST_F(QueueTest, FetchLatestWithoutMessage) {
174 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x254).Send();
175 EXPECT_TRUE(my_test_queue.FetchLatest());
176 EXPECT_FALSE(my_test_queue.FetchLatest());
177 EXPECT_FALSE(my_test_queue.FetchLatest());
178 EXPECT_EQ(0x254, my_test_queue->test_int);
179}
180
181// Tests that fetching without a message returns false.
182TEST_F(QueueTest, FetchOnFreshQueue) {
183 EXPECT_FALSE(my_test_queue.FetchLatest());
184 EXPECT_EQ(static_cast<TestingMessage*>(NULL), my_test_queue.get());
185}
186
187// Tests that fetch next without a message returns false.
188TEST_F(QueueTest, FetchNextOnFreshQueue) {
189 EXPECT_FALSE(my_test_queue.FetchNext());
190 EXPECT_EQ(static_cast<TestingMessage*>(NULL), my_test_queue.get());
191}
192
193// Tests that fetch next without a new message returns false.
194TEST_F(QueueTest, FetchNextWithoutMessage) {
195 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x254).Send();
196 EXPECT_TRUE(my_test_queue.FetchNext());
197 EXPECT_FALSE(my_test_queue.FetchNext());
198 EXPECT_NE(static_cast<TestingMessage*>(NULL), my_test_queue.get());
199}
200
201// Tests that age makes some sense.
202TEST_F(QueueTest, Age) {
203 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
204
205 ASSERT_TRUE(my_test_queue.FetchLatest());
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800206 EXPECT_TRUE(my_test_queue.IsNewerThan(chrono::milliseconds(100)));
207 const auto age = my_test_queue.Age();
208 EXPECT_GE(chrono::nanoseconds(100000000), age);
brians343bc112013-02-10 01:53:46 +0000209}
210
211
212class GroupTest : public ::testing::Test {
213 protected:
brians343bc112013-02-10 01:53:46 +0000214 GroupTest()
215 : my_test_queuegroup(".aos.common.testing.test_queuegroup",
216 0x20561114,
217 ".aos.common.testing.test_queuegroup.first",
218 ".aos.common.testing.test_queuegroup.second") {}
Brian Silvermanf5f8d8e2015-12-06 18:39:12 -0500219
220 // Create a new instance of the test group so that it invalidates the queue
221 // that it points to. Otherwise, we will have a pointer to shared memory that
222 // is no longer valid.
223 TwoQueues my_test_queuegroup;
224
225 private:
226 ::aos::testing::TestSharedMemory my_shm_;
brians343bc112013-02-10 01:53:46 +0000227};
228
229// Tests that the hash gets preserved.
230TEST_F(GroupTest, Hash) {
231 EXPECT_EQ(static_cast<uint32_t>(0x20561114), my_test_queuegroup.hash());
232}
233
234// Tests that the hash works.
235TEST_F(GroupTest, RealHash) {
Brian Silverman981a7bb2014-02-16 21:17:04 -0800236 EXPECT_EQ(static_cast<uint32_t>(0x93596b2f), test_queuegroup.hash());
brians343bc112013-02-10 01:53:46 +0000237}
238
239// Tests that name works.
240TEST_F(GroupTest, Name) {
241 EXPECT_EQ(std::string(".aos.common.testing.test_queuegroup"),
242 std::string(my_test_queuegroup.name()));
243}
244
245
246class MessageTest : public ::testing::Test {
247 public:
248 TestingMessage msg;
249};
250
251TEST_F(MessageTest, Zeroing) {
252 msg.test_bool = true;
253 msg.test_int = 0x254;
254 msg.SetTimeToNow();
255
256 msg.Zero();
257
258 EXPECT_FALSE(msg.test_bool);
259 EXPECT_EQ(0, msg.test_int);
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800260 EXPECT_EQ(monotonic_clock::min_time, msg.sent_time);
brians343bc112013-02-10 01:53:46 +0000261}
262
263TEST_F(MessageTest, Size) {
264 EXPECT_EQ(static_cast<size_t>(13), msg.Size());
265}
266
267TEST_F(MessageTest, Serialize) {
268 char serialized_data[msg.Size()];
269 msg.test_bool = true;
270 msg.test_int = 0x254;
271 msg.SetTimeToNow();
272
273 msg.Serialize(serialized_data);
274
275 TestingMessage new_msg;
276 new_msg.Deserialize(serialized_data);
277
278 EXPECT_EQ(msg.test_bool, new_msg.test_bool);
279 EXPECT_EQ(msg.test_int, new_msg.test_int);
280 EXPECT_EQ(msg.sent_time, new_msg.sent_time);
281}
282
283// Tests that Print prints out a message nicely.
284TEST_F(MessageTest, Print) {
285 char printdata[1024];
286 msg.test_bool = true;
287 msg.test_int = 2056;
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800288 msg.sent_time = monotonic_clock::time_point(chrono::seconds(971) +
289 chrono::nanoseconds(254));
brians343bc112013-02-10 01:53:46 +0000290
Brian Silverman981a7bb2014-02-16 21:17:04 -0800291 std::string golden("971.000000254s, T, 2056");
brians343bc112013-02-10 01:53:46 +0000292 EXPECT_EQ(golden.size(), msg.Print(printdata, sizeof(printdata)));
293
294 EXPECT_EQ(golden, std::string(printdata));
295}
296
297// Tests that the hash never changes. If it changes, then someone broke the
298// hash routine or changed the message declaration. Both changes need to be
299// validated by hand.
300TEST_F(MessageTest, Hash) {
Brian Silverman981a7bb2014-02-16 21:17:04 -0800301 EXPECT_EQ(static_cast<uint32_t>(0xc33651ac),
brians343bc112013-02-10 01:53:46 +0000302 static_cast<uint32_t>(TestingMessage::kHash));
303}
304
305TEST_F(MessageTest, SetNow) {
306 msg.SetTimeToNow();
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800307 EXPECT_LE(msg.sent_time - monotonic_clock::now(), chrono::milliseconds(20));
brians343bc112013-02-10 01:53:46 +0000308}
309
Brian Silverman203a0fc2015-03-16 15:21:00 -0700310// Tests that EqualsNoTime works.
311TEST_F(MessageTest, EqualsNoTime) {
312 msg.test_bool = true;
313 msg.test_int = 971;
314 TestingMessage other;
315 other.test_int = 971;
316 EXPECT_FALSE(other.EqualsNoTime(msg));
317 EXPECT_FALSE(msg.EqualsNoTime(other));
318 other.test_bool = true;
319 EXPECT_TRUE(other.EqualsNoTime(msg));
320 EXPECT_TRUE(msg.EqualsNoTime(other));
321 msg.SetTimeToNow();
322 EXPECT_TRUE(msg.EqualsNoTime(other));
323}
324
brians343bc112013-02-10 01:53:46 +0000325} // namespace testing
326} // namespace common
327} // namespace aos