test_server_unix_socket.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. // Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this
  5. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. #ifndef TEST_SERVER_UNIX_SOCKET_H
  7. #define TEST_SERVER_UNIX_SOCKET_H
  8. #include <config.h>
  9. #include <asiolink/interval_timer.h>
  10. #include <asiolink/io_service.h>
  11. #include <util/threads/thread.h>
  12. #include <util/threads/sync.h>
  13. #include <boost/shared_ptr.hpp>
  14. #include <gtest/gtest.h>
  15. #include <list>
  16. #include <stdint.h>
  17. #include <string>
  18. namespace isc {
  19. namespace asiolink {
  20. namespace test {
  21. class ConnectionPool;
  22. /// @brief Provides unix domain socket functionality for unit tests.
  23. ///
  24. /// This class represents a server side socket. It can be used to
  25. /// test client's transmission over the unix domain socket. By default,
  26. /// the server side socket echoes the client's message so the client's
  27. /// message (prefixed with the word "received").
  28. ///
  29. /// It is also possible to specify a custom response from the server
  30. /// instead of echoing back the request.
  31. ///
  32. /// It is possible to make multiple connections to the server side
  33. /// socket simultaneously.
  34. ///
  35. /// The test should perform IOService::run_one until it finds that
  36. /// the number of responses sent by the server is greater than
  37. /// expected. The number of responses sent so far can be retrieved
  38. /// using @ref TestServerUnixSocket::getResponseNum.
  39. ///
  40. /// This class uses @c shared_from_this() to pass its instance to the
  41. /// @c boost::bind function, thus the caller must store shared pointer
  42. /// to this object.
  43. class TestServerUnixSocket {
  44. public:
  45. /// @brief Constructor.
  46. ///
  47. /// @param io_service IO service.
  48. /// @param socket_file_path Socket file path.
  49. /// @param custom_response Custom response to be sent to the client.
  50. TestServerUnixSocket(IOService& io_service,
  51. const std::string& socket_file_path,
  52. const std::string& custom_response = "");
  53. /// @brief Destructor.
  54. ///
  55. /// Closes active connections.
  56. ~TestServerUnixSocket();
  57. /// @brief Starts timer for detecting test timeout.
  58. ///
  59. /// @param test_timeout Test timeout in milliseconds.
  60. void startTimer(const long test_timeout);
  61. /// @brief Cancels all asynchronous operations.
  62. void stopServer();
  63. /// @brief Generates response of a given length.
  64. ///
  65. /// Note: The response may be a few bytes larger than requested.
  66. ///
  67. /// @param response_size Desired response size.
  68. void generateCustomResponse(const uint64_t response_size);
  69. /// @brief Creates and binds server socket.
  70. ///
  71. /// @param use_thread Boolean value indicating if the IO service
  72. /// is running in thread.
  73. void bindServerSocket(const bool use_thread = false);
  74. /// @brief Server acceptor handler.
  75. ///
  76. /// @param ec Error code.
  77. void acceptHandler(const boost::system::error_code& ec);
  78. /// @brief Callback function invoke upon test timeout.
  79. ///
  80. /// It stops the IO service and reports test timeout.
  81. void timeoutHandler();
  82. /// @brief Return number of responses sent so far to the clients.
  83. size_t getResponseNum() const;
  84. /// @brief Indicates if the server has been stopped.
  85. bool isStopped() {
  86. return (stopped_);
  87. }
  88. /// @brief Waits for the server signal that it is running.
  89. ///
  90. /// When the caller starts the service he indicates whether
  91. /// IO service will be running in thread or not. If threads
  92. /// are used the caller has to wait for the IO service to
  93. /// actually run. In such case this function should be invoked
  94. /// which waits for a posted callback to be executed. When this
  95. /// happens it means that IO service is running and the main
  96. /// thread can move forward.
  97. void waitForRunning();
  98. private:
  99. /// @brief Asynchronously accept new connections.
  100. void accept();
  101. /// @brief Handler invoked to signal that server is running.
  102. ///
  103. /// This is used only when thread is used to run IO service.
  104. void signalRunning();
  105. /// @brief IO service used by the tests.
  106. IOService& io_service_;
  107. /// @brief Server endpoint.
  108. boost::asio::local::stream_protocol::endpoint server_endpoint_;
  109. /// @brief Server acceptor.
  110. boost::asio::local::stream_protocol::acceptor server_acceptor_;
  111. /// @brief Asynchronous timer service to detect timeouts.
  112. IntervalTimer test_timer_;
  113. /// @brief Holds custom response to be sent to the client.
  114. std::string custom_response_;
  115. /// @brief Pool of connections.
  116. boost::shared_ptr<ConnectionPool> connection_pool_;
  117. /// @brief Indicates if IO service has been stopped as a result of
  118. /// a timeout.
  119. bool stopped_;
  120. /// @brief Indicates if the server in a thread is running.
  121. bool running_;
  122. /// @brief Mutex used by the server.
  123. ///
  124. /// Mutex is used in situations when server's IO service is being run in a
  125. /// thread to synchronize this thread with a main thread using
  126. /// @ref signalRunning and @ref waitForRunning.
  127. isc::util::thread::Mutex mutex_;
  128. /// @brief Conditional variable used by the server.
  129. ///
  130. /// Conditional variable is used in situations when server's IO service is
  131. /// being run in a thread to synchronize this thread with a main thread
  132. /// using @ref signalRunning and @ref waitForRunning.
  133. isc::util::thread::CondVar condvar_;
  134. };
  135. /// @brief Pointer to the @ref TestServerUnixSocket.
  136. typedef boost::shared_ptr<TestServerUnixSocket> TestServerUnixSocketPtr;
  137. } // end of namespace isc::asiolink::test
  138. } // end of namespace isc::asiolink
  139. } // end of namespace isc
  140. #endif // TEST_SERVER_UNIX_SOCKET_H