PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/common/io/DescriptorTest.cpp

https://code.google.com/
C++ | 301 lines | 179 code | 48 blank | 74 comment | 0 complexity | b79da0841a3808d406c28d0e8d2e007b MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0
  1. /*
  2. * This program is free software; you can redistribute it and/or modify
  3. * it under the terms of the GNU General Public License as published by
  4. * the Free Software Foundation; either version 2 of the License, or
  5. * (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU Library General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program; if not, write to the Free Software
  14. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15. *
  16. * DescriptorTest.cpp
  17. * Test fixture for the Descriptor classes
  18. * Copyright (C) 2005-2008 Simon Newton
  19. */
  20. #include <cppunit/extensions/HelperMacros.h>
  21. #include <stdint.h>
  22. #include <string.h>
  23. #include <string>
  24. #include "ola/Callback.h"
  25. #include "ola/Logging.h"
  26. #include "ola/io/Descriptor.h"
  27. #include "ola/io/SelectServer.h"
  28. using std::string;
  29. using ola::io::ConnectedDescriptor;
  30. using ola::io::LoopbackDescriptor;
  31. using ola::io::PipeDescriptor;
  32. using ola::io::UnixSocket;
  33. using ola::io::SelectServer;
  34. static const unsigned char test_cstring[] = "Foo";
  35. // used to set a timeout which aborts the tests
  36. static const int ABORT_TIMEOUT_IN_MS = 1000;
  37. class DescriptorTest: public CppUnit::TestFixture {
  38. CPPUNIT_TEST_SUITE(DescriptorTest);
  39. CPPUNIT_TEST(testLoopbackDescriptor);
  40. CPPUNIT_TEST(testPipeDescriptorClientClose);
  41. CPPUNIT_TEST(testPipeDescriptorServerClose);
  42. CPPUNIT_TEST(testUnixSocketClientClose);
  43. CPPUNIT_TEST(testUnixSocketServerClose);
  44. CPPUNIT_TEST_SUITE_END();
  45. public:
  46. void setUp();
  47. void tearDown();
  48. void testLoopbackDescriptor();
  49. void testPipeDescriptorClientClose();
  50. void testPipeDescriptorServerClose();
  51. void testUnixSocketClientClose();
  52. void testUnixSocketServerClose();
  53. // timing out indicates something went wrong
  54. void Timeout() {
  55. CPPUNIT_ASSERT(false);
  56. m_timeout_closure = NULL;
  57. }
  58. // Socket data actions
  59. void ReceiveAndClose(ConnectedDescriptor *socket);
  60. void ReceiveAndTerminate(ConnectedDescriptor *socket);
  61. void Receive(ConnectedDescriptor *socket);
  62. void ReceiveAndSend(ConnectedDescriptor *socket);
  63. void ReceiveSendAndClose(ConnectedDescriptor *socket);
  64. // Socket close actions
  65. void TerminateOnClose() {
  66. m_ss->Terminate();
  67. }
  68. private:
  69. SelectServer *m_ss;
  70. ola::SingleUseCallback0<void> *m_timeout_closure;
  71. void SocketClientClose(ConnectedDescriptor *socket,
  72. ConnectedDescriptor *socket2);
  73. void SocketServerClose(ConnectedDescriptor *socket,
  74. ConnectedDescriptor *socket2);
  75. };
  76. CPPUNIT_TEST_SUITE_REGISTRATION(DescriptorTest);
  77. /*
  78. * Setup the select server
  79. */
  80. void DescriptorTest::setUp() {
  81. ola::InitLogging(ola::OLA_LOG_INFO, ola::OLA_LOG_STDERR);
  82. m_ss = new SelectServer();
  83. m_timeout_closure = ola::NewSingleCallback(this, &DescriptorTest::Timeout);
  84. CPPUNIT_ASSERT(m_ss->RegisterSingleTimeout(ABORT_TIMEOUT_IN_MS,
  85. m_timeout_closure));
  86. }
  87. /*
  88. * Cleanup the select server
  89. */
  90. void DescriptorTest::tearDown() {
  91. delete m_ss;
  92. }
  93. /*
  94. * Test a loopback socket works correctly
  95. */
  96. void DescriptorTest::testLoopbackDescriptor() {
  97. LoopbackDescriptor socket;
  98. CPPUNIT_ASSERT(socket.Init());
  99. CPPUNIT_ASSERT(!socket.Init());
  100. socket.SetOnData(ola::NewCallback(this, &DescriptorTest::ReceiveAndTerminate,
  101. static_cast<ConnectedDescriptor*>(&socket)));
  102. CPPUNIT_ASSERT(m_ss->AddReadDescriptor(&socket));
  103. ssize_t bytes_sent = socket.Send(
  104. static_cast<const uint8_t*>(test_cstring),
  105. sizeof(test_cstring));
  106. CPPUNIT_ASSERT_EQUAL(static_cast<ssize_t>(sizeof(test_cstring)), bytes_sent);
  107. m_ss->Run();
  108. m_ss->RemoveReadDescriptor(&socket);
  109. }
  110. /*
  111. * Test a pipe socket works correctly.
  112. * The client sends some data and expects the same data to be returned. The
  113. * client then closes the connection.
  114. */
  115. void DescriptorTest::testPipeDescriptorClientClose() {
  116. PipeDescriptor socket;
  117. CPPUNIT_ASSERT(socket.Init());
  118. CPPUNIT_ASSERT(!socket.Init());
  119. SocketClientClose(&socket, socket.OppositeEnd());
  120. }
  121. /*
  122. * Test a pipe socket works correctly.
  123. * The client sends some data. The server echos the data and closes the
  124. * connection.
  125. */
  126. void DescriptorTest::testPipeDescriptorServerClose() {
  127. PipeDescriptor socket;
  128. CPPUNIT_ASSERT(socket.Init());
  129. CPPUNIT_ASSERT(!socket.Init());
  130. SocketServerClose(&socket, socket.OppositeEnd());
  131. }
  132. /*
  133. * Test a unix socket works correctly.
  134. * The client sends some data and expects the same data to be returned. The
  135. * client then closes the connection.
  136. */
  137. void DescriptorTest::testUnixSocketClientClose() {
  138. UnixSocket socket;
  139. CPPUNIT_ASSERT(socket.Init());
  140. CPPUNIT_ASSERT(!socket.Init());
  141. SocketClientClose(&socket, socket.OppositeEnd());
  142. }
  143. /*
  144. * Test a unix socket works correctly.
  145. * The client sends some data. The server echos the data and closes the
  146. * connection.
  147. */
  148. void DescriptorTest::testUnixSocketServerClose() {
  149. UnixSocket socket;
  150. CPPUNIT_ASSERT(socket.Init());
  151. CPPUNIT_ASSERT(!socket.Init());
  152. SocketServerClose(&socket, socket.OppositeEnd());
  153. }
  154. /*
  155. * Receive some data and close the socket
  156. */
  157. void DescriptorTest::ReceiveAndClose(ConnectedDescriptor *socket) {
  158. Receive(socket);
  159. m_ss->RemoveReadDescriptor(socket);
  160. socket->Close();
  161. }
  162. /*
  163. * Receive some data and terminate
  164. */
  165. void DescriptorTest::ReceiveAndTerminate(ConnectedDescriptor *socket) {
  166. Receive(socket);
  167. m_ss->Terminate();
  168. }
  169. /*
  170. * Receive some data and check it's what we expected.
  171. */
  172. void DescriptorTest::Receive(ConnectedDescriptor *socket) {
  173. // try to read more than what we sent to test non-blocking
  174. uint8_t buffer[sizeof(test_cstring) + 10];
  175. unsigned int data_read;
  176. CPPUNIT_ASSERT(!socket->Receive(buffer, sizeof(buffer), data_read));
  177. CPPUNIT_ASSERT_EQUAL(static_cast<unsigned int>(sizeof(test_cstring)),
  178. data_read);
  179. CPPUNIT_ASSERT(!memcmp(test_cstring, buffer, data_read));
  180. }
  181. /*
  182. * Receive some data and send it back
  183. */
  184. void DescriptorTest::ReceiveAndSend(ConnectedDescriptor *socket) {
  185. uint8_t buffer[sizeof(test_cstring) + 10];
  186. unsigned int data_read;
  187. socket->Receive(buffer, sizeof(buffer), data_read);
  188. CPPUNIT_ASSERT_EQUAL(static_cast<unsigned int>(sizeof(test_cstring)),
  189. data_read);
  190. ssize_t bytes_sent = socket->Send(buffer, data_read);
  191. CPPUNIT_ASSERT_EQUAL(static_cast<ssize_t>(sizeof(test_cstring)), bytes_sent);
  192. }
  193. /*
  194. * Receive some data, send the same data and close
  195. */
  196. void DescriptorTest::ReceiveSendAndClose(ConnectedDescriptor *socket) {
  197. ReceiveAndSend(socket);
  198. m_ss->RemoveReadDescriptor(socket);
  199. socket->Close();
  200. }
  201. /**
  202. * Generic method to test client initiated close
  203. */
  204. void DescriptorTest::SocketClientClose(ConnectedDescriptor *socket,
  205. ConnectedDescriptor *socket2) {
  206. CPPUNIT_ASSERT(socket);
  207. socket->SetOnData(
  208. ola::NewCallback(this, &DescriptorTest::ReceiveAndClose,
  209. static_cast<ConnectedDescriptor*>(socket)));
  210. CPPUNIT_ASSERT(m_ss->AddReadDescriptor(socket));
  211. CPPUNIT_ASSERT(socket2);
  212. socket2->SetOnData(
  213. ola::NewCallback(this, &DescriptorTest::ReceiveAndSend,
  214. static_cast<ConnectedDescriptor*>(socket2)));
  215. socket2->SetOnClose(
  216. ola::NewSingleCallback(this,
  217. &DescriptorTest::TerminateOnClose));
  218. CPPUNIT_ASSERT(m_ss->AddReadDescriptor(socket2));
  219. ssize_t bytes_sent = socket->Send(
  220. static_cast<const uint8_t*>(test_cstring),
  221. sizeof(test_cstring));
  222. CPPUNIT_ASSERT_EQUAL(static_cast<ssize_t>(sizeof(test_cstring)), bytes_sent);
  223. m_ss->Run();
  224. m_ss->RemoveReadDescriptor(socket);
  225. m_ss->RemoveReadDescriptor(socket2);
  226. delete socket2;
  227. }
  228. /**
  229. * Generic method to test server initiated close
  230. */
  231. void DescriptorTest::SocketServerClose(ConnectedDescriptor *socket,
  232. ConnectedDescriptor *socket2) {
  233. CPPUNIT_ASSERT(socket);
  234. socket->SetOnData(ola::NewCallback(
  235. this, &DescriptorTest::Receive,
  236. static_cast<ConnectedDescriptor*>(socket)));
  237. socket->SetOnClose(
  238. ola::NewSingleCallback(this, &DescriptorTest::TerminateOnClose));
  239. CPPUNIT_ASSERT(m_ss->AddReadDescriptor(socket));
  240. CPPUNIT_ASSERT(socket2);
  241. socket2->SetOnData(ola::NewCallback(
  242. this, &DescriptorTest::ReceiveSendAndClose,
  243. static_cast<ConnectedDescriptor*>(socket2)));
  244. CPPUNIT_ASSERT(m_ss->AddReadDescriptor(socket2));
  245. ssize_t bytes_sent = socket->Send(
  246. static_cast<const uint8_t*>(test_cstring),
  247. sizeof(test_cstring));
  248. CPPUNIT_ASSERT_EQUAL(static_cast<ssize_t>(sizeof(test_cstring)), bytes_sent);
  249. m_ss->Run();
  250. m_ss->RemoveReadDescriptor(socket);
  251. m_ss->RemoveReadDescriptor(socket2);
  252. delete socket2;
  253. }