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