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
)
72 m_evtLoopOld
= wxEventLoopBase::GetActive();
77 virtual ~SocketTestEventLoop()
81 wxEventLoopBase::SetActive(m_evtLoopOld
);
87 wxEventLoopBase
*m_evtLoopOld
;
90 // get the address to connect to, if NULL is returned it means that the
91 // test is disabled and shouldn't run at all
92 wxSockAddressPtr
GetServer() const;
94 // get the socket to read HTTP reply from, returns NULL if the test is
96 wxSocketClientPtr
GetHTTPSocket(int flags
= wxSOCKET_NONE
) const;
98 void PseudoTest_SetUseEventLoop() { ms_useLoop
= true; }
100 void BlockingConnect();
101 void NonblockingConnect();
109 static bool ms_useLoop
;
111 DECLARE_NO_COPY_CLASS(SocketTestCase
)
114 bool SocketTestCase::ms_useLoop
= false;
116 CPPUNIT_TEST_SUITE_REGISTRATION( SocketTestCase
);
117 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( SocketTestCase
, "SocketTestCase" );
119 wxSockAddressPtr
SocketTestCase::GetServer() const
121 if ( gs_serverHost
.empty() )
122 return wxSockAddressPtr();
124 wxIPV4address
*addr
= new wxIPV4address
;
125 addr
->Hostname(gs_serverHost
);
126 addr
->Service("www");
128 return wxSockAddressPtr(addr
);
131 wxSocketClientPtr
SocketTestCase::GetHTTPSocket(int flags
) const
133 wxSockAddressPtr addr
= GetServer();
135 return wxSocketClientPtr();
137 wxSocketClient
*sock
= new wxSocketClient(flags
);
139 CPPUNIT_ASSERT( sock
->Connect(*addr
) );
141 const wxString httpGetRoot
=
143 "Host: " + gs_serverHost
+ "\r\n"
146 sock
->Write(httpGetRoot
.ToAscii(), httpGetRoot
.length());
148 return wxSocketClientPtr(sock
);
151 void SocketTestCase::BlockingConnect()
153 wxSockAddressPtr addr
= GetServer();
158 CPPUNIT_ASSERT( sock
.Connect(*addr
) );
161 void SocketTestCase::NonblockingConnect()
163 wxSockAddressPtr addr
= GetServer();
167 SocketTestEventLoop
loop(ms_useLoop
);
170 sock
.Connect(*addr
, false);
171 sock
.WaitOnConnect(10);
173 CPPUNIT_ASSERT( sock
.IsConnected() );
176 void SocketTestCase::ReadNormal()
178 SocketTestEventLoop
loop(ms_useLoop
);
180 wxSocketClientPtr
sock(GetHTTPSocket());
185 sock
->Read(bufSmall
, WXSIZEOF(bufSmall
));
187 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR
, sock
->LastError() );
188 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(bufSmall
), (size_t)sock
->LastCount() );
189 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(bufSmall
), (size_t)sock
->LastReadCount() );
193 sock
->Read(bufBig
, WXSIZEOF(bufBig
));
195 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR
, sock
->LastError() );
196 CPPUNIT_ASSERT( WXSIZEOF(bufBig
) >= sock
->LastCount() );
197 CPPUNIT_ASSERT( WXSIZEOF(bufBig
) >= sock
->LastReadCount() );
200 void SocketTestCase::ReadBlock()
202 wxSocketClientPtr
sock(GetHTTPSocket(wxSOCKET_BLOCK
));
207 sock
->Read(bufSmall
, WXSIZEOF(bufSmall
));
209 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR
, sock
->LastError() );
210 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(bufSmall
), (size_t)sock
->LastCount() );
211 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(bufSmall
), (size_t)sock
->LastReadCount() );
215 sock
->Read(bufBig
, WXSIZEOF(bufBig
));
217 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR
, sock
->LastError() );
218 CPPUNIT_ASSERT( WXSIZEOF(bufBig
) >= sock
->LastCount() );
219 CPPUNIT_ASSERT( WXSIZEOF(bufBig
) >= sock
->LastReadCount() );
222 void SocketTestCase::ReadNowait()
224 wxSocketClientPtr
sock(GetHTTPSocket(wxSOCKET_NOWAIT
));
229 sock
->Read(buf
, WXSIZEOF(buf
));
230 if ( sock
->LastError() != wxSOCKET_WOULDBLOCK
)
232 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR
, sock
->LastError() );
236 void SocketTestCase::ReadWaitall()
238 SocketTestEventLoop
loop(ms_useLoop
);
240 wxSocketClientPtr
sock(GetHTTPSocket(wxSOCKET_WAITALL
));
245 sock
->Read(buf
, WXSIZEOF(buf
));
247 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR
, sock
->LastError() );
248 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(buf
), (size_t)sock
->LastCount() );
249 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(buf
), (size_t)sock
->LastReadCount() );
252 void SocketTestCase::UrlTest()
254 if ( gs_serverHost
.empty() )
257 SocketTestEventLoop
loop(ms_useLoop
);
259 wxURL
url("http://" + gs_serverHost
);
261 const std::auto_ptr
<wxInputStream
> in(url
.GetInputStream());
262 CPPUNIT_ASSERT( in
.get() );
264 wxStringOutputStream out
;
265 CPPUNIT_ASSERT_EQUAL( wxSTREAM_EOF
, in
->Read(out
).GetLastError() );
268 #endif // wxUSE_SOCKETS