]>
Commit | Line | Data |
---|---|---|
e7ce668e VZ |
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 | ||
4c141c5a VZ |
18 | // this test needs threads as it runs the test server in a secondary thread |
19 | #if wxUSE_THREADS | |
20 | ||
e7ce668e VZ |
21 | // for all others, include the necessary headers |
22 | #ifndef WX_PRECOMP | |
4c141c5a | 23 | #include "wx/app.h" |
e7ce668e VZ |
24 | #endif |
25 | ||
e7ce668e VZ |
26 | #include "wx/ipc.h" |
27 | #include "wx/thread.h" | |
28 | ||
02ab8d3a VZ |
29 | #define wxUSE_SOCKETS_FOR_IPC (!wxUSE_DDE_FOR_IPC) |
30 | ||
e7ce668e VZ |
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 | ||
02ab8d3a | 96 | #if wxUSE_SOCKETS_FOR_IPC |
e7ce668e VZ |
97 | // we must call this from the main thread |
98 | wxSocketBase::Initialize(); | |
02ab8d3a | 99 | #endif // wxUSE_SOCKETS_FOR_IPC |
e7ce668e VZ |
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; | |
4c141c5a VZ |
113 | |
114 | delete m_conn; | |
e7ce668e | 115 | |
02ab8d3a | 116 | #if wxUSE_SOCKETS_FOR_IPC |
e7ce668e | 117 | wxSocketBase::Shutdown(); |
02ab8d3a | 118 | #endif // wxUSE_SOCKETS_FOR_IPC |
e7ce668e VZ |
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 | ||
76a10a0d | 186 | static IPCTestClient *gs_client = NULL; |
e7ce668e VZ |
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 | ||
02ab8d3a | 211 | CPPUNIT_TEST_SUITE_REGISTRATION( IPCTestCase ); |
e7ce668e VZ |
212 | CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( IPCTestCase, "IPCTestCase" ); |
213 | ||
214 | void IPCTestCase::Connect() | |
215 | { | |
216 | gs_server = new IPCTestServer; | |
76a10a0d | 217 | gs_client = new IPCTestClient; |
e7ce668e VZ |
218 | |
219 | // connecting to the wrong port should fail | |
76a10a0d | 220 | CPPUNIT_ASSERT( !gs_client->Connect("localhost", "2424", IPC_TEST_TOPIC) ); |
e7ce668e VZ |
221 | |
222 | // connecting using an unsupported topic should fail (unless the server | |
223 | // expects a ROT-13'd topic name...) | |
76a10a0d | 224 | CPPUNIT_ASSERT( !gs_client->Connect("localhost", IPC_TEST_PORT, "VCP GRFG") ); |
e7ce668e VZ |
225 | |
226 | // connecting to the right port on the right topic should succeed | |
76a10a0d | 227 | CPPUNIT_ASSERT( gs_client->Connect("localhost", IPC_TEST_PORT, IPC_TEST_TOPIC) ); |
e7ce668e VZ |
228 | } |
229 | ||
230 | void IPCTestCase::Execute() | |
231 | { | |
76a10a0d | 232 | wxConnectionBase& conn = gs_client->GetConn(); |
e7ce668e VZ |
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 | { | |
76a10a0d VZ |
244 | if ( gs_client ) |
245 | { | |
246 | gs_client->Disconnect(); | |
247 | delete gs_client; | |
248 | gs_client = NULL; | |
249 | } | |
e7ce668e VZ |
250 | |
251 | if ( gs_server ) | |
252 | { | |
253 | delete gs_server; | |
254 | gs_server = NULL; | |
255 | } | |
256 | } | |
257 | ||
258 | #endif // wxUSE_THREADS |