2015-01-29 10:13:29 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2014, 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/core.h>
|
2015-01-31 01:52:14 +00:00
|
|
|
#include <osquery/registry.h>
|
2015-02-03 05:21:36 +00:00
|
|
|
#include <osquery/sql.h>
|
2015-01-31 01:52:14 +00:00
|
|
|
|
2015-02-03 05:21:36 +00:00
|
|
|
#include "osquery/sql/virtual_table.h"
|
2015-01-29 10:13:29 +00:00
|
|
|
|
|
|
|
namespace osquery {
|
|
|
|
|
|
|
|
class VirtualTableTests : public testing::Test {};
|
|
|
|
|
|
|
|
// sample plugin used on tests
|
|
|
|
class sampleTablePlugin : public TablePlugin {
|
2015-01-31 01:52:14 +00:00
|
|
|
private:
|
2015-02-11 03:18:56 +00:00
|
|
|
TableColumns columns() const {
|
2015-01-31 01:52:14 +00:00
|
|
|
return {
|
|
|
|
{"foo", "INTEGER"}, {"bar", "TEXT"},
|
|
|
|
};
|
2015-01-29 10:13:29 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-01-29 16:38:20 +00:00
|
|
|
TEST_F(VirtualTableTests, test_tableplugin_columndefinition) {
|
2015-02-01 11:32:18 +00:00
|
|
|
auto table = std::make_shared<sampleTablePlugin>();
|
2015-09-23 18:03:24 +00:00
|
|
|
EXPECT_EQ("(`foo` INTEGER, `bar` TEXT)", table->columnDefinition());
|
2015-01-29 16:38:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(VirtualTableTests, test_sqlite3_attach_vtable) {
|
2015-02-01 11:32:18 +00:00
|
|
|
auto table = std::make_shared<sampleTablePlugin>();
|
|
|
|
table->setName("sample");
|
2015-04-27 09:12:58 +00:00
|
|
|
|
|
|
|
// Request a managed "connection".
|
|
|
|
// This will be a single (potentially locked) instance or a transient
|
|
|
|
// SQLite database if there is contention and a lock was not requested.
|
2015-02-11 22:27:19 +00:00
|
|
|
auto dbc = SQLiteDBManager::get();
|
2015-01-31 01:52:14 +00:00
|
|
|
|
|
|
|
// Virtual tables require the registry/plugin API to query tables.
|
2015-05-21 08:22:00 +00:00
|
|
|
auto status = attachTableInternal("failed_sample", "(foo INTEGER)", dbc.db());
|
2015-02-23 05:56:52 +00:00
|
|
|
EXPECT_EQ(status.getCode(), SQLITE_ERROR);
|
2015-01-31 01:52:14 +00:00
|
|
|
|
|
|
|
// The table attach will complete only when the table name is registered.
|
2015-01-31 08:25:51 +00:00
|
|
|
Registry::add<sampleTablePlugin>("table", "sample");
|
2015-02-23 05:56:52 +00:00
|
|
|
PluginResponse response;
|
|
|
|
status = Registry::call("table", "sample", {{"action", "columns"}}, response);
|
|
|
|
EXPECT_TRUE(status.ok());
|
|
|
|
|
|
|
|
// Use the table name, plugin-generated schema to attach.
|
2015-05-21 08:22:00 +00:00
|
|
|
status = attachTableInternal("sample", columnDefinition(response), dbc.db());
|
2015-02-23 05:56:52 +00:00
|
|
|
EXPECT_EQ(status.getCode(), SQLITE_OK);
|
2015-01-31 01:52:14 +00:00
|
|
|
|
2015-01-29 16:38:20 +00:00
|
|
|
std::string q = "SELECT sql FROM sqlite_temp_master WHERE tbl_name='sample';";
|
2015-02-03 05:21:36 +00:00
|
|
|
QueryData results;
|
2015-02-23 05:56:52 +00:00
|
|
|
status = queryInternal(q, results, dbc.db());
|
2015-09-23 18:03:24 +00:00
|
|
|
EXPECT_EQ(
|
|
|
|
"CREATE VIRTUAL TABLE sample USING sample(`foo` INTEGER, `bar` TEXT)",
|
|
|
|
results[0]["sql"]);
|
2015-01-29 16:38:20 +00:00
|
|
|
}
|
2015-07-15 02:09:55 +00:00
|
|
|
|
|
|
|
TEST_F(VirtualTableTests, test_sqlite3_table_joins) {
|
|
|
|
// Get a database connection.
|
|
|
|
auto dbc = SQLiteDBManager::get();
|
|
|
|
|
|
|
|
QueryData results;
|
|
|
|
// Run a query with a join within.
|
|
|
|
std::string statement =
|
|
|
|
"SELECT p.pid FROM osquery_info oi, processes p WHERE oi.pid=p.pid";
|
|
|
|
auto status = queryInternal(statement, results, dbc.db());
|
|
|
|
EXPECT_TRUE(status.ok());
|
|
|
|
EXPECT_EQ(results.size(), 1);
|
|
|
|
}
|
2015-01-29 10:13:29 +00:00
|
|
|
}
|