1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/net/socket.cpp
3 // Purpose: wxSocket unit tests
4 // Author: Vadim Zeitlin
5 // Copyright: (c) 2008 Vadim Zeitlin
6 // Licence: wxWindows licence
7 ///////////////////////////////////////////////////////////////////////////////
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
17 // For compilers that support precompilation, includes "wx/wx.h".
27 #include "wx/socket.h"
29 #include "wx/sstream.h"
30 #include "wx/evtloop.h"
33 typedef std::auto_ptr
<wxSockAddress
> wxSockAddressPtr
;
34 typedef std::auto_ptr
<wxSocketClient
> wxSocketClientPtr
;
36 static wxString
gs_serverHost(wxGetenv("WX_TEST_SERVER"));
38 class SocketTestCase
: public CppUnit::TestCase
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 ); \
52 CPPUNIT_TEST( ReadWaitall ); \
53 CPPUNIT_TEST( UrlTest )
55 CPPUNIT_TEST_SUITE( SocketTestCase
);
57 CPPUNIT_TEST( PseudoTest_SetUseEventLoop
);
59 CPPUNIT_TEST_SUITE_END();
61 // helper event loop class which sets itself as active only if we pass it
63 class SocketTestEventLoop
: public wxEventLoop
66 SocketTestEventLoop(bool useLoop
)
71 m_evtLoopOld
= wxEventLoopBase::GetActive();
76 virtual ~SocketTestEventLoop()
80 wxEventLoopBase::SetActive(m_evtLoopOld
);
86 wxEventLoopBase
*m_evtLoopOld
;
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;
93 // get the socket to read HTTP reply from, returns NULL if the test is
95 wxSocketClientPtr
GetHTTPSocket(int flags
= wxSOCKET_NONE
) const;
97 void PseudoTest_SetUseEventLoop() { ms_useLoop
= true; }
99 void BlockingConnect();
100 void NonblockingConnect();
108 static bool ms_useLoop
;
110 DECLARE_NO_COPY_CLASS(SocketTestCase
)
113 bool SocketTestCase::ms_useLoop
= false;
115 CPPUNIT_TEST_SUITE_REGISTRATION( SocketTestCase
);
116 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( SocketTestCase
, "SocketTestCase" );
118 wxSockAddressPtr
SocketTestCase::GetServer() const
120 if ( gs_serverHost
.empty() )
121 return wxSockAddressPtr();
123 wxIPV4address
*addr
= new wxIPV4address
;
124 addr
->Hostname(gs_serverHost
);
125 addr
->Service("www");
127 return wxSockAddressPtr(addr
);
130 wxSocketClientPtr
SocketTestCase::GetHTTPSocket(int flags
) const
132 wxSockAddressPtr addr
= GetServer();
134 return wxSocketClientPtr();
136 wxSocketClient
*sock
= new wxSocketClient(flags
);
138 CPPUNIT_ASSERT( sock
->Connect(*addr
) );
140 const wxString httpGetRoot
=
142 "Host: " + gs_serverHost
+ "\r\n"
145 sock
->Write(httpGetRoot
.ToAscii(), httpGetRoot
.length());
147 return wxSocketClientPtr(sock
);
150 void SocketTestCase::BlockingConnect()
152 wxSockAddressPtr addr
= GetServer();
157 CPPUNIT_ASSERT( sock
.Connect(*addr
) );
160 void SocketTestCase::NonblockingConnect()
162 wxSockAddressPtr addr
= GetServer();
166 SocketTestEventLoop
loop(ms_useLoop
);
169 sock
.Connect(*addr
, false);
170 sock
.WaitOnConnect(10);
172 CPPUNIT_ASSERT( sock
.IsConnected() );
175 void SocketTestCase::ReadNormal()
177 SocketTestEventLoop
loop(ms_useLoop
);
179 wxSocketClientPtr
sock(GetHTTPSocket());
184 sock
->Read(bufSmall
, WXSIZEOF(bufSmall
));
186 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR
, sock
->LastError() );
187 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(bufSmall
), (size_t)sock
->LastCount() );
188 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(bufSmall
), (size_t)sock
->LastReadCount() );
192 sock
->Read(bufBig
, WXSIZEOF(bufBig
));
194 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR
, sock
->LastError() );
195 CPPUNIT_ASSERT( WXSIZEOF(bufBig
) >= sock
->LastCount() );
196 CPPUNIT_ASSERT( WXSIZEOF(bufBig
) >= sock
->LastReadCount() );
199 void SocketTestCase::ReadBlock()
201 wxSocketClientPtr
sock(GetHTTPSocket(wxSOCKET_BLOCK
));
206 sock
->Read(bufSmall
, WXSIZEOF(bufSmall
));
208 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR
, sock
->LastError() );
209 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(bufSmall
), (size_t)sock
->LastCount() );
210 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(bufSmall
), (size_t)sock
->LastReadCount() );
214 sock
->Read(bufBig
, WXSIZEOF(bufBig
));
216 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR
, sock
->LastError() );
217 CPPUNIT_ASSERT( WXSIZEOF(bufBig
) >= sock
->LastCount() );
218 CPPUNIT_ASSERT( WXSIZEOF(bufBig
) >= sock
->LastReadCount() );
221 void SocketTestCase::ReadNowait()
223 wxSocketClientPtr
sock(GetHTTPSocket(wxSOCKET_NOWAIT
));
228 sock
->Read(buf
, WXSIZEOF(buf
));
229 if ( sock
->LastError() != wxSOCKET_WOULDBLOCK
)
231 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR
, sock
->LastError() );
235 void SocketTestCase::ReadWaitall()
237 SocketTestEventLoop
loop(ms_useLoop
);
239 wxSocketClientPtr
sock(GetHTTPSocket(wxSOCKET_WAITALL
));
244 sock
->Read(buf
, WXSIZEOF(buf
));
246 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR
, sock
->LastError() );
247 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(buf
), (size_t)sock
->LastCount() );
248 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(buf
), (size_t)sock
->LastReadCount() );
251 void SocketTestCase::UrlTest()
253 if ( gs_serverHost
.empty() )
256 SocketTestEventLoop
loop(ms_useLoop
);
258 wxURL
url("http://" + gs_serverHost
);
260 const std::auto_ptr
<wxInputStream
> in(url
.GetInputStream());
261 CPPUNIT_ASSERT( in
.get() );
263 wxStringOutputStream out
;
264 CPPUNIT_ASSERT_EQUAL( wxSTREAM_EOF
, in
->Read(out
).GetLastError() );
267 #endif // wxUSE_SOCKETS