]> git.saurik.com Git - wxWidgets.git/blame - tests/net/socket.cpp
fix handling of errors due to the other end of the socket being closed
[wxWidgets.git] / tests / net / socket.cpp
CommitLineData
62fb86a5
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: tests/net/socket.cpp
3// Purpose: wxSocket unit tests
4// Author: Vadim Zeitlin
5// RCS-ID: $Id$
6// Copyright: (c) 2008 Vadim Zeitlin
7// Licence: wxWidgets licence
8///////////////////////////////////////////////////////////////////////////////
9
10/*
11 IMPORTANT NOTE: the environment variable WX_TEST_SERVER must be set to the
12 hostname of the server to use for the tests below, if it is not set all
13 tests are silently skipped (rationale: this makes it possible to run the
14 test in the restricted environments (e.g. sandboxes) without any network
15 connectivity).
16 */
17
18// For compilers that support precompilation, includes "wx/wx.h".
19// and "wx/cppunit.h"
20#include "testprec.h"
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
26#if wxUSE_SOCKETS
27
28#include "wx/socket.h"
7b9b06e3 29#include "wx/evtloop.h"
62fb86a5
VZ
30#include <memory>
31
32typedef std::auto_ptr<wxSockAddress> wxSockAddressPtr;
33typedef std::auto_ptr<wxSocketClient> wxSocketClientPtr;
34
35static wxString gs_serverHost(wxGetenv("WX_TEST_SERVER"));
36
37class SocketTestCase : public CppUnit::TestCase
38{
39public:
8d8087fc 40 SocketTestCase() { }
62fb86a5
VZ
41
42private:
6e7fd3ca
VZ
43 // we need to repeat the tests twice as the sockets behave differently when
44 // there is an active event loop and without it
45 #define ALL_SOCKET_TESTS() \
46 CPPUNIT_TEST( BlockingConnect ); \
47 CPPUNIT_TEST( NonblockingConnect ); \
48 CPPUNIT_TEST( ReadNormal ); \
49 CPPUNIT_TEST( ReadBlock ); \
50 CPPUNIT_TEST( ReadNowait ); \
51 CPPUNIT_TEST( ReadWaitall )
52
62fb86a5 53 CPPUNIT_TEST_SUITE( SocketTestCase );
6e7fd3ca
VZ
54 ALL_SOCKET_TESTS();
55 CPPUNIT_TEST( PseudoTest_SetUseEventLoop );
56 ALL_SOCKET_TESTS();
62fb86a5
VZ
57 CPPUNIT_TEST_SUITE_END();
58
6e7fd3ca
VZ
59 // helper event loop class which sets itself as active only if we pass it
60 // true in ctor
61 class SocketTestEventLoop : public wxEventLoop
62 {
63 public:
64 SocketTestEventLoop(bool useLoop)
65 {
66 m_useLoop = useLoop;
67 if ( useLoop )
68 SetActive(this);
69 }
70
71 virtual ~SocketTestEventLoop()
72 {
73 if ( m_useLoop )
74 SetActive(NULL);
75 }
76
77 private:
78 bool m_useLoop;
79 };
80
62fb86a5
VZ
81 // get the address to connect to, if NULL is returned it means that the
82 // test is disabled and shouldn't run at all
83 wxSockAddressPtr GetServer() const;
84
85 // get the socket to read HTTP reply from, returns NULL if the test is
86 // disabled
87 wxSocketClientPtr GetHTTPSocket(int flags = wxSOCKET_NONE) const;
88
8d8087fc 89 void PseudoTest_SetUseEventLoop() { ms_useLoop = true; }
6e7fd3ca 90
62fb86a5
VZ
91 void BlockingConnect();
92 void NonblockingConnect();
93 void ReadNormal();
7b9b06e3 94 void ReadBlock();
62fb86a5
VZ
95 void ReadNowait();
96 void ReadWaitall();
97
8d8087fc 98 static bool ms_useLoop;
6e7fd3ca 99
62fb86a5
VZ
100 DECLARE_NO_COPY_CLASS(SocketTestCase)
101};
102
8d8087fc
VZ
103bool SocketTestCase::ms_useLoop = false;
104
62fb86a5
VZ
105CPPUNIT_TEST_SUITE_REGISTRATION( SocketTestCase );
106CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( SocketTestCase, "SocketTestCase" );
107
108wxSockAddressPtr SocketTestCase::GetServer() const
109{
b245cbc5
VZ
110 if ( gs_serverHost.empty() )
111 return wxSockAddressPtr();
62fb86a5 112
b245cbc5
VZ
113 wxIPV4address *addr = new wxIPV4address;
114 addr->Hostname(gs_serverHost);
115 addr->Service("www");
62fb86a5 116
b245cbc5 117 return wxSockAddressPtr(addr);
62fb86a5
VZ
118}
119
120wxSocketClientPtr SocketTestCase::GetHTTPSocket(int flags) const
121{
62fb86a5
VZ
122 wxSockAddressPtr addr = GetServer();
123 if ( !addr.get() )
b245cbc5 124 return wxSocketClientPtr();
62fb86a5
VZ
125
126 wxSocketClient *sock = new wxSocketClient(flags);
127 sock->SetTimeout(1);
128 CPPUNIT_ASSERT( sock->Connect(*addr) );
129
130 const wxString httpGetRoot =
131 "GET / HTTP/1.1\r\n"
132 "Host: " + gs_serverHost + "\r\n"
133 "\r\n";
134
6b6b233a 135 sock->Write(httpGetRoot.ToAscii(), httpGetRoot.length());
62fb86a5 136
b245cbc5 137 return wxSocketClientPtr(sock);
62fb86a5
VZ
138}
139
140void SocketTestCase::BlockingConnect()
141{
142 wxSockAddressPtr addr = GetServer();
143 if ( !addr.get() )
144 return;
145
146 wxSocketClient sock;
147 CPPUNIT_ASSERT( sock.Connect(*addr) );
148}
149
150void SocketTestCase::NonblockingConnect()
151{
152 wxSockAddressPtr addr = GetServer();
153 if ( !addr.get() )
154 return;
155
8d8087fc 156 SocketTestEventLoop loop(ms_useLoop);
7b9b06e3 157
62fb86a5
VZ
158 wxSocketClient sock;
159 sock.Connect(*addr, false);
160 sock.WaitOnConnect(10);
161
162 CPPUNIT_ASSERT( sock.IsConnected() );
163}
164
165void SocketTestCase::ReadNormal()
166{
8d8087fc 167 SocketTestEventLoop loop(ms_useLoop);
7b9b06e3 168
62fb86a5
VZ
169 wxSocketClientPtr sock(GetHTTPSocket());
170 if ( !sock.get() )
171 return;
172
173 char bufSmall[128];
174 sock->Read(bufSmall, WXSIZEOF(bufSmall));
175
176 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
177 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(bufSmall), sock->LastCount() );
178
179
3afc646c 180 char bufBig[102400];
62fb86a5
VZ
181 sock->Read(bufBig, WXSIZEOF(bufBig));
182
183 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
184 CPPUNIT_ASSERT( WXSIZEOF(bufBig) >= sock->LastCount() );
185}
186
7b9b06e3
VZ
187void SocketTestCase::ReadBlock()
188{
189 wxSocketClientPtr sock(GetHTTPSocket(wxSOCKET_BLOCK));
190 if ( !sock.get() )
191 return;
192
193 char bufSmall[128];
194 sock->Read(bufSmall, WXSIZEOF(bufSmall));
195
196 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
197 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(bufSmall), sock->LastCount() );
198
199
200 char bufBig[102400];
201 sock->Read(bufBig, WXSIZEOF(bufBig));
202
203 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
204 CPPUNIT_ASSERT( WXSIZEOF(bufBig) >= sock->LastCount() );
205}
206
62fb86a5
VZ
207void SocketTestCase::ReadNowait()
208{
209 wxSocketClientPtr sock(GetHTTPSocket(wxSOCKET_NOWAIT));
210 if ( !sock.get() )
211 return;
212
213 char buf[1024];
214 sock->Read(buf, WXSIZEOF(buf));
215 if ( sock->LastError() != wxSOCKET_WOULDBLOCK )
216 {
217 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
218 }
219}
220
221void SocketTestCase::ReadWaitall()
222{
8d8087fc 223 SocketTestEventLoop loop(ms_useLoop);
7b9b06e3 224
62fb86a5
VZ
225 wxSocketClientPtr sock(GetHTTPSocket(wxSOCKET_WAITALL));
226 if ( !sock.get() )
227 return;
228
229 char buf[128];
230 sock->Read(buf, WXSIZEOF(buf));
231
232 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
233 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(buf), sock->LastCount() );
234}
235
236#endif // wxUSE_SOCKETS