tables: Add constraints and testing (#6105)

Co-Authored-By: Teddy Reed <teddy@casualhacking.io>
This commit is contained in:
seph 2019-12-12 20:45:15 -05:00 committed by Teddy Reed
parent df20cb120a
commit a73ffad3bf
28 changed files with 242 additions and 249 deletions

View File

@ -29,15 +29,15 @@ namespace tables {
/// Number of fields when splitting metadata and info.
const size_t kNumFields = 2;
const std::set<std::string> kPythonPath = {
"/usr/local/lib/python2.7/dist-packages/",
"/usr/local/lib/python2.7/site-packages/",
"/usr/lib/python2.7/dist-packages/",
"/usr/lib/python2.7/site-packages/",
"/Library/Python/2.7/site-packages/",
"/usr/local/lib/python%/dist-packages",
"/usr/local/lib/python%/site-packages",
"/usr/lib/python%/dist-packages",
"/usr/lib/python%/site-packages",
"/Library/Python/%/site-packages",
};
const std::set<std::string> kDarwinPythonPath = {
"/System/Library/Frameworks/Python.framework/Versions/",
"/System/Library/Frameworks/Python.framework/Versions",
};
const std::string kWinPythonInstallKey =
@ -127,7 +127,13 @@ QueryData genPythonPackages(QueryContext& context) {
context.constraints.at("directory").exists(EQUALS)) {
paths = context.constraints["directory"].getAll(EQUALS);
} else {
paths = kPythonPath;
for (const auto& path : kPythonPath) {
std::vector<std::string> sites;
resolveFilePattern(path, sites);
for (const auto& site : sites) {
paths.insert(site);
}
}
}
for (const auto& key : paths) {
genSiteDirectories(key, results);
@ -148,7 +154,7 @@ QueryData genPythonPackages(QueryContext& context) {
}
auto complete = version + "lib/python" +
version_path.filename().string() + "/site-packages/";
version_path.filename().string() + "/site-packages";
genSiteDirectories(complete, results);
}
}

View File

@ -4,10 +4,10 @@ schema([
Column("time", BIGINT, "Time at which the carve was kicked off"),
Column("sha256", TEXT, "A SHA256 sum of the carved archive"),
Column("size", INTEGER, "Size of the carved archive"),
Column("path", TEXT, "The path of the requested carve"),
Column("path", TEXT, "The path of the requested carve", required=True),
Column("status", TEXT, "Status of the carve, can be STARTING, PENDING, SUCCESS, or FAILED"),
Column("carve_guid", TEXT, "Identifying value of the carve session"),
Column("carve", INTEGER, "Set this value to '1' to start a file carve")
Column("carve_guid", TEXT, "Identifying value of the carve session", index=True),
Column("carve", INTEGER, "Set this value to '1' to start a file carve", additional=True)
])
attributes(user_data=True)
implementation("forensic/carves@genCarves")

View File

@ -2,7 +2,7 @@ table_name("apps")
description("OS X applications installed in known search paths (e.g., /Applications).")
schema([
Column("name", TEXT, "Name of the Name.app folder"),
Column("path", TEXT, "Absolute and full Name.app path"),
Column("path", TEXT, "Absolute and full Name.app path", index=True),
Column("bundle_executable", TEXT,
"Info properties CFBundleExecutable label"),
Column("bundle_identifier", TEXT,

View File

@ -4,19 +4,19 @@ description("Queries the Apple System Log data structure for system events.")
# Columns pulled from asl.h
# Descriptions mostly as retrieved from asl.h, some with clarifications
schema([
Column("time", INTEGER, "Unix timestamp. Set automatically"),
Column("time_nano_sec", INTEGER, "Nanosecond time."),
Column("host", TEXT, "Sender's address (set by the server)."),
Column("sender", TEXT, "Sender's identification string. Default is process name."),
Column("facility", TEXT, "Sender's facility. Default is 'user'."),
Column("pid", INTEGER, "Sending process ID encoded as a string. Set automatically."),
Column("time", INTEGER, "Unix timestamp. Set automatically", additional=True),
Column("time_nano_sec", INTEGER, "Nanosecond time.", additional=True),
Column("host", TEXT, "Sender's address (set by the server).", additional=True),
Column("sender", TEXT, "Sender's identification string. Default is process name.", additional=True),
Column("facility", TEXT, "Sender's facility. Default is 'user'.", additional=True),
Column("pid", INTEGER, "Sending process ID encoded as a string. Set automatically.", additional=True),
# UID and GID of 4294967294 have been encountered
Column("gid", BIGINT, "GID that sent the log message (set by the server)."),
Column("uid", BIGINT, "UID that sent the log message (set by the server)."),
Column("level", INTEGER, "Log level number. See levels in asl.h."),
Column("message", TEXT, "Message text."),
Column("ref_pid", INTEGER, "Reference PID for messages proxied by launchd"),
Column("ref_proc", TEXT, "Reference process for messages proxied by launchd"),
Column("gid", BIGINT, "GID that sent the log message (set by the server).", additional=True),
Column("uid", BIGINT, "UID that sent the log message (set by the server).", additional=True),
Column("level", INTEGER, "Log level number. See levels in asl.h.", additional=True),
Column("message", TEXT, "Message text.", additional=True),
Column("ref_pid", INTEGER, "Reference PID for messages proxied by launchd", additional=True),
Column("ref_proc", TEXT, "Reference process for messages proxied by launchd", additional=True),
# Gather anything extra into the "extra" column
Column("extra", TEXT, "Extra columns, in JSON format. Queries against this column are performed entirely in SQLite, so do not benefit from efficient querying via asl.h."),
])

View File

@ -1,11 +1,11 @@
table_name("running_apps")
description("OSX applications currently running on the host system.")
description("macOS applications currently running on the host system.")
schema([
Column("pid", INTEGER, "The pid of the application"),
Column("pid", INTEGER, "The pid of the application", index=True),
Column("bundle_identifier", TEXT, "The bundle identifier of the application"),
Column("is_active", INTEGER, "1 if the application is in focus, 0 otherwise")
Column("is_active", INTEGER, "1 if the application is in focus, 0 otherwise", additional=True)
])
implementation("running_apps@genRunningApps")

View File

@ -15,7 +15,7 @@ schema([
Column("subject_key_id", TEXT, "SKID an optionally included SHA1"),
Column("authority_key_id", TEXT, "AKID an optionally included SHA1"),
Column("sha1", TEXT, "SHA1 hash of the raw certificate contents"),
Column("path", TEXT, "Path to Keychain or PEM bundle"),
Column("path", TEXT, "Path to Keychain or PEM bundle", additional=True),
Column("serial", TEXT, "Certificate serial number"),
])

View File

@ -3,7 +3,7 @@ description("Docker container mounts.")
schema([
Column("id", TEXT, "Container ID", index=True),
Column("type", TEXT, "Type of mount (bind, volume)"),
Column("name", TEXT, "Optional mount name"),
Column("name", TEXT, "Optional mount name", index=True),
Column("source", TEXT, "Source path on host"),
Column("destination", TEXT, "Destination path inside container"),
Column("driver", TEXT, "Driver providing the mount"),
@ -16,4 +16,4 @@ examples([
"select * from docker_container_mounts",
"select * from docker_container_mounts where id = '1234567890abcdef'",
"select * from docker_container_mounts where id = '11b2399e1426d906e62a0c357650e363426d6c56dbe2f35cbaa9b452250e3355'"
])
])

View File

@ -2,7 +2,7 @@ table_name("docker_container_networks")
description("Docker container networks.")
schema([
Column("id", TEXT, "Container ID", index=True),
Column("name", TEXT, "Network name"),
Column("name", TEXT, "Network name", index=True),
Column("network_id", TEXT, "Network ID"),
Column("endpoint_id", TEXT, "Endpoint ID"),
Column("gateway", TEXT, "Gateway"),
@ -18,4 +18,4 @@ examples([
"select * from docker_container_networks",
"select * from docker_container_networks where id = '1234567890abcdef'",
"select * from docker_container_networks where id = '11b2399e1426d906e62a0c357650e363426d6c56dbe2f35cbaa9b452250e3355'"
])
])

View File

@ -1,7 +1,7 @@
table_name("docker_container_ports")
description("Docker container ports.")
schema([
Column("id", TEXT, "Container ID", index=True),
Column("id", TEXT, "Container ID", additional=True),
Column("type", TEXT, "Protocol (tcp, udp)"),
Column("port", INTEGER, "Port inside the container"),
Column("host_ip", TEXT, "Host IP address on which public port is listening"),
@ -12,4 +12,4 @@ examples([
"select * from docker_container_ports",
"select * from docker_container_ports where id = '1234567890abcdef'",
"select * from docker_container_ports where id = '11b2399e1426d906e62a0c357650e363426d6c56dbe2f35cbaa9b452250e3355'"
])
])

View File

@ -3,7 +3,7 @@ description("Docker container processes.")
schema([
Column("id", TEXT, "Container ID", index=True, required=True),
Column("pid", BIGINT, "Process ID"),
Column("name", TEXT, "The process path or shorthand argv[0]"),
Column("name", TEXT, "The process path or shorthand argv[0]", index=True),
Column("cmdline", TEXT, "Complete argv"),
Column("state", TEXT, "Process state"),
Column("uid", BIGINT, "User ID"),
@ -31,4 +31,4 @@ implementation("applications/docker@genContainerProcesses")
examples([
"select * from docker_container_processes where id = '1234567890abcdef'",
"select * from docker_container_processes where id = '11b2399e1426d906e62a0c357650e363426d6c56dbe2f35cbaa9b452250e3355'"
])
])

View File

@ -2,7 +2,7 @@ table_name("docker_container_stats")
description("Docker container statistics. Queries on this table take at least one second.")
schema([
Column("id", TEXT, "Container ID", index=True, required=True),
Column("name", TEXT, "Container name"),
Column("name", TEXT, "Container name", index=True),
Column("pids", INTEGER, "Number of processes"),
Column("read", BIGINT, "UNIX time when stats were read"),
Column("preread", BIGINT, "UNIX time when stats were last read"),
@ -30,4 +30,4 @@ implementation("applications/docker@genContainerStats")
examples([
"select * from docker_container_stats where id = 'de8cfdc74c850967'",
"select * from docker_container_stats where id = 'de8cfdc74c850967fd3832e128f4d12e2d5476a4aea282734bfb7e57f66fce2f'"
])
])

View File

@ -2,7 +2,7 @@ table_name("docker_containers")
description("Docker containers information.")
schema([
Column("id", TEXT, "Container ID", index=True),
Column("name", TEXT, "Container name"),
Column("name", TEXT, "Container name", index=True),
Column("image", TEXT, "Docker image (name) used to launch this container"),
Column("image_id", TEXT, "Docker image ID"),
Column("command", TEXT, "Command with arguments"),

View File

@ -9,7 +9,7 @@ schema([
Column("interface", TEXT, "Route local interface"),
Column("mtu", INTEGER, "Maximum Transmission Unit for the route"),
Column("metric", INTEGER, "Cost of route. Lowest is preferred"),
Column("type", TEXT, "Type of route"),
Column("type", TEXT, "Type of route", additional=True),
])
extended_schema(POSIX, [

View File

@ -1,10 +1,10 @@
table_name("ntfs_acl_permissions")
description("Retrieve NTFS ACL permission information for files and directories.")
schema([
Column("path", TEXT, "Path to the file or directory."),
Column("path", TEXT, "Path to the file or directory.", required=True, index=True),
Column("type", TEXT, "Type of access mode for the access control entry."),
Column("principal", TEXT, "User or group to which the ACE applies."),
Column("access", TEXT, "Specific permissions that indicate the rights described by the ACE."),
Column("inherited_from", TEXT, "The inheritance policy of the ACE."),
])
implementation("system/windows/ntfs_acl_permissions@genNtfsAclPerms")
implementation("system/windows/ntfs_acl_permissions@genNtfsAclPerms")

View File

@ -22,38 +22,37 @@ class apps : public testing::Test {
};
TEST_F(apps, test_sanity) {
// 1. Query data
ValidationMap row_map = {
{"name", NormalType},
{"path", NormalType},
{"bundle_executable", NormalType},
{"bundle_identifier", NormalType},
{"bundle_name", NormalType},
{"bundle_short_version", NormalType},
{"bundle_version", NormalType},
{"bundle_package_type", NormalType},
{"environment", NormalType},
{"element", NormalType},
{"compiler", NormalType},
{"development_region", NormalType},
{"display_name", NormalType},
{"info_string", NormalType},
{"minimum_system_version", NormalType},
{"category", NormalType},
{"applescript_enabled", NormalType},
{"copyright", NormalType},
{"last_opened_time", NormalType},
};
auto const data = execute_query("select * from apps");
// 2. Check size before validation
// ASSERT_GE(data.size(), 0ul);
// ASSERT_EQ(data.size(), 1ul);
// ASSERT_EQ(data.size(), 0ul);
// 3. Build validation map
// See helper.h for avaialbe flags
// Or use custom DataCheck object
// ValidationMap row_map = {
// {"name", NormalType}
// {"path", NormalType}
// {"bundle_executable", NormalType}
// {"bundle_identifier", NormalType}
// {"bundle_name", NormalType}
// {"bundle_short_version", NormalType}
// {"bundle_version", NormalType}
// {"bundle_package_type", NormalType}
// {"environment", NormalType}
// {"element", NormalType}
// {"compiler", NormalType}
// {"development_region", NormalType}
// {"display_name", NormalType}
// {"info_string", NormalType}
// {"minimum_system_version", NormalType}
// {"category", NormalType}
// {"applescript_enabled", NormalType}
// {"copyright", NormalType}
// {"last_opened_time", NormalType}
//}
// 4. Perform validation
// validate_rows(data, row_map);
ASSERT_FALSE(data.empty());
validate_rows(data, row_map);
// Not totally sure what apps we expect on the VMs used by CI.
auto const data1 = execute_query(
"select * from apps where path = '/Applications/Preview.app'");
ASSERT_EQ(data1.size(), 1ul);
validate_rows(data1, row_map);
}
} // namespace table_tests

View File

@ -22,32 +22,25 @@ class asl : public testing::Test {
};
TEST_F(asl, test_sanity) {
// 1. Query data
auto const data = execute_query("select * from asl");
// 2. Check size before validation
// ASSERT_GE(data.size(), 0ul);
// ASSERT_EQ(data.size(), 1ul);
// ASSERT_EQ(data.size(), 0ul);
// 3. Build validation map
// See helper.h for avaialbe flags
// Or use custom DataCheck object
// ValidationMap row_map = {
// {"time", IntType}
// {"time_nano_sec", IntType}
// {"host", NormalType}
// {"sender", NormalType}
// {"facility", NormalType}
// {"pid", IntType}
// {"gid", IntType}
// {"uid", IntType}
// {"level", IntType}
// {"message", NormalType}
// {"ref_pid", IntType}
// {"ref_proc", NormalType}
// {"extra", NormalType}
//}
// 4. Perform validation
// validate_rows(data, row_map);
ValidationMap row_map = {
{"time", IntType},
{"time_nano_sec", IntType},
{"host", NormalType},
{"sender", NormalType},
{"facility", NormalType},
{"pid", IntType},
{"gid", IntType},
{"uid", IntType},
{"level", IntType},
{"message", NormalType},
{"ref_pid", IntOrEmpty},
{"ref_proc", NormalType},
{"extra", NormalType},
};
auto const data = execute_query("select * from asl limit 1");
ASSERT_FALSE(data.empty());
validate_rows(data, row_map);
}
} // namespace table_tests

View File

@ -22,29 +22,27 @@ class browserPlugins : public testing::Test {
};
TEST_F(browserPlugins, test_sanity) {
// 1. Query data
ValidationMap row_map = {
{"uid", IntType},
{"name", NormalType},
{"identifier", NormalType},
{"version", NormalType},
{"sdk", NormalType},
{"description", NormalType},
{"development_region", NormalType},
{"native", IntType},
{"path", NormalType},
{"disabled", IntType},
};
auto const data = execute_query("select * from browser_plugins");
// 2. Check size before validation
// ASSERT_GE(data.size(), 0ul);
// ASSERT_EQ(data.size(), 1ul);
// ASSERT_EQ(data.size(), 0ul);
// 3. Build validation map
// See helper.h for avaialbe flags
// Or use custom DataCheck object
// ValidationMap row_map = {
// {"uid", IntType}
// {"name", NormalType}
// {"identifier", NormalType}
// {"version", NormalType}
// {"sdk", NormalType}
// {"description", NormalType}
// {"development_region", NormalType}
// {"native", IntType}
// {"path", NormalType}
// {"disabled", IntType}
//}
// 4. Perform validation
// validate_rows(data, row_map);
ASSERT_FALSE(data.empty());
validate_rows(data, row_map);
auto const datauser =
execute_query("select * from browser_plugins where uid = 0");
ASSERT_FALSE(datauser.empty());
validate_rows(datauser, row_map);
}
} // namespace table_tests

View File

@ -23,7 +23,7 @@ class carves : public testing::Test {
TEST_F(carves, test_sanity) {
// 1. Query data
auto const data = execute_query("select * from carves");
auto const data = execute_query("select * from carves where path = ''");
// 2. Check size before validation
// ASSERT_GE(data.size(), 0ul);
// ASSERT_EQ(data.size(), 1ul);

View File

@ -22,35 +22,32 @@ class crashes : public testing::Test {
};
TEST_F(crashes, test_sanity) {
// 1. Query data
auto const data = execute_query("select * from crashes");
// 2. Check size before validation
// ASSERT_GE(data.size(), 0ul);
// ASSERT_EQ(data.size(), 1ul);
// ASSERT_EQ(data.size(), 0ul);
// 3. Build validation map
// See helper.h for avaialbe flags
// Or use custom DataCheck object
// ValidationMap row_map = {
// {"type", NormalType}
// {"pid", IntType}
// {"path", NormalType}
// {"crash_path", NormalType}
// {"identifier", NormalType}
// {"version", NormalType}
// {"parent", IntType}
// {"responsible", NormalType}
// {"uid", IntType}
// {"datetime", NormalType}
// {"crashed_thread", IntType}
// {"stack_trace", NormalType}
// {"exception_type", NormalType}
// {"exception_codes", NormalType}
// {"exception_notes", NormalType}
// {"registers", NormalType}
//}
// 4. Perform validation
// validate_rows(data, row_map);
ValidationMap row_map = {
{"type", NormalType},
{"pid", IntType},
{"path", NormalType},
{"crash_path", NormalType},
{"identifier", NormalType},
{"version", NormalType},
{"parent", IntType},
{"responsible", NormalType},
{"uid", IntType},
{"datetime", NormalType},
{"crashed_thread", IntType},
{"stack_trace", NormalType},
{"exception_type", NormalType},
{"exception_codes", NormalType},
{"exception_notes", NormalType},
{"registers", NormalType},
};
auto const data = execute_query(
"select crashes.* from users CROSS JOIN crashes "
"USING(uid)");
if (!data.empty()) {
// Lets not assume there are crashes on the host.
validate_rows(data, row_map);
}
}
} // namespace table_tests

View File

@ -203,6 +203,20 @@ bool is_valid_hex(const std::string& value) {
}
bool validate_value_using_flags(const std::string& value, int flags) {
// Early return on EmptyOk
if ((flags & EmptyOk) > 0) {
if (value.length() == 0) {
return true;
}
}
// Early return on NullOk
if ((flags & NullOk)) {
if (value == "null") {
return true;
}
}
if ((flags & NonEmpty) > 0) {
if (value.length() == 0) {
return false;

View File

@ -71,9 +71,12 @@ enum {
SHA256 = 1 << 9,
SHA1 = 1 << 10,
Bool = 1 << 11,
EmptyOk = 1 << 12,
NullOk = 1 << 13,
NonNegativeInt = IntType | NonEmpty | NonNull | (1 << 12),
NonNegativeOrErrorInt = IntType | NonEmpty | NonNull | (1 << 13),
NonEmptyString = NonEmpty | NormalType | NonNull,
IntOrEmpty = IntType | EmptyOk | NullOk,
};
using CustomCheckerType = std::function<bool(const std::string&)>;

View File

@ -22,8 +22,6 @@ class KeychainItemsTest : public testing::Test {
};
TEST_F(KeychainItemsTest, test_sanity) {
auto const data = execute_query("select * from keychain_items");
ASSERT_GT(data.size(), 0ul);
ValidationMap row_map = {
{"label", NormalType},
{"description", NormalType},
@ -38,6 +36,9 @@ TEST_F(KeychainItemsTest, test_sanity) {
"private key"}},
{"path", NonEmptyString},
};
auto const data = execute_query("select * from keychain_items");
ASSERT_FALSE(data.empty());
validate_rows(data, row_map);
}

View File

@ -22,24 +22,18 @@ class ntfsAclPermissions : public testing::Test {
};
TEST_F(ntfsAclPermissions, test_sanity) {
// 1. Query data
auto const data = execute_query("select * from ntfs_acl_permissions");
// 2. Check size before validation
// ASSERT_GE(data.size(), 0ul);
// ASSERT_EQ(data.size(), 1ul);
// ASSERT_EQ(data.size(), 0ul);
// 3. Build validation map
// See helper.h for avaialbe flags
// Or use custom DataCheck object
// ValidationMap row_map = {
// {"path", NormalType}
// {"type", NormalType}
// {"principal", NormalType}
// {"access", NormalType}
// {"inherited_from", NormalType}
//}
// 4. Perform validation
// validate_rows(data, row_map);
ValidationMap row_map = {
{"path", NormalType},
{"type", NormalType},
{"principal", NormalType},
{"access", NormalType},
{"inherited_from", NormalType},
};
auto const data =
execute_query("select * from ntfs_acl_permissions where path = 'C:\\'");
ASSERT_FALSE(data.empty());
validate_rows(data, row_map);
}
} // namespace table_tests

View File

@ -22,26 +22,25 @@ class preferences : public testing::Test {
};
TEST_F(preferences, test_sanity) {
// 1. Query data
ValidationMap row_map = {
{"domain", NormalType},
{"key", NormalType},
{"subkey", NormalType},
{"value", NormalType},
{"forced", IntType},
{"username", NormalType},
{"host", NormalType},
};
auto const data = execute_query("select * from preferences");
// 2. Check size before validation
// ASSERT_GE(data.size(), 0ul);
// ASSERT_EQ(data.size(), 1ul);
// ASSERT_EQ(data.size(), 0ul);
// 3. Build validation map
// See helper.h for avaialbe flags
// Or use custom DataCheck object
// ValidationMap row_map = {
// {"domain", NormalType}
// {"key", NormalType}
// {"subkey", NormalType}
// {"value", NormalType}
// {"forced", IntType}
// {"username", NormalType}
// {"host", NormalType}
//}
// 4. Perform validation
// validate_rows(data, row_map);
ASSERT_FALSE(data.empty());
validate_rows(data, row_map);
auto const datajoin = execute_query(
"select users.username, preferences.* from users CROSS JOIN preferences "
"USING(username) where preferences.domain = 'com.apple.Preferences';");
ASSERT_FALSE(datajoin.empty());
validate_rows(datajoin, row_map);
}
} // namespace table_tests

View File

@ -10,6 +10,7 @@
// Spec file: specs/process_open_sockets.table
#include <osquery/tests/integration/tables/helper.h>
#include <osquery/utils/info/platform_type.h>
namespace osquery {
namespace table_tests {
@ -22,31 +23,27 @@ class processOpenSockets : public testing::Test {
};
TEST_F(processOpenSockets, test_sanity) {
// 1. Query data
ValidationMap row_map = {
{"pid", IntType},
{"fd", IntOrEmpty},
{"socket", IntOrEmpty},
{"family", IntType},
{"protocol", IntType},
{"local_address", NormalType},
{"remote_address", NormalType},
{"local_port", IntType},
{"remote_port", IntType},
{"path", NormalType},
{"state", NormalType},
};
if (isPlatform(PlatformType::TYPE_LINUX)) {
row_map["net_namespace"] = IntType;
}
auto const data = execute_query("select * from process_open_sockets");
// 2. Check size before validation
// ASSERT_GE(data.size(), 0ul);
// ASSERT_EQ(data.size(), 1ul);
// ASSERT_EQ(data.size(), 0ul);
// 3. Build validation map
// See helper.h for avaialbe flags
// Or use custom DataCheck object
// ValidationMap row_map = {
// {"pid", IntType}
// {"fd", IntType}
// {"socket", IntType}
// {"family", IntType}
// {"protocol", IntType}
// {"local_address", NormalType}
// {"remote_address", NormalType}
// {"local_port", IntType}
// {"remote_port", IntType}
// {"path", NormalType}
// {"state", NormalType}
// {"net_namespace", NormalType}
//}
// 4. Perform validation
// validate_rows(data, row_map);
ASSERT_FALSE(data.empty());
validate_rows(data, row_map);
}
} // namespace table_tests

View File

@ -22,26 +22,19 @@ class pythonPackages : public testing::Test {
};
TEST_F(pythonPackages, test_sanity) {
// 1. Query data
ValidationMap row_map = {
{"name", NormalType},
{"version", NormalType},
{"summary", NormalType},
{"author", NormalType},
{"license", NormalType},
{"path", NormalType},
{"directory", NormalType},
};
auto const data = execute_query("select * from python_packages");
// 2. Check size before validation
// ASSERT_GE(data.size(), 0ul);
// ASSERT_EQ(data.size(), 1ul);
// ASSERT_EQ(data.size(), 0ul);
// 3. Build validation map
// See helper.h for avaialbe flags
// Or use custom DataCheck object
// ValidationMap row_map = {
// {"name", NormalType}
// {"version", NormalType}
// {"summary", NormalType}
// {"author", NormalType}
// {"license", NormalType}
// {"path", NormalType}
// {"directory", NormalType}
//}
// 4. Perform validation
// validate_rows(data, row_map);
ASSERT_FALSE(data.empty());
validate_rows(data, row_map);
}
} // namespace table_tests

View File

@ -22,8 +22,6 @@ class RoutesTest : public testing::Test {
};
TEST_F(RoutesTest, test_sanity) {
QueryData const data = execute_query("select * from routes");
auto const row_map = ValidationMap{
{"destination", verifyIpAddress},
{"netmask", IntMinMaxCheck(0, 128)},
@ -49,7 +47,15 @@ TEST_F(RoutesTest, test_sanity) {
{"hopcount", IntMinMaxCheck(0, 255)},
#endif
};
auto const data = execute_query("select * from routes");
ASSERT_FALSE(data.empty());
validate_rows(data, row_map);
auto const datatype =
execute_query("select * from routes where type = 'local'");
ASSERT_FALSE(datatype.empty());
validate_rows(datatype, row_map);
}
} // namespace table_tests

View File

@ -22,24 +22,17 @@ class runningApps : public testing::Test {
};
TEST_F(runningApps, test_sanity) {
// 1. Query data
QueryData general_query_data = execute_query("select * from running_apps");
QueryData specific_query_data =
execute_query("select * from running_apps where is_active = 1");
// 2. Check size before validation
ASSERT_GT(general_query_data.size(), 0ul);
ASSERT_EQ(general_query_data[0].size(), 3ul);
ASSERT_EQ(specific_query_data.size(), 1ul);
ASSERT_EQ(specific_query_data[0].size(), 3ul);
// 3. Build validation map
// See IntegrationTableTest.cpp for avaialbe flags
// Or use custom DataCheck object
ValidationMap row_map = {{"pid", IntType},
{"bundle_identifier", NormalType},
{"is_active", IntType}};
// 4. Perform validation
QueryData general_query_data = execute_query("select * from running_apps");
ASSERT_FALSE(general_query_data.empty());
validate_rows(general_query_data, row_map);
QueryData specific_query_data =
execute_query("select * from running_apps where is_active = 1");
ASSERT_EQ(specific_query_data.size(), 1ul);
validate_rows(specific_query_data, row_map);
}