VirtualBox

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

Last change on this file since 93115 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

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