create local event loop for the operations which need it; test reading with wxSOCKET_...
[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/evtloop.h"
30 #include <memory>
31
32 typedef std::auto_ptr<wxSockAddress> wxSockAddressPtr;
33 typedef std::auto_ptr<wxSocketClient> wxSocketClientPtr;
34
35 static wxString gs_serverHost(wxGetenv("WX_TEST_SERVER"));
36
37 class SocketTestCase : public CppUnit::TestCase
38 {
39 public:
40 SocketTestCase() { }
41
42 private:
43 CPPUNIT_TEST_SUITE( SocketTestCase );
44 CPPUNIT_TEST( BlockingConnect );
45 CPPUNIT_TEST( NonblockingConnect );
46 CPPUNIT_TEST( ReadNormal );
47 CPPUNIT_TEST( ReadBlock );
48 CPPUNIT_TEST( ReadNowait );
49 CPPUNIT_TEST( ReadWaitall );
50 CPPUNIT_TEST_SUITE_END();
51
52 // get the address to connect to, if NULL is returned it means that the
53 // test is disabled and shouldn't run at all
54 wxSockAddressPtr GetServer() const;
55
56 // get the socket to read HTTP reply from, returns NULL if the test is
57 // disabled
58 wxSocketClientPtr GetHTTPSocket(int flags = wxSOCKET_NONE) const;
59
60 void BlockingConnect();
61 void NonblockingConnect();
62 void ReadNormal();
63 void ReadBlock();
64 void ReadNowait();
65 void ReadWaitall();
66
67 DECLARE_NO_COPY_CLASS(SocketTestCase)
68 };
69
70 CPPUNIT_TEST_SUITE_REGISTRATION( SocketTestCase );
71 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( SocketTestCase, "SocketTestCase" );
72
73 wxSockAddressPtr SocketTestCase::GetServer() const
74 {
75 wxSockAddressPtr ptr;
76 if ( !gs_serverHost.empty() )
77 {
78 wxIPV4address *addr = new wxIPV4address;
79 addr->Hostname(gs_serverHost);
80 addr->Service("www");
81
82 ptr.reset(addr);
83 }
84
85 return ptr;
86 }
87
88 wxSocketClientPtr SocketTestCase::GetHTTPSocket(int flags) const
89 {
90 wxSocketClientPtr ptr;
91
92 wxSockAddressPtr addr = GetServer();
93 if ( !addr.get() )
94 return ptr;
95
96 wxSocketClient *sock = new wxSocketClient(flags);
97 sock->SetTimeout(1);
98 CPPUNIT_ASSERT( sock->Connect(*addr) );
99
100 const wxString httpGetRoot =
101 "GET / HTTP/1.1\r\n"
102 "Host: " + gs_serverHost + "\r\n"
103 "\r\n";
104
105 sock->Write(httpGetRoot.ToAscii(), httpGetRoot.length());
106
107 ptr.reset(sock);
108 return ptr;
109 }
110
111 void SocketTestCase::BlockingConnect()
112 {
113 wxSockAddressPtr addr = GetServer();
114 if ( !addr.get() )
115 return;
116
117 wxSocketClient sock;
118 CPPUNIT_ASSERT( sock.Connect(*addr) );
119 }
120
121 void SocketTestCase::NonblockingConnect()
122 {
123 wxSockAddressPtr addr = GetServer();
124 if ( !addr.get() )
125 return;
126
127 wxEventLoopGuarantor loop;
128
129 wxSocketClient sock;
130 sock.Connect(*addr, false);
131 sock.WaitOnConnect(10);
132
133 CPPUNIT_ASSERT( sock.IsConnected() );
134 }
135
136 void SocketTestCase::ReadNormal()
137 {
138 wxEventLoopGuarantor loop;
139
140 wxSocketClientPtr sock(GetHTTPSocket());
141 if ( !sock.get() )
142 return;
143
144 char bufSmall[128];
145 sock->Read(bufSmall, WXSIZEOF(bufSmall));
146
147 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
148 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(bufSmall), sock->LastCount() );
149
150
151 char bufBig[102400];
152 sock->Read(bufBig, WXSIZEOF(bufBig));
153
154 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
155 CPPUNIT_ASSERT( WXSIZEOF(bufBig) >= sock->LastCount() );
156 }
157
158 void SocketTestCase::ReadBlock()
159 {
160 wxSocketClientPtr sock(GetHTTPSocket(wxSOCKET_BLOCK));
161 if ( !sock.get() )
162 return;
163
164 char bufSmall[128];
165 sock->Read(bufSmall, WXSIZEOF(bufSmall));
166
167 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
168 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(bufSmall), sock->LastCount() );
169
170
171 char bufBig[102400];
172 sock->Read(bufBig, WXSIZEOF(bufBig));
173
174 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
175 CPPUNIT_ASSERT( WXSIZEOF(bufBig) >= sock->LastCount() );
176 }
177
178 void SocketTestCase::ReadNowait()
179 {
180 wxSocketClientPtr sock(GetHTTPSocket(wxSOCKET_NOWAIT));
181 if ( !sock.get() )
182 return;
183
184 char buf[1024];
185 sock->Read(buf, WXSIZEOF(buf));
186 if ( sock->LastError() != wxSOCKET_WOULDBLOCK )
187 {
188 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
189 }
190 }
191
192 void SocketTestCase::ReadWaitall()
193 {
194 wxEventLoopGuarantor loop;
195
196 wxSocketClientPtr sock(GetHTTPSocket(wxSOCKET_WAITALL));
197 if ( !sock.get() )
198 return;
199
200 char buf[128];
201 sock->Read(buf, WXSIZEOF(buf));
202
203 CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
204 CPPUNIT_ASSERT_EQUAL( WXSIZEOF(buf), sock->LastCount() );
205 }
206
207 #endif // wxUSE_SOCKETS