wxWidgets/tests/net/ipc.cpp

259 lines
5.7 KiB
C++

///////////////////////////////////////////////////////////////////////////////
// Name: tests/net/ipc.cpp
// Purpose: IPC classes unit tests
// Author: Vadim Zeitlin
// RCS-ID: $Id$
// Copyright: (c) 2008 Vadim Zeitlin
// Licence: wxWidgets licence
///////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx/wx.h".
// and "wx/cppunit.h"
#include "testprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// this test needs threads as it runs the test server in a secondary thread
#if wxUSE_THREADS
// for all others, include the necessary headers
#ifndef WX_PRECOMP
#include "wx/app.h"
#endif
#include "wx/ipc.h"
#include "wx/thread.h"
#define wxUSE_SOCKETS_FOR_IPC (!wxUSE_DDE_FOR_IPC)
namespace
{
const char *IPC_TEST_PORT = "4242";
const char *IPC_TEST_TOPIC = "IPC TEST";
} // anonymous namespace
// ----------------------------------------------------------------------------
// test connection class used by IPCTestServer
// ----------------------------------------------------------------------------
class IPCTestConnection : public wxConnection
{
public:
IPCTestConnection() { }
virtual bool OnExec(const wxString& topic, const wxString& data)
{
if ( topic != IPC_TEST_TOPIC )
return false;
return data == "Date";
}
private:
DECLARE_NO_COPY_CLASS(IPCTestConnection)
};
// ----------------------------------------------------------------------------
// event dispatching thread class
// ----------------------------------------------------------------------------
class EventThread : public wxThread
{
public:
EventThread()
: wxThread(wxTHREAD_JOINABLE)
{
Create();
Run();
}
protected:
virtual void *Entry()
{
wxTheApp->MainLoop();
return NULL;
}
DECLARE_NO_COPY_CLASS(EventThread)
};
// ----------------------------------------------------------------------------
// test server class
// ----------------------------------------------------------------------------
class IPCTestServer : public wxServer
{
public:
IPCTestServer()
{
m_conn = NULL;
#if wxUSE_SOCKETS_FOR_IPC
// we must call this from the main thread
wxSocketBase::Initialize();
#endif // wxUSE_SOCKETS_FOR_IPC
// we need event dispatching to work for IPC server to work
m_thread = new EventThread;
Create(IPC_TEST_PORT);
}
virtual ~IPCTestServer()
{
wxTheApp->ExitMainLoop();
m_thread->Wait();
delete m_thread;
delete m_conn;
#if wxUSE_SOCKETS_FOR_IPC
wxSocketBase::Shutdown();
#endif // wxUSE_SOCKETS_FOR_IPC
}
virtual wxConnectionBase *OnAcceptConnection(const wxString& topic)
{
if ( topic != IPC_TEST_TOPIC )
return NULL;
m_conn = new IPCTestConnection;
return m_conn;
}
private:
EventThread *m_thread;
IPCTestConnection *m_conn;
DECLARE_NO_COPY_CLASS(IPCTestServer)
};
static IPCTestServer *gs_server = NULL;
// ----------------------------------------------------------------------------
// test client class
// ----------------------------------------------------------------------------
class IPCTestClient : public wxClient
{
public:
IPCTestClient()
{
m_conn = NULL;
}
virtual ~IPCTestClient()
{
Disconnect();
}
bool
Connect(const wxString& host, const wxString& service, const wxString& topic)
{
m_conn = MakeConnection(host, service, topic);
return m_conn != NULL;
}
void Disconnect()
{
if ( m_conn )
{
delete m_conn;
m_conn = NULL;
}
}
wxConnectionBase& GetConn() const
{
CPPUNIT_ASSERT( m_conn );
return *m_conn;
}
private:
wxConnectionBase *m_conn;
DECLARE_NO_COPY_CLASS(IPCTestClient)
};
static IPCTestClient *gs_client = NULL;
// ----------------------------------------------------------------------------
// the test code itself
// ----------------------------------------------------------------------------
class IPCTestCase : public CppUnit::TestCase
{
public:
IPCTestCase() { }
private:
CPPUNIT_TEST_SUITE( IPCTestCase );
CPPUNIT_TEST( Connect );
CPPUNIT_TEST( Execute );
CPPUNIT_TEST( Disconnect );
CPPUNIT_TEST_SUITE_END();
void Connect();
void Execute();
void Disconnect();
DECLARE_NO_COPY_CLASS(IPCTestCase)
};
CPPUNIT_TEST_SUITE_REGISTRATION( IPCTestCase );
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( IPCTestCase, "IPCTestCase" );
void IPCTestCase::Connect()
{
gs_server = new IPCTestServer;
gs_client = new IPCTestClient;
// connecting to the wrong port should fail
CPPUNIT_ASSERT( !gs_client->Connect("localhost", "2424", IPC_TEST_TOPIC) );
// connecting using an unsupported topic should fail (unless the server
// expects a ROT-13'd topic name...)
CPPUNIT_ASSERT( !gs_client->Connect("localhost", IPC_TEST_PORT, "VCP GRFG") );
// connecting to the right port on the right topic should succeed
CPPUNIT_ASSERT( gs_client->Connect("localhost", IPC_TEST_PORT, IPC_TEST_TOPIC) );
}
void IPCTestCase::Execute()
{
wxConnectionBase& conn = gs_client->GetConn();
const wxString s("Date");
CPPUNIT_ASSERT( conn.Execute(s) );
CPPUNIT_ASSERT( conn.Execute(s.mb_str(), s.length() + 1) );
char bytes[] = { 1, 2, 3 };
CPPUNIT_ASSERT( conn.Execute(bytes, WXSIZEOF(bytes)) );
}
void IPCTestCase::Disconnect()
{
if ( gs_client )
{
gs_client->Disconnect();
delete gs_client;
gs_client = NULL;
}
if ( gs_server )
{
delete gs_server;
gs_server = NULL;
}
}
#endif // wxUSE_THREADS