blob: dc8c62cefe46bd5878ecf9402eb13b622d514f02 [file] [log] [blame]
brians343bc112013-02-10 01:53:46 +00001#include <unistd.h>
2
3#include <memory>
4
5#include "gtest/gtest.h"
Brian Silvermanf5f8d8e2015-12-06 18:39:12 -05006
brians343bc112013-02-10 01:53:46 +00007#include "aos/common/test_queue.q.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"
Brian Silvermanf5f8d8e2015-12-06 18:39:12 -050010#include "aos/testing/test_shm.h"
brians343bc112013-02-10 01:53:46 +000011
12using ::aos::time::Time;
13
14namespace aos {
15namespace common {
brians343bc112013-02-10 01:53:46 +000016namespace testing {
17
18class QueueTest : public ::testing::Test {
19 protected:
Brian Silverman8d2e56e2013-09-23 17:55:03 -070020 void SetUp() override {
21 SetDieTestMode(true);
22 }
23
Brian Silvermanf5f8d8e2015-12-06 18:39:12 -050024 ::aos::testing::TestSharedMemory my_shm_;
brians343bc112013-02-10 01:53:46 +000025 // Create a new instance of the test queue so that it invalidates the queue
26 // that it points to. Otherwise, we will have a pointer to shared memory that
27 // is no longer valid.
28 ::aos::Queue<TestingMessage> my_test_queue;
29
30 QueueTest() : my_test_queue(".aos.common.testing.test_queue") {}
31};
32
Brian Silverman798c7782013-03-28 16:48:02 -070033class MyThread : public util::Thread {
brians343bc112013-02-10 01:53:46 +000034 public:
35 MyThread() : threaded_test_queue(".aos.common.testing.test_queue") {}
36
37 virtual void Run() {
Brian Silverman428de562014-04-10 15:59:19 -070038 threaded_test_queue.FetchNextBlocking();
brians343bc112013-02-10 01:53:46 +000039 EXPECT_TRUE(threaded_test_queue->test_bool);
40 EXPECT_EQ(0x971, threaded_test_queue->test_int);
41 }
42
43 ::aos::Queue<TestingMessage> threaded_test_queue;
44 private:
45 DISALLOW_COPY_AND_ASSIGN(MyThread);
46};
47
48
49// Tests that we can send a message to another thread and it blocking receives
50// it at the correct time.
51TEST_F(QueueTest, FetchBlocking) {
52 MyThread t;
53 t.Start();
54 usleep(50000);
55 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
56 t.Join();
Brian Silverman653491d2014-05-13 16:53:29 -070057 EXPECT_LE(t.threaded_test_queue.Age(), time::Time::InMS(57));
brians343bc112013-02-10 01:53:46 +000058}
59
60// Tests that we can send a message with the message pointer and get it back.
61TEST_F(QueueTest, SendMessage) {
62 ScopedMessagePtr<TestingMessage> msg = my_test_queue.MakeMessage();
63 msg->test_bool = true;
64 msg->test_int = 0x971;
65 msg.Send();
66
67 ASSERT_TRUE(my_test_queue.FetchLatest());
68 EXPECT_TRUE(my_test_queue->test_bool);
69 EXPECT_EQ(0x971, my_test_queue->test_int);
70}
71
brians343bc112013-02-10 01:53:46 +000072// Tests that we can send a message with the builder and get it back.
73TEST_F(QueueTest, SendWithBuilder) {
74 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
75
76 ASSERT_TRUE(my_test_queue.FetchLatest());
77 EXPECT_EQ(true, my_test_queue->test_bool);
78 EXPECT_EQ(0x971, my_test_queue->test_int);
79 EXPECT_EQ(true, my_test_queue.IsNewerThanMS(10000));
80}
81
Brian Silverman89c609d2015-04-03 16:14:15 -040082// Tests that multiple queue instances don't break each other.
83TEST_F(QueueTest, MultipleQueues) {
84 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
85 ASSERT_TRUE(my_test_queue.FetchLatest());
86 EXPECT_TRUE(my_test_queue.get());
87
88 {
89 ::aos::Queue<TestingMessage> my_other_test_queue(
90 ".aos.common.testing.queue_name");
91 my_other_test_queue.MakeMessage();
92 EXPECT_FALSE(my_other_test_queue.FetchLatest());
93 EXPECT_FALSE(my_test_queue.FetchLatest());
94 }
95
96 EXPECT_TRUE(my_test_queue.get());
97}
98
99// Tests that using a queue from multiple threads works correctly.
100TEST_F(QueueTest, MultipleThreads) {
101 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
102 ASSERT_TRUE(my_test_queue.FetchLatest());
103 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x254).Send();
104 EXPECT_EQ(0x971, my_test_queue->test_int);
105
106 ::aos::util::FunctionThread::RunInOtherThread([this]() {
107 ASSERT_TRUE(my_test_queue.FetchLatest());
108 EXPECT_EQ(0x254, my_test_queue->test_int);
109 });
110 EXPECT_EQ(0x254, my_test_queue->test_int);
111}
112
Brian Silverman42456d82014-08-19 12:43:59 -0400113// Makes sure that MakeWithBuilder zeros the message initially.
114// This might randomly succeed sometimes, but it will fail with asan if it
115// doesn't.
116TEST_F(QueueTest, BuilderZero) {
117 my_test_queue.MakeWithBuilder().Send();
118
119 ASSERT_TRUE(my_test_queue.FetchLatest());
120 EXPECT_FALSE(my_test_queue->test_bool);
121 EXPECT_EQ(0, my_test_queue->test_int);
122}
123
brians343bc112013-02-10 01:53:46 +0000124// Tests that various pointer deref functions at least seem to work.
125TEST_F(QueueTest, PointerDeref) {
126 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
127
128 ASSERT_TRUE(my_test_queue.FetchLatest());
129 const TestingMessage *msg_ptr = my_test_queue.get();
130 ASSERT_NE(static_cast<TestingMessage*>(NULL), msg_ptr);
131 EXPECT_EQ(0x971, msg_ptr->test_int);
132 EXPECT_EQ(msg_ptr, &(*my_test_queue));
133}
134
135// Tests that FetchNext doesn't miss any messages.
136TEST_F(QueueTest, FetchNext) {
137 for (int i = 0; i < 10; ++i) {
138 my_test_queue.MakeWithBuilder().test_bool(true).test_int(i).Send();
139 }
140
141 for (int i = 0; i < 10; ++i) {
142 ASSERT_TRUE(my_test_queue.FetchNext());
143 EXPECT_EQ(i, my_test_queue->test_int);
144 }
145}
146
147// Tests that FetchLatest skips a missing message.
148TEST_F(QueueTest, FetchLatest) {
149 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x254).Send();
150 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
151
152 ASSERT_TRUE(my_test_queue.FetchLatest());
153 EXPECT_EQ(0x971, my_test_queue->test_int);
154}
155
156// Tests that FetchLatest works with multiple readers.
157TEST_F(QueueTest, FetchLatestMultiple) {
158 ::aos::Queue<TestingMessage> my_second_test_queue(
159 ".aos.common.testing.test_queue");
160 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x254).Send();
161 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
162
163 ASSERT_TRUE(my_test_queue.FetchLatest());
164 EXPECT_EQ(0x971, my_test_queue->test_int);
165 ASSERT_TRUE(my_second_test_queue.FetchLatest());
166 ASSERT_TRUE(my_second_test_queue.get() != NULL);
167 EXPECT_EQ(0x971, my_second_test_queue->test_int);
168}
169
170
171// Tests that fetching without a new message returns false.
172TEST_F(QueueTest, FetchLatestWithoutMessage) {
173 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x254).Send();
174 EXPECT_TRUE(my_test_queue.FetchLatest());
175 EXPECT_FALSE(my_test_queue.FetchLatest());
176 EXPECT_FALSE(my_test_queue.FetchLatest());
177 EXPECT_EQ(0x254, my_test_queue->test_int);
178}
179
180// Tests that fetching without a message returns false.
181TEST_F(QueueTest, FetchOnFreshQueue) {
182 EXPECT_FALSE(my_test_queue.FetchLatest());
183 EXPECT_EQ(static_cast<TestingMessage*>(NULL), my_test_queue.get());
184}
185
186// Tests that fetch next without a message returns false.
187TEST_F(QueueTest, FetchNextOnFreshQueue) {
188 EXPECT_FALSE(my_test_queue.FetchNext());
189 EXPECT_EQ(static_cast<TestingMessage*>(NULL), my_test_queue.get());
190}
191
192// Tests that fetch next without a new message returns false.
193TEST_F(QueueTest, FetchNextWithoutMessage) {
194 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x254).Send();
195 EXPECT_TRUE(my_test_queue.FetchNext());
196 EXPECT_FALSE(my_test_queue.FetchNext());
197 EXPECT_NE(static_cast<TestingMessage*>(NULL), my_test_queue.get());
198}
199
200// Tests that age makes some sense.
201TEST_F(QueueTest, Age) {
202 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
203
204 ASSERT_TRUE(my_test_queue.FetchLatest());
205 EXPECT_TRUE(my_test_queue.IsNewerThanMS(100));
206 const Time age = my_test_queue.Age();
207 EXPECT_EQ(0, age.sec());
208 EXPECT_GE(100000000, age.nsec());
209}
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);
260 EXPECT_EQ(0, msg.sent_time.sec());
261 EXPECT_EQ(0, msg.sent_time.nsec());
262}
263
264TEST_F(MessageTest, Size) {
265 EXPECT_EQ(static_cast<size_t>(13), msg.Size());
266}
267
268TEST_F(MessageTest, Serialize) {
269 char serialized_data[msg.Size()];
270 msg.test_bool = true;
271 msg.test_int = 0x254;
272 msg.SetTimeToNow();
273
274 msg.Serialize(serialized_data);
275
276 TestingMessage new_msg;
277 new_msg.Deserialize(serialized_data);
278
279 EXPECT_EQ(msg.test_bool, new_msg.test_bool);
280 EXPECT_EQ(msg.test_int, new_msg.test_int);
281 EXPECT_EQ(msg.sent_time, new_msg.sent_time);
282}
283
284// Tests that Print prints out a message nicely.
285TEST_F(MessageTest, Print) {
286 char printdata[1024];
287 msg.test_bool = true;
288 msg.test_int = 2056;
289 msg.sent_time = Time(971, 254);
290
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();
307 EXPECT_LE(msg.sent_time - Time::Now(), Time::InMS(20));
308}
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