fix memory leak in URL test
[wxWidgets.git] / tests / net / socket.cpp
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"
29 #include "wx/url.h"
30 #include "wx/sstream.h"
31 #include "wx/evtloop.h"
32 #include <memory>
33
34 typedef std::auto_ptr<wxSockAddress> wxSockAddressPtr;
35 typedef std::auto_ptr<wxSocketClient> wxSocketClientPtr;
36
37 static wxString gs_serverHost(wxGetenv("WX_TEST_SERVER"));
38
39 class SocketTestCase : public CppUnit::TestCase
40 {
41 public:
42 SocketTestCase() { }
43
44 private:
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 ); \
53 CPPUNIT_TEST( ReadWaitall ); \
54 CPPUNIT_TEST( UrlTest )
55
56 CPPUNIT_TEST_SUITE( SocketTestCase );
57 ALL_SOCKET_TESTS();
58 CPPUNIT_TEST( PseudoTest_SetUseEventLoop );
59 ALL_SOCKET_TESTS();
60 CPPUNIT_TEST_SUITE_END();
61
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
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
92 void PseudoTest_SetUseEventLoop() { ms_useLoop = true; }
93
94 void BlockingConnect();
95 void NonblockingConnect();
96 void ReadNormal();
97 void ReadBlock();
98 void ReadNowait();
99 void ReadWaitall();
100
101 void UrlTest();
102
103 static bool ms_useLoop;
104
105 DECLARE_NO_COPY_CLASS(SocketTestCase)
106 };
107
108 bool SocketTestCase::ms_useLoop = false;
109
110 CPPUNIT_TEST_SUITE_REGISTRATION( SocketTestCase );
111 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( SocketTestCase, "SocketTestCase" );
112
113 wxSockAddressPtr SocketTestCase::GetServer() const
114 {
115 if ( gs_serverHost.empty() )
116 return wxSockAddressPtr();
117
118 wxIPV4address *addr = new wxIPV4address;
119 addr->Hostname(gs_serverHost);
120 addr->Service("www");
121
122 return wxSockAddressPtr(addr);
123 }
124
125 wxSocketClientPtr SocketTestCase::GetHTTPSocket(int flags) const
126 {
127 wxSockAddressPtr addr = GetServer();
128 if ( !addr.get() )
129 return wxSocketClientPtr();
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
140 sock->Write(httpGetRoot.ToAscii(), httpGetRoot.length());
141
142 return wxSocketClientPtr(sock);
143 }
144
145 void 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
155 void SocketTestCase::NonblockingConnect()
156 {
157 wxSockAddressPtr addr = GetServer();
158 if ( !addr.get() )
159 return;
160
161 SocketTestEventLoop loop(ms_useLoop);
162
163 wxSocketClient sock;
164 sock.Connect(*addr, false);
165 sock.WaitOnConnect(10);
166
167 CPPUNIT_ASSERT( sock.IsConnected() );
168 }
169
170 void SocketTestCase::ReadNormal()
171 {
172 SocketTestEventLoop loop(ms_useLoop);
173
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() );
182 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(bufSmall), sock->LastCount() );
183
184
185 char bufBig[102400];
186 sock->Read(bufBig, WXSIZEOF(bufBig));
187
188 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
189 CPPUNIT_ASSERT( WXSIZEOF(bufBig) >= sock->LastCount() );
190 }
191
192 void 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() );
202 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(bufSmall), sock->LastCount() );
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
212 void 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
226 void SocketTestCase::ReadWaitall()
227 {
228 SocketTestEventLoop loop(ms_useLoop);
229
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() );
238 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(buf), sock->LastCount() );
239 }
240
241 void SocketTestCase::UrlTest()
242 {
243 if ( gs_serverHost.empty() )
244 return;
245
246 SocketTestEventLoop loop(ms_useLoop);
247
248 wxURL url("http://" + gs_serverHost);
249
250 const std::auto_ptr<wxInputStream> in(url.GetInputStream());
251 CPPUNIT_ASSERT( in.get() );
252
253 wxStringOutputStream out;
254 CPPUNIT_ASSERT_EQUAL( wxSTREAM_EOF, in->Read(out).GetLastError() );
255 }
256
257 #endif // wxUSE_SOCKETS