VirtualBox

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

Last change on this file since 100762 was 99775, checked in by vboxsync, 19 months ago

*: Mark functions as static if not used outside of a given compilation unit. Enables the compiler to optimize inlining, reduces the symbol tables, exposes unused functions and in some rare cases exposes mismtaches between function declarations and definitions, but most importantly reduces the number of parfait reports for the extern-function-no-forward-declaration category. This should not result in any functional changes, bugref:3409

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.1 KB
Line 
1/* $Id: tstRTTcp-1.cpp 99775 2023-05-12 12:21:58Z vboxsync $ */
2/** @file
3 * IPRT testcase - TCP.
4 */
5
6/*
7 * Copyright (C) 2010-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37
38/*********************************************************************************************************************************
39* Header Files *
40*********************************************************************************************************************************/
41#include <iprt/tcp.h>
42
43#include <iprt/err.h>
44#include <iprt/string.h>
45#include <iprt/test.h>
46
47
48/*********************************************************************************************************************************
49* Global Variables *
50*********************************************************************************************************************************/
51static RTTEST g_hTest;
52
53
54/* * * * * * * * Test 3 * * * * * * * */
55
56static DECLCALLBACK(int) test3Server(RTSOCKET hSocket, void *pvUser)
57{
58 RT_NOREF_PV(pvUser);
59
60 RTTestSetDefault(g_hTest, NULL);
61 char szBuf[4096];
62
63 /* say hello */
64 RTTESTI_CHECK_RC_RET(RTTcpWrite(hSocket, "hello\n", sizeof("hello\n") - 1), VINF_SUCCESS, VERR_TCP_SERVER_STOP);
65 RT_ZERO(szBuf);
66 RTTESTI_CHECK_RC_RET(RTTcpRead(hSocket, szBuf, sizeof("dude!\n") - 1, NULL), VINF_SUCCESS, VERR_TCP_SERVER_STOP);
67 szBuf[sizeof("dude!\n") - 1] = '\0';
68 RTTESTI_CHECK_RET(strcmp(szBuf, "dude!\n") == 0, VERR_TCP_SERVER_STOP);
69
70 /* Send ~20 MB of data that the client receives while trying to disconnect. */
71 RT_ZERO(szBuf);
72 size_t cbSent = 0;
73 while (cbSent < 20 * _1M)
74 {
75 RTTESTI_CHECK_RC_RET(RTTcpWrite(hSocket, szBuf, sizeof(szBuf)), VINF_SUCCESS, VERR_TCP_SERVER_STOP);
76 cbSent += sizeof(szBuf);
77 }
78
79 return VERR_TCP_SERVER_STOP;
80}
81
82
83static void test3()
84{
85 RTTestSub(g_hTest, "Graceful disconnect");
86
87 uint32_t cStartErrors = RTTestErrorCount(g_hTest);
88 for (unsigned i = 0; i < 100 && cStartErrors == RTTestErrorCount(g_hTest); i++)
89 {
90 PRTTCPSERVER pServer;
91 int rc = RTTcpServerCreate("localhost", 9999, RTTHREADTYPE_DEFAULT, "server-2", test3Server, NULL, &pServer);
92#if defined(RT_OS_SOLARIS) || defined(RT_OS_LINUX)
93 /** @todo testboxsh1 occationally hits this for some stupid reason. i=21 in
94 * one occurrence. Fudge a bit for now and see if it helps.
95 * Same for testboxopt, i=98 in another case. */
96 if (rc == VERR_NET_ADDRESS_IN_USE)
97 {
98 RTThreadSleep(500);
99 rc = RTTcpServerCreate("localhost", 9999, RTTHREADTYPE_DEFAULT, "server-2", test3Server, NULL, &pServer);
100 }
101#endif
102 if (rc != VINF_SUCCESS)
103 {
104 RTTestIFailed("RTTcpServerCreate -> %Rrc, i=%d", rc, i);
105 return;
106 }
107
108 RTSOCKET hSocket;
109 RTTESTI_CHECK_RC(rc = RTTcpClientConnect("localhost", 9999, &hSocket), VINF_SUCCESS);
110 if (RT_SUCCESS(rc))
111 {
112 char szBuf[512];
113 RT_ZERO(szBuf);
114 do /* break non-loop */
115 {
116 RTTESTI_CHECK_RC_BREAK(RTTcpRead(hSocket, szBuf, sizeof("hello\n") - 1, NULL), VINF_SUCCESS);
117 RTTESTI_CHECK_BREAK(strcmp(szBuf, "hello\n") == 0);
118 RTTESTI_CHECK_RC_BREAK(RTTcpWrite(hSocket, "dude!\n", sizeof("dude!\n") - 1), VINF_SUCCESS);
119 } while (0);
120
121 RTTESTI_CHECK_RC(RTTcpClientClose(hSocket), VINF_SUCCESS);
122 }
123
124 RTTESTI_CHECK_RC(RTTcpServerDestroy(pServer), VINF_SUCCESS);
125 }
126}
127
128
129/* * * * * * * * Test 2 * * * * * * * */
130
131static DECLCALLBACK(int) test2Server(RTSOCKET hSocket, void *pvUser)
132{
133 RT_NOREF_PV(pvUser);
134
135 RTTestSetDefault(g_hTest, NULL);
136 char szBuf[512];
137
138 /* say hello */
139 RTTESTI_CHECK_RC_RET(RTTcpWrite(hSocket, "hello\n", sizeof("hello\n") - 1), VINF_SUCCESS, VERR_TCP_SERVER_STOP);
140 RT_ZERO(szBuf);
141 RTTESTI_CHECK_RC_RET(RTTcpRead(hSocket, szBuf, sizeof("dude!\n") - 1, NULL), VINF_SUCCESS, VERR_TCP_SERVER_STOP);
142 szBuf[sizeof("dude!\n") - 1] = '\0';
143 RTTESTI_CHECK_RET(strcmp(szBuf, "dude!\n") == 0, VERR_TCP_SERVER_STOP);
144
145 /* wait for a goodbye which doesn't arrive. */
146 RT_ZERO(szBuf);
147 RTTESTI_CHECK_RC_RET(RTTcpRead(hSocket, szBuf, sizeof("byebye\n") - 1, NULL), VERR_NET_SHUTDOWN, VERR_TCP_SERVER_STOP);
148
149 return VERR_TCP_SERVER_STOP;
150}
151
152
153static void test2()
154{
155 RTTestSub(g_hTest, "Rude client");
156
157 PRTTCPSERVER pServer;
158 RTTESTI_CHECK_RC_RETV(RTTcpServerCreate("localhost", 9999, RTTHREADTYPE_DEFAULT, "server-2",
159 test2Server, NULL, &pServer), VINF_SUCCESS);
160
161 int rc;
162 RTSOCKET hSocket;
163 RTTESTI_CHECK_RC(rc = RTTcpClientConnect("localhost", 9999, &hSocket), VINF_SUCCESS);
164 if (RT_SUCCESS(rc))
165 {
166 char szBuf[512];
167 RT_ZERO(szBuf);
168 do /* break non-loop */
169 {
170 RTTESTI_CHECK_RC_BREAK(RTTcpRead(hSocket, szBuf, sizeof("hello\n") - 1, NULL), VINF_SUCCESS);
171 RTTESTI_CHECK_BREAK(strcmp(szBuf, "hello\n") == 0);
172 RTTESTI_CHECK_RC_BREAK(RTTcpWrite(hSocket, "dude!\n", sizeof("dude!\n") - 1), VINF_SUCCESS);
173 } while (0);
174
175 RTTESTI_CHECK_RC(RTTcpClientClose(hSocket), VINF_SUCCESS);
176 }
177
178 RTTESTI_CHECK_RC(RTTcpServerDestroy(pServer), VINF_SUCCESS);
179}
180
181
182/* * * * * * * * Test 1 * * * * * * * */
183
184static DECLCALLBACK(int) test1Server(RTSOCKET hSocket, void *pvUser)
185{
186 RTTestSetDefault(g_hTest, NULL);
187
188 char szBuf[512];
189 RTTESTI_CHECK_RET(pvUser == NULL, VERR_TCP_SERVER_STOP);
190
191 /* say hello */
192 RTTESTI_CHECK_RC_RET(RTTcpWrite(hSocket, "hello\n", sizeof("hello\n") - 1), VINF_SUCCESS, VERR_TCP_SERVER_STOP);
193 RTTESTI_CHECK_RC_RET(RTTcpRead(hSocket, szBuf, sizeof("dude!\n") - 1, NULL), VINF_SUCCESS, VERR_TCP_SERVER_STOP);
194 szBuf[sizeof("dude!\n") - 1] = '\0';
195 RTTESTI_CHECK_RET(strcmp(szBuf, "dude!\n") == 0, VERR_TCP_SERVER_STOP);
196
197 /* say goodbye */
198 RTTESTI_CHECK_RC_RET(RTTcpRead(hSocket, szBuf, sizeof("byebye\n") - 1, NULL), VINF_SUCCESS, VERR_TCP_SERVER_STOP);
199 szBuf[sizeof("byebye\n") - 1] = '\0';
200 RTTESTI_CHECK_RET(strcmp(szBuf, "byebye\n") == 0, VERR_TCP_SERVER_STOP);
201 RTTESTI_CHECK_RC_RET(RTTcpWrite(hSocket, "bye\n", sizeof("bye\n") - 1), VINF_SUCCESS, VERR_TCP_SERVER_STOP);
202
203 return VERR_TCP_SERVER_STOP;
204}
205
206
207static void test1()
208{
209 RTTestSub(g_hTest, "Simple server-client setup");
210
211 PRTTCPSERVER pServer;
212 RTTESTI_CHECK_RC_RETV(RTTcpServerCreate("localhost", 9999, RTTHREADTYPE_DEFAULT, "server-1",
213 test1Server, NULL, &pServer), VINF_SUCCESS);
214
215 int rc;
216 RTSOCKET hSocket;
217 RTTESTI_CHECK_RC(rc = RTTcpClientConnect("localhost", 9999, &hSocket), VINF_SUCCESS);
218 if (RT_SUCCESS(rc))
219 {
220 do /* break non-loop */
221 {
222 char szBuf[512];
223 RT_ZERO(szBuf);
224 RTTESTI_CHECK_RC_BREAK(RTTcpRead(hSocket, szBuf, sizeof("hello\n") - 1, NULL), VINF_SUCCESS);
225 RTTESTI_CHECK_BREAK(strcmp(szBuf, "hello\n") == 0);
226 RTTESTI_CHECK_RC_BREAK(RTTcpWrite(hSocket, "dude!\n", sizeof("dude!\n") - 1), VINF_SUCCESS);
227
228 RTTESTI_CHECK_RC_BREAK(RTTcpWrite(hSocket, "byebye\n", sizeof("byebye\n") - 1), VINF_SUCCESS);
229 RT_ZERO(szBuf);
230 RTTESTI_CHECK_RC_BREAK(RTTcpRead(hSocket, szBuf, sizeof("bye\n") - 1, NULL), VINF_SUCCESS);
231 RTTESTI_CHECK_BREAK(strcmp(szBuf, "bye\n") == 0);
232 } while (0);
233
234 RTTESTI_CHECK_RC(RTTcpClientClose(hSocket), VINF_SUCCESS);
235 }
236
237 RTTESTI_CHECK_RC(RTTcpServerDestroy(pServer), VINF_SUCCESS);
238}
239
240
241int main()
242{
243 RTEXITCODE rcExit = RTTestInitAndCreate("tstRTTcp-1", &g_hTest);
244 if (rcExit != RTEXITCODE_SUCCESS)
245 return rcExit;
246 RTTestBanner(g_hTest);
247
248 test1();
249 test2();
250 test3();
251
252 /** @todo test the full RTTcp API. */
253
254 return RTTestSummaryAndDestroy(g_hTest);
255}
256
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