OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 #include "vm/message_handler.h" | |
6 #include "vm/unit_test.h" | |
7 | |
8 namespace dart { | |
9 | |
10 class MessageHandlerTestPeer { | |
11 public: | |
12 explicit MessageHandlerTestPeer(MessageHandler* handler) | |
13 : handler_(handler) {} | |
14 | |
15 void PostMessage(Message* message) { handler_->PostMessage(message); } | |
16 void ClosePort(Dart_Port port) { handler_->ClosePort(port); } | |
17 void CloseAllPorts() { handler_->CloseAllPorts(); } | |
18 | |
19 void increment_live_ports() { handler_->increment_live_ports(); } | |
20 void decrement_live_ports() { handler_->decrement_live_ports(); } | |
21 | |
22 MessageQueue* queue() const { return handler_->queue_; } | |
23 MessageQueue* oob_queue() const { return handler_->oob_queue_; } | |
24 | |
25 private: | |
26 MessageHandler* handler_; | |
27 | |
28 DISALLOW_COPY_AND_ASSIGN(MessageHandlerTestPeer); | |
29 }; | |
30 | |
31 | |
32 class TestMessageHandler : public MessageHandler { | |
33 public: | |
34 TestMessageHandler() | |
35 : port_buffer_(strdup("")), | |
36 notify_count_(0), | |
37 message_count_(0), | |
38 result_(true) {} | |
39 | |
40 ~TestMessageHandler() { | |
41 free(port_buffer_); | |
42 } | |
43 | |
44 void MessageNotify(Message::Priority priority) { | |
45 notify_count_++; | |
46 } | |
47 | |
48 bool HandleMessage(Message* message) { | |
49 // For testing purposes, keep a string with a list of the ports | |
50 // for all messages we receive. | |
51 intptr_t len = | |
52 OS::SNPrint(NULL, 0, "%s %d", port_buffer_, message->dest_port()) + 1; | |
53 char* buffer = reinterpret_cast<char*>(malloc(len)); | |
54 OS::SNPrint(buffer, len, "%s %d", port_buffer_, message->dest_port()); | |
55 free(port_buffer_); | |
56 port_buffer_ = buffer; | |
57 delete message; | |
58 message_count_++; | |
59 return result_; | |
60 } | |
61 | |
62 | |
63 bool Start() { | |
64 intptr_t len = | |
65 OS::SNPrint(NULL, 0, "%s start", port_buffer_) + 1; | |
66 char* buffer = reinterpret_cast<char*>(malloc(len)); | |
67 OS::SNPrint(buffer, len, "%s start", port_buffer_); | |
68 free(port_buffer_); | |
69 port_buffer_ = buffer; | |
70 return true; | |
71 } | |
72 | |
73 | |
74 void End() { | |
75 intptr_t len = | |
76 OS::SNPrint(NULL, 0, "%s end", port_buffer_) + 1; | |
77 char* buffer = reinterpret_cast<char*>(malloc(len)); | |
78 OS::SNPrint(buffer, len, "%s end", port_buffer_); | |
79 free(port_buffer_); | |
80 port_buffer_ = buffer; | |
81 } | |
82 | |
83 | |
84 const char* port_buffer() const { return port_buffer_; } | |
85 int notify_count() const { return notify_count_; } | |
86 int message_count() const { return message_count_; } | |
87 | |
88 void set_result(bool result) { result_ = result; } | |
89 | |
90 private: | |
91 char* port_buffer_; | |
92 int notify_count_; | |
93 int message_count_; | |
94 bool result_; | |
95 | |
96 DISALLOW_COPY_AND_ASSIGN(TestMessageHandler); | |
97 }; | |
98 | |
99 | |
100 bool TestStartFunction(uword data) { | |
101 return (reinterpret_cast<TestMessageHandler*>(data))->Start(); | |
102 } | |
103 | |
104 | |
105 void TestEndFunction(uword data) { | |
106 return (reinterpret_cast<TestMessageHandler*>(data))->End(); | |
107 } | |
108 | |
109 | |
110 UNIT_TEST_CASE(MessageHandler_PostMessage) { | |
111 TestMessageHandler handler; | |
112 MessageHandlerTestPeer handler_peer(&handler); | |
113 EXPECT_EQ(0, handler.notify_count()); | |
114 | |
115 // Post a message. | |
116 Message* message = new Message(0, 0, NULL, Message::kNormalPriority); | |
117 handler_peer.PostMessage(message); | |
118 | |
119 // The notify callback is called. | |
120 EXPECT_EQ(1, handler.notify_count()); | |
121 | |
122 // The message has been added to the correct queue. | |
123 EXPECT(message == handler_peer.queue()->Dequeue()); | |
124 EXPECT(NULL == handler_peer.oob_queue()->Dequeue()); | |
125 delete message; | |
126 | |
127 // Post an oob message. | |
128 message = new Message(0, 0, NULL, Message::kOOBPriority); | |
129 handler_peer.PostMessage(message); | |
130 | |
131 // The notify callback is called. | |
132 EXPECT_EQ(2, handler.notify_count()); | |
133 | |
134 // The message has been added to the correct queue. | |
135 EXPECT(message == handler_peer.oob_queue()->Dequeue()); | |
136 EXPECT(NULL == handler_peer.queue()->Dequeue()); | |
137 delete message; | |
138 } | |
139 | |
140 | |
141 UNIT_TEST_CASE(MessageHandler_ClosePort) { | |
142 TestMessageHandler handler; | |
143 MessageHandlerTestPeer handler_peer(&handler); | |
144 Message* message1 = new Message(1, 0, NULL, Message::kNormalPriority); | |
145 handler_peer.PostMessage(message1); | |
146 Message* message2 = new Message(2, 0, NULL, Message::kNormalPriority); | |
147 handler_peer.PostMessage(message2); | |
148 | |
149 handler_peer.ClosePort(1); | |
150 | |
151 // The message on port 1 is dropped from the queue. | |
152 EXPECT(message2 == handler_peer.queue()->Dequeue()); | |
153 EXPECT(NULL == handler_peer.queue()->Dequeue()); | |
154 delete message2; | |
155 } | |
156 | |
157 | |
158 UNIT_TEST_CASE(MessageHandler_CloseAllPorts) { | |
159 TestMessageHandler handler; | |
160 MessageHandlerTestPeer handler_peer(&handler); | |
161 Message* message1 = new Message(1, 0, NULL, Message::kNormalPriority); | |
162 handler_peer.PostMessage(message1); | |
163 Message* message2 = new Message(2, 0, NULL, Message::kNormalPriority); | |
164 handler_peer.PostMessage(message2); | |
165 | |
166 handler_peer.CloseAllPorts(); | |
167 | |
168 // All messages are dropped from the queue. | |
169 EXPECT(NULL == handler_peer.queue()->Dequeue()); | |
170 } | |
171 | |
172 | |
173 UNIT_TEST_CASE(MessageHandler_HandleNextMessage) { | |
174 TestMessageHandler handler; | |
175 MessageHandlerTestPeer handler_peer(&handler); | |
176 Message* message1 = new Message(1, 0, NULL, Message::kNormalPriority); | |
177 handler_peer.PostMessage(message1); | |
178 Message* oob_message1 = new Message(3, 0, NULL, Message::kOOBPriority); | |
179 handler_peer.PostMessage(oob_message1); | |
180 Message* message2 = new Message(2, 0, NULL, Message::kNormalPriority); | |
181 handler_peer.PostMessage(message2); | |
182 Message* oob_message2 = new Message(4, 0, NULL, Message::kOOBPriority); | |
183 handler_peer.PostMessage(oob_message2); | |
184 | |
185 // We handle both oob messages and a single normal message. | |
186 EXPECT(handler.HandleNextMessage()); | |
187 EXPECT_STREQ(" 3 4 1", handler.port_buffer()); | |
188 handler_peer.CloseAllPorts(); | |
189 } | |
190 | |
191 | |
192 UNIT_TEST_CASE(MessageHandler_HandleOOBMessages) { | |
193 TestMessageHandler handler; | |
194 MessageHandlerTestPeer handler_peer(&handler); | |
195 Message* message1 = new Message(1, 0, NULL, Message::kNormalPriority); | |
196 handler_peer.PostMessage(message1); | |
197 Message* message2 = new Message(2, 0, NULL, Message::kNormalPriority); | |
198 handler_peer.PostMessage(message2); | |
199 Message* oob_message1 = new Message(3, 0, NULL, Message::kOOBPriority); | |
200 handler_peer.PostMessage(oob_message1); | |
201 Message* oob_message2 = new Message(4, 0, NULL, Message::kOOBPriority); | |
202 handler_peer.PostMessage(oob_message2); | |
203 | |
204 // We handle both oob messages but no normal messages. | |
205 EXPECT(handler.HandleOOBMessages()); | |
206 EXPECT_STREQ(" 3 4", handler.port_buffer()); | |
207 handler_peer.CloseAllPorts(); | |
208 } | |
209 | |
210 | |
211 struct ThreadStartInfo { | |
212 MessageHandler* handler; | |
213 int count; | |
214 }; | |
215 | |
216 | |
217 static void SendMessages(uword param) { | |
218 ThreadStartInfo* info = reinterpret_cast<ThreadStartInfo*>(param); | |
219 MessageHandler* handler = info->handler; | |
220 MessageHandlerTestPeer handler_peer(handler); | |
221 for (int i = 0; i < info->count; i++) { | |
222 Message* message = new Message(i + 1, 0, NULL, Message::kNormalPriority); | |
223 handler_peer.PostMessage(message); | |
224 } | |
225 } | |
226 | |
227 | |
228 UNIT_TEST_CASE(MessageHandler_Run) { | |
229 ThreadPool pool; | |
230 TestMessageHandler handler; | |
231 MessageHandlerTestPeer handler_peer(&handler); | |
232 | |
233 EXPECT(!handler.HasLivePorts()); | |
234 handler_peer.increment_live_ports(); | |
235 | |
236 handler.Run(&pool, | |
237 TestStartFunction, | |
238 TestEndFunction, | |
239 reinterpret_cast<uword>(&handler)); | |
240 Message* message = new Message(100, 0, NULL, Message::kNormalPriority); | |
241 handler_peer.PostMessage(message); | |
242 | |
243 // Wait for the first message to be handled. | |
244 while (handler.message_count() < 1) { | |
245 OS::Sleep(10); | |
246 } | |
247 EXPECT_STREQ(" start 100", handler.port_buffer()); | |
248 | |
249 // Start a thread which sends more messages. | |
250 ThreadStartInfo info; | |
251 info.handler = &handler; | |
252 info.count = 10; | |
253 Thread::Start(SendMessages, reinterpret_cast<uword>(&info)); | |
254 while (handler.message_count() < 11) { | |
255 OS::Sleep(10); | |
256 } | |
siva
2012/04/18 22:05:00
if there is a bug this test will hang forever, do
turnidge
2012/04/19 19:46:55
I've added code to limit the test to about 20 seco
| |
257 EXPECT_STREQ(" start 100 1 2 3 4 5 6 7 8 9 10", handler.port_buffer()); | |
258 | |
259 handler_peer.decrement_live_ports(); | |
260 EXPECT(!handler.HasLivePorts()); | |
261 } | |
262 | |
263 } // namespace dart | |
OLD | NEW |