|
1 /* |
|
2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: ?Description |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <errno.h> |
|
19 #include "monitor.h" |
|
20 #include "TestHarness.h" |
|
21 #include "logger.h" |
|
22 |
|
23 #include "commsserverendpoint.h" |
|
24 #include "commsclientendpoint.h" |
|
25 #include "commsmessage.h" |
|
26 #include "echoserver.h" |
|
27 |
|
28 using namespace java::comms; |
|
29 using java::util::Monitor; |
|
30 |
|
31 TEST_GROUP(Connect) |
|
32 { |
|
33 CommsServerEndpoint comms; |
|
34 |
|
35 TEST_SETUP() |
|
36 { |
|
37 comms.start(IPC_ADDRESS_COMMS_MODULE_TEST); |
|
38 } |
|
39 |
|
40 TEST_TEARDOWN() |
|
41 { |
|
42 comms.stop(); |
|
43 } |
|
44 }; |
|
45 |
|
46 /** |
|
47 * Test open connection |
|
48 * 1. Normal connect, disconnect |
|
49 * 2. Multiple connect calls without disconnect |
|
50 * 3. Disconnect before connect |
|
51 * 4. Connect to non-existing host |
|
52 */ |
|
53 |
|
54 TEST(Connect, OpenConnection) |
|
55 { |
|
56 CommsClientEndpoint client; |
|
57 |
|
58 // 1. Normal connect, disconnect |
|
59 CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); |
|
60 CHECK(!client.disconnect()); |
|
61 |
|
62 // 2. Multiple connect calls without disconnect |
|
63 CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); |
|
64 CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); |
|
65 CHECK(!client.disconnect()); |
|
66 |
|
67 // 3. Disconnect before connect |
|
68 CHECK(!client.disconnect()); |
|
69 CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); |
|
70 CHECK(!client.disconnect()); |
|
71 |
|
72 // 4. Connect to non-existing host |
|
73 CHECK(client.connect(IPC_ADDRESS_COMMS_MODULE_TEST+666)); |
|
74 CHECK(!client.disconnect()); |
|
75 } |
|
76 |
|
77 /** |
|
78 * Test open connection with multiple clients |
|
79 * 1. Normal connect, disconnect |
|
80 * 2. Multiple connect/disconnects |
|
81 */ |
|
82 |
|
83 TEST(Connect, MultiClient) |
|
84 { |
|
85 CommsClientEndpoint a, b, c, d, e; |
|
86 |
|
87 // 1. Normal connect, disconnect |
|
88 CHECK(!a.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); |
|
89 CHECK(!b.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); |
|
90 CHECK(!c.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); |
|
91 CHECK(!d.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); |
|
92 CHECK(!e.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); |
|
93 CHECK(!e.disconnect()); |
|
94 CHECK(!d.disconnect()); |
|
95 CHECK(!c.disconnect()); |
|
96 CHECK(!b.disconnect()); |
|
97 CHECK(!a.disconnect()); |
|
98 |
|
99 // 2. Multiple connect/disconnects |
|
100 for (int i=0; i<10; i++) |
|
101 { |
|
102 CHECK(!a.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); |
|
103 CHECK(!b.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); |
|
104 CHECK(!c.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); |
|
105 CHECK(!d.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); |
|
106 CHECK(!e.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); |
|
107 CHECK(!e.disconnect()); |
|
108 CHECK(!d.disconnect()); |
|
109 CHECK(!c.disconnect()); |
|
110 CHECK(!b.disconnect()); |
|
111 CHECK(!a.disconnect()); |
|
112 } |
|
113 } |
|
114 |
|
115 /** |
|
116 * Test server cases |
|
117 * 1. Server exits while client is connected |
|
118 * 2. Address is already in use |
|
119 * 3. Start/Connect using different addresses |
|
120 */ |
|
121 |
|
122 TEST(Connect, Server) |
|
123 { |
|
124 CommsServerEndpoint server; |
|
125 CommsClientEndpoint client; |
|
126 int ADDR = IPC_ADDRESS_COMMS_MODULE_TEST + 1; |
|
127 |
|
128 // 1. Server exits while client is connected |
|
129 CHECK(!server.start(ADDR)); |
|
130 CHECK(!client.connect(ADDR)); |
|
131 CHECK(!server.stop()); |
|
132 CHECK(!client.disconnect()); |
|
133 |
|
134 // 2. Address is already in use |
|
135 CHECK(server.start(IPC_ADDRESS_COMMS_MODULE_TEST)!=0); |
|
136 CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); |
|
137 CHECK(!server.stop()); |
|
138 CHECK(!client.disconnect()); |
|
139 |
|
140 // 3. Start/Connect using different addresses |
|
141 CHECK(!server.start(ADDR)); |
|
142 CHECK(!client.connect(ADDR)); |
|
143 CHECK(!client.disconnect()); |
|
144 CHECK(!server.stop()); |
|
145 |
|
146 CHECK(!server.start(ADDR+1)); |
|
147 CHECK(!client.connect(ADDR+1)); |
|
148 CHECK(!client.disconnect()); |
|
149 CHECK(!server.stop()); |
|
150 |
|
151 } |
|
152 |
|
153 /** |
|
154 * Test connect/disconnect from separate threads |
|
155 * 1. connect/disconnect from separate threads |
|
156 * 2. start/stop from separate threads |
|
157 */ |
|
158 |
|
159 void doDisconnect(CommsClientEndpoint* aClient) |
|
160 { |
|
161 CHECK(!aClient->disconnect()); |
|
162 } |
|
163 void* disconnectThread(void* aComms) |
|
164 { |
|
165 CommsClientEndpoint* client = reinterpret_cast<CommsClientEndpoint*>(aComms); |
|
166 doDisconnect(client); |
|
167 return 0; |
|
168 } |
|
169 |
|
170 void doStop(CommsServerEndpoint* aServer) |
|
171 { |
|
172 CHECK(!aServer->stop()); |
|
173 } |
|
174 void* stopThread(void* aComms) |
|
175 { |
|
176 CommsServerEndpoint* server = reinterpret_cast<CommsServerEndpoint*>(aComms); |
|
177 doStop(server); |
|
178 return 0; |
|
179 } |
|
180 |
|
181 TEST(Connect, separateThread) |
|
182 { |
|
183 CommsServerEndpoint server; |
|
184 CommsClientEndpoint client; |
|
185 int ADDR = IPC_ADDRESS_COMMS_MODULE_TEST + 1; |
|
186 |
|
187 CommsMessage msg; |
|
188 |
|
189 // 1. connect/disconnect from separate threads |
|
190 CHECK(!server.start(ADDR)); |
|
191 CHECK(!client.connect(ADDR)); |
|
192 |
|
193 CHECK(client.send(msg) == 0); |
|
194 pthread_t threadId = 0; |
|
195 pthread_create(&threadId, 0, disconnectThread, &client); |
|
196 pthread_join(threadId, 0); |
|
197 CHECK(client.send(msg) != 0); |
|
198 |
|
199 // 2. start/stop from separate threads |
|
200 pthread_create(&threadId, 0, stopThread, &server); |
|
201 pthread_join(threadId, 0); |
|
202 |
|
203 CommsServerEndpoint server2; |
|
204 CHECK(!server2.start(ADDR)); |
|
205 CHECK(!server2.stop()); |
|
206 } |
|
207 |
|
208 /** |
|
209 * Check that onStart and onExit callbacks are done |
|
210 * (ensures that ipc provider implementation is done correctly) |
|
211 * 1. Callbacks are done after connect/disconnect |
|
212 * 2. Callbacks are done after start/stop |
|
213 */ |
|
214 |
|
215 class OnStartExitClient : public CommsClientEndpoint |
|
216 { |
|
217 public: |
|
218 OnStartExitClient() : mOnStart(false), mOnExit(false) {} |
|
219 |
|
220 virtual void onStart() |
|
221 { |
|
222 mOnStart = true; |
|
223 } |
|
224 virtual void onExit() |
|
225 { |
|
226 mOnExit = true; |
|
227 } |
|
228 |
|
229 bool mOnStart; |
|
230 bool mOnExit; |
|
231 }; |
|
232 |
|
233 class OnStartExitServer : public CommsServerEndpoint |
|
234 { |
|
235 public: |
|
236 OnStartExitServer() : mOnStart(false), mOnExit(false) {} |
|
237 |
|
238 virtual void onStart() |
|
239 { |
|
240 mOnStart = true; |
|
241 } |
|
242 virtual void onExit() |
|
243 { |
|
244 mOnExit = true; |
|
245 } |
|
246 |
|
247 bool mOnStart; |
|
248 bool mOnExit; |
|
249 }; |
|
250 |
|
251 TEST(Connect, onStartExit) |
|
252 { |
|
253 // 1. Callbacks are done after connect/disconnect |
|
254 OnStartExitClient client; |
|
255 CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); |
|
256 CHECK(!client.disconnect()); |
|
257 CHECK(client.mOnStart); |
|
258 CHECK(client.mOnExit); |
|
259 |
|
260 // 2. Callbacks are done after start/stop |
|
261 OnStartExitServer server; |
|
262 CHECK(!server.start(IPC_ADDRESS_COMMS_MODULE_TEST+1)); |
|
263 CHECK(!server.stop()); |
|
264 CHECK(server.mOnStart); |
|
265 CHECK(server.mOnExit); |
|
266 } |
|
267 |
|
268 |
|
269 /** |
|
270 * Test disconnect/stop while sendReceive is pending |
|
271 * 1. disconnect while sendReceive is pending in client |
|
272 * 2. stop while sendReceive is pending in client |
|
273 * 3. disconnect while sendReceive is pending in server |
|
274 * 4. stop while sendReceive is pending in server |
|
275 */ |
|
276 |
|
277 void doSendReceive(CommsEndpoint* aComms) |
|
278 { |
|
279 CommsMessage msg; |
|
280 msg.setModuleId(MODULE_ID_NO_REPLY); |
|
281 CommsMessage receivedMsg; |
|
282 |
|
283 int rc = aComms->sendReceive(msg, receivedMsg, 3); |
|
284 CHECK(rc != 0); |
|
285 CHECK(rc != ETIMEDOUT); |
|
286 |
|
287 // check that next send fails as other party is disconnected |
|
288 // (and receive thread may still be running depending on timing) |
|
289 rc = aComms->send(msg); |
|
290 CHECK(rc != 0); |
|
291 } |
|
292 |
|
293 void* sendReceiveThread(void* aComms) |
|
294 { |
|
295 CommsEndpoint* comms = reinterpret_cast<CommsEndpoint*>(aComms); |
|
296 doSendReceive(comms); |
|
297 return 0; |
|
298 } |
|
299 |
|
300 class Notifier : public CommsListener |
|
301 { |
|
302 public: |
|
303 Notifier(Monitor& aMonitor) : mMonitor(aMonitor) {} |
|
304 virtual void processMessage(CommsMessage&) |
|
305 { |
|
306 mMonitor.notify(); |
|
307 |
|
308 } |
|
309 private: |
|
310 Monitor& mMonitor; |
|
311 }; |
|
312 |
|
313 struct threadData |
|
314 { |
|
315 CommsEndpoint* comms; |
|
316 int clientAddress; |
|
317 }; |
|
318 |
|
319 void doServer(CommsEndpoint* aComms, int aAddress) |
|
320 { |
|
321 CommsMessage msg; |
|
322 msg.setReceiver(aAddress); |
|
323 CommsMessage receivedMsg; |
|
324 |
|
325 int rc = aComms->sendReceive(msg, receivedMsg, 3); |
|
326 CHECK(rc != 0); |
|
327 CHECK(rc != ETIMEDOUT); |
|
328 } |
|
329 |
|
330 void* serverThread(void* aData) |
|
331 { |
|
332 threadData* data = reinterpret_cast<threadData*>(aData); |
|
333 doServer(data->comms, data->clientAddress); |
|
334 delete data; |
|
335 return 0; |
|
336 } |
|
337 |
|
338 class ServerListener : public CommsListener |
|
339 { |
|
340 public: |
|
341 ServerListener(CommsEndpoint& aComms) : mComms(aComms) {} |
|
342 virtual void processMessage(CommsMessage& aMsg) |
|
343 { |
|
344 threadData* data = new threadData; |
|
345 data->comms = &mComms; |
|
346 data->clientAddress = aMsg.getSender(); |
|
347 pthread_t threadId = 0; |
|
348 pthread_create(&threadId, 0, serverThread, data); |
|
349 } |
|
350 private: |
|
351 CommsEndpoint& mComms; |
|
352 }; |
|
353 |
|
354 TEST(Connect, sendReceivePending) |
|
355 { |
|
356 std::auto_ptr<Monitor> monitor(Monitor::createMonitor()); |
|
357 |
|
358 Notifier listener(*monitor); |
|
359 CommsClientEndpoint client; |
|
360 |
|
361 // 1. disconnect while sendReceive is pending in client |
|
362 CHECK(!comms.registerDefaultListener(&listener)); |
|
363 CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST)); |
|
364 |
|
365 pthread_t threadId = 0; |
|
366 pthread_create(&threadId, 0, sendReceiveThread, &client); |
|
367 |
|
368 monitor->wait(); |
|
369 CHECK(!client.disconnect()); |
|
370 |
|
371 pthread_join(threadId, 0); |
|
372 CHECK(!comms.unregisterDefaultListener(&listener)); |
|
373 |
|
374 // 2. stop while sendReceive is pending in client |
|
375 CommsServerEndpoint server; |
|
376 CHECK(!server.start(IPC_ADDRESS_COMMS_MODULE_TEST+1)); |
|
377 CHECK(!server.registerDefaultListener(&listener)); |
|
378 |
|
379 CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST+1)); |
|
380 |
|
381 threadId = 0; |
|
382 pthread_create(&threadId, 0, sendReceiveThread, &client); |
|
383 |
|
384 monitor->wait(); |
|
385 CHECK(!server.stop()); |
|
386 |
|
387 pthread_join(threadId, 0); |
|
388 CHECK(!client.disconnect()); |
|
389 CHECK(!server.unregisterDefaultListener(&listener)); |
|
390 |
|
391 // 3. disconnect while sendReceive is pending in server |
|
392 ServerListener serverListener(server); |
|
393 |
|
394 CHECK(!server.registerDefaultListener(&serverListener)); |
|
395 CHECK(!client.registerDefaultListener(&listener)); |
|
396 |
|
397 CHECK(!server.start(IPC_ADDRESS_COMMS_MODULE_TEST+1)); |
|
398 CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST+1)); |
|
399 |
|
400 CommsMessage msg; |
|
401 CHECK(!client.send(msg)); |
|
402 monitor->wait(); |
|
403 CHECK(!client.disconnect()); |
|
404 |
|
405 CHECK(!server.stop()); |
|
406 CHECK(!server.unregisterDefaultListener(&serverListener)); |
|
407 CHECK(!client.unregisterDefaultListener(&listener)); |
|
408 |
|
409 // 4. stop while sendReceive is pending in server |
|
410 CHECK(!server.registerDefaultListener(&serverListener)); |
|
411 CHECK(!client.registerDefaultListener(&listener)); |
|
412 |
|
413 CHECK(!server.start(IPC_ADDRESS_COMMS_MODULE_TEST+1)); |
|
414 CHECK(!client.connect(IPC_ADDRESS_COMMS_MODULE_TEST+1)); |
|
415 |
|
416 CHECK(!client.send(msg)); |
|
417 monitor->wait(); |
|
418 CHECK(!server.stop()); |
|
419 |
|
420 CHECK(!client.disconnect()); |
|
421 CHECK(!server.unregisterDefaultListener(&serverListener)); |
|
422 CHECK(!client.unregisterDefaultListener(&listener)); |
|
423 } |
|
424 |