This should have been done in b8c9cd3528
to avoid all warnings about std::auto_ptr<> being deprecated when using
g++ 6 or later which compiles in C++14 mode by default.
		
	
		
			
				
	
	
		
			268 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			268 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
///////////////////////////////////////////////////////////////////////////////
 | 
						|
// Name:        tests/net/socket.cpp
 | 
						|
// Purpose:     wxSocket unit tests
 | 
						|
// Author:      Vadim Zeitlin
 | 
						|
// Copyright:   (c) 2008 Vadim Zeitlin
 | 
						|
// Licence:     wxWindows licence
 | 
						|
///////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
/*
 | 
						|
    IMPORTANT NOTE: the environment variable WX_TEST_SERVER must be set to the
 | 
						|
    hostname of the server to use for the tests below, if it is not set all
 | 
						|
    tests are silently skipped (rationale: this makes it possible to run the
 | 
						|
    test in the restricted environments (e.g. sandboxes) without any network
 | 
						|
    connectivity).
 | 
						|
 */
 | 
						|
 | 
						|
// For compilers that support precompilation, includes "wx/wx.h".
 | 
						|
// and "wx/cppunit.h"
 | 
						|
#include "testprec.h"
 | 
						|
 | 
						|
#ifdef __BORLANDC__
 | 
						|
    #pragma hdrstop
 | 
						|
#endif
 | 
						|
 | 
						|
#if wxUSE_SOCKETS
 | 
						|
 | 
						|
#include "wx/socket.h"
 | 
						|
#include "wx/url.h"
 | 
						|
#include "wx/scopedptr.h"
 | 
						|
#include "wx/sstream.h"
 | 
						|
#include "wx/evtloop.h"
 | 
						|
 | 
						|
typedef wxScopedPtr<wxSockAddress> wxSockAddressPtr;
 | 
						|
typedef wxScopedPtr<wxSocketClient> wxSocketClientPtr;
 | 
						|
 | 
						|
static wxString gs_serverHost(wxGetenv("WX_TEST_SERVER"));
 | 
						|
 | 
						|
class SocketTestCase : public CppUnit::TestCase
 | 
						|
{
 | 
						|
public:
 | 
						|
    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 );
 | 
						|
        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
 | 
						|
    wxSockAddress* GetServer() const;
 | 
						|
 | 
						|
    // get the socket to read HTTP reply from, returns NULL if the test is
 | 
						|
    // disabled
 | 
						|
    wxSocketClient* 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;
 | 
						|
 | 
						|
    wxDECLARE_NO_COPY_CLASS(SocketTestCase);
 | 
						|
};
 | 
						|
 | 
						|
bool SocketTestCase::ms_useLoop = false;
 | 
						|
 | 
						|
CPPUNIT_TEST_SUITE_REGISTRATION( SocketTestCase );
 | 
						|
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( SocketTestCase, "SocketTestCase" );
 | 
						|
 | 
						|
wxSockAddress* SocketTestCase::GetServer() const
 | 
						|
{
 | 
						|
    if ( gs_serverHost.empty() )
 | 
						|
        return NULL;
 | 
						|
 | 
						|
    wxIPV4address *addr = new wxIPV4address;
 | 
						|
    addr->Hostname(gs_serverHost);
 | 
						|
    addr->Service("www");
 | 
						|
 | 
						|
    return addr;
 | 
						|
}
 | 
						|
 | 
						|
wxSocketClient* SocketTestCase::GetHTTPSocket(int flags) const
 | 
						|
{
 | 
						|
    wxSockAddress *addr = GetServer();
 | 
						|
    if ( !addr )
 | 
						|
        return NULL;
 | 
						|
 | 
						|
    wxSocketClient *sock = new wxSocketClient(flags);
 | 
						|
    sock->SetTimeout(1);
 | 
						|
    CPPUNIT_ASSERT( sock->Connect(*addr) );
 | 
						|
 | 
						|
    const wxString httpGetRoot =
 | 
						|
        "GET / HTTP/1.1\r\n"
 | 
						|
        "Host: " + gs_serverHost + "\r\n"
 | 
						|
        "\r\n";
 | 
						|
 | 
						|
    sock->Write(httpGetRoot.ToAscii(), httpGetRoot.length());
 | 
						|
 | 
						|
    return sock;
 | 
						|
}
 | 
						|
 | 
						|
void SocketTestCase::BlockingConnect()
 | 
						|
{
 | 
						|
    wxSockAddressPtr addr(GetServer());
 | 
						|
    if ( !addr.get() )
 | 
						|
        return;
 | 
						|
 | 
						|
    wxSocketClient sock;
 | 
						|
    CPPUNIT_ASSERT( sock.Connect(*addr) );
 | 
						|
}
 | 
						|
 | 
						|
void SocketTestCase::NonblockingConnect()
 | 
						|
{
 | 
						|
    wxSockAddressPtr addr(GetServer());
 | 
						|
    if ( !addr.get() )
 | 
						|
        return;
 | 
						|
 | 
						|
    SocketTestEventLoop loop(ms_useLoop);
 | 
						|
 | 
						|
    wxSocketClient sock;
 | 
						|
    sock.Connect(*addr, false);
 | 
						|
    sock.WaitOnConnect(10);
 | 
						|
 | 
						|
    CPPUNIT_ASSERT( sock.IsConnected() );
 | 
						|
}
 | 
						|
 | 
						|
void SocketTestCase::ReadNormal()
 | 
						|
{
 | 
						|
    SocketTestEventLoop loop(ms_useLoop);
 | 
						|
 | 
						|
    wxSocketClientPtr sock(GetHTTPSocket());
 | 
						|
    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::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()
 | 
						|
{
 | 
						|
    wxSocketClientPtr sock(GetHTTPSocket(wxSOCKET_NOWAIT));
 | 
						|
    if ( !sock.get() )
 | 
						|
        return;
 | 
						|
 | 
						|
    char buf[1024];
 | 
						|
    sock->Read(buf, WXSIZEOF(buf));
 | 
						|
    if ( sock->LastError() != wxSOCKET_WOULDBLOCK )
 | 
						|
    {
 | 
						|
        CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void SocketTestCase::ReadWaitall()
 | 
						|
{
 | 
						|
    SocketTestEventLoop loop(ms_useLoop);
 | 
						|
 | 
						|
    wxSocketClientPtr sock(GetHTTPSocket(wxSOCKET_WAITALL));
 | 
						|
    if ( !sock.get() )
 | 
						|
        return;
 | 
						|
 | 
						|
    char buf[128];
 | 
						|
    sock->Read(buf, WXSIZEOF(buf));
 | 
						|
 | 
						|
    CPPUNIT_ASSERT_EQUAL( wxSOCKET_NOERROR, sock->LastError() );
 | 
						|
    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 wxScopedPtr<wxInputStream> in(url.GetInputStream());
 | 
						|
    CPPUNIT_ASSERT( in.get() );
 | 
						|
 | 
						|
    wxStringOutputStream out;
 | 
						|
    CPPUNIT_ASSERT_EQUAL( wxSTREAM_EOF, in->Read(out).GetLastError() );
 | 
						|
}
 | 
						|
 | 
						|
#endif // wxUSE_SOCKETS
 |