blob: 310301d87696fc134f529e37d7d43bdba600dfda [file] [log] [blame]
brians343bc112013-02-10 01:53:46 +00001#include <unistd.h>
2
3#include <memory>
4
5#include "gtest/gtest.h"
6#include "aos/common/test_queue.q.h"
7#include "aos/common/queue_testutils.h"
Brian Silverman798c7782013-03-28 16:48:02 -07008#include "aos/common/util/thread.h"
Brian Silverman8d2e56e2013-09-23 17:55:03 -07009#include "aos/common/die.h"
brians343bc112013-02-10 01:53:46 +000010
11using ::aos::time::Time;
12
13namespace aos {
14namespace common {
brians343bc112013-02-10 01:53:46 +000015namespace testing {
16
17class QueueTest : public ::testing::Test {
18 protected:
Brian Silverman8d2e56e2013-09-23 17:55:03 -070019 void SetUp() override {
20 SetDieTestMode(true);
21 }
22
brians343bc112013-02-10 01:53:46 +000023 GlobalCoreInstance my_core;
24 // Create a new instance of the test queue so that it invalidates the queue
25 // that it points to. Otherwise, we will have a pointer to shared memory that
26 // is no longer valid.
27 ::aos::Queue<TestingMessage> my_test_queue;
28
29 QueueTest() : my_test_queue(".aos.common.testing.test_queue") {}
30};
31
Brian Silverman798c7782013-03-28 16:48:02 -070032class MyThread : public util::Thread {
brians343bc112013-02-10 01:53:46 +000033 public:
34 MyThread() : threaded_test_queue(".aos.common.testing.test_queue") {}
35
36 virtual void Run() {
Brian Silverman428de562014-04-10 15:59:19 -070037 threaded_test_queue.FetchNextBlocking();
brians343bc112013-02-10 01:53:46 +000038 EXPECT_TRUE(threaded_test_queue->test_bool);
39 EXPECT_EQ(0x971, threaded_test_queue->test_int);
40 }
41
42 ::aos::Queue<TestingMessage> threaded_test_queue;
43 private:
44 DISALLOW_COPY_AND_ASSIGN(MyThread);
45};
46
47
48// Tests that we can send a message to another thread and it blocking receives
49// it at the correct time.
50TEST_F(QueueTest, FetchBlocking) {
51 MyThread t;
52 t.Start();
53 usleep(50000);
54 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
55 t.Join();
Brian Silverman653491d2014-05-13 16:53:29 -070056 EXPECT_LE(t.threaded_test_queue.Age(), time::Time::InMS(57));
brians343bc112013-02-10 01:53:46 +000057}
58
59// Tests that we can send a message with the message pointer and get it back.
60TEST_F(QueueTest, SendMessage) {
61 ScopedMessagePtr<TestingMessage> msg = my_test_queue.MakeMessage();
62 msg->test_bool = true;
63 msg->test_int = 0x971;
64 msg.Send();
65
66 ASSERT_TRUE(my_test_queue.FetchLatest());
67 EXPECT_TRUE(my_test_queue->test_bool);
68 EXPECT_EQ(0x971, my_test_queue->test_int);
69}
70
brians343bc112013-02-10 01:53:46 +000071// Tests that we can send a message with the builder and get it back.
72TEST_F(QueueTest, SendWithBuilder) {
73 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
74
75 ASSERT_TRUE(my_test_queue.FetchLatest());
76 EXPECT_EQ(true, my_test_queue->test_bool);
77 EXPECT_EQ(0x971, my_test_queue->test_int);
78 EXPECT_EQ(true, my_test_queue.IsNewerThanMS(10000));
79}
80
Brian Silverman89c609d2015-04-03 16:14:15 -040081// Tests that multiple queue instances don't break each other.
82TEST_F(QueueTest, MultipleQueues) {
83 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
84 ASSERT_TRUE(my_test_queue.FetchLatest());
85 EXPECT_TRUE(my_test_queue.get());
86
87 {
88 ::aos::Queue<TestingMessage> my_other_test_queue(
89 ".aos.common.testing.queue_name");
90 my_other_test_queue.MakeMessage();
91 EXPECT_FALSE(my_other_test_queue.FetchLatest());
92 EXPECT_FALSE(my_test_queue.FetchLatest());
93 }
94
95 EXPECT_TRUE(my_test_queue.get());
96}
97
98// Tests that using a queue from multiple threads works correctly.
99TEST_F(QueueTest, MultipleThreads) {
100 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
101 ASSERT_TRUE(my_test_queue.FetchLatest());
102 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x254).Send();
103 EXPECT_EQ(0x971, my_test_queue->test_int);
104
105 ::aos::util::FunctionThread::RunInOtherThread([this]() {
106 ASSERT_TRUE(my_test_queue.FetchLatest());
107 EXPECT_EQ(0x254, my_test_queue->test_int);
108 });
109 EXPECT_EQ(0x254, my_test_queue->test_int);
110}
111
Brian Silverman42456d82014-08-19 12:43:59 -0400112// Makes sure that MakeWithBuilder zeros the message initially.
113// This might randomly succeed sometimes, but it will fail with asan if it
114// doesn't.
115TEST_F(QueueTest, BuilderZero) {
116 my_test_queue.MakeWithBuilder().Send();
117
118 ASSERT_TRUE(my_test_queue.FetchLatest());
119 EXPECT_FALSE(my_test_queue->test_bool);
120 EXPECT_EQ(0, my_test_queue->test_int);
121}
122
brians343bc112013-02-10 01:53:46 +0000123// Tests that various pointer deref functions at least seem to work.
124TEST_F(QueueTest, PointerDeref) {
125 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
126
127 ASSERT_TRUE(my_test_queue.FetchLatest());
128 const TestingMessage *msg_ptr = my_test_queue.get();
129 ASSERT_NE(static_cast<TestingMessage*>(NULL), msg_ptr);
130 EXPECT_EQ(0x971, msg_ptr->test_int);
131 EXPECT_EQ(msg_ptr, &(*my_test_queue));
132}
133
134// Tests that FetchNext doesn't miss any messages.
135TEST_F(QueueTest, FetchNext) {
136 for (int i = 0; i < 10; ++i) {
137 my_test_queue.MakeWithBuilder().test_bool(true).test_int(i).Send();
138 }
139
140 for (int i = 0; i < 10; ++i) {
141 ASSERT_TRUE(my_test_queue.FetchNext());
142 EXPECT_EQ(i, my_test_queue->test_int);
143 }
144}
145
146// Tests that FetchLatest skips a missing message.
147TEST_F(QueueTest, FetchLatest) {
148 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x254).Send();
149 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
150
151 ASSERT_TRUE(my_test_queue.FetchLatest());
152 EXPECT_EQ(0x971, my_test_queue->test_int);
153}
154
155// Tests that FetchLatest works with multiple readers.
156TEST_F(QueueTest, FetchLatestMultiple) {
157 ::aos::Queue<TestingMessage> my_second_test_queue(
158 ".aos.common.testing.test_queue");
159 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x254).Send();
160 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
161
162 ASSERT_TRUE(my_test_queue.FetchLatest());
163 EXPECT_EQ(0x971, my_test_queue->test_int);
164 ASSERT_TRUE(my_second_test_queue.FetchLatest());
165 ASSERT_TRUE(my_second_test_queue.get() != NULL);
166 EXPECT_EQ(0x971, my_second_test_queue->test_int);
167}
168
169
170// Tests that fetching without a new message returns false.
171TEST_F(QueueTest, FetchLatestWithoutMessage) {
172 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x254).Send();
173 EXPECT_TRUE(my_test_queue.FetchLatest());
174 EXPECT_FALSE(my_test_queue.FetchLatest());
175 EXPECT_FALSE(my_test_queue.FetchLatest());
176 EXPECT_EQ(0x254, my_test_queue->test_int);
177}
178
179// Tests that fetching without a message returns false.
180TEST_F(QueueTest, FetchOnFreshQueue) {
181 EXPECT_FALSE(my_test_queue.FetchLatest());
182 EXPECT_EQ(static_cast<TestingMessage*>(NULL), my_test_queue.get());
183}
184
185// Tests that fetch next without a message returns false.
186TEST_F(QueueTest, FetchNextOnFreshQueue) {
187 EXPECT_FALSE(my_test_queue.FetchNext());
188 EXPECT_EQ(static_cast<TestingMessage*>(NULL), my_test_queue.get());
189}
190
191// Tests that fetch next without a new message returns false.
192TEST_F(QueueTest, FetchNextWithoutMessage) {
193 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x254).Send();
194 EXPECT_TRUE(my_test_queue.FetchNext());
195 EXPECT_FALSE(my_test_queue.FetchNext());
196 EXPECT_NE(static_cast<TestingMessage*>(NULL), my_test_queue.get());
197}
198
199// Tests that age makes some sense.
200TEST_F(QueueTest, Age) {
201 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
202
203 ASSERT_TRUE(my_test_queue.FetchLatest());
204 EXPECT_TRUE(my_test_queue.IsNewerThanMS(100));
205 const Time age = my_test_queue.Age();
206 EXPECT_EQ(0, age.sec());
207 EXPECT_GE(100000000, age.nsec());
208}
209
210
211class GroupTest : public ::testing::Test {
212 protected:
213 GlobalCoreInstance my_core;
214 // Create a new instance of the test group so that it invalidates the queue
215 // that it points to. Otherwise, we will have a pointer to shared memory that
216 // is no longer valid.
217 TwoQueues my_test_queuegroup;
218
219 GroupTest()
220 : my_test_queuegroup(".aos.common.testing.test_queuegroup",
221 0x20561114,
222 ".aos.common.testing.test_queuegroup.first",
223 ".aos.common.testing.test_queuegroup.second") {}
224};
225
226// Tests that the hash gets preserved.
227TEST_F(GroupTest, Hash) {
228 EXPECT_EQ(static_cast<uint32_t>(0x20561114), my_test_queuegroup.hash());
229}
230
231// Tests that the hash works.
232TEST_F(GroupTest, RealHash) {
Brian Silverman981a7bb2014-02-16 21:17:04 -0800233 EXPECT_EQ(static_cast<uint32_t>(0x93596b2f), test_queuegroup.hash());
brians343bc112013-02-10 01:53:46 +0000234}
235
236// Tests that name works.
237TEST_F(GroupTest, Name) {
238 EXPECT_EQ(std::string(".aos.common.testing.test_queuegroup"),
239 std::string(my_test_queuegroup.name()));
240}
241
242
243class MessageTest : public ::testing::Test {
244 public:
245 TestingMessage msg;
246};
247
248TEST_F(MessageTest, Zeroing) {
249 msg.test_bool = true;
250 msg.test_int = 0x254;
251 msg.SetTimeToNow();
252
253 msg.Zero();
254
255 EXPECT_FALSE(msg.test_bool);
256 EXPECT_EQ(0, msg.test_int);
257 EXPECT_EQ(0, msg.sent_time.sec());
258 EXPECT_EQ(0, msg.sent_time.nsec());
259}
260
261TEST_F(MessageTest, Size) {
262 EXPECT_EQ(static_cast<size_t>(13), msg.Size());
263}
264
265TEST_F(MessageTest, Serialize) {
266 char serialized_data[msg.Size()];
267 msg.test_bool = true;
268 msg.test_int = 0x254;
269 msg.SetTimeToNow();
270
271 msg.Serialize(serialized_data);
272
273 TestingMessage new_msg;
274 new_msg.Deserialize(serialized_data);
275
276 EXPECT_EQ(msg.test_bool, new_msg.test_bool);
277 EXPECT_EQ(msg.test_int, new_msg.test_int);
278 EXPECT_EQ(msg.sent_time, new_msg.sent_time);
279}
280
281// Tests that Print prints out a message nicely.
282TEST_F(MessageTest, Print) {
283 char printdata[1024];
284 msg.test_bool = true;
285 msg.test_int = 2056;
286 msg.sent_time = Time(971, 254);
287
Brian Silverman981a7bb2014-02-16 21:17:04 -0800288 std::string golden("971.000000254s, T, 2056");
brians343bc112013-02-10 01:53:46 +0000289 EXPECT_EQ(golden.size(), msg.Print(printdata, sizeof(printdata)));
290
291 EXPECT_EQ(golden, std::string(printdata));
292}
293
294// Tests that the hash never changes. If it changes, then someone broke the
295// hash routine or changed the message declaration. Both changes need to be
296// validated by hand.
297TEST_F(MessageTest, Hash) {
Brian Silverman981a7bb2014-02-16 21:17:04 -0800298 EXPECT_EQ(static_cast<uint32_t>(0xc33651ac),
brians343bc112013-02-10 01:53:46 +0000299 static_cast<uint32_t>(TestingMessage::kHash));
300}
301
302TEST_F(MessageTest, SetNow) {
303 msg.SetTimeToNow();
304 EXPECT_LE(msg.sent_time - Time::Now(), Time::InMS(20));
305}
306
Brian Silverman203a0fc2015-03-16 15:21:00 -0700307// Tests that EqualsNoTime works.
308TEST_F(MessageTest, EqualsNoTime) {
309 msg.test_bool = true;
310 msg.test_int = 971;
311 TestingMessage other;
312 other.test_int = 971;
313 EXPECT_FALSE(other.EqualsNoTime(msg));
314 EXPECT_FALSE(msg.EqualsNoTime(other));
315 other.test_bool = true;
316 EXPECT_TRUE(other.EqualsNoTime(msg));
317 EXPECT_TRUE(msg.EqualsNoTime(other));
318 msg.SetTimeToNow();
319 EXPECT_TRUE(msg.EqualsNoTime(other));
320}
321
brians343bc112013-02-10 01:53:46 +0000322} // namespace testing
323} // namespace common
324} // namespace aos