| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -513,6 +513,7 @@ class EventSubscriberPlugin : public Plugin { | |||
| 513 | 513 | FRIEND_TEST(EventsDatabaseTests, test_record_indexing); | |
| 514 | 514 | FRIEND_TEST(EventsDatabaseTests, test_record_range); | |
| 515 | 515 | FRIEND_TEST(EventsDatabaseTests, test_record_expiration); | |
| 516 | + FRIEND_TEST(EventsDatabaseTests, test_gentable); | ||
| 516 | 517 | friend class BenchmarkEventSubscriber; | |
| 517 | 518 | }; | |
| 518 | 519 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -141,8 +141,8 @@ std::set<std::string> EventSubscriberPlugin::getIndexes(EventTime start, | |||
| 141 | 141 | ||
| 142 | 142 | std::string time_list; | |
| 143 | 143 | auto list_type = boost::lexical_cast<std::string>(size); | |
| 144 | - auto status = db->Get(kEvents, index_key + "." + list_type, time_list); | ||
| 145 | - if (time_list.length() == 0) { | ||
| 144 | + db->Get(kEvents, index_key + "." + list_type, time_list); | ||
| 145 | + if (time_list.empty()) { | ||
| 146 | 146 | // No events in this binning size. | |
| 147 | 147 | return indexes; | |
| 148 | 148 | } | |
@@ -186,6 +186,7 @@ std::set<std::string> EventSubscriberPlugin::getIndexes(EventTime start, | |||
| 186 | 186 | size_t bin_stop = size * (step + 1); | |
| 187 | 187 | if (expire_events_ && expire_time_ > 0) { | |
| 188 | 188 | if (bin_stop <= expire_time_) { | |
| 189 | + // This entire bin will be expired. | ||
| 189 | 190 | expirations.push_back(bin); | |
| 190 | 191 | } else if (bin_start < expire_time_) { | |
| 191 | 192 | expireRecords(list_type, bin, false); | |
@@ -200,11 +201,11 @@ std::set<std::string> EventSubscriberPlugin::getIndexes(EventTime start, | |||
| 200 | 201 | } | |
| 201 | 202 | ||
| 202 | 203 | // Rewrite the index lists and delete each expired item. | |
| 203 | - if (expirations.size() > 0) { | ||
| 204 | + if (!expirations.empty()) { | ||
| 204 | 205 | expireIndexes(list_type, all_bins, expirations); | |
| 205 | 206 | } | |
| 206 | 207 | ||
| 207 | - if (bins.size() != 0) { | ||
| 208 | + if (!bins.empty()) { | ||
| 208 | 209 | // If more precision was achieved though this list's binning. | |
| 209 | 210 | local_start = timeFromRecord(bins.front()) * size; | |
| 210 | 211 | start_max = (local_start < start_max) ? local_start : start_max; | |
@@ -286,11 +287,8 @@ std::vector<EventRecord> EventSubscriberPlugin::getRecords( | |||
| 286 | 287 | std::vector<std::string> bin_records; | |
| 287 | 288 | { | |
| 288 | 289 | std::string record_value; | |
| 289 | - if (!db->Get(kEvents, record_key + "." + index, record_value).ok()) { | ||
| 290 | - return records; | ||
| 291 | - } | ||
| 292 | - | ||
| 293 | - if (record_value.length() == 0) { | ||
| 290 | + db->Get(kEvents, record_key + "." + index, record_value); | ||
| 291 | + if (record_value.empty()) { | ||
| 294 | 292 | // There are actually no events in this bin, interesting error case. | |
| 295 | 293 | continue; | |
| 296 | 294 | } | |
@@ -395,17 +393,9 @@ EventID EventSubscriberPlugin::getEventID() { | |||
| 395 | 393 | ||
| 396 | 394 | QueryData EventSubscriberPlugin::get(EventTime start, EventTime stop) { | |
| 397 | 395 | QueryData results; | |
| 398 | - Status status; | ||
| 399 | - | ||
| 400 | - std::shared_ptr<DBHandle> db = nullptr; | ||
| 401 | - try { | ||
| 402 | - db = DBHandle::getInstance(); | ||
| 403 | - } catch (const std::runtime_error& e) { | ||
| 404 | - LOG(ERROR) << "Cannot retrieve subscriber results database is locked"; | ||
| 405 | - return results; | ||
| 406 | - } | ||
| 407 | 396 | ||
| 408 | 397 | // Get the records for this time range. | |
| 398 | + auto db = DBHandle::getInstance(); | ||
| 409 | 399 | auto indexes = getIndexes(start, stop); | |
| 410 | 400 | auto records = getRecords(indexes); | |
| 411 | 401 | std::string events_key = "data." + dbNamespace(); | |
@@ -421,7 +411,7 @@ QueryData EventSubscriberPlugin::get(EventTime start, EventTime stop) { | |||
| 421 | 411 | std::string data_value; | |
| 422 | 412 | for (const auto& record : mapped_records) { | |
| 423 | 413 | Row r; | |
| 424 | - status = db->Get(kEvents, record, data_value); | ||
| 414 | + auto status = db->Get(kEvents, record, data_value); | ||
| 425 | 415 | if (data_value.length() == 0) { | |
| 426 | 416 | // There is no record here, interesting error case. | |
| 427 | 417 | continue; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -13,13 +13,18 @@ | |||
| 13 | 13 | ||
| 14 | 14 | #include <gtest/gtest.h> | |
| 15 | 15 | ||
| 16 | + #include <osquery/core.h> | ||
| 17 | + #include <osquery/database.h> | ||
| 16 | 18 | #include <osquery/events.h> | |
| 19 | + #include <osquery/flags.h> | ||
| 17 | 20 | #include <osquery/tables.h> | |
| 18 | 21 | ||
| 19 | 22 | #include "osquery/database/db_handle.h" | |
| 20 | 23 | ||
| 21 | 24 | namespace osquery { | |
| 22 | 25 | ||
| 26 | + DECLARE_uint64(events_expiry); | ||
| 27 | + | ||
| 23 | 28 | class EventsDatabaseTests : public ::testing::Test {}; | |
| 24 | 29 | ||
| 25 | 30 | class DBFakeEventPublisher | |
@@ -68,9 +73,10 @@ TEST_F(EventsDatabaseTests, test_record_indexing) { | |||
| 68 | 73 | auto output = boost::algorithm::join(indexes, ", "); | |
| 69 | 74 | EXPECT_EQ(output, "3600.0, 3600.1, 3600.2"); | |
| 70 | 75 | ||
| 71 | - // Restrict range to "most specific". | ||
| 76 | + // Restrict range to "most specific", which is an index by 10. | ||
| 72 | 77 | indexes = sub->getIndexes(0, 5); | |
| 73 | 78 | output = boost::algorithm::join(indexes, ", "); | |
| 79 | + // The order 10, 0th index include results with t = [0, 10). | ||
| 74 | 80 | EXPECT_EQ(output, "10.0"); | |
| 75 | 81 | ||
| 76 | 82 | // Get a mix of indexes for the lower bounding. | |
@@ -79,6 +85,7 @@ TEST_F(EventsDatabaseTests, test_record_indexing) { | |||
| 79 | 85 | EXPECT_EQ(output, "10.0, 10.1, 3600.1, 3600.2, 60.1"); | |
| 80 | 86 | ||
| 81 | 87 | // Rare, but test ONLY intermediate indexes. | |
| 88 | + // Provide an optional third parameter to getIndexes: 1 = 10,(60),3600. | ||
| 82 | 89 | indexes = sub->getIndexes(2, (3 * 3600), 1); | |
| 83 | 90 | output = boost::algorithm::join(indexes, ", "); | |
| 84 | 91 | EXPECT_EQ(output, "60.0, 60.1, 60.120, 60.60"); | |
@@ -148,9 +155,46 @@ TEST_F(EventsDatabaseTests, test_record_expiration) { | |||
| 148 | 155 | EXPECT_EQ(records.size(), 3U); // 11, 61, 3601 | |
| 149 | 156 | ||
| 150 | 157 | // Check that get/deletes did not act on cache. | |
| 158 | + // This implies that RocksDB is flushing the requested delete records. | ||
| 151 | 159 | sub->expire_time_ = 0; | |
| 152 | 160 | indexes = sub->getIndexes(0, 5000); | |
| 153 | 161 | records = sub->getRecords(indexes); | |
| 154 | 162 | EXPECT_EQ(records.size(), 3U); // 11, 61, 3601 | |
| 155 | 163 | } | |
| 164 | + | ||
| 165 | + TEST_F(EventsDatabaseTests, test_gentable) { | ||
| 166 | + auto sub = std::make_shared<DBFakeEventSubscriber>(); | ||
| 167 | + ASSERT_EQ(sub->optimize_time_, 0U); | ||
| 168 | + ASSERT_EQ(sub->expire_time_, 0U); | ||
| 169 | + | ||
| 170 | + sub->testAdd(getUnixTime() - 1); | ||
| 171 | + sub->testAdd(getUnixTime()); | ||
| 172 | + sub->testAdd(getUnixTime() + 1); | ||
| 173 | + | ||
| 174 | + // Test the expire workflow by creating a short expiration time. | ||
| 175 | + FLAGS_events_expiry = 10; | ||
| 176 | + | ||
| 177 | + std::vector<std::string> keys; | ||
| 178 | + scanDatabaseKeys("events", keys); | ||
| 179 | + EXPECT_GT(keys.size(), 10U); | ||
| 180 | + | ||
| 181 | + // Perform a "select" equivalent. | ||
| 182 | + QueryContext context; | ||
| 183 | + auto results = sub->genTable(context); | ||
| 184 | + // Expect all non-expired results: 11, + | ||
| 185 | + EXPECT_EQ(results.size(), 9U); | ||
| 186 | + // The expiration time is now - events_expiry. | ||
| 187 | + EXPECT_GT(sub->expire_time_, getUnixTime() - (FLAGS_events_expiry * 2)); | ||
| 188 | + EXPECT_LT(sub->expire_time_, getUnixTime()); | ||
| 189 | + | ||
| 190 | + results = sub->genTable(context); | ||
| 191 | + EXPECT_EQ(results.size(), 3U); | ||
| 192 | + | ||
| 193 | + results = sub->genTable(context); | ||
| 194 | + EXPECT_EQ(results.size(), 3U); | ||
| 195 | + | ||
| 196 | + keys.clear(); | ||
| 197 | + scanDatabaseKeys("events", keys); | ||
| 198 | + EXPECT_LT(keys.size(), 30U); | ||
| 199 | + } | ||
| 156 | 200 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments