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