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