blob: 58c88dc557149934edabbea4d489476e07291e52 [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() {
37 ASSERT_TRUE(threaded_test_queue.FetchNextBlocking());
38 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 Silverman4c04efd2013-09-07 14:51:33 -070056 EXPECT_LE(t.threaded_test_queue.Age(), time::Time::InMS(55));
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
71// Tests that we can send a message with the message pointer and get it back.
72TEST_F(QueueTest, SendMessageBlockingSafe) {
73 SafeScopedMessagePtr<TestingMessage> msg = my_test_queue.SafeMakeMessage();
74 msg->test_bool = true;
75 msg->test_int = 0x971;
76 ASSERT_TRUE(msg.SendBlocking());
77
78 ASSERT_TRUE(my_test_queue.FetchLatest());
79 EXPECT_TRUE(my_test_queue->test_bool);
80 EXPECT_EQ(0x971, my_test_queue->test_int);
81}
82
83// Tests that we can send a message with the message pointer and get it back.
84TEST_F(QueueTest, SendMessageSafe) {
85 SafeScopedMessagePtr<TestingMessage> msg = my_test_queue.SafeMakeMessage();
86 msg->test_bool = true;
87 msg->test_int = 0x971;
88 msg.Send();
89
90 ASSERT_TRUE(my_test_queue.FetchLatest());
91 EXPECT_TRUE(my_test_queue->test_bool);
92 EXPECT_EQ(0x971, my_test_queue->test_int);
93}
94
95// Tests that we can send a message with the builder and get it back.
96TEST_F(QueueTest, SendWithBuilder) {
97 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
98
99 ASSERT_TRUE(my_test_queue.FetchLatest());
100 EXPECT_EQ(true, my_test_queue->test_bool);
101 EXPECT_EQ(0x971, my_test_queue->test_int);
102 EXPECT_EQ(true, my_test_queue.IsNewerThanMS(10000));
103}
104
105// Tests that various pointer deref functions at least seem to work.
106TEST_F(QueueTest, PointerDeref) {
107 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
108
109 ASSERT_TRUE(my_test_queue.FetchLatest());
110 const TestingMessage *msg_ptr = my_test_queue.get();
111 ASSERT_NE(static_cast<TestingMessage*>(NULL), msg_ptr);
112 EXPECT_EQ(0x971, msg_ptr->test_int);
113 EXPECT_EQ(msg_ptr, &(*my_test_queue));
114}
115
116// Tests that FetchNext doesn't miss any messages.
117TEST_F(QueueTest, FetchNext) {
118 for (int i = 0; i < 10; ++i) {
119 my_test_queue.MakeWithBuilder().test_bool(true).test_int(i).Send();
120 }
121
122 for (int i = 0; i < 10; ++i) {
123 ASSERT_TRUE(my_test_queue.FetchNext());
124 EXPECT_EQ(i, my_test_queue->test_int);
125 }
126}
127
128// Tests that FetchLatest skips a missing message.
129TEST_F(QueueTest, FetchLatest) {
130 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x254).Send();
131 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
132
133 ASSERT_TRUE(my_test_queue.FetchLatest());
134 EXPECT_EQ(0x971, my_test_queue->test_int);
135}
136
137// Tests that FetchLatest works with multiple readers.
138TEST_F(QueueTest, FetchLatestMultiple) {
139 ::aos::Queue<TestingMessage> my_second_test_queue(
140 ".aos.common.testing.test_queue");
141 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x254).Send();
142 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
143
144 ASSERT_TRUE(my_test_queue.FetchLatest());
145 EXPECT_EQ(0x971, my_test_queue->test_int);
146 ASSERT_TRUE(my_second_test_queue.FetchLatest());
147 ASSERT_TRUE(my_second_test_queue.get() != NULL);
148 EXPECT_EQ(0x971, my_second_test_queue->test_int);
149}
150
151
152// Tests that fetching without a new message returns false.
153TEST_F(QueueTest, FetchLatestWithoutMessage) {
154 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x254).Send();
155 EXPECT_TRUE(my_test_queue.FetchLatest());
156 EXPECT_FALSE(my_test_queue.FetchLatest());
157 EXPECT_FALSE(my_test_queue.FetchLatest());
158 EXPECT_EQ(0x254, my_test_queue->test_int);
159}
160
161// Tests that fetching without a message returns false.
162TEST_F(QueueTest, FetchOnFreshQueue) {
163 EXPECT_FALSE(my_test_queue.FetchLatest());
164 EXPECT_EQ(static_cast<TestingMessage*>(NULL), my_test_queue.get());
165}
166
167// Tests that fetch next without a message returns false.
168TEST_F(QueueTest, FetchNextOnFreshQueue) {
169 EXPECT_FALSE(my_test_queue.FetchNext());
170 EXPECT_EQ(static_cast<TestingMessage*>(NULL), my_test_queue.get());
171}
172
173// Tests that fetch next without a new message returns false.
174TEST_F(QueueTest, FetchNextWithoutMessage) {
175 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x254).Send();
176 EXPECT_TRUE(my_test_queue.FetchNext());
177 EXPECT_FALSE(my_test_queue.FetchNext());
178 EXPECT_NE(static_cast<TestingMessage*>(NULL), my_test_queue.get());
179}
180
181// Tests that age makes some sense.
182TEST_F(QueueTest, Age) {
183 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
184
185 ASSERT_TRUE(my_test_queue.FetchLatest());
186 EXPECT_TRUE(my_test_queue.IsNewerThanMS(100));
187 const Time age = my_test_queue.Age();
188 EXPECT_EQ(0, age.sec());
189 EXPECT_GE(100000000, age.nsec());
190}
191
192
193class GroupTest : public ::testing::Test {
194 protected:
195 GlobalCoreInstance my_core;
196 // Create a new instance of the test group so that it invalidates the queue
197 // that it points to. Otherwise, we will have a pointer to shared memory that
198 // is no longer valid.
199 TwoQueues my_test_queuegroup;
200
201 GroupTest()
202 : my_test_queuegroup(".aos.common.testing.test_queuegroup",
203 0x20561114,
204 ".aos.common.testing.test_queuegroup.first",
205 ".aos.common.testing.test_queuegroup.second") {}
206};
207
208// Tests that the hash gets preserved.
209TEST_F(GroupTest, Hash) {
210 EXPECT_EQ(static_cast<uint32_t>(0x20561114), my_test_queuegroup.hash());
211}
212
213// Tests that the hash works.
214TEST_F(GroupTest, RealHash) {
Brian Silverman981a7bb2014-02-16 21:17:04 -0800215 EXPECT_EQ(static_cast<uint32_t>(0x93596b2f), test_queuegroup.hash());
brians343bc112013-02-10 01:53:46 +0000216}
217
218// Tests that name works.
219TEST_F(GroupTest, Name) {
220 EXPECT_EQ(std::string(".aos.common.testing.test_queuegroup"),
221 std::string(my_test_queuegroup.name()));
222}
223
224
225class MessageTest : public ::testing::Test {
226 public:
227 TestingMessage msg;
228};
229
230TEST_F(MessageTest, Zeroing) {
231 msg.test_bool = true;
232 msg.test_int = 0x254;
233 msg.SetTimeToNow();
234
235 msg.Zero();
236
237 EXPECT_FALSE(msg.test_bool);
238 EXPECT_EQ(0, msg.test_int);
239 EXPECT_EQ(0, msg.sent_time.sec());
240 EXPECT_EQ(0, msg.sent_time.nsec());
241}
242
243TEST_F(MessageTest, Size) {
244 EXPECT_EQ(static_cast<size_t>(13), msg.Size());
245}
246
247TEST_F(MessageTest, Serialize) {
248 char serialized_data[msg.Size()];
249 msg.test_bool = true;
250 msg.test_int = 0x254;
251 msg.SetTimeToNow();
252
253 msg.Serialize(serialized_data);
254
255 TestingMessage new_msg;
256 new_msg.Deserialize(serialized_data);
257
258 EXPECT_EQ(msg.test_bool, new_msg.test_bool);
259 EXPECT_EQ(msg.test_int, new_msg.test_int);
260 EXPECT_EQ(msg.sent_time, new_msg.sent_time);
261}
262
263// Tests that Print prints out a message nicely.
264TEST_F(MessageTest, Print) {
265 char printdata[1024];
266 msg.test_bool = true;
267 msg.test_int = 2056;
268 msg.sent_time = Time(971, 254);
269
Brian Silverman981a7bb2014-02-16 21:17:04 -0800270 std::string golden("971.000000254s, T, 2056");
brians343bc112013-02-10 01:53:46 +0000271 EXPECT_EQ(golden.size(), msg.Print(printdata, sizeof(printdata)));
272
273 EXPECT_EQ(golden, std::string(printdata));
274}
275
276// Tests that the hash never changes. If it changes, then someone broke the
277// hash routine or changed the message declaration. Both changes need to be
278// validated by hand.
279TEST_F(MessageTest, Hash) {
Brian Silverman981a7bb2014-02-16 21:17:04 -0800280 EXPECT_EQ(static_cast<uint32_t>(0xc33651ac),
brians343bc112013-02-10 01:53:46 +0000281 static_cast<uint32_t>(TestingMessage::kHash));
282}
283
284TEST_F(MessageTest, SetNow) {
285 msg.SetTimeToNow();
286 EXPECT_LE(msg.sent_time - Time::Now(), Time::InMS(20));
287}
288
289} // namespace testing
290} // namespace common
291} // namespace aos