really fix VC6 compilation of all testsi (without breaking VC9)
[wxWidgets.git] / tests / net / ipc.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/net/ipc.cpp
3 // Purpose: IPC classes unit tests
4 // Author: Vadim Zeitlin
5 // RCS-ID: $Id$
6 // Copyright: (c) 2008 Vadim Zeitlin
7 // Licence: wxWidgets licence
8 ///////////////////////////////////////////////////////////////////////////////
9
10 // For compilers that support precompilation, includes "wx/wx.h".
11 // and "wx/cppunit.h"
12 #include "testprec.h"
13
14 #ifdef __BORLANDC__
15 #pragma hdrstop
16 #endif
17
18 // this test needs threads as it runs the test server in a secondary thread
19 #if wxUSE_THREADS
20
21 // for all others, include the necessary headers
22 #ifndef WX_PRECOMP
23 #include "wx/app.h"
24 #endif
25
26 #include "wx/ipc.h"
27 #include "wx/thread.h"
28
29 #define wxUSE_SOCKETS_FOR_IPC (!wxUSE_DDE_FOR_IPC)
30
31 namespace
32 {
33
34 const char *IPC_TEST_PORT = "4242";
35 const char *IPC_TEST_TOPIC = "IPC TEST";
36
37 } // anonymous namespace
38
39 // ----------------------------------------------------------------------------
40 // test connection class used by IPCTestServer
41 // ----------------------------------------------------------------------------
42
43 class IPCTestConnection : public wxConnection
44 {
45 public:
46 IPCTestConnection() { }
47
48 virtual bool OnExec(const wxString& topic, const wxString& data)
49 {
50 if ( topic != IPC_TEST_TOPIC )
51 return false;
52
53 return data == "Date";
54 }
55
56 private:
57 DECLARE_NO_COPY_CLASS(IPCTestConnection)
58 };
59
60 // ----------------------------------------------------------------------------
61 // event dispatching thread class
62 // ----------------------------------------------------------------------------
63
64 class EventThread : public wxThread
65 {
66 public:
67 EventThread()
68 : wxThread(wxTHREAD_JOINABLE)
69 {
70 Create();
71 Run();
72 }
73
74 protected:
75 virtual void *Entry()
76 {
77 wxTheApp->MainLoop();
78
79 return NULL;
80 }
81
82 DECLARE_NO_COPY_CLASS(EventThread)
83 };
84
85 // ----------------------------------------------------------------------------
86 // test server class
87 // ----------------------------------------------------------------------------
88
89 class IPCTestServer : public wxServer
90 {
91 public:
92 IPCTestServer()
93 {
94 m_conn = NULL;
95
96 #if wxUSE_SOCKETS_FOR_IPC
97 // we must call this from the main thread
98 wxSocketBase::Initialize();
99 #endif // wxUSE_SOCKETS_FOR_IPC
100
101 // we need event dispatching to work for IPC server to work
102 m_thread = new EventThread;
103
104 Create(IPC_TEST_PORT);
105 }
106
107 virtual ~IPCTestServer()
108 {
109 wxTheApp->ExitMainLoop();
110
111 m_thread->Wait();
112 delete m_thread;
113
114 delete m_conn;
115
116 #if wxUSE_SOCKETS_FOR_IPC
117 wxSocketBase::Shutdown();
118 #endif // wxUSE_SOCKETS_FOR_IPC
119 }
120
121 virtual wxConnectionBase *OnAcceptConnection(const wxString& topic)
122 {
123 if ( topic != IPC_TEST_TOPIC )
124 return NULL;
125
126 m_conn = new IPCTestConnection;
127 return m_conn;
128 }
129
130 private:
131 EventThread *m_thread;
132 IPCTestConnection *m_conn;
133
134 DECLARE_NO_COPY_CLASS(IPCTestServer)
135 };
136
137 static IPCTestServer *gs_server = NULL;
138
139 // ----------------------------------------------------------------------------
140 // test client class
141 // ----------------------------------------------------------------------------
142
143 class IPCTestClient : public wxClient
144 {
145 public:
146 IPCTestClient()
147 {
148 m_conn = NULL;
149 }
150
151 virtual ~IPCTestClient()
152 {
153 Disconnect();
154 }
155
156 bool
157 Connect(const wxString& host, const wxString& service, const wxString& topic)
158 {
159 m_conn = MakeConnection(host, service, topic);
160
161 return m_conn != NULL;
162 }
163
164 void Disconnect()
165 {
166 if ( m_conn )
167 {
168 delete m_conn;
169 m_conn = NULL;
170 }
171 }
172
173 wxConnectionBase& GetConn() const
174 {
175 CPPUNIT_ASSERT( m_conn );
176
177 return *m_conn;
178 }
179
180 private:
181 wxConnectionBase *m_conn;
182
183 DECLARE_NO_COPY_CLASS(IPCTestClient)
184 };
185
186 static IPCTestClient *gs_client = NULL;
187
188 // ----------------------------------------------------------------------------
189 // the test code itself
190 // ----------------------------------------------------------------------------
191
192 class IPCTestCase : public CppUnit::TestCase
193 {
194 public:
195 IPCTestCase() { }
196
197 private:
198 CPPUNIT_TEST_SUITE( IPCTestCase );
199 CPPUNIT_TEST( Connect );
200 CPPUNIT_TEST( Execute );
201 CPPUNIT_TEST( Disconnect );
202 CPPUNIT_TEST_SUITE_END();
203
204 void Connect();
205 void Execute();
206 void Disconnect();
207
208 DECLARE_NO_COPY_CLASS(IPCTestCase)
209 };
210
211 CPPUNIT_TEST_SUITE_REGISTRATION( IPCTestCase );
212 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( IPCTestCase, "IPCTestCase" );
213
214 void IPCTestCase::Connect()
215 {
216 gs_server = new IPCTestServer;
217 gs_client = new IPCTestClient;
218
219 // connecting to the wrong port should fail
220 CPPUNIT_ASSERT( !gs_client->Connect("localhost", "2424", IPC_TEST_TOPIC) );
221
222 // connecting using an unsupported topic should fail (unless the server
223 // expects a ROT-13'd topic name...)
224 CPPUNIT_ASSERT( !gs_client->Connect("localhost", IPC_TEST_PORT, "VCP GRFG") );
225
226 // connecting to the right port on the right topic should succeed
227 CPPUNIT_ASSERT( gs_client->Connect("localhost", IPC_TEST_PORT, IPC_TEST_TOPIC) );
228 }
229
230 void IPCTestCase::Execute()
231 {
232 wxConnectionBase& conn = gs_client->GetConn();
233
234 const wxString s("Date");
235 CPPUNIT_ASSERT( conn.Execute(s) );
236 CPPUNIT_ASSERT( conn.Execute(s.mb_str(), s.length() + 1) );
237
238 char bytes[] = { 1, 2, 3 };
239 CPPUNIT_ASSERT( conn.Execute(bytes, WXSIZEOF(bytes)) );
240 }
241
242 void IPCTestCase::Disconnect()
243 {
244 if ( gs_client )
245 {
246 gs_client->Disconnect();
247 delete gs_client;
248 gs_client = NULL;
249 }
250
251 if ( gs_server )
252 {
253 delete gs_server;
254 gs_server = NULL;
255 }
256 }
257
258 #endif // wxUSE_THREADS