2015-01-12 18:02:44 +00:00
|
|
|
/*
|
2016-02-11 19:48:58 +00:00
|
|
|
* Copyright (c) 2014-present, Facebook, Inc.
|
2015-01-12 18:02:44 +00:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This source code is licensed under the BSD-style license found in the
|
2015-01-22 21:57:14 +00:00
|
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
2015-01-12 18:02:44 +00:00
|
|
|
* 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);
|
2015-10-17 00:18:35 +00:00
|
|
|
EXPECT_EQ(cl.constraints_.size(), 1U);
|
2015-01-12 18:02:44 +00:00
|
|
|
|
|
|
|
constraint = Constraint(EQUALS);
|
|
|
|
constraint.expr = "some_other";
|
|
|
|
cl.add(constraint);
|
|
|
|
|
|
|
|
constraint = Constraint(GREATER_THAN);
|
|
|
|
constraint.expr = "more_than";
|
|
|
|
cl.add(constraint);
|
2015-10-17 00:18:35 +00:00
|
|
|
EXPECT_EQ(cl.constraints_.size(), 3U);
|
2015-01-12 18:02:44 +00:00
|
|
|
|
|
|
|
auto all_equals = cl.getAll(EQUALS);
|
2015-10-17 00:18:35 +00:00
|
|
|
EXPECT_EQ(all_equals.size(), 2U);
|
2015-01-12 18:02:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(TablesTests, test_constraint_matching) {
|
|
|
|
struct ConstraintList cl;
|
|
|
|
// An empty constraint list has expectations.
|
|
|
|
EXPECT_FALSE(cl.exists());
|
2015-05-29 20:47:04 +00:00
|
|
|
EXPECT_FALSE(cl.exists(GREATER_THAN));
|
2015-01-12 18:02:44 +00:00
|
|
|
EXPECT_TRUE(cl.notExistsOrMatches("some"));
|
|
|
|
|
|
|
|
auto constraint = Constraint(EQUALS);
|
|
|
|
constraint.expr = "some";
|
|
|
|
cl.add(constraint);
|
|
|
|
|
2015-05-29 20:47:04 +00:00
|
|
|
// Test existence checks based on flags.
|
2015-01-12 18:02:44 +00:00
|
|
|
EXPECT_TRUE(cl.exists());
|
2015-05-29 20:47:04 +00:00
|
|
|
EXPECT_TRUE(cl.exists(EQUALS));
|
|
|
|
EXPECT_TRUE(cl.exists(EQUALS | LESS_THAN));
|
|
|
|
EXPECT_FALSE(cl.exists(LESS_THAN));
|
|
|
|
|
2015-01-12 18:02:44 +00:00
|
|
|
EXPECT_TRUE(cl.notExistsOrMatches("some"));
|
|
|
|
EXPECT_TRUE(cl.matches("some"));
|
|
|
|
EXPECT_FALSE(cl.notExistsOrMatches("not_some"));
|
|
|
|
|
|
|
|
struct ConstraintList cl2;
|
2015-11-09 09:19:45 +00:00
|
|
|
cl2.affinity = INTEGER_TYPE;
|
2015-01-12 18:02:44 +00:00
|
|
|
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;
|
|
|
|
|
2016-02-17 07:10:08 +00:00
|
|
|
cm["path"].add(Constraint(EQUALS, "some"));
|
2015-01-12 18:02:44 +00:00
|
|
|
|
2015-03-26 23:18:28 +00:00
|
|
|
// If a constraint list exists for a map key, normal constraints apply.
|
2015-01-12 18:02:44 +00:00
|
|
|
EXPECT_TRUE(cm["path"].matches("some"));
|
2015-03-26 23:18:28 +00:00
|
|
|
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"));
|
2015-01-12 18:02:44 +00:00
|
|
|
}
|
2015-11-09 02:31:50 +00:00
|
|
|
|
|
|
|
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));
|
|
|
|
}
|
2015-01-12 18:02:44 +00:00
|
|
|
}
|