VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTLocalIpc.cpp@ 47168

Last change on this file since 47168 was 47168, checked in by vboxsync, 12 years ago

IPRT/localipc-win.cpp: Update.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.0 KB
Line 
1/* $Id: tstRTLocalIpc.cpp 47168 2013-07-15 14:53:55Z vboxsync $ */
2/** @file
3 * IPRT Testcase - RTLocalIpc.
4 */
5
6/*
7 * Copyright (C) 2013 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#include <iprt/env.h>
32#include <iprt/localipc.h>
33#include <iprt/mem.h>
34#include <iprt/path.h>
35#include <iprt/process.h>
36#include <iprt/string.h>
37#include <iprt/test.h>
38#include <iprt/thread.h>
39#include <iprt/time.h>
40
41
42typedef struct LOCALIPCTHREADCTX
43{
44 /** The IPC server handle. */
45 RTLOCALIPCSERVER hServer;
46 /** The test handle. */
47 RTTEST hTest;
48} LOCALIPCTHREADCTX, *PLOCALIPCTHREADCTX;
49
50static int testServerListenAndCancel2(const char *pszExecPath)
51{
52 const char *apszArgs[4] = { pszExecPath, "child", "testServerListenAndCancel", NULL };
53 RTPROCESS hProc;
54 int rc = RTProcCreate(pszExecPath, apszArgs, RTENV_DEFAULT, 0 /* fFlags*/, &hProc);
55
56 return rc;
57}
58
59static DECLCALLBACK(int) testServerListenAndCancelThread(RTTHREAD hSelf, void *pvUser)
60{
61 PRTLOCALIPCSERVER pServer = (PRTLOCALIPCSERVER)pvUser;
62 AssertPtr(pServer);
63
64 RTThreadSleep(5000); /* Wait a bit to simulate waiting in main thread. */
65
66 int rc = RTLocalIpcServerCancel(*pServer);
67 AssertRC(rc);
68
69 return 0;
70}
71
72static int testServerListenAndCancel(RTTEST hTest, const char *pszExecPath)
73{
74 RTTestSub(hTest, "testServerListenAndCancel");
75
76 RTLOCALIPCSERVER ipcServer;
77 int rc = RTLocalIpcServerCreate(&ipcServer, "testServerListenAndCancel",
78 RTLOCALIPC_FLAGS_MULTI_SESSION);
79 if (RT_SUCCESS(rc))
80 {
81 /* Spawn a simple worker thread and let it listen for incoming connections.
82 * In the meanwhile we try to cancel the server and see what happens. */
83 RTTHREAD hThread;
84 rc = RTThreadCreate(&hThread, testServerListenAndCancelThread,
85 &ipcServer, 0 /* Stack */, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "tstIpc1");
86 if (RT_SUCCESS(rc))
87 {
88 do
89 {
90 RTTestPrintf(hTest, RTTESTLVL_INFO, "Listening for incoming connections ...\n");
91 RTLOCALIPCSESSION ipcSession;
92 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcServerListen(ipcServer, &ipcSession), VERR_CANCELLED);
93 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcServerCancel(ipcServer), VINF_SUCCESS);
94 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcServerDestroy(ipcServer), VINF_SUCCESS);
95
96 RTTestPrintf(hTest, RTTESTLVL_INFO, "Waiting for thread to exit ...\n");
97 RTTEST_CHECK_RC(hTest, RTThreadWait(hThread,
98 30 * 1000 /* 30s timeout */, NULL), VINF_SUCCESS);
99 } while (0);
100 }
101 else
102 RTTestIFailed("Unable to create thread for cancelling server, rc=%Rrc\n", rc);
103 }
104 else
105 RTTestIFailed("Unable to create IPC server, rc=%Rrc\n", rc);
106
107 return VINF_SUCCESS;
108}
109
110static DECLCALLBACK(int) testSessionConnectionThread(RTTHREAD hSelf, void *pvUser)
111{
112 PLOCALIPCTHREADCTX pCtx = (PLOCALIPCTHREADCTX)pvUser;
113 AssertPtr(pCtx);
114
115 int rc;
116 RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionConnectionThread: Listening for incoming connections ...\n");
117 for (;;)
118 {
119 RTLOCALIPCSESSION ipcSession;
120 rc = RTLocalIpcServerListen(pCtx->hServer, &ipcSession);
121 RTTestPrintf(pCtx->hTest, RTTESTLVL_DEBUG, "testSessionConnectionThread: Listening returned with rc=%Rrc\n", rc);
122 if (RT_SUCCESS(rc))
123 {
124 RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionConnectionThread: Got new client connection\n");
125 }
126 else
127 break;
128 }
129
130 RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionConnectionThread: Ended with rc=%Rrc\n", rc);
131 return rc;
132}
133
134static RTEXITCODE testSessionConnectionChild(int argc, char **argv, RTTEST hTest)
135{
136 do
137 {
138 RTThreadSleep(2000); /* Fudge */
139 RTLOCALIPCSESSION clientSession;
140 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionConnect(&clientSession, "tstRTLocalIpcSessionConnection",
141 0 /* Flags */), VINF_SUCCESS);
142 RTThreadSleep(5000); /* Fudge */
143 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionClose(clientSession), VINF_SUCCESS);
144
145 } while (0);
146
147 return !RTTestErrorCount(hTest) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
148}
149
150static int testSessionConnection(RTTEST hTest, const char *pszExecPath)
151{
152 RTTestSub(hTest, "testSessionConnection");
153
154 RTLOCALIPCSERVER ipcServer;
155 int rc = RTLocalIpcServerCreate(&ipcServer, "tstRTLocalIpcSessionConnection",
156 RTLOCALIPC_FLAGS_MULTI_SESSION);
157 if (RT_SUCCESS(rc))
158 {
159#ifndef VBOX_TESTCASES_WITH_NO_THREADING
160 LOCALIPCTHREADCTX threadCtx = { ipcServer, hTest };
161
162 /* Spawn a simple worker thread and let it listen for incoming connections.
163 * In the meanwhile we try to cancel the server and see what happens. */
164 RTTHREAD hThread;
165 rc = RTThreadCreate(&hThread, testSessionConnectionThread,
166 &threadCtx, 0 /* Stack */, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "tstIpc2");
167 if (RT_SUCCESS(rc))
168 {
169 do
170 {
171 RTPROCESS hProc;
172 const char *apszArgs[4] = { pszExecPath, "child", "tstRTLocalIpcSessionConnectionFork", NULL };
173 RTTEST_CHECK_RC_BREAK(hTest, RTProcCreate(pszExecPath, apszArgs,
174 RTENV_DEFAULT, 0 /* fFlags*/, &hProc), VINF_SUCCESS);
175 RTPROCSTATUS stsChild;
176 RTTEST_CHECK_RC_BREAK(hTest, RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &stsChild), VINF_SUCCESS);
177 RTTestPrintf(hTest, RTTESTLVL_INFO, "Child terminated, waiting for server thread ...\n");
178 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcServerCancel(ipcServer), VINF_SUCCESS);
179 int threadRc;
180 RTTEST_CHECK_RC(hTest, RTThreadWait(hThread,
181 30 * 1000 /* 30s timeout */, &threadRc), VINF_SUCCESS);
182 RTTEST_CHECK_RC_BREAK(hTest, threadRc, VERR_CANCELLED);
183 RTTestPrintf(hTest, RTTESTLVL_INFO, "Server thread terminated successfully\n");
184 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcServerDestroy(ipcServer), VINF_SUCCESS);
185 RTTEST_CHECK_BREAK(hTest, stsChild.enmReason == RTPROCEXITREASON_NORMAL);
186 RTTEST_CHECK_BREAK(hTest, stsChild.iStatus == 0);
187 }
188 while (0);
189 }
190 else
191 RTTestFailed(hTest, "Unable to create thread for cancelling server, rc=%Rrc\n", rc);
192#else
193 do
194 {
195 RTPROCESS hProc;
196 const char *apszArgs[4] = { pszExecPath, "child", "tstRTLocalIpcSessionConnectionFork", NULL };
197 RTTEST_CHECK_RC_BREAK(hTest, RTProcCreate(pszExecPath, apszArgs,
198 RTENV_DEFAULT, 0 /* fFlags*/, &hProc), VINF_SUCCESS);
199 RTLOCALIPCSESSION ipcSession;
200 rc = RTLocalIpcServerListen(ipcServer, &ipcSession);
201 if (RT_SUCCESS(rc))
202 {
203 RTTestPrintf(hTest, RTTESTLVL_INFO, "testSessionConnectionThread: Got new client connection\n");
204 }
205 else
206 RTTestFailed(hTest, "Error while listening, rc=%Rrc\n", rc);
207
208 } while (0);
209#endif
210 }
211 else
212 RTTestFailed(hTest, "Unable to create IPC server, rc=%Rrc\n", rc);
213
214 return VINF_SUCCESS;
215}
216
217static DECLCALLBACK(int) testSessionWaitThread(RTTHREAD hSelf, void *pvUser)
218{
219 PLOCALIPCTHREADCTX pCtx = (PLOCALIPCTHREADCTX)pvUser;
220 AssertPtr(pCtx);
221
222 int rc;
223 for (;;)
224 {
225 RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionWaitThread: Listening for incoming connections ...\n");
226 RTLOCALIPCSESSION ipcSession;
227 rc = RTLocalIpcServerListen(pCtx->hServer, &ipcSession);
228 if (RT_SUCCESS(rc))
229 {
230 RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionWaitThread: Got new client connection, waiting a bit ...\n");
231 RTThreadSleep(2000);
232 rc = RTLocalIpcSessionClose(ipcSession);
233 }
234 else
235 {
236 RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionWaitThread: Listening ended with rc=%Rrc\n", rc);
237 break;
238 }
239 }
240
241 RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionWaitThread: Ended with rc=%Rrc\n", rc);
242 return rc;
243}
244
245static RTEXITCODE testSessionWaitChild(int argc, char **argv, RTTEST hTest)
246{
247 do
248 {
249 RTThreadSleep(2000); /* Fudge. */
250 RTLOCALIPCSESSION clientSession;
251 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionConnect(&clientSession, "tstRTLocalIpcSessionWait",
252 0 /* Flags */), VINF_SUCCESS);
253 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionWaitForData(clientSession, 100 /* 100ms timeout */),
254 VERR_TIMEOUT);
255 /* Next, try 60s timeout. Should be returning way earlier because the server closed the
256 * connection after the first client connected. */
257 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionWaitForData(clientSession, 60 * 1000),
258 VERR_BROKEN_PIPE);
259 /* Last try, also should fail because the server should be not around anymore. */
260 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionWaitForData(clientSession, 5 * 1000),
261 VERR_BROKEN_PIPE);
262 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionClose(clientSession), VINF_SUCCESS);
263
264 } while (0);
265
266 return !RTTestErrorCount(hTest) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
267}
268
269static int testSessionWait(RTTEST hTest, const char *pszExecPath)
270{
271 RTTestSub(hTest, "testSessionWait");
272
273 RTLOCALIPCSERVER ipcServer;
274 int rc = RTLocalIpcServerCreate(&ipcServer, "tstRTLocalIpcSessionWait",
275 RTLOCALIPC_FLAGS_MULTI_SESSION);
276 if (RT_SUCCESS(rc))
277 {
278 LOCALIPCTHREADCTX threadCtx = { ipcServer, hTest };
279
280 /* Spawn a simple worker thread and let it listen for incoming connections.
281 * In the meanwhile we try to cancel the server and see what happens. */
282 RTTHREAD hThread;
283 rc = RTThreadCreate(&hThread, testSessionWaitThread,
284 &threadCtx, 0 /* Stack */, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "tstIpc3");
285 if (RT_SUCCESS(rc))
286 {
287 do
288 {
289 RTPROCESS hProc;
290 const char *apszArgs[4] = { pszExecPath, "child", "tstRTLocalIpcSessionWaitFork", NULL };
291 RTTEST_CHECK_RC_BREAK(hTest, RTProcCreate(pszExecPath, apszArgs,
292 RTENV_DEFAULT, 0 /* fFlags*/, &hProc), VINF_SUCCESS);
293 RTThreadSleep(5000); /* Let the server run for some time ... */
294 RTTestPrintf(hTest, RTTESTLVL_INFO, "Cancelling server listening\n");
295 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcServerCancel(ipcServer), VINF_SUCCESS);
296 /* Wait for the server thread to terminate. */
297 int threadRc;
298 RTTEST_CHECK_RC(hTest, RTThreadWait(hThread,
299 30 * 1000 /* 30s timeout */, &threadRc), VINF_SUCCESS);
300 RTTEST_CHECK_RC_BREAK(hTest, threadRc, VERR_CANCELLED);
301 RTTEST_CHECK_RC(hTest, RTLocalIpcServerDestroy(ipcServer), VINF_SUCCESS);
302 RTTestPrintf(hTest, RTTESTLVL_INFO, "Server thread terminated successfully\n");
303 /* Check if the child ran successfully. */
304 RTPROCSTATUS stsChild;
305 RTTEST_CHECK_RC_BREAK(hTest, RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &stsChild), VINF_SUCCESS);
306 RTTestPrintf(hTest, RTTESTLVL_INFO, "Child terminated\n");
307 RTTEST_CHECK_BREAK(hTest, stsChild.enmReason == RTPROCEXITREASON_NORMAL);
308 RTTEST_CHECK_BREAK(hTest, stsChild.iStatus == 0);
309 }
310 while (0);
311 }
312 else
313 RTTestFailed(hTest, "Unable to create thread for cancelling server, rc=%Rrc\n", rc);
314 }
315 else
316 RTTestFailed(hTest, "Unable to create IPC server, rc=%Rrc\n", rc);
317
318 return VINF_SUCCESS;
319}
320
321/**
322 * Simple structure holding the test IPC messages.
323 */
324typedef struct LOCALIPCTESTMSG
325{
326 /** The actual message. */
327 char szOp[255];
328} LOCALIPCTESTMSG, *PLOCALIPCTESTMSG;
329
330static DECLCALLBACK(int) testSessionDataThread(RTTHREAD hSelf, void *pvUser)
331{
332 PLOCALIPCTHREADCTX pCtx = (PLOCALIPCTHREADCTX)pvUser;
333 AssertPtr(pCtx);
334
335 do
336 {
337 /* Note: At the moment we only support one client per run. */
338 RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionDataThread: Listening for incoming connections ...\n");
339 RTLOCALIPCSESSION ipcSession;
340 RTTEST_CHECK_RC_BREAK(pCtx->hTest, RTLocalIpcServerListen(pCtx->hServer, &ipcSession), VINF_SUCCESS);
341 RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionDataThread: Got new client connection\n");
342 uint32_t cRounds = 256; /** @todo Use RTRand(). */
343 RTTEST_CHECK_RC_BREAK(pCtx->hTest, RTLocalIpcSessionWrite(ipcSession, &cRounds, sizeof(cRounds)), VINF_SUCCESS);
344 RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionDataThread: Written number of rounds\n");
345 for (uint32_t i = 0; i < cRounds; i++)
346 {
347 LOCALIPCTESTMSG msg;
348 RTTEST_CHECK_BREAK(pCtx->hTest, RTStrPrintf(msg.szOp, sizeof(msg.szOp),
349 "YayIGotRound%RU32FromTheServer", i) > 0);
350 RTTEST_CHECK_RC_BREAK(pCtx->hTest, RTLocalIpcSessionWrite(ipcSession, &msg, sizeof(msg)), VINF_SUCCESS);
351 }
352 RTThreadSleep(10 * 1000); /* Fudge. */
353 RTTEST_CHECK_RC_BREAK(pCtx->hTest, RTLocalIpcSessionClose(ipcSession), VINF_SUCCESS);
354 RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionDataThread: Data successfully written\n");
355
356 } while (0);
357
358 return !RTTestErrorCount(pCtx->hTest) ? VINF_SUCCESS : VERR_GENERAL_FAILURE /* Doesn't matter */;
359}
360
361static RTEXITCODE testSessionDataChild(int argc, char **argv, RTTEST hTest)
362{
363 uint8_t *pvScratchBuf = (uint8_t*)RTMemAlloc(_1K);
364 RTTEST_CHECK_RET(hTest, pvScratchBuf != NULL, RTEXITCODE_FAILURE);
365
366 do
367 {
368 RTThreadSleep(2000); /* Fudge. */
369 RTLOCALIPCSESSION clientSession;
370 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionConnect(&clientSession, "tstRTLocalIpcSessionData",
371 0 /* Flags */), VINF_SUCCESS);
372 /* Get number of rounds we want to read/write. */
373 uint32_t cRounds = 0; size_t cbRead;
374 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionWaitForData(clientSession, RT_INDEFINITE_WAIT),
375 VINF_SUCCESS);
376 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionRead(clientSession, &cRounds, sizeof(cRounds),
377 NULL /* Get exactly sizeof(cRounds) bytes */), VINF_SUCCESS);
378 RTTEST_CHECK_BREAK(hTest, cRounds == 256); /** @todo Check for != 0 when using RTRand(). */
379 /* Process all rounds. */
380 size_t uOffScratchBuf = 0;
381 char szStr[32];
382 for (uint32_t i = 0; i < 1; cRounds++)
383 {
384 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionWaitForData(clientSession, RT_INDEFINITE_WAIT),
385 VINF_SUCCESS);
386 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionRead(clientSession, pvScratchBuf,
387 sizeof(*pvScratchBuf) - uOffScratchBuf,
388 &cbRead), VINF_SUCCESS);
389
390 uOffScratchBuf += cbRead;
391 RTTEST_CHECK_BREAK(hTest, uOffScratchBuf <= sizeof(*pvScratchBuf));
392 if (uOffScratchBuf >= sizeof(LOCALIPCTESTMSG)) /* Got a complete test message? */
393 {
394 PLOCALIPCTESTMSG pMsg = (PLOCALIPCTESTMSG)pvScratchBuf;
395 RTTEST_CHECK_BREAK(hTest, pMsg != NULL);
396 RTTEST_CHECK_BREAK(hTest, RTStrPrintf(szStr, sizeof(szStr), "YayIGotRound%RU32FromTheServer", i) > 0);
397 RTTEST_CHECK_BREAK(hTest, !RTStrICmp(pMsg->szOp, szStr));
398 memcpy(pvScratchBuf, (void*)pvScratchBuf[sizeof(LOCALIPCTESTMSG)], cbRead);
399 }
400 if (RTTestErrorCount(hTest))
401 break;
402 }
403 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionClose(clientSession), VINF_SUCCESS);
404
405 } while (0);
406
407 RTMemFree(pvScratchBuf);
408 return !RTTestErrorCount(hTest) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
409}
410
411static int testSessionData(RTTEST hTest, const char *pszExecPath)
412{
413 RTTestSub(hTest, "testSessionData");
414
415 RTLOCALIPCSERVER ipcServer;
416 int rc = RTLocalIpcServerCreate(&ipcServer, "tstRTLocalIpcSessionData",
417 RTLOCALIPC_FLAGS_MULTI_SESSION);
418 if (RT_SUCCESS(rc))
419 {
420 LOCALIPCTHREADCTX threadCtx = { ipcServer, hTest };
421
422 /* Spawn a simple worker thread and let it listen for incoming connections.
423 * In the meanwhile we try to cancel the server and see what happens. */
424 RTTHREAD hThread;
425 rc = RTThreadCreate(&hThread, testSessionDataThread,
426 &threadCtx, 0 /* Stack */, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "tstIpc4");
427 if (RT_SUCCESS(rc))
428 {
429 do
430 {
431 RTPROCESS hProc;
432 const char *apszArgs[4] = { pszExecPath, "child", "tstRTLocalIpcSessionDataFork", NULL };
433 RTTEST_CHECK_RC_BREAK(hTest, RTProcCreate(pszExecPath, apszArgs,
434 RTENV_DEFAULT, 0 /* fFlags*/, &hProc), VINF_SUCCESS);
435 /* Wait for the server thread to terminate. */
436 int threadRc;
437 RTTEST_CHECK_RC(hTest, RTThreadWait(hThread,
438 5 * 60 * 1000 /* 5 minutes timeout */, &threadRc), VINF_SUCCESS);
439 RTTEST_CHECK_RC_BREAK(hTest, threadRc, VINF_SUCCESS);
440 RTTEST_CHECK_RC(hTest, RTLocalIpcServerDestroy(ipcServer), VINF_SUCCESS);
441 RTTestPrintf(hTest, RTTESTLVL_INFO, "Server thread terminated successfully\n");
442 /* Check if the child ran successfully. */
443 RTPROCSTATUS stsChild;
444 RTTEST_CHECK_RC_BREAK(hTest, RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &stsChild), VINF_SUCCESS);
445 RTTestPrintf(hTest, RTTESTLVL_INFO, "Child terminated\n");
446 RTTEST_CHECK_BREAK(hTest, stsChild.enmReason == RTPROCEXITREASON_NORMAL);
447 RTTEST_CHECK_BREAK(hTest, stsChild.iStatus == 0);
448 }
449 while (0);
450 }
451 else
452 RTTestFailed(hTest, "Unable to create thread for cancelling server, rc=%Rrc\n", rc);
453 }
454 else
455 RTTestFailed(hTest, "Unable to create IPC server, rc=%Rrc\n", rc);
456
457 return VINF_SUCCESS;
458}
459
460static RTEXITCODE mainChild(int argc, char **argv)
461{
462 if (argc < 3) /* Safety first. */
463 return RTEXITCODE_FAILURE;
464 /* Note: We assume argv[2] always contains the actual test type to perform. */
465 RTTEST hTest;
466 RTEXITCODE rcExit = RTTestInitAndCreate(argv[2], &hTest);
467 if (rcExit)
468 return rcExit;
469 RTTestBanner(hTest);
470
471 RTAssertSetMayPanic(false);
472#ifdef DEBUG_andy
473 RTAssertSetQuiet(false);
474#endif
475
476 if (!RTStrICmp(argv[2], "tstRTLocalIpcSessionConnectionFork"))
477 rcExit = testSessionConnectionChild(argc, argv, hTest);
478 else if (!RTStrICmp(argv[2], "tstRTLocalIpcSessionWaitFork"))
479 rcExit = testSessionWaitChild(argc, argv, hTest);
480 else if (!RTStrICmp(argv[2], "tstRTLocalIpcSessionDataFork"))
481 rcExit = testSessionDataChild(argc, argv, hTest);
482
483 return RTTestSummaryAndDestroy(hTest);
484}
485
486int main(int argc, char **argv)
487{
488 if ( argc > 2
489 && !RTStrICmp(argv[1], "child"))
490 return mainChild(argc, argv);
491
492 RTTEST hTest;
493 RTEXITCODE rcExit = RTTestInitAndCreate("tstRTLocalIpc", &hTest);
494 if (rcExit)
495 return rcExit;
496 RTTestBanner(hTest);
497
498 char szExecPath[RTPATH_MAX];
499 if (!RTProcGetExecutablePath(szExecPath, sizeof(szExecPath)))
500 RTStrCopy(szExecPath, sizeof(szExecPath), argv[0]);
501
502 RTTestISub("Basics");
503
504 RTAssertSetMayPanic(false);
505#ifdef DEBUG_andy
506 RTAssertSetQuiet(false);
507#endif
508
509 /* Server-side. */
510 RTTESTI_CHECK_RC_RET(RTLocalIpcServerCreate(NULL, NULL, 0), VERR_INVALID_POINTER, 1);
511 RTLOCALIPCSERVER ipcServer;
512 RTTESTI_CHECK_RC_RET(RTLocalIpcServerCreate(&ipcServer, NULL, 0), VERR_INVALID_POINTER, 1);
513 RTTESTI_CHECK_RC_RET(RTLocalIpcServerCreate(&ipcServer, "", 0), VERR_INVALID_PARAMETER, 1);
514 RTTESTI_CHECK_RC_RET(RTLocalIpcServerCreate(&ipcServer, "BasicTest", 0 /* Invalid flags */), VERR_INVALID_PARAMETER, 1);
515 RTTESTI_CHECK_RC_RET(RTLocalIpcServerCreate(&ipcServer, "BasicTest", 1234 /* Invalid flags */), VERR_INVALID_PARAMETER, 1);
516 RTTESTI_CHECK_RC_RET(RTLocalIpcServerCancel(NULL), VERR_INVALID_HANDLE, 1);
517 RTTESTI_CHECK_RC_RET(RTLocalIpcServerDestroy(NULL), VINF_SUCCESS, 1);
518 /* Basic server creation / destruction. */
519 RTTESTI_CHECK_RC_RET(RTLocalIpcServerCreate(&ipcServer, "BasicTest", RTLOCALIPC_FLAGS_MULTI_SESSION), VINF_SUCCESS, 1);
520 RTTESTI_CHECK_RC_RET(RTLocalIpcServerCancel(ipcServer), VINF_SUCCESS, 1);
521 RTTESTI_CHECK_RC_RET(RTLocalIpcServerDestroy(ipcServer), VINF_SUCCESS, 1);
522
523 /* Client-side (per session). */
524 RTTESTI_CHECK_RC_RET(RTLocalIpcSessionConnect(NULL, NULL, 0), VERR_INVALID_POINTER, 1);
525 RTLOCALIPCSESSION ipcSession;
526 RTTESTI_CHECK_RC_RET(RTLocalIpcSessionConnect(&ipcSession, NULL, 0), VERR_INVALID_POINTER, 1);
527 RTTESTI_CHECK_RC_RET(RTLocalIpcSessionConnect(&ipcSession, "", 0), VERR_INVALID_PARAMETER, 1);
528 RTTESTI_CHECK_RC_RET(RTLocalIpcSessionConnect(&ipcSession, "BasicTest", 1234 /* Invalid flags */), VERR_INVALID_PARAMETER, 1);
529 RTTESTI_CHECK_RC_RET(RTLocalIpcSessionCancel(NULL), VERR_INVALID_HANDLE, 1);
530 RTTESTI_CHECK_RC_RET(RTLocalIpcSessionClose(NULL), VINF_SUCCESS, 1);
531 /* Basic client creation / destruction. */
532 RTTESTI_CHECK_RC_RET(RTLocalIpcSessionConnect(&ipcSession, "BasicTest", 0), VERR_FILE_NOT_FOUND, 1);
533 RTTESTI_CHECK_RC_RET(RTLocalIpcServerCancel(ipcServer), VERR_INVALID_MAGIC, 1);
534 RTTESTI_CHECK_RC_RET(RTLocalIpcServerDestroy(ipcServer), VERR_INVALID_MAGIC, 1);
535
536 if (RTTestErrorCount(hTest) == 0)
537 {
538 /*RTTESTI_CHECK_RC_RET(testServerListenAndCancel(hTest, szExecPath), VINF_SUCCESS, 1);
539 RTTESTI_CHECK_RC_RET(testSessionConnection(hTest, szExecPath), VINF_SUCCESS, 1);
540 RTTESTI_CHECK_RC_RET(testSessionWait(hTest, szExecPath), VINF_SUCCESS, 1);*/
541 RTTESTI_CHECK_RC_RET(testSessionData(hTest, szExecPath), VINF_SUCCESS, 1);
542 }
543
544 /*
545 * Summary.
546 */
547 return RTTestSummaryAndDestroy(hTest);
548}
549
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette