2017-12-19 00:04:06 +00:00
|
|
|
/**
|
2016-02-11 19:48:58 +00:00
|
|
|
* Copyright (c) 2014-present, Facebook, Inc.
|
2014-12-18 18:50:47 +00:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
2017-12-19 00:04:06 +00:00
|
|
|
* This source code is licensed under both the Apache 2.0 license (found in the
|
|
|
|
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
|
|
|
* in the COPYING file in the root directory of this source tree).
|
|
|
|
* You may select, at your option, one of the above-listed licenses.
|
2014-12-18 18:50:47 +00:00
|
|
|
*/
|
2014-07-31 00:35:19 +00:00
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
#include <ctime>
|
|
|
|
#include <deque>
|
|
|
|
|
2014-09-22 21:30:52 +00:00
|
|
|
#include <boost/filesystem/operations.hpp>
|
|
|
|
|
2014-07-31 00:35:19 +00:00
|
|
|
#include <gtest/gtest.h>
|
|
|
|
|
2017-08-20 09:44:38 +00:00
|
|
|
#include <osquery/query.h>
|
|
|
|
|
2016-09-19 23:45:13 +00:00
|
|
|
#include "osquery/tests/test_util.h"
|
2014-07-31 00:35:19 +00:00
|
|
|
|
2014-08-15 07:25:30 +00:00
|
|
|
namespace osquery {
|
2014-07-31 00:35:19 +00:00
|
|
|
|
2016-03-05 17:29:51 +00:00
|
|
|
class QueryTests : public testing::Test {};
|
2014-07-31 00:35:19 +00:00
|
|
|
|
|
|
|
TEST_F(QueryTests, test_private_members) {
|
|
|
|
auto query = getOsqueryScheduledQuery();
|
2015-03-22 21:58:00 +00:00
|
|
|
auto cf = Query("foobar", query);
|
2014-07-31 00:35:19 +00:00
|
|
|
EXPECT_EQ(cf.query_, query);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(QueryTests, test_add_and_get_current_results) {
|
2015-04-27 21:57:04 +00:00
|
|
|
// Test adding a "current" set of results to a scheduled query instance.
|
2014-07-31 00:35:19 +00:00
|
|
|
auto query = getOsqueryScheduledQuery();
|
2015-03-22 21:58:00 +00:00
|
|
|
auto cf = Query("foobar", query);
|
2017-09-07 22:01:15 +00:00
|
|
|
uint64_t counter = 128;
|
|
|
|
auto status = cf.addNewResults(getTestDBExpectedResults(), 0, counter);
|
2015-04-27 21:57:04 +00:00
|
|
|
EXPECT_TRUE(status.ok());
|
|
|
|
EXPECT_EQ(status.toString(), "OK");
|
2017-09-07 22:01:15 +00:00
|
|
|
EXPECT_EQ(counter, 0UL);
|
2015-04-27 21:57:04 +00:00
|
|
|
|
|
|
|
// Simulate results from several schedule runs, calculate differentials.
|
2017-09-07 22:01:15 +00:00
|
|
|
uint64_t expected_counter = counter + 1;
|
2014-07-31 00:35:19 +00:00
|
|
|
for (auto result : getTestDBResultStream()) {
|
2016-03-05 17:29:51 +00:00
|
|
|
// Get the results from the previous query execution (from the DB).
|
2015-04-27 21:57:04 +00:00
|
|
|
QueryData previous_qd;
|
2016-11-06 09:17:04 +00:00
|
|
|
status = cf.getPreviousQueryResults(previous_qd);
|
2015-04-27 21:57:04 +00:00
|
|
|
EXPECT_TRUE(status.ok());
|
|
|
|
EXPECT_EQ(status.toString(), "OK");
|
|
|
|
|
|
|
|
// Add the "current" results and output the differentials.
|
2014-07-31 00:35:19 +00:00
|
|
|
DiffResults dr;
|
2017-09-07 22:01:15 +00:00
|
|
|
counter = 128;
|
|
|
|
auto s = cf.addNewResults(result.second, 0, counter, dr, true);
|
2014-07-31 00:35:19 +00:00
|
|
|
EXPECT_TRUE(s.ok());
|
2017-09-07 22:01:15 +00:00
|
|
|
EXPECT_EQ(counter, expected_counter++);
|
2015-04-27 21:57:04 +00:00
|
|
|
|
|
|
|
// Call the diffing utility directly.
|
|
|
|
DiffResults expected = diff(previous_qd, result.second);
|
2014-07-31 00:35:19 +00:00
|
|
|
EXPECT_EQ(dr, expected);
|
2015-04-27 21:57:04 +00:00
|
|
|
|
|
|
|
// After Query::addNewResults the previous results are now current.
|
2014-07-31 00:35:19 +00:00
|
|
|
QueryData qd;
|
2016-03-05 17:29:51 +00:00
|
|
|
cf.getPreviousQueryResults(qd);
|
2014-07-31 00:35:19 +00:00
|
|
|
EXPECT_EQ(qd, result.second);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-27 21:57:04 +00:00
|
|
|
TEST_F(QueryTests, test_get_query_results) {
|
|
|
|
// Grab an expected set of query data and add it as the previous result.
|
|
|
|
auto encoded_qd = getSerializedQueryDataJSON();
|
2014-07-31 00:35:19 +00:00
|
|
|
auto query = getOsqueryScheduledQuery();
|
2016-03-05 17:29:51 +00:00
|
|
|
auto status = setDatabaseValue(kQueries, "foobar", encoded_qd.first);
|
2015-04-27 21:57:04 +00:00
|
|
|
EXPECT_TRUE(status.ok());
|
|
|
|
|
|
|
|
// Use the Query retrieval API to check the now "previous" result.
|
|
|
|
QueryData previous_qd;
|
2015-03-22 21:58:00 +00:00
|
|
|
auto cf = Query("foobar", query);
|
2016-03-05 17:29:51 +00:00
|
|
|
status = cf.getPreviousQueryResults(previous_qd);
|
2015-04-27 21:57:04 +00:00
|
|
|
EXPECT_TRUE(status.ok());
|
2014-07-31 00:35:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(QueryTests, test_query_name_not_found_in_db) {
|
2015-04-27 21:57:04 +00:00
|
|
|
// Try to retrieve results from a query that has not executed.
|
|
|
|
QueryData previous_qd;
|
2014-07-31 00:35:19 +00:00
|
|
|
auto query = getOsqueryScheduledQuery();
|
2015-03-22 21:58:00 +00:00
|
|
|
auto cf = Query("not_a_real_query", query);
|
2016-03-05 17:29:51 +00:00
|
|
|
auto status = cf.getPreviousQueryResults(previous_qd);
|
2016-09-19 23:45:13 +00:00
|
|
|
EXPECT_FALSE(status.ok());
|
|
|
|
EXPECT_TRUE(previous_qd.empty());
|
2014-07-31 00:35:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(QueryTests, test_is_query_name_in_database) {
|
|
|
|
auto query = getOsqueryScheduledQuery();
|
2015-03-22 21:58:00 +00:00
|
|
|
auto cf = Query("foobar", query);
|
2015-04-27 21:57:04 +00:00
|
|
|
auto encoded_qd = getSerializedQueryDataJSON();
|
2016-03-05 17:29:51 +00:00
|
|
|
auto status = setDatabaseValue(kQueries, "foobar", encoded_qd.first);
|
2015-04-27 21:57:04 +00:00
|
|
|
EXPECT_TRUE(status.ok());
|
|
|
|
// Now test that the query name exists.
|
2016-03-05 17:29:51 +00:00
|
|
|
EXPECT_TRUE(cf.isQueryNameInDatabase());
|
2014-07-31 00:35:19 +00:00
|
|
|
}
|
|
|
|
|
2016-09-19 23:45:13 +00:00
|
|
|
TEST_F(QueryTests, test_query_name_updated) {
|
|
|
|
// Try to retrieve results from a query that has not executed.
|
|
|
|
QueryData previous_qd;
|
|
|
|
auto query = getOsqueryScheduledQuery();
|
|
|
|
auto cf = Query("will_update_query", query);
|
|
|
|
EXPECT_TRUE(cf.isNewQuery());
|
|
|
|
EXPECT_TRUE(cf.isNewQuery());
|
|
|
|
|
|
|
|
DiffResults dr;
|
2017-09-07 22:01:15 +00:00
|
|
|
uint64_t counter = 128;
|
2016-09-19 23:45:13 +00:00
|
|
|
auto results = getTestDBExpectedResults();
|
2017-09-07 22:01:15 +00:00
|
|
|
cf.addNewResults(results, 0, counter, dr);
|
2016-09-19 23:45:13 +00:00
|
|
|
EXPECT_FALSE(cf.isNewQuery());
|
2017-09-07 22:01:15 +00:00
|
|
|
EXPECT_EQ(counter, 0UL);
|
2016-09-19 23:45:13 +00:00
|
|
|
|
|
|
|
query.query += " LIMIT 1";
|
2017-09-07 22:01:15 +00:00
|
|
|
counter = 128;
|
2016-09-19 23:45:13 +00:00
|
|
|
auto cf2 = Query("will_update_query", query);
|
|
|
|
EXPECT_TRUE(cf2.isQueryNameInDatabase());
|
|
|
|
EXPECT_TRUE(cf2.isNewQuery());
|
2017-09-07 22:01:15 +00:00
|
|
|
cf2.addNewResults(results, 0, counter, dr);
|
2016-09-19 23:45:13 +00:00
|
|
|
EXPECT_FALSE(cf2.isNewQuery());
|
2017-09-07 22:01:15 +00:00
|
|
|
EXPECT_EQ(counter, 0UL);
|
2016-09-19 23:45:13 +00:00
|
|
|
}
|
|
|
|
|
2014-07-31 00:35:19 +00:00
|
|
|
TEST_F(QueryTests, test_get_stored_query_names) {
|
|
|
|
auto query = getOsqueryScheduledQuery();
|
2015-03-22 21:58:00 +00:00
|
|
|
auto cf = Query("foobar", query);
|
2015-04-27 21:57:04 +00:00
|
|
|
auto encoded_qd = getSerializedQueryDataJSON();
|
2016-03-05 17:29:51 +00:00
|
|
|
auto status = setDatabaseValue(kQueries, "foobar", encoded_qd.first);
|
2015-04-27 21:57:04 +00:00
|
|
|
EXPECT_TRUE(status.ok());
|
|
|
|
|
|
|
|
// Stored query names is a factory method included alongside every query.
|
|
|
|
// It will include the set of query names with existing "previous" results.
|
2016-03-05 17:29:51 +00:00
|
|
|
auto names = cf.getStoredQueryNames();
|
2015-03-22 21:58:00 +00:00
|
|
|
auto in_vector = std::find(names.begin(), names.end(), "foobar");
|
2014-07-31 00:35:19 +00:00
|
|
|
EXPECT_NE(in_vector, names.end());
|
|
|
|
}
|
2014-08-15 07:25:30 +00:00
|
|
|
}
|