ipc.cpp 5.9 KB

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