VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTTcp-1.cpp@ 66404

Last change on this file since 66404 was 63483, checked in by vboxsync, 8 years ago

tstRTTcp-1: apply Solaris VERR_NET_ADDRESS_IN_USE fudge to Linux as well

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.4 KB
Line 
1/* $Id: tstRTTcp-1.cpp 63483 2016-08-15 14:25:03Z vboxsync $ */
2/** @file
3 * IPRT testcase - TCP.
4 */
5
6/*
7 * Copyright (C) 2010-2016 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#include <iprt/tcp.h>
29
30#include <iprt/string.h>
31#include <iprt/test.h>
32
33
34/*********************************************************************************************************************************
35* Global Variables *
36*********************************************************************************************************************************/
37static RTTEST g_hTest;
38
39
40/* * * * * * * * Test 3 * * * * * * * */
41
42static DECLCALLBACK(int) test3Server(RTSOCKET hSocket, void *pvUser)
43{
44 RT_NOREF_PV(pvUser);
45
46 RTTestSetDefault(g_hTest, NULL);
47 char szBuf[4096];
48
49 /* say hello */
50 RTTESTI_CHECK_RC_RET(RTTcpWrite(hSocket, "hello\n", sizeof("hello\n") - 1), VINF_SUCCESS, VERR_TCP_SERVER_STOP);
51 RT_ZERO(szBuf);
52 RTTESTI_CHECK_RC_RET(RTTcpRead(hSocket, szBuf, sizeof("dude!\n") - 1, NULL), VINF_SUCCESS, VERR_TCP_SERVER_STOP);
53 szBuf[sizeof("dude!\n") - 1] = '\0';
54 RTTESTI_CHECK_RET(strcmp(szBuf, "dude!\n") == 0, VERR_TCP_SERVER_STOP);
55
56 /* Send ~20 MB of data that the client receives while trying to disconnect. */
57 RT_ZERO(szBuf);
58 size_t cbSent = 0;
59 while (cbSent < 20 * _1M)
60 {
61 RTTESTI_CHECK_RC_RET(RTTcpWrite(hSocket, szBuf, sizeof(szBuf)), VINF_SUCCESS, VERR_TCP_SERVER_STOP);
62 cbSent += sizeof(szBuf);
63 }
64
65 return VERR_TCP_SERVER_STOP;
66}
67
68
69void test3()
70{
71 RTTestSub(g_hTest, "Graceful disconnect");
72
73 uint32_t cStartErrors = RTTestErrorCount(g_hTest);
74 for (unsigned i = 0; i < 100 && cStartErrors == RTTestErrorCount(g_hTest); i++)
75 {
76 PRTTCPSERVER pServer;
77 int rc = RTTcpServerCreate("localhost", 9999, RTTHREADTYPE_DEFAULT, "server-2", test3Server, NULL, &pServer);
78#if defined(RT_OS_SOLARIS) || defined(RT_OS_LINUX)
79 /** @todo testboxsh1 occationally hits this for some stupid reason. i=21 in
80 * one occurrence. Fudge a bit for now and see if it helps.
81 * Same for testboxopt, i=98 in another case. */
82 if (rc == VERR_NET_ADDRESS_IN_USE)
83 {
84 RTThreadSleep(500);
85 rc = RTTcpServerCreate("localhost", 9999, RTTHREADTYPE_DEFAULT, "server-2", test3Server, NULL, &pServer);
86 }
87#endif
88 if (rc != VINF_SUCCESS)
89 {
90 RTTestIFailed("RTTcpServerCreate -> %Rrc, i=%d", rc, i);
91 return;
92 }
93
94 RTSOCKET hSocket;
95 RTTESTI_CHECK_RC(rc = RTTcpClientConnect("localhost", 9999, &hSocket), VINF_SUCCESS);
96 if (RT_SUCCESS(rc))
97 {
98 char szBuf[512];
99 RT_ZERO(szBuf);
100 do /* break non-loop */
101 {
102 RTTESTI_CHECK_RC_BREAK(RTTcpRead(hSocket, szBuf, sizeof("hello\n") - 1, NULL), VINF_SUCCESS);
103 RTTESTI_CHECK_BREAK(strcmp(szBuf, "hello\n") == 0);
104 RTTESTI_CHECK_RC_BREAK(RTTcpWrite(hSocket, "dude!\n", sizeof("dude!\n") - 1), VINF_SUCCESS);
105 } while (0);
106
107 RTTESTI_CHECK_RC(RTTcpClientClose(hSocket), VINF_SUCCESS);
108 }
109
110 RTTESTI_CHECK_RC(RTTcpServerDestroy(pServer), VINF_SUCCESS);
111 }
112}
113
114
115/* * * * * * * * Test 2 * * * * * * * */
116
117static DECLCALLBACK(int) test2Server(RTSOCKET hSocket, void *pvUser)
118{
119 RT_NOREF_PV(pvUser);
120
121 RTTestSetDefault(g_hTest, NULL);
122 char szBuf[512];
123
124 /* say hello */
125 RTTESTI_CHECK_RC_RET(RTTcpWrite(hSocket, "hello\n", sizeof("hello\n") - 1), VINF_SUCCESS, VERR_TCP_SERVER_STOP);
126 RT_ZERO(szBuf);
127 RTTESTI_CHECK_RC_RET(RTTcpRead(hSocket, szBuf, sizeof("dude!\n") - 1, NULL), VINF_SUCCESS, VERR_TCP_SERVER_STOP);
128 szBuf[sizeof("dude!\n") - 1] = '\0';
129 RTTESTI_CHECK_RET(strcmp(szBuf, "dude!\n") == 0, VERR_TCP_SERVER_STOP);
130
131 /* wait for a goodbye which doesn't arrive. */
132 RT_ZERO(szBuf);
133 RTTESTI_CHECK_RC_RET(RTTcpRead(hSocket, szBuf, sizeof("byebye\n") - 1, NULL), VERR_NET_SHUTDOWN, VERR_TCP_SERVER_STOP);
134
135 return VERR_TCP_SERVER_STOP;
136}
137
138
139void test2()
140{
141 RTTestSub(g_hTest, "Rude client");
142
143 PRTTCPSERVER pServer;
144 RTTESTI_CHECK_RC_RETV(RTTcpServerCreate("localhost", 9999, RTTHREADTYPE_DEFAULT, "server-2",
145 test2Server, NULL, &pServer), VINF_SUCCESS);
146
147 int rc;
148 RTSOCKET hSocket;
149 RTTESTI_CHECK_RC(rc = RTTcpClientConnect("localhost", 9999, &hSocket), VINF_SUCCESS);
150 if (RT_SUCCESS(rc))
151 {
152 char szBuf[512];
153 RT_ZERO(szBuf);
154 do /* break non-loop */
155 {
156 RTTESTI_CHECK_RC_BREAK(RTTcpRead(hSocket, szBuf, sizeof("hello\n") - 1, NULL), VINF_SUCCESS);
157 RTTESTI_CHECK_BREAK(strcmp(szBuf, "hello\n") == 0);
158 RTTESTI_CHECK_RC_BREAK(RTTcpWrite(hSocket, "dude!\n", sizeof("dude!\n") - 1), VINF_SUCCESS);
159 } while (0);
160
161 RTTESTI_CHECK_RC(RTTcpClientClose(hSocket), VINF_SUCCESS);
162 }
163
164 RTTESTI_CHECK_RC(RTTcpServerDestroy(pServer), VINF_SUCCESS);
165}
166
167
168/* * * * * * * * Test 1 * * * * * * * */
169
170static DECLCALLBACK(int) test1Server(RTSOCKET hSocket, void *pvUser)
171{
172 RTTestSetDefault(g_hTest, NULL);
173
174 char szBuf[512];
175 RTTESTI_CHECK_RET(pvUser == NULL, VERR_TCP_SERVER_STOP);
176
177 /* say hello */
178 RTTESTI_CHECK_RC_RET(RTTcpWrite(hSocket, "hello\n", sizeof("hello\n") - 1), VINF_SUCCESS, VERR_TCP_SERVER_STOP);
179 RTTESTI_CHECK_RC_RET(RTTcpRead(hSocket, szBuf, sizeof("dude!\n") - 1, NULL), VINF_SUCCESS, VERR_TCP_SERVER_STOP);
180 szBuf[sizeof("dude!\n") - 1] = '\0';
181 RTTESTI_CHECK_RET(strcmp(szBuf, "dude!\n") == 0, VERR_TCP_SERVER_STOP);
182
183 /* say goodbye */
184 RTTESTI_CHECK_RC_RET(RTTcpRead(hSocket, szBuf, sizeof("byebye\n") - 1, NULL), VINF_SUCCESS, VERR_TCP_SERVER_STOP);
185 szBuf[sizeof("byebye\n") - 1] = '\0';
186 RTTESTI_CHECK_RET(strcmp(szBuf, "byebye\n") == 0, VERR_TCP_SERVER_STOP);
187 RTTESTI_CHECK_RC_RET(RTTcpWrite(hSocket, "bye\n", sizeof("bye\n") - 1), VINF_SUCCESS, VERR_TCP_SERVER_STOP);
188
189 return VERR_TCP_SERVER_STOP;
190}
191
192
193void test1()
194{
195 RTTestSub(g_hTest, "Simple server-client setup");
196
197 PRTTCPSERVER pServer;
198 RTTESTI_CHECK_RC_RETV(RTTcpServerCreate("localhost", 9999, RTTHREADTYPE_DEFAULT, "server-1",
199 test1Server, NULL, &pServer), VINF_SUCCESS);
200
201 int rc;
202 RTSOCKET hSocket;
203 RTTESTI_CHECK_RC(rc = RTTcpClientConnect("localhost", 9999, &hSocket), VINF_SUCCESS);
204 if (RT_SUCCESS(rc))
205 {
206 do /* break non-loop */
207 {
208 char szBuf[512];
209 RT_ZERO(szBuf);
210 RTTESTI_CHECK_RC_BREAK(RTTcpRead(hSocket, szBuf, sizeof("hello\n") - 1, NULL), VINF_SUCCESS);
211 RTTESTI_CHECK_BREAK(strcmp(szBuf, "hello\n") == 0);
212 RTTESTI_CHECK_RC_BREAK(RTTcpWrite(hSocket, "dude!\n", sizeof("dude!\n") - 1), VINF_SUCCESS);
213
214 RTTESTI_CHECK_RC_BREAK(RTTcpWrite(hSocket, "byebye\n", sizeof("byebye\n") - 1), VINF_SUCCESS);
215 RT_ZERO(szBuf);
216 RTTESTI_CHECK_RC_BREAK(RTTcpRead(hSocket, szBuf, sizeof("bye\n") - 1, NULL), VINF_SUCCESS);
217 RTTESTI_CHECK_BREAK(strcmp(szBuf, "bye\n") == 0);
218 } while (0);
219
220 RTTESTI_CHECK_RC(RTTcpClientClose(hSocket), VINF_SUCCESS);
221 }
222
223 RTTESTI_CHECK_RC(RTTcpServerDestroy(pServer), VINF_SUCCESS);
224}
225
226
227int main()
228{
229 RTEXITCODE rcExit = RTTestInitAndCreate("tstRTTcp-1", &g_hTest);
230 if (rcExit != RTEXITCODE_SUCCESS)
231 return rcExit;
232 RTTestBanner(g_hTest);
233
234 test1();
235 test2();
236 test3();
237
238 /** @todo test the full RTTcp API. */
239
240 return RTTestSummaryAndDestroy(g_hTest);
241}
242
Note: See TracBrowser for help on using the repository browser.

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