mirror of
https://github.com/valitydev/osquery-1.git
synced 2024-11-08 18:33:54 +00:00
c7355b19aa
Summary: Pull Request resolved: https://github.com/facebook/osquery/pull/5452 As suggested in another diff, this diff updates the language we use to describe the osquery licensing terms. We are changing all instances of //This source code is licensed as defined on the LICENSE file found in the root directory of this source tree.// to //This source code is licensed in accordance with the terms specified in the LICENSE file found in the root directory of this source tree.// We accomplish this with a codemod: $ codemod -md xplat/osquery/oss --extensions cpp,h,in,py,sh,mm,ps1 "(.\s+)This source code is licensed as defined on the LICENSE file found in the(.*)root directory of this source tree\." "\1This source code is licensed in accordance with the terms specified in\2the LICENSE file found in the root directory of this source tree." Reviewed By: fmanco Differential Revision: D14131290 fbshipit-source-id: 52c90da342263e2a80f5a678ecd760c19cf7513e
147 lines
3.4 KiB
C++
147 lines
3.4 KiB
C++
/**
|
|
* Copyright (c) 2014-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed in accordance with the terms specified in
|
|
* the LICENSE file found in the root directory of this source tree.
|
|
*/
|
|
|
|
#include <chrono>
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include <osquery/dispatcher.h>
|
|
#include <osquery/utils/status/status.h>
|
|
|
|
namespace osquery {
|
|
|
|
class DispatcherTests : public testing::Test {
|
|
void TearDown() override {
|
|
Dispatcher::instance().resetStopping();
|
|
}
|
|
};
|
|
|
|
TEST_F(DispatcherTests, test_singleton) {
|
|
auto& one = Dispatcher::instance();
|
|
auto& two = Dispatcher::instance();
|
|
EXPECT_EQ(&one, &two);
|
|
}
|
|
|
|
class InternalTestableRunnable : public InternalRunnable {
|
|
public:
|
|
InternalTestableRunnable(const std::string& name) : InternalRunnable(name) {}
|
|
|
|
bool interrupted() override {
|
|
// A small conditional to force-skip an interruption check, used in testing.
|
|
if (!checked_) {
|
|
checked_ = true;
|
|
return false;
|
|
} else {
|
|
return InternalRunnable::interrupted();
|
|
}
|
|
}
|
|
|
|
private:
|
|
/// Testing only, track the interruptible check for interruption.
|
|
bool checked_{false};
|
|
};
|
|
|
|
class TestRunnable : public InternalTestableRunnable {
|
|
public:
|
|
explicit TestRunnable() : InternalTestableRunnable("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->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->reset();
|
|
|
|
Dispatcher::addService(r1);
|
|
Dispatcher::addService(r2);
|
|
Dispatcher::joinServices();
|
|
|
|
EXPECT_EQ(2U, r1->count());
|
|
}
|
|
|
|
class BlockingTestRunnable : public InternalTestableRunnable {
|
|
public:
|
|
explicit BlockingTestRunnable()
|
|
: InternalTestableRunnable("BlockingTestRunnable") {}
|
|
|
|
virtual void start() override {
|
|
// Wow that's a long sleep!
|
|
pause(std::chrono::seconds(100));
|
|
}
|
|
};
|
|
|
|
TEST_F(DispatcherTests, test_interruption) {
|
|
auto r1 = std::make_shared<BlockingTestRunnable>();
|
|
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);
|
|
}
|
|
}
|