osquery-1/osquery/dispatcher/tests/dispatcher_tests.cpp

128 lines
2.9 KiB
C++
Raw Normal View History

/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
2015-04-27 09:12:58 +00:00
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#include <gtest/gtest.h>
2016-03-21 22:27:51 +00:00
#include <osquery/dispatcher.h>
namespace osquery {
class DispatcherTests : public testing::Test {
void TearDown() override { Dispatcher::instance().resetStopping(); }
};
TEST_F(DispatcherTests, test_singleton) {
2015-05-04 03:02:01 +00:00
auto& one = Dispatcher::instance();
auto& two = Dispatcher::instance();
EXPECT_EQ(&one, &two);
}
2015-02-04 03:55:16 +00:00
class TestRunnable : public InternalRunnable {
public:
explicit TestRunnable() {}
virtual void start() override {
++i;
}
void reset() {
i = 0;
}
size_t count() {
return i;
}
private:
static std::atomic<size_t> i;
};
std::atomic<size_t> TestRunnable::i{0};
TEST_F(DispatcherTests, test_service_count) {
auto runnable = std::make_shared<TestRunnable>();
auto service_count = Dispatcher::instance().serviceCount();
// The service exits after incrementing.
auto s = Dispatcher::addService(runnable);
EXPECT_TRUE(s);
// Wait for the service to stop.
Dispatcher::joinServices();
// Make sure the service is removed.
EXPECT_EQ(service_count, Dispatcher::instance().serviceCount());
}
TEST_F(DispatcherTests, test_run) {
auto runnable = std::make_shared<TestRunnable>();
runnable->mustRun();
runnable->reset();
// The service exits after incrementing.
Dispatcher::addService(runnable);
Dispatcher::joinServices();
EXPECT_EQ(1U, runnable->count());
EXPECT_TRUE(runnable->hasRun());
// This runnable cannot be executed again.
auto s = Dispatcher::addService(runnable);
EXPECT_FALSE(s);
Dispatcher::joinServices();
EXPECT_EQ(1U, runnable->count());
}
TEST_F(DispatcherTests, test_independent_run) {
// Nothing stops two instances of the same service from running.
auto r1 = std::make_shared<TestRunnable>();
auto r2 = std::make_shared<TestRunnable>();
r1->mustRun();
r2->mustRun();
r1->reset();
Dispatcher::addService(r1);
Dispatcher::addService(r2);
Dispatcher::joinServices();
EXPECT_EQ(2U, r1->count());
}
class BlockingTestRunnable : public InternalRunnable {
public:
explicit BlockingTestRunnable() {}
virtual void start() override {
// Wow that's a long sleep!
pauseMilli(100 * 1000);
}
};
TEST_F(DispatcherTests, test_interruption) {
auto r1 = std::make_shared<BlockingTestRunnable>();
r1->mustRun();
Dispatcher::addService(r1);
// This service would normally wait for 100 seconds.
r1->interrupt();
Dispatcher::joinServices();
EXPECT_TRUE(r1->hasRun());
}
TEST_F(DispatcherTests, test_stop_dispatcher) {
Dispatcher::stopServices();
auto r1 = std::make_shared<TestRunnable>();
auto s = Dispatcher::addService(r1);
EXPECT_FALSE(s);
}
}