osquery-1/osquery/core/tests/tables_tests.cpp
2016-02-21 22:40:37 -08:00

168 lines
4.8 KiB
C++

/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* 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>
#include <osquery/tables.h>
namespace osquery {
class TablesTests : public testing::Test {};
TEST_F(TablesTests, test_constraint) {
auto constraint = Constraint(EQUALS);
constraint.expr = "none";
EXPECT_EQ(constraint.op, EQUALS);
EXPECT_EQ(constraint.expr, "none");
}
TEST_F(TablesTests, test_constraint_list) {
struct ConstraintList cl;
auto constraint = Constraint(EQUALS);
constraint.expr = "some";
// The constraint list is a simple struct.
cl.add(constraint);
EXPECT_EQ(cl.constraints_.size(), 1U);
constraint = Constraint(EQUALS);
constraint.expr = "some_other";
cl.add(constraint);
constraint = Constraint(GREATER_THAN);
constraint.expr = "more_than";
cl.add(constraint);
EXPECT_EQ(cl.constraints_.size(), 3U);
auto all_equals = cl.getAll(EQUALS);
EXPECT_EQ(all_equals.size(), 2U);
}
TEST_F(TablesTests, test_constraint_matching) {
struct ConstraintList cl;
// An empty constraint list has expectations.
EXPECT_FALSE(cl.exists());
EXPECT_FALSE(cl.exists(GREATER_THAN));
EXPECT_TRUE(cl.notExistsOrMatches("some"));
auto constraint = Constraint(EQUALS);
constraint.expr = "some";
cl.add(constraint);
// Test existence checks based on flags.
EXPECT_TRUE(cl.exists());
EXPECT_TRUE(cl.exists(EQUALS));
EXPECT_TRUE(cl.exists(EQUALS | LESS_THAN));
EXPECT_FALSE(cl.exists(LESS_THAN));
EXPECT_TRUE(cl.notExistsOrMatches("some"));
EXPECT_TRUE(cl.matches("some"));
EXPECT_FALSE(cl.notExistsOrMatches("not_some"));
struct ConstraintList cl2;
cl2.affinity = INTEGER_TYPE;
constraint = Constraint(LESS_THAN);
constraint.expr = "1000";
cl2.add(constraint);
constraint = Constraint(GREATER_THAN);
constraint.expr = "1";
cl2.add(constraint);
// Test both SQL-provided string types.
EXPECT_TRUE(cl2.matches("10"));
// ...and the type literal.
EXPECT_TRUE(cl2.matches(10));
// Test operator lower bounds.
EXPECT_FALSE(cl2.matches(0));
EXPECT_FALSE(cl2.matches(1));
// Test operator upper bounds.
EXPECT_FALSE(cl2.matches(1000));
EXPECT_FALSE(cl2.matches(1001));
// Now test inclusive bounds.
struct ConstraintList cl3;
constraint = Constraint(LESS_THAN_OR_EQUALS);
constraint.expr = "1000";
cl3.add(constraint);
constraint = Constraint(GREATER_THAN_OR_EQUALS);
constraint.expr = "1";
cl3.add(constraint);
EXPECT_FALSE(cl3.matches(1001));
EXPECT_TRUE(cl3.matches(1000));
EXPECT_FALSE(cl3.matches(0));
EXPECT_TRUE(cl3.matches(1));
}
TEST_F(TablesTests, test_constraint_map) {
ConstraintMap cm;
cm["path"].add(Constraint(EQUALS, "some"));
// If a constraint list exists for a map key, normal constraints apply.
EXPECT_TRUE(cm["path"].matches("some"));
EXPECT_FALSE(cm["path"].matches("not_some"));
// If a constraint list does not exist, then all checks will match.
// If there is no predicate clause then all results will match.
EXPECT_TRUE(cm["not_path"].matches("some"));
EXPECT_TRUE(cm["not_path"].notExistsOrMatches("some"));
EXPECT_FALSE(cm["not_path"].exists());
EXPECT_FALSE(cm["not_path"].existsAndMatches("some"));
// And of the column has constraints:
EXPECT_TRUE(cm["path"].notExistsOrMatches("some"));
EXPECT_FALSE(cm["path"].notExistsOrMatches("not_some"));
EXPECT_TRUE(cm["path"].exists());
EXPECT_TRUE(cm["path"].existsAndMatches("some"));
}
class TestTablePlugin : public TablePlugin {
public:
void testSetCache(size_t step, size_t interval) {
QueryData r;
setCache(step, interval, r);
}
bool testIsCached(size_t interval) { return isCached(interval); }
};
TEST_F(TablesTests, test_caching) {
TestTablePlugin test;
// By default the interval and step is 0, so a step of 5 will not be cached.
EXPECT_FALSE(test.testIsCached(5));
TablePlugin::kCacheInterval = 5;
TablePlugin::kCacheStep = 1;
EXPECT_FALSE(test.testIsCached(5));
// Set the current time to 1, and the interval at 5.
test.testSetCache(TablePlugin::kCacheStep, TablePlugin::kCacheInterval);
// Time at 1 is cached for an interval of 5, so at time 5 the cache is fresh.
EXPECT_TRUE(test.testIsCached(5));
// 6 is the end of the cache, it is not fresh.
EXPECT_FALSE(test.testIsCached(6));
// 7 is past the cache, it is not fresh.
EXPECT_FALSE(test.testIsCached(7));
// Set the time at now to 2.
TablePlugin::kCacheStep = 2;
test.testSetCache(TablePlugin::kCacheStep, TablePlugin::kCacheInterval);
EXPECT_TRUE(test.testIsCached(5));
// Now 6 is within the freshness of 2 + 5.
EXPECT_TRUE(test.testIsCached(6));
EXPECT_FALSE(test.testIsCached(7));
}
}