blob: b24fcd559ccfb4f0c0ad3b5d08824b0af684528f [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"
8
9
10using ::aos::time::Time;
11
12namespace aos {
13namespace common {
14
15// TODO(aschuh): Pull this out somewhere and test it.
16class Thread {
17 public:
18 Thread () {
19 started_ = false;
20 joined_ = false;
21 }
22
23 ~Thread() {
24 if (!joined_ && started_) {
25 assert(false);
26 }
27 }
28
29 void Start() {
30 assert(!started_);
31 pthread_create(&thread_, NULL, &Thread::StaticRun, this);
32 started_ = true;
33 }
34
35 virtual void Run() = 0;
36
37 void Join() {
38 assert(!joined_);
39 pthread_join(thread_, NULL);
40 joined_ = true;
41 }
42 private:
43 static void *StaticRun(void *thread_class) {
44 static_cast<Thread *>(thread_class)->Run();
45 return NULL;
46 }
47
48 pthread_t thread_;
49 bool started_;
50 bool joined_;
51
52 DISALLOW_COPY_AND_ASSIGN(Thread);
53};
54
55namespace testing {
56
57class QueueTest : public ::testing::Test {
58 protected:
59 GlobalCoreInstance my_core;
60 // Create a new instance of the test queue so that it invalidates the queue
61 // that it points to. Otherwise, we will have a pointer to shared memory that
62 // is no longer valid.
63 ::aos::Queue<TestingMessage> my_test_queue;
64
65 QueueTest() : my_test_queue(".aos.common.testing.test_queue") {}
66};
67
68class MyThread : public Thread {
69 public:
70 MyThread() : threaded_test_queue(".aos.common.testing.test_queue") {}
71
72 virtual void Run() {
73 ASSERT_TRUE(threaded_test_queue.FetchNextBlocking());
74 EXPECT_TRUE(threaded_test_queue->test_bool);
75 EXPECT_EQ(0x971, threaded_test_queue->test_int);
76 }
77
78 ::aos::Queue<TestingMessage> threaded_test_queue;
79 private:
80 DISALLOW_COPY_AND_ASSIGN(MyThread);
81};
82
83
84// Tests that we can send a message to another thread and it blocking receives
85// it at the correct time.
86TEST_F(QueueTest, FetchBlocking) {
87 MyThread t;
88 t.Start();
89 usleep(50000);
90 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
91 t.Join();
92 EXPECT_EQ(true, t.threaded_test_queue.IsNewerThanMS(20));
93}
94
95// Tests that we can send a message with the message pointer and get it back.
96TEST_F(QueueTest, SendMessage) {
97 ScopedMessagePtr<TestingMessage> msg = my_test_queue.MakeMessage();
98 msg->test_bool = true;
99 msg->test_int = 0x971;
100 msg.Send();
101
102 ASSERT_TRUE(my_test_queue.FetchLatest());
103 EXPECT_TRUE(my_test_queue->test_bool);
104 EXPECT_EQ(0x971, my_test_queue->test_int);
105}
106
107// Tests that we can send a message with the message pointer and get it back.
108TEST_F(QueueTest, SendMessageBlockingSafe) {
109 SafeScopedMessagePtr<TestingMessage> msg = my_test_queue.SafeMakeMessage();
110 msg->test_bool = true;
111 msg->test_int = 0x971;
112 ASSERT_TRUE(msg.SendBlocking());
113
114 ASSERT_TRUE(my_test_queue.FetchLatest());
115 EXPECT_TRUE(my_test_queue->test_bool);
116 EXPECT_EQ(0x971, my_test_queue->test_int);
117}
118
119// Tests that we can send a message with the message pointer and get it back.
120TEST_F(QueueTest, SendMessageSafe) {
121 SafeScopedMessagePtr<TestingMessage> msg = my_test_queue.SafeMakeMessage();
122 msg->test_bool = true;
123 msg->test_int = 0x971;
124 msg.Send();
125
126 ASSERT_TRUE(my_test_queue.FetchLatest());
127 EXPECT_TRUE(my_test_queue->test_bool);
128 EXPECT_EQ(0x971, my_test_queue->test_int);
129}
130
131// Tests that we can send a message with the builder and get it back.
132TEST_F(QueueTest, SendWithBuilder) {
133 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
134
135 ASSERT_TRUE(my_test_queue.FetchLatest());
136 EXPECT_EQ(true, my_test_queue->test_bool);
137 EXPECT_EQ(0x971, my_test_queue->test_int);
138 EXPECT_EQ(true, my_test_queue.IsNewerThanMS(10000));
139}
140
141// Tests that various pointer deref functions at least seem to work.
142TEST_F(QueueTest, PointerDeref) {
143 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
144
145 ASSERT_TRUE(my_test_queue.FetchLatest());
146 const TestingMessage *msg_ptr = my_test_queue.get();
147 ASSERT_NE(static_cast<TestingMessage*>(NULL), msg_ptr);
148 EXPECT_EQ(0x971, msg_ptr->test_int);
149 EXPECT_EQ(msg_ptr, &(*my_test_queue));
150}
151
152// Tests that FetchNext doesn't miss any messages.
153TEST_F(QueueTest, FetchNext) {
154 for (int i = 0; i < 10; ++i) {
155 my_test_queue.MakeWithBuilder().test_bool(true).test_int(i).Send();
156 }
157
158 for (int i = 0; i < 10; ++i) {
159 ASSERT_TRUE(my_test_queue.FetchNext());
160 EXPECT_EQ(i, my_test_queue->test_int);
161 }
162}
163
164// Tests that FetchLatest skips a missing message.
165TEST_F(QueueTest, FetchLatest) {
166 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x254).Send();
167 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
168
169 ASSERT_TRUE(my_test_queue.FetchLatest());
170 EXPECT_EQ(0x971, my_test_queue->test_int);
171}
172
173// Tests that FetchLatest works with multiple readers.
174TEST_F(QueueTest, FetchLatestMultiple) {
175 ::aos::Queue<TestingMessage> my_second_test_queue(
176 ".aos.common.testing.test_queue");
177 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x254).Send();
178 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
179
180 ASSERT_TRUE(my_test_queue.FetchLatest());
181 EXPECT_EQ(0x971, my_test_queue->test_int);
182 ASSERT_TRUE(my_second_test_queue.FetchLatest());
183 ASSERT_TRUE(my_second_test_queue.get() != NULL);
184 EXPECT_EQ(0x971, my_second_test_queue->test_int);
185}
186
187
188// Tests that fetching without a new message returns false.
189TEST_F(QueueTest, FetchLatestWithoutMessage) {
190 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x254).Send();
191 EXPECT_TRUE(my_test_queue.FetchLatest());
192 EXPECT_FALSE(my_test_queue.FetchLatest());
193 EXPECT_FALSE(my_test_queue.FetchLatest());
194 EXPECT_EQ(0x254, my_test_queue->test_int);
195}
196
197// Tests that fetching without a message returns false.
198TEST_F(QueueTest, FetchOnFreshQueue) {
199 EXPECT_FALSE(my_test_queue.FetchLatest());
200 EXPECT_EQ(static_cast<TestingMessage*>(NULL), my_test_queue.get());
201}
202
203// Tests that fetch next without a message returns false.
204TEST_F(QueueTest, FetchNextOnFreshQueue) {
205 EXPECT_FALSE(my_test_queue.FetchNext());
206 EXPECT_EQ(static_cast<TestingMessage*>(NULL), my_test_queue.get());
207}
208
209// Tests that fetch next without a new message returns false.
210TEST_F(QueueTest, FetchNextWithoutMessage) {
211 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x254).Send();
212 EXPECT_TRUE(my_test_queue.FetchNext());
213 EXPECT_FALSE(my_test_queue.FetchNext());
214 EXPECT_NE(static_cast<TestingMessage*>(NULL), my_test_queue.get());
215}
216
217// Tests that age makes some sense.
218TEST_F(QueueTest, Age) {
219 my_test_queue.MakeWithBuilder().test_bool(true).test_int(0x971).Send();
220
221 ASSERT_TRUE(my_test_queue.FetchLatest());
222 EXPECT_TRUE(my_test_queue.IsNewerThanMS(100));
223 const Time age = my_test_queue.Age();
224 EXPECT_EQ(0, age.sec());
225 EXPECT_GE(100000000, age.nsec());
226}
227
228
229class GroupTest : public ::testing::Test {
230 protected:
231 GlobalCoreInstance my_core;
232 // Create a new instance of the test group so that it invalidates the queue
233 // that it points to. Otherwise, we will have a pointer to shared memory that
234 // is no longer valid.
235 TwoQueues my_test_queuegroup;
236
237 GroupTest()
238 : my_test_queuegroup(".aos.common.testing.test_queuegroup",
239 0x20561114,
240 ".aos.common.testing.test_queuegroup.first",
241 ".aos.common.testing.test_queuegroup.second") {}
242};
243
244// Tests that the hash gets preserved.
245TEST_F(GroupTest, Hash) {
246 EXPECT_EQ(static_cast<uint32_t>(0x20561114), my_test_queuegroup.hash());
247}
248
249// Tests that the hash works.
250TEST_F(GroupTest, RealHash) {
251 EXPECT_EQ(static_cast<uint32_t>(0x5b25097f), test_queuegroup.hash());
252}
253
254// Tests that name works.
255TEST_F(GroupTest, Name) {
256 EXPECT_EQ(std::string(".aos.common.testing.test_queuegroup"),
257 std::string(my_test_queuegroup.name()));
258}
259
260
261class MessageTest : public ::testing::Test {
262 public:
263 TestingMessage msg;
264};
265
266TEST_F(MessageTest, Zeroing) {
267 msg.test_bool = true;
268 msg.test_int = 0x254;
269 msg.SetTimeToNow();
270
271 msg.Zero();
272
273 EXPECT_FALSE(msg.test_bool);
274 EXPECT_EQ(0, msg.test_int);
275 EXPECT_EQ(0, msg.sent_time.sec());
276 EXPECT_EQ(0, msg.sent_time.nsec());
277}
278
279TEST_F(MessageTest, Size) {
280 EXPECT_EQ(static_cast<size_t>(13), msg.Size());
281}
282
283TEST_F(MessageTest, Serialize) {
284 char serialized_data[msg.Size()];
285 msg.test_bool = true;
286 msg.test_int = 0x254;
287 msg.SetTimeToNow();
288
289 msg.Serialize(serialized_data);
290
291 TestingMessage new_msg;
292 new_msg.Deserialize(serialized_data);
293
294 EXPECT_EQ(msg.test_bool, new_msg.test_bool);
295 EXPECT_EQ(msg.test_int, new_msg.test_int);
296 EXPECT_EQ(msg.sent_time, new_msg.sent_time);
297}
298
299// Tests that Print prints out a message nicely.
300TEST_F(MessageTest, Print) {
301 char printdata[1024];
302 msg.test_bool = true;
303 msg.test_int = 2056;
304 msg.sent_time = Time(971, 254);
305
306 std::string golden("971.000000254s, t, 2056");
307 EXPECT_EQ(golden.size(), msg.Print(printdata, sizeof(printdata)));
308
309 EXPECT_EQ(golden, std::string(printdata));
310}
311
312// Tests that the hash never changes. If it changes, then someone broke the
313// hash routine or changed the message declaration. Both changes need to be
314// validated by hand.
315TEST_F(MessageTest, Hash) {
316 EXPECT_EQ(static_cast<uint32_t>(0xcf740cc1),
317 static_cast<uint32_t>(TestingMessage::kHash));
318}
319
320TEST_F(MessageTest, SetNow) {
321 msg.SetTimeToNow();
322 EXPECT_LE(msg.sent_time - Time::Now(), Time::InMS(20));
323}
324
325} // namespace testing
326} // namespace common
327} // namespace aos