// Not configured for multi-threading, start a client in ST mode.
client_.reset(new HttpClient(*io_service_, 0));
} else {
- // Start a client in MT mode.
+ // Create an MT-mode client.
client_.reset(new HttpClient(*io_service_,
- config_->getHttpClientThreads()));
+ config_->getHttpClientThreads(), true));
// If we're configured to use our own listener create and start it.
if (config_->getHttpDedicatedListener()) {
void
HAService::startClientAndListener() {
+ if (client_) {
+ client_->start();
+ }
+
if (listener_) {
listener_->start();
}
}
+void
+HAService::pauseClientAndListener() {
+ if (client_) {
+ client_->pause();
+ }
+
+ if (listener_) {
+ listener_->pause();
+ }
+}
+
+void
+HAService::resumeClientAndListener() {
+ if (client_) {
+ client_->resume();
+ }
+
+ if (listener_) {
+ listener_->resume();
+ }
+}
+
void
HAService::stopClientAndListener() {
if (client_) {
/// @brief Start the client and(or) listener instances.
///
- /// Starts the dedicated listener thread pool, if the listener exists.
- /// Nothing is required for the client as it does not currently support
- /// a discrete "start" method, rather it is "started" during its
- /// construction.
+ /// When HA+Mt is enabled it starts the client's thread pool
+ /// and the dedicated listener thread pool, if the listener exists.
void startClientAndListener();
+ /// @brief Pauses client and(or) listener thread pool operations.
+ ///
+ /// Suspends the client and listener thread pool event processing.
+ /// Has no effect in single-threaded mode or if thread pools are
+ /// not currently running.
+ void pauseClientAndListener();
+
+ /// @brief Resumes client and(or) listener thread pool operations.
+ ///
+ /// Resumes the client and listener thread pool event processing.
+ /// Has no effect in single-threaded mode or if thread pools are
+ /// not currently paused.
+ void resumeClientAndListener();
+
/// @brief Stop the client and(or) listener instances.
///
- /// Closing connections and stops the thread pools for the client
+ /// Closes all connections and stops the thread pools for the client
/// and listener, if they exist.
- ///
- /// @note Once stopped the service cannot be restarted, it must
- /// be recreated.
void stopClientAndListener();
protected:
#include <ha_test.h>
#include <ha_config.h>
#include <ha_service.h>
+#include <http/http_thread_pool.h>
#include <util/multi_threading_mgr.h>
#include <testutils/gtest_utils.h>
using namespace isc::ha;
using namespace isc::ha::test;
+using namespace isc::http;
using namespace isc::util;
namespace {
}
};
+// Verifies HA+MT start, pause, resume, and stop.
+TEST_F(HAMtServiceTest, multiThreadingBasics) {
+
+ // Build the HA JSON configuration.
+ std::stringstream ss;
+ ss <<
+ "["
+ " {"
+ " \"this-server-name\": \"server1\","
+ " \"mode\": \"passive-backup\","
+ " \"wait-backup-ack\": true,"
+ " \"peers\": ["
+ " {"
+ " \"name\": \"server1\","
+ " \"url\": \"http://127.0.0.1:8080/\","
+ " \"role\": \"primary\""
+ " },"
+ " {"
+ " \"name\": \"server2\","
+ " \"url\": \"http://127.0.0.1:8081/\","
+ " \"role\": \"backup\""
+ " }"
+ " ]";
+
+ // Enable MT, listener, and 3 threads for both client and listener.
+ ss << "," << makeHAMtJson(true, true, 3, 3) << "}]";
+ ConstElementPtr config_json;
+ ASSERT_NO_THROW_LOG(config_json = Element::fromJSON(ss.str()));
+
+ // Enable DHCP multi-threading configuration in CfgMgr with 3 threads.
+ setDHCPMultiThreadingConfig(true, 3);
+
+ /// @todo this is a hack... we have chicken-egg... CmdHttpListener won't
+ /// start if MT is not enabled BUT that happens after config hook point
+ MultiThreadingMgr::instance().setMode(true);
+
+ // Create the HA configuration
+ HAConfigPtr ha_config(new HAConfig());
+ HAConfigParser parser;
+ ASSERT_NO_THROW_LOG(parser.parse(ha_config, config_json));
+
+ // Instantiate the service.
+ TestHAServicePtr service;
+ ASSERT_NO_THROW_LOG(service.reset(new TestHAService(io_service_, network_state_,
+ ha_config)));
+ // Multi-threading should be enabled.
+ ASSERT_TRUE(ha_config->getEnableMultiThreading());
+
+ // Now we'll start, pause, resume and stop a few times.
+ for (int i = 0; i < 3; ++i) {
+ // Verify we're stopped.
+ // Client should exist but be stopped.
+ ASSERT_TRUE(service->client_);
+ ASSERT_TRUE(service->client_->isStopped());
+
+ // Listener should exist but not be stopped..
+ ASSERT_TRUE(service->listener_);
+ ASSERT_TRUE(service->client_->isStopped());
+
+ // Start client and listener.
+ ASSERT_NO_THROW_LOG(service->startClientAndListener());
+
+ // Verify we've started.
+ // Client should be running.
+ ASSERT_TRUE(service->client_->isRunning());
+ ASSERT_TRUE(service->client_->getThreadIOService());
+ EXPECT_FALSE(service->client_->getThreadIOService()->stopped());
+ EXPECT_EQ(service->client_->getThreadPoolSize(), 3);
+ EXPECT_EQ(service->client_->getThreadCount(), 3);
+
+ // Listener should be running.
+ ASSERT_TRUE(service->listener_->isRunning());
+ ASSERT_TRUE(service->listener_->getThreadIOService());
+ EXPECT_FALSE(service->listener_->getThreadIOService()->stopped());
+ EXPECT_EQ(service->listener_->getThreadPoolSize(), 3);
+ EXPECT_EQ(service->listener_->getThreadCount(), 3);
+
+ // Pause client and listener.
+ ASSERT_NO_THROW_LOG(service->pauseClientAndListener());
+
+ // Client should be paused.
+ ASSERT_TRUE(service->client_->isPaused());
+ EXPECT_TRUE(service->client_->getThreadIOService()->stopped());
+
+ // Listener should be paused.
+ ASSERT_TRUE(service->listener_->isPaused());
+ EXPECT_TRUE(service->listener_->getThreadIOService()->stopped());
+
+ // Now resume client and listener.
+ ASSERT_NO_THROW_LOG(service->resumeClientAndListener());
+
+ // Client should be running.
+ ASSERT_TRUE(service->client_->isRunning());
+ EXPECT_FALSE(service->client_->getThreadIOService()->stopped());
+
+ // Listener should be running.
+ ASSERT_TRUE(service->listener_->isRunning());
+ EXPECT_FALSE(service->listener_->getThreadIOService()->stopped());
+
+ // Stop should succeed.
+ ASSERT_NO_THROW_LOG(service->stopClientAndListener());
+ }
+}
+
// Verifies permutations of HA+MT configuration and start-up.
-TEST_F(HAMtServiceTest, multiThreadingStartup) {
+TEST_F(HAMtServiceTest, multiThreadingConfigStartup) {
// Structure describing a test scenario.
struct Scenario {
TestHAServicePtr service;
ASSERT_NO_THROW_LOG(service.reset(new TestHAService(io_service_, network_state_,
ha_config)));
- ASSERT_NO_THROW(service->startClientAndListener());
+ ASSERT_NO_THROW_LOG(service->startClientAndListener());
// Verify the configuration is as expected.
if (!scenario.exp_ha_mt_enabled_) {
// When HA+MT is enabled, client should be multi-threaded.
ASSERT_TRUE(service->client_);
+ EXPECT_TRUE(service->client_->isRunning());
EXPECT_TRUE(service->client_->getThreadIOService());
EXPECT_EQ(service->client_->getThreadPoolSize(), scenario.exp_client_threads_);
// Currently thread count should be the same as thread pool size. This might
continue;
}
- // We should have a listening listener with the expected number of threads.
+ // We should have a running listener with the expected number of threads.
ASSERT_TRUE(service->listener_);
- EXPECT_TRUE(service->listener_->isListening());
+ EXPECT_TRUE(service->listener_->isRunning());
EXPECT_EQ(service->listener_->getThreadPoolSize(), scenario.exp_listener_threads_);
+
// Currently thread count should be the same as thread pool size. This might
// change if we go to so some sort of dynamic thread instance management.
EXPECT_EQ(service->listener_->getThreadCount(), scenario.exp_listener_threads_);
+
+ ASSERT_NO_THROW_LOG(service->stopClientAndListener());
}
}
CmdHttpListener::CmdHttpListener(const IOAddress& address, const uint16_t port,
const uint16_t thread_pool_size /* = 1 */)
- : address_(address), port_(port), io_service_(), http_listener_(),
+ : address_(address), port_(port), thread_io_service_(), http_listener_(),
thread_pool_size_(thread_pool_size), threads_() {
}
" when multi-threading is disabled");
}
- // Punt if we're already listening.
- if (isListening()) {
- isc_throw(InvalidOperation, "CmdHttpListener is already listening!");
+ // Punt if we're already started.
+ if (!isStopped()) {
+ isc_throw(InvalidOperation, "CmdHttpListener already started!");
}
try {
// Create a new IOService.
- io_service_.reset(new IOService());
+ thread_io_service_.reset(new IOService());
// Create the response creator factory first. It will be used to
// generate response creators. Each response creator will be
// Create the HTTP listener. It will open up a TCP socket and be
// prepared to accept incoming connections.
TlsContextPtr tls_context;
- http_listener_.reset(new HttpListener(*io_service_, address_, port_,
+ http_listener_.reset(new HttpListener(*thread_io_service_, address_, port_,
tls_context, rcf,
HttpListener::RequestTimeout(TIMEOUT_AGENT_RECEIVE_COMMAND),
HttpListener::IdleTimeout(TIMEOUT_AGENT_IDLE_CONNECTION_TIMEOUT)));
- // Create the thread pooli with immediate start.
- threads_.reset(new HttpThreadPool(io_service_, thread_pool_size_));
+ // Create the thread pooi with immediate start.
+ threads_.reset(new HttpThreadPool(thread_io_service_, thread_pool_size_));
// Instruct the HTTP listener to actually open socket, install
// callback and start listening.
void
CmdHttpListener::stop() {
// Nothing to do.
- if (!io_service_) {
+ if (!thread_io_service_) {
return;
}
http_listener_.reset();
// Ditch the IOService.
- io_service_.reset();
+ thread_io_service_.reset();
LOG_DEBUG(command_logger, DBG_COMMAND, COMMAND_HTTP_LISTENER_STOPPED)
.arg(address_)
return (threads_->getRunState());
}
-bool
-CmdHttpListener::isListening() const {
- return (threads_ && (threads_->getRunState() == HttpThreadPool::RunState::PAUSED
- || threads_->getRunState() == HttpThreadPool::RunState::RUN));
+bool
+CmdHttpListener::isRunning() {
+ if (threads_) {
+ return (threads_->getRunState() == HttpThreadPool::RunState::RUN);
+ }
+
+ return (false);
+}
+
+bool
+CmdHttpListener::isStopped() {
+ if (threads_) {
+ return (threads_->getRunState() == HttpThreadPool::RunState::STOPPED);
+ }
+
+ return (true);
+}
+
+bool
+CmdHttpListener::isPaused() {
+ if (threads_) {
+ return (threads_->getRunState() == HttpThreadPool::RunState::PAUSED);
+ }
+
+ return (false);
}
} // namespace isc::config
/// @return Run state of the pool.
http::HttpThreadPool::RunState getRunState() const;
- /// @brief Checks if we are listening to the HTTP requests.
+ /// @brief Indicates if the thread pool processing is running.
///
- /// @return true if we are listening.
- bool isListening() const;
+ /// @return True if the thread pool exists and is in the RUN state,
+ /// false otherwise.
+ bool isRunning();
+
+ /// @brief Indicates if the thread pool is stopped.
+ ///
+ /// @return True if the thread pool does not exist or it
+ /// is in the STOPPED state, False otherwise.
+ bool isStopped();
+
+ /// @brief Indicates if the thread pool processing is running.
+ ///
+ /// @return True if the thread pool exists and is in the PAUSED state,
+ /// false otherwise.
+ bool isPaused();
/// @brief Fetches the IP address on which to listen.
///
return (threads_->getThreadCount());
}
- asiolink::IOServicePtr getIOService() const {
- return(io_service_);
+ asiolink::IOServicePtr getThreadIOService() const {
+ return(thread_io_service_);
}
private:
uint16_t port_;
/// @brief IOService instance that drives our IO.
- isc::asiolink::IOServicePtr io_service_;
+ isc::asiolink::IOServicePtr thread_io_service_;
/// @brief The HttpListener instance
http::HttpListenerPtr http_listener_;
SERVER_PORT, num_threads)));
ASSERT_TRUE(listener_);
- // Start it and verify it is listening.
+ // Start it and verify it is running.
ASSERT_NO_THROW_LOG(listener_->start());
- ASSERT_TRUE(listener_->isListening());
+ ASSERT_TRUE(listener_->isRunning());
EXPECT_EQ(listener_->getThreadCount(), num_threads);
// Maps the number of clients served by a given thread-id.
// Stop the listener and then verify it has stopped.
ASSERT_NO_THROW_LOG(listener_->stop());
- ASSERT_FALSE(listener_->isListening());
+ ASSERT_TRUE(listener_->isStopped());
EXPECT_EQ(listener_->getThreadCount(), 0);
// Iterate over the clients, checking their outcomes.
// It should not have an IOService, should not be listening
// should have no threads.
- ASSERT_FALSE(listener_->getIOService());
- EXPECT_FALSE(listener_->isListening());
+ ASSERT_FALSE(listener_->getThreadIOService());
+ EXPECT_TRUE(listener_->isStopped());
EXPECT_EQ(listener_->getThreadCount(), 0);
ASSERT_THROW_MSG(listener_->getRunState(), InvalidOperation,
"CmdHttpListener::getRunState - no thread pool!");
" when multi-threading is disabled");
// It should still not be listening and have no threads.
- EXPECT_FALSE(listener_->isListening());
+ EXPECT_TRUE(listener_->isStopped());
EXPECT_EQ(listener_->getThreadCount(), 0);
// Enable multi-threading.
// Make sure we can start it and it's listening with 1 thread.
ASSERT_NO_THROW_LOG(listener_->start());
- ASSERT_TRUE(listener_->isListening());
+ ASSERT_TRUE(listener_->isRunning());
EXPECT_EQ(listener_->getThreadCount(), 1);
- ASSERT_TRUE(listener_->getIOService());
- EXPECT_FALSE(listener_->getIOService()->stopped());
+ ASSERT_TRUE(listener_->getThreadIOService());
+ EXPECT_FALSE(listener_->getThreadIOService()->stopped());
EXPECT_EQ(listener_->getRunState(), HttpThreadPool::RunState::RUN);
// Trying to start it again should fail.
ASSERT_THROW_MSG(listener_->start(), InvalidOperation,
- "CmdHttpListener is already listening!");
+ "CmdHttpListener already started!");
// Stop it and verify we're no longer listening.
ASSERT_NO_THROW_LOG(listener_->stop());
- ASSERT_FALSE(listener_->isListening());
+ ASSERT_TRUE(listener_->isStopped());
EXPECT_EQ(listener_->getThreadCount(), 0);
EXPECT_EQ(listener_->getRunState(), HttpThreadPool::RunState::STOPPED);
- ASSERT_FALSE(listener_->getIOService());
+ ASSERT_FALSE(listener_->getThreadIOService());
// Make sure we can call stop again without problems.
ASSERT_NO_THROW_LOG(listener_->stop());
// We should be able to restart it.
ASSERT_NO_THROW_LOG(listener_->start());
- ASSERT_TRUE(listener_->isListening());
+ ASSERT_TRUE(listener_->isRunning());
EXPECT_EQ(listener_->getThreadCount(), 1);
- ASSERT_TRUE(listener_->getIOService());
- EXPECT_FALSE(listener_->getIOService()->stopped());
- EXPECT_EQ(listener_->getRunState(), HttpThreadPool::RunState::RUN);
+ ASSERT_TRUE(listener_->getThreadIOService());
+ EXPECT_FALSE(listener_->getThreadIOService()->stopped());
// Destroying it should also stop it.
// If the test timeouts we know it didn't!
EXPECT_EQ(listener_->getAddress(), address);
EXPECT_EQ(listener_->getPort(), port);
EXPECT_EQ(listener_->getThreadPoolSize(), 4);
- ASSERT_TRUE(listener_->isListening());
- ASSERT_TRUE(listener_->getIOService());
- EXPECT_FALSE(listener_->getIOService()->stopped());
+ ASSERT_TRUE(listener_->isRunning());
+ ASSERT_TRUE(listener_->getThreadIOService());
+ EXPECT_FALSE(listener_->getThreadIOService()->stopped());
// Verify we can pause it. We should still be listening, threads intact,
// IOservice stopped, state set to PAUSED.
ASSERT_NO_THROW_LOG(listener_->pause());
- ASSERT_TRUE(listener_->isListening());
+ ASSERT_TRUE(listener_->isPaused());
EXPECT_EQ(listener_->getThreadCount(), 4);
- ASSERT_TRUE(listener_->getIOService());
- EXPECT_TRUE(listener_->getIOService()->stopped());
- EXPECT_EQ(listener_->getRunState(), HttpThreadPool::RunState::PAUSED);
+ ASSERT_TRUE(listener_->getThreadIOService());
+ EXPECT_TRUE(listener_->getThreadIOService()->stopped());
// Verify we can resume it.
ASSERT_NO_THROW_LOG(listener_->resume());
- ASSERT_TRUE(listener_->isListening());
+ ASSERT_TRUE(listener_->isRunning());
EXPECT_EQ(listener_->getThreadCount(), 4);
- ASSERT_TRUE(listener_->getIOService());
- EXPECT_FALSE(listener_->getIOService()->stopped());
- EXPECT_EQ(listener_->getRunState(), HttpThreadPool::RunState::RUN);
+ ASSERT_TRUE(listener_->getThreadIOService());
+ EXPECT_FALSE(listener_->getThreadIOService()->stopped());
// Stop it and verify we're no longer listening.
ASSERT_NO_THROW_LOG(listener_->stop());
- ASSERT_FALSE(listener_->isListening());
+ ASSERT_TRUE(listener_->isStopped());
EXPECT_EQ(listener_->getThreadCount(), 0);
- ASSERT_FALSE(listener_->getIOService());
+ ASSERT_FALSE(listener_->getThreadIOService());
EXPECT_EQ(listener_->getRunState(), HttpThreadPool::RunState::STOPPED);
}
// Start the listener and verify it's listening with 1 thread.
ASSERT_NO_THROW_LOG(listener_->start());
- ASSERT_TRUE(listener_->isListening());
+ ASSERT_TRUE(listener_->isRunning());
EXPECT_EQ(listener_->getThreadCount(), 1);
// Now let's send a "foo" command. This should create a client, connect
EXPECT_EQ(hr->getBody(), "[ { \"arguments\": [ \"bar\" ], \"result\": 0 } ]");
// Make sure the listener is still listening.
- ASSERT_TRUE(listener_->isListening());
+ ASSERT_TRUE(listener_->isRunning());
EXPECT_EQ(listener_->getThreadCount(), 1);
// Stop the listener then verify it has stopped.
ASSERT_NO_THROW_LOG(listener_->stop());
- ASSERT_FALSE(listener_->isListening());
+ ASSERT_TRUE(listener_->isStopped());
EXPECT_EQ(listener_->getThreadCount(), 0);
}
}
}
+ /// @brief Pauses the thread pool operation.
+ ///
+ /// Suspends thread pool event processing.
void pause() {
if (!threads_) {
isc_throw(InvalidOperation, "HttpClient::pause - no thread pool");
threads_->pause();
}
- /// @brief Pauses the thread pool's worker threads.
+ /// @brief Resumes the thread pool operation.
+ ///
+ /// Resumes thread pool event processing.
void resume() {
if (!threads_) {
isc_throw(InvalidOperation, "HttpClient::resume - no thread pool");
threads_->resume();
}
+ /// @brief Fetches the thread pool's operational state.
+ ///
+ /// @return Operational state of the thread pool.
HttpThreadPool::RunState getRunState() const {
if (!threads_) {
isc_throw(InvalidOperation, "HttpClient::getRunState - no thread pool");
return (threads_->getRunState());
}
+ /// @brief Indicates if the thread pool processing is running.
+ ///
+ /// @return True if the thread pool exists and is in the RUN state,
+ /// false otherwise.
+ bool isRunning() {
+ if (threads_) {
+ return (threads_->getRunState() == HttpThreadPool::RunState::RUN);
+ }
+
+ return (false);
+ }
+
+ /// @brief Indicates if the thread pool is stopped.
+ ///
+ /// @return True if the thread pool exists and is in the STOPPED state,
+ /// false otherwise
+ bool isStopped() {
+ if (threads_) {
+ return (threads_->getRunState() == HttpThreadPool::RunState::STOPPED);
+ }
+
+ return (false);
+ }
+
+ /// @brief Indicates if the thread pool processing is running.
+ ///
+ /// @return True if the thread pool exists and is in the PAUSED state,
+ /// false otherwise.
+ bool isPaused() {
+ if (threads_) {
+ return (threads_->getRunState() == HttpThreadPool::RunState::PAUSED);
+ }
+
+ return (false);
+ }
+
/// @brief Fetches the internal IOService used in multi-threaded mode.
///
/// @return A pointer to the IOService, or an empty pointer when
return (impl_->getRunState());
}
+bool
+HttpClient::isRunning() {
+ return (impl_->isRunning());
+}
+
+bool
+HttpClient::isStopped() {
+ return (impl_->isStopped());
+}
+
+bool
+HttpClient::isPaused() {
+ return (impl_->isPaused());
+}
+
} // end of namespace isc::http
} // end of namespace isc
/// @return the number of running threads.
uint16_t getThreadCount() const;
+ /// @brief Pauses the thread pool operation.
+ ///
+ /// Suspends thread pool event processing.
+ /// @throw InvalidOperation if the thread pool does not exist.
void pause();
+
+ /// @brief Resumes the thread pool operation.
+ ///
+ /// Resumes thread pool event processing.
+ /// @throw InvalidOperation if the thread pool does not exist.
void resume();
+
+ /// @brief Fetches the thread pool's operational state.
+ ///
+ /// @return Operational state of the thread pool.
+ /// @throw InvalidOperation if the thread pool does not exist.
HttpThreadPool::RunState getRunState() const;
+ /// @brief Indicates if the thread pool processing is running.
+ ///
+ /// @return True if the thread pool exists and is in the RUN state,
+ /// false otherwise.
+ bool isRunning();
+
+ /// @brief Indicates if the thread pool is stopped.
+ ///
+ /// @return True if the thread pool exists and is in the STOPPED state,
+ /// false otherwise.
+ bool isStopped();
+
+ /// @brief Indicates if the thread pool processing is running.
+ ///
+ /// @return True if the thread pool exists and is in the PAUSED state,
+ /// false otherwise.
+ bool isPaused();
+
private:
/// @brief Pointer to the HTTP client implementation.
ASSERT_NO_THROW_LOG(client_.reset(new HttpClient(io_service_, num_threads)));
ASSERT_TRUE(client_);
+ // Check convenience functions.
+ ASSERT_TRUE(client_->isRunning());
+ ASSERT_FALSE(client_->isPaused());
+ ASSERT_FALSE(client_->isStopped());
+
if (num_threads_ == 0) {
// If we single-threaded client should not have it's own IOService.
ASSERT_FALSE(client_->getThreadIOService());
// Pause the client.
ASSERT_NO_THROW(client_->pause());
ASSERT_EQ(HttpThreadPool::RunState::PAUSED, client_->getRunState());
+
+ // Check convenience functions.
+ ASSERT_FALSE(client_->isRunning());
+ ASSERT_TRUE(client_->isPaused());
+ ASSERT_FALSE(client_->isStopped());
}
// We should have completed at least the expected number of requests
ASSERT_EQ(client->getThreadCount(), 3);
ASSERT_EQ(client->getRunState(), HttpThreadPool::RunState::RUN);
+ // Check convenience functions.
+ ASSERT_TRUE(client->isRunning());
+ ASSERT_FALSE(client->isPaused());
+ ASSERT_FALSE(client->isStopped());
+
// Verify stop doesn't throw.
ASSERT_NO_THROW_LOG(client->stop());
ASSERT_EQ(client->getThreadPoolSize(), 3);
ASSERT_EQ(client->getThreadCount(), 0);
+ // Check convenience functions.
+ ASSERT_FALSE(client->isRunning());
+ ASSERT_FALSE(client->isPaused());
+ ASSERT_TRUE(client->isStopped());
+
// Verify a second call to stop() doesn't throw.
ASSERT_NO_THROW_LOG(client->stop());
ASSERT_EQ(client->getThreadCount(), 0);
ASSERT_EQ(client->getRunState(), HttpThreadPool::RunState::STOPPED);
+ // Check convenience functions.
+ ASSERT_FALSE(client->isRunning());
+ ASSERT_FALSE(client->isPaused());
+ ASSERT_TRUE(client->isStopped());
+
// We should be able to start it.
ASSERT_NO_THROW(client->start());
ASSERT_FALSE(client->getThreadIOService()->stopped());
ASSERT_EQ(client->getRunState(), HttpThreadPool::RunState::RUN);
+ // Check convenience functions.
+ ASSERT_TRUE(client->isRunning());
+ ASSERT_FALSE(client->isPaused());
+ ASSERT_FALSE(client->isStopped());
+
// Cannot start it twice.
ASSERT_THROW_MSG(client->start(), InvalidOperation,
"HttpThreadPool::start already started!");
}
// Verifies that we can cleanly work, pause, and resume repeatedly.
-TEST_F(MtHttpClientTest, workPauseResumee) {
+TEST_F(MtHttpClientTest, workPauseResume) {
size_t num_threads = 12;
size_t num_batches = 12;
size_t num_listeners = 12;