// Author: Vadim Zeitlin
// RCS-ID: $Id$
// Copyright: (c) 2008 Vadim Zeitlin
-// Licence: wxWidgets licence
+// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
/*
#if wxUSE_SOCKETS
#include "wx/socket.h"
+#include "wx/url.h"
+#include "wx/sstream.h"
+#include "wx/evtloop.h"
#include <memory>
typedef std::auto_ptr<wxSockAddress> wxSockAddressPtr;
SocketTestCase() { }
private:
+ // we need to repeat the tests twice as the sockets behave differently when
+ // there is an active event loop and without it
+ #define ALL_SOCKET_TESTS() \
+ CPPUNIT_TEST( BlockingConnect ); \
+ CPPUNIT_TEST( NonblockingConnect ); \
+ CPPUNIT_TEST( ReadNormal ); \
+ CPPUNIT_TEST( ReadBlock ); \
+ CPPUNIT_TEST( ReadNowait ); \
+ CPPUNIT_TEST( ReadWaitall ); \
+ CPPUNIT_TEST( UrlTest )
+
CPPUNIT_TEST_SUITE( SocketTestCase );
- CPPUNIT_TEST( BlockingConnect );
- CPPUNIT_TEST( NonblockingConnect );
- CPPUNIT_TEST( ReadNormal );
- CPPUNIT_TEST( ReadNowait );
- CPPUNIT_TEST( ReadWaitall );
+ ALL_SOCKET_TESTS();
+ CPPUNIT_TEST( PseudoTest_SetUseEventLoop );
+ ALL_SOCKET_TESTS();
CPPUNIT_TEST_SUITE_END();
+ // helper event loop class which sets itself as active only if we pass it
+ // true in ctor
+ class SocketTestEventLoop : public wxEventLoop
+ {
+ public:
+ SocketTestEventLoop(bool useLoop)
+ {
+ m_useLoop = useLoop;
+ if ( useLoop )
+ {
+ m_evtLoopOld = wxEventLoopBase::GetActive();
+ SetActive(this);
+ }
+ }
+
+ virtual ~SocketTestEventLoop()
+ {
+ if ( m_useLoop )
+ {
+ wxEventLoopBase::SetActive(m_evtLoopOld);
+ }
+ }
+
+ private:
+ bool m_useLoop;
+ wxEventLoopBase *m_evtLoopOld;
+ };
+
// get the address to connect to, if NULL is returned it means that the
// test is disabled and shouldn't run at all
wxSockAddressPtr GetServer() const;
// disabled
wxSocketClientPtr GetHTTPSocket(int flags = wxSOCKET_NONE) const;
+ void PseudoTest_SetUseEventLoop() { ms_useLoop = true; }
+
void BlockingConnect();
void NonblockingConnect();
void ReadNormal();
+ void ReadBlock();
void ReadNowait();
void ReadWaitall();
+ void UrlTest();
+
+ static bool ms_useLoop;
+
DECLARE_NO_COPY_CLASS(SocketTestCase)
};
+bool SocketTestCase::ms_useLoop = false;
+
CPPUNIT_TEST_SUITE_REGISTRATION( SocketTestCase );
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( SocketTestCase, "SocketTestCase" );
wxSockAddressPtr SocketTestCase::GetServer() const
{
- wxSockAddressPtr ptr;
- if ( !gs_serverHost.empty() )
- {
- wxIPV4address *addr = new wxIPV4address;
- addr->Hostname(gs_serverHost);
- addr->Service("www");
+ if ( gs_serverHost.empty() )
+ return wxSockAddressPtr();
- ptr.reset(addr);
- }
+ wxIPV4address *addr = new wxIPV4address;
+ addr->Hostname(gs_serverHost);
+ addr->Service("www");
- return ptr;
+ return wxSockAddressPtr(addr);
}
wxSocketClientPtr SocketTestCase::GetHTTPSocket(int flags) const
{
- wxSocketClientPtr ptr;
-
wxSockAddressPtr addr = GetServer();
if ( !addr.get() )
- return ptr;
+ return wxSocketClientPtr();
wxSocketClient *sock = new wxSocketClient(flags);
sock->SetTimeout(1);
"Host: " + gs_serverHost + "\r\n"
"\r\n";
- sock->Write(httpGetRoot, httpGetRoot.length());
+ sock->Write(httpGetRoot.ToAscii(), httpGetRoot.length());
- ptr.reset(sock);
- return ptr;
+ return wxSocketClientPtr(sock);
}
void SocketTestCase::BlockingConnect()
if ( !addr.get() )
return;
+ SocketTestEventLoop loop(ms_useLoop);
+
wxSocketClient sock;
sock.Connect(*addr, false);
sock.WaitOnConnect(10);
void SocketTestCase::ReadNormal()
{
+ SocketTestEventLoop loop(ms_useLoop);
+
wxSocketClientPtr sock(GetHTTPSocket());
if ( !sock.get() )
return;
sock->Read(bufSmall, WXSIZEOF(bufSmall));
CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
- CPPUNIT_ASSERT_EQUAL( WXSIZEOF(bufSmall), sock->LastCount() );
+ CPPUNIT_ASSERT_EQUAL( WXSIZEOF(bufSmall), (size_t)sock->LastCount() );
+ CPPUNIT_ASSERT_EQUAL( WXSIZEOF(bufSmall), (size_t)sock->LastReadCount() );
- char bufBig[1024*1024];
+ char bufBig[102400];
sock->Read(bufBig, WXSIZEOF(bufBig));
CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
CPPUNIT_ASSERT( WXSIZEOF(bufBig) >= sock->LastCount() );
+ CPPUNIT_ASSERT( WXSIZEOF(bufBig) >= sock->LastReadCount() );
+}
+
+void SocketTestCase::ReadBlock()
+{
+ wxSocketClientPtr sock(GetHTTPSocket(wxSOCKET_BLOCK));
+ if ( !sock.get() )
+ return;
+
+ char bufSmall[128];
+ sock->Read(bufSmall, WXSIZEOF(bufSmall));
+
+ CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
+ CPPUNIT_ASSERT_EQUAL( WXSIZEOF(bufSmall), (size_t)sock->LastCount() );
+ CPPUNIT_ASSERT_EQUAL( WXSIZEOF(bufSmall), (size_t)sock->LastReadCount() );
+
+
+ char bufBig[102400];
+ sock->Read(bufBig, WXSIZEOF(bufBig));
+
+ CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
+ CPPUNIT_ASSERT( WXSIZEOF(bufBig) >= sock->LastCount() );
+ CPPUNIT_ASSERT( WXSIZEOF(bufBig) >= sock->LastReadCount() );
}
void SocketTestCase::ReadNowait()
void SocketTestCase::ReadWaitall()
{
+ SocketTestEventLoop loop(ms_useLoop);
+
wxSocketClientPtr sock(GetHTTPSocket(wxSOCKET_WAITALL));
if ( !sock.get() )
return;
sock->Read(buf, WXSIZEOF(buf));
CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
- CPPUNIT_ASSERT_EQUAL( WXSIZEOF(buf), sock->LastCount() );
+ CPPUNIT_ASSERT_EQUAL( WXSIZEOF(buf), (size_t)sock->LastCount() );
+ CPPUNIT_ASSERT_EQUAL( WXSIZEOF(buf), (size_t)sock->LastReadCount() );
+}
+
+void SocketTestCase::UrlTest()
+{
+ if ( gs_serverHost.empty() )
+ return;
+
+ SocketTestEventLoop loop(ms_useLoop);
+
+ wxURL url("http://" + gs_serverHost);
+
+ const std::auto_ptr<wxInputStream> in(url.GetInputStream());
+ CPPUNIT_ASSERT( in.get() );
+
+ wxStringOutputStream out;
+ CPPUNIT_ASSERT_EQUAL( wxSTREAM_EOF, in->Read(out).GetLastError() );
}
#endif // wxUSE_SOCKETS