1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/net/socket.cpp
3 // Purpose: wxSocket unit tests
4 // Author: Vadim Zeitlin
6 // Copyright: (c) 2008 Vadim Zeitlin
7 // Licence: wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
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
18 // For compilers that support precompilation, includes "wx/wx.h".
28 #include "wx/socket.h"
30 #include "wx/sstream.h"
31 #include "wx/evtloop.h"
34 typedef std::auto_ptr
<wxSockAddress
> wxSockAddressPtr
;
35 typedef std::auto_ptr
<wxSocketClient
> wxSocketClientPtr
;
37 static wxString
gs_serverHost(wxGetenv("WX_TEST_SERVER"));
39 class SocketTestCase
: public CppUnit::TestCase
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 )
56 CPPUNIT_TEST_SUITE( SocketTestCase
);
58 CPPUNIT_TEST( PseudoTest_SetUseEventLoop
);
60 CPPUNIT_TEST_SUITE_END();
62 // helper event loop class which sets itself as active only if we pass it
64 class SocketTestEventLoop
: public wxEventLoop
67 SocketTestEventLoop(bool useLoop
)
74 virtual ~SocketTestEventLoop()
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;
88 // get the socket to read HTTP reply from, returns NULL if the test is
90 wxSocketClientPtr
GetHTTPSocket(int flags
= wxSOCKET_NONE
) const;
92 void PseudoTest_SetUseEventLoop() { ms_useLoop
= true; }
94 void BlockingConnect();
95 void NonblockingConnect();
103 static bool ms_useLoop
;
105 DECLARE_NO_COPY_CLASS(SocketTestCase
)
108 bool SocketTestCase::ms_useLoop
= false;
110 CPPUNIT_TEST_SUITE_REGISTRATION( SocketTestCase
);
111 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( SocketTestCase
, "SocketTestCase" );
113 wxSockAddressPtr
SocketTestCase::GetServer() const
115 if ( gs_serverHost
.empty() )
116 return wxSockAddressPtr();
118 wxIPV4address
*addr
= new wxIPV4address
;
119 addr
->Hostname(gs_serverHost
);
120 addr
->Service("www");
122 return wxSockAddressPtr(addr
);
125 wxSocketClientPtr
SocketTestCase::GetHTTPSocket(int flags
) const
127 wxSockAddressPtr addr
= GetServer();
129 return wxSocketClientPtr();
131 wxSocketClient
*sock
= new wxSocketClient(flags
);
133 CPPUNIT_ASSERT( sock
->Connect(*addr
) );
135 const wxString httpGetRoot
=
137 "Host: " + gs_serverHost
+ "\r\n"
140 sock
->Write(httpGetRoot
.ToAscii(), httpGetRoot
.length());
142 return wxSocketClientPtr(sock
);
145 void SocketTestCase::BlockingConnect()
147 wxSockAddressPtr addr
= GetServer();
152 CPPUNIT_ASSERT( sock
.Connect(*addr
) );
155 void SocketTestCase::NonblockingConnect()
157 wxSockAddressPtr addr
= GetServer();
161 SocketTestEventLoop
loop(ms_useLoop
);
164 sock
.Connect(*addr
, false);
165 sock
.WaitOnConnect(10);
167 CPPUNIT_ASSERT( sock
.IsConnected() );
170 void SocketTestCase::ReadNormal()
172 SocketTestEventLoop
loop(ms_useLoop
);
174 wxSocketClientPtr
sock(GetHTTPSocket());
179 sock
->Read(bufSmall
, WXSIZEOF(bufSmall
));
181 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR
, sock
->LastError() );
182 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(bufSmall
), (size_t)sock
->LastCount() );
186 sock
->Read(bufBig
, WXSIZEOF(bufBig
));
188 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR
, sock
->LastError() );
189 CPPUNIT_ASSERT( WXSIZEOF(bufBig
) >= sock
->LastCount() );
192 void SocketTestCase::ReadBlock()
194 wxSocketClientPtr
sock(GetHTTPSocket(wxSOCKET_BLOCK
));
199 sock
->Read(bufSmall
, WXSIZEOF(bufSmall
));
201 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR
, sock
->LastError() );
202 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(bufSmall
), (size_t)sock
->LastCount() );
206 sock
->Read(bufBig
, WXSIZEOF(bufBig
));
208 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR
, sock
->LastError() );
209 CPPUNIT_ASSERT( WXSIZEOF(bufBig
) >= sock
->LastCount() );
212 void SocketTestCase::ReadNowait()
214 wxSocketClientPtr
sock(GetHTTPSocket(wxSOCKET_NOWAIT
));
219 sock
->Read(buf
, WXSIZEOF(buf
));
220 if ( sock
->LastError() != wxSOCKET_WOULDBLOCK
)
222 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR
, sock
->LastError() );
226 void SocketTestCase::ReadWaitall()
228 SocketTestEventLoop
loop(ms_useLoop
);
230 wxSocketClientPtr
sock(GetHTTPSocket(wxSOCKET_WAITALL
));
235 sock
->Read(buf
, WXSIZEOF(buf
));
237 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR
, sock
->LastError() );
238 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(buf
), (size_t)sock
->LastCount() );
241 void SocketTestCase::UrlTest()
243 if ( gs_serverHost
.empty() )
246 SocketTestEventLoop
loop(ms_useLoop
);
248 wxURL
url("http://" + gs_serverHost
);
250 const std::auto_ptr
<wxInputStream
> in(url
.GetInputStream());
251 CPPUNIT_ASSERT( in
.get() );
253 wxStringOutputStream out
;
254 CPPUNIT_ASSERT_EQUAL( wxSTREAM_EOF
, in
->Read(out
).GetLastError() );
257 #endif // wxUSE_SOCKETS