]> git.saurik.com Git - wxWidgets.git/blame - tests/net/socket.cpp
added wxProtocolLog class for logging network requests/responses (closes #7464)
[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"
6799c5e2
VZ
29#include "wx/url.h"
30#include "wx/sstream.h"
7b9b06e3 31#include "wx/evtloop.h"
62fb86a5
VZ
32#include <memory>
33
34typedef std::auto_ptr<wxSockAddress> wxSockAddressPtr;
35typedef std::auto_ptr<wxSocketClient> wxSocketClientPtr;
36
37static wxString gs_serverHost(wxGetenv("WX_TEST_SERVER"));
38
39class SocketTestCase : public CppUnit::TestCase
40{
41public:
8d8087fc 42 SocketTestCase() { }
62fb86a5
VZ
43
44private:
6e7fd3ca
VZ
45 // we need to repeat the tests twice as the sockets behave differently when
46 // there is an active event loop and without it
47 #define ALL_SOCKET_TESTS() \
48 CPPUNIT_TEST( BlockingConnect ); \
49 CPPUNIT_TEST( NonblockingConnect ); \
50 CPPUNIT_TEST( ReadNormal ); \
51 CPPUNIT_TEST( ReadBlock ); \
52 CPPUNIT_TEST( ReadNowait ); \
16685812
VZ
53 CPPUNIT_TEST( ReadWaitall ); \
54 CPPUNIT_TEST( UrlTest )
6e7fd3ca 55
62fb86a5 56 CPPUNIT_TEST_SUITE( SocketTestCase );
6e7fd3ca
VZ
57 ALL_SOCKET_TESTS();
58 CPPUNIT_TEST( PseudoTest_SetUseEventLoop );
59 ALL_SOCKET_TESTS();
62fb86a5
VZ
60 CPPUNIT_TEST_SUITE_END();
61
6e7fd3ca
VZ
62 // helper event loop class which sets itself as active only if we pass it
63 // true in ctor
64 class SocketTestEventLoop : public wxEventLoop
65 {
66 public:
67 SocketTestEventLoop(bool useLoop)
68 {
69 m_useLoop = useLoop;
70 if ( useLoop )
71 SetActive(this);
72 }
73
74 virtual ~SocketTestEventLoop()
75 {
76 if ( m_useLoop )
77 SetActive(NULL);
78 }
79
80 private:
81 bool m_useLoop;
82 };
83
62fb86a5
VZ
84 // get the address to connect to, if NULL is returned it means that the
85 // test is disabled and shouldn't run at all
86 wxSockAddressPtr GetServer() const;
87
88 // get the socket to read HTTP reply from, returns NULL if the test is
89 // disabled
90 wxSocketClientPtr GetHTTPSocket(int flags = wxSOCKET_NONE) const;
91
8d8087fc 92 void PseudoTest_SetUseEventLoop() { ms_useLoop = true; }
6e7fd3ca 93
62fb86a5
VZ
94 void BlockingConnect();
95 void NonblockingConnect();
96 void ReadNormal();
7b9b06e3 97 void ReadBlock();
62fb86a5
VZ
98 void ReadNowait();
99 void ReadWaitall();
100
6799c5e2
VZ
101 void UrlTest();
102
8d8087fc 103 static bool ms_useLoop;
6e7fd3ca 104
62fb86a5
VZ
105 DECLARE_NO_COPY_CLASS(SocketTestCase)
106};
107
8d8087fc
VZ
108bool SocketTestCase::ms_useLoop = false;
109
62fb86a5
VZ
110CPPUNIT_TEST_SUITE_REGISTRATION( SocketTestCase );
111CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( SocketTestCase, "SocketTestCase" );
112
113wxSockAddressPtr SocketTestCase::GetServer() const
114{
b245cbc5
VZ
115 if ( gs_serverHost.empty() )
116 return wxSockAddressPtr();
62fb86a5 117
b245cbc5
VZ
118 wxIPV4address *addr = new wxIPV4address;
119 addr->Hostname(gs_serverHost);
120 addr->Service("www");
62fb86a5 121
b245cbc5 122 return wxSockAddressPtr(addr);
62fb86a5
VZ
123}
124
125wxSocketClientPtr SocketTestCase::GetHTTPSocket(int flags) const
126{
62fb86a5
VZ
127 wxSockAddressPtr addr = GetServer();
128 if ( !addr.get() )
b245cbc5 129 return wxSocketClientPtr();
62fb86a5
VZ
130
131 wxSocketClient *sock = new wxSocketClient(flags);
132 sock->SetTimeout(1);
133 CPPUNIT_ASSERT( sock->Connect(*addr) );
134
135 const wxString httpGetRoot =
136 "GET / HTTP/1.1\r\n"
137 "Host: " + gs_serverHost + "\r\n"
138 "\r\n";
139
6b6b233a 140 sock->Write(httpGetRoot.ToAscii(), httpGetRoot.length());
62fb86a5 141
b245cbc5 142 return wxSocketClientPtr(sock);
62fb86a5
VZ
143}
144
145void SocketTestCase::BlockingConnect()
146{
147 wxSockAddressPtr addr = GetServer();
148 if ( !addr.get() )
149 return;
150
151 wxSocketClient sock;
152 CPPUNIT_ASSERT( sock.Connect(*addr) );
153}
154
155void SocketTestCase::NonblockingConnect()
156{
157 wxSockAddressPtr addr = GetServer();
158 if ( !addr.get() )
159 return;
160
8d8087fc 161 SocketTestEventLoop loop(ms_useLoop);
7b9b06e3 162
62fb86a5
VZ
163 wxSocketClient sock;
164 sock.Connect(*addr, false);
165 sock.WaitOnConnect(10);
166
167 CPPUNIT_ASSERT( sock.IsConnected() );
168}
169
170void SocketTestCase::ReadNormal()
171{
8d8087fc 172 SocketTestEventLoop loop(ms_useLoop);
7b9b06e3 173
62fb86a5
VZ
174 wxSocketClientPtr sock(GetHTTPSocket());
175 if ( !sock.get() )
176 return;
177
178 char bufSmall[128];
179 sock->Read(bufSmall, WXSIZEOF(bufSmall));
180
181 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
68888eea 182 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(bufSmall), (size_t)sock->LastCount() );
62fb86a5
VZ
183
184
3afc646c 185 char bufBig[102400];
62fb86a5
VZ
186 sock->Read(bufBig, WXSIZEOF(bufBig));
187
188 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
189 CPPUNIT_ASSERT( WXSIZEOF(bufBig) >= sock->LastCount() );
190}
191
7b9b06e3
VZ
192void SocketTestCase::ReadBlock()
193{
194 wxSocketClientPtr sock(GetHTTPSocket(wxSOCKET_BLOCK));
195 if ( !sock.get() )
196 return;
197
198 char bufSmall[128];
199 sock->Read(bufSmall, WXSIZEOF(bufSmall));
200
201 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
68888eea 202 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(bufSmall), (size_t)sock->LastCount() );
7b9b06e3
VZ
203
204
205 char bufBig[102400];
206 sock->Read(bufBig, WXSIZEOF(bufBig));
207
208 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
209 CPPUNIT_ASSERT( WXSIZEOF(bufBig) >= sock->LastCount() );
210}
211
62fb86a5
VZ
212void SocketTestCase::ReadNowait()
213{
214 wxSocketClientPtr sock(GetHTTPSocket(wxSOCKET_NOWAIT));
215 if ( !sock.get() )
216 return;
217
218 char buf[1024];
219 sock->Read(buf, WXSIZEOF(buf));
220 if ( sock->LastError() != wxSOCKET_WOULDBLOCK )
221 {
222 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
223 }
224}
225
226void SocketTestCase::ReadWaitall()
227{
8d8087fc 228 SocketTestEventLoop loop(ms_useLoop);
7b9b06e3 229
62fb86a5
VZ
230 wxSocketClientPtr sock(GetHTTPSocket(wxSOCKET_WAITALL));
231 if ( !sock.get() )
232 return;
233
234 char buf[128];
235 sock->Read(buf, WXSIZEOF(buf));
236
237 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
68888eea 238 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(buf), (size_t)sock->LastCount() );
62fb86a5
VZ
239}
240
6799c5e2
VZ
241void SocketTestCase::UrlTest()
242{
243 if ( gs_serverHost.empty() )
244 return;
245
246 SocketTestEventLoop loop(ms_useLoop);
247
248 wxURL url("http://" + gs_serverHost);
1f30c75e
VZ
249
250 const std::auto_ptr<wxInputStream> in(url.GetInputStream());
251 CPPUNIT_ASSERT( in.get() );
6799c5e2
VZ
252
253 wxStringOutputStream out;
254 CPPUNIT_ASSERT_EQUAL( wxSTREAM_EOF, in->Read(out).GetLastError() );
255}
256
62fb86a5 257#endif // wxUSE_SOCKETS