auditd-plugin-clickhouse/test_audit_record.cpp
2020-01-29 14:47:27 +03:00

207 lines
6.3 KiB
C++

/*
* This is an auditd plugin for sending auditd data
* to clickhouse DB.
* Copyright (C) 2020 Aleksei Nikiforov <darktemplar@basealt.ru>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include <stdio.h>
#include <stdexcept>
#include <sstream>
#include <memory>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <gtest/gtest.h>
#include "auditd-record.hpp"
static AuditRecord generateTestRecord()
{
AuditRecord original_record;
original_record.time = 12345678;
original_record.milliseconds = 9876;
original_record.serial = 12345;
original_record.node = "test node name";
original_record.filename = "some random file name";
auto string_field = InterpretedStringRecordField::createRecord();
string_field->setStringValue(std::string("string_record_value"));
original_record.fields["string_record"] = string_field;
auto integer_field = IntegerRecordField::createRecord();
integer_field->setIntValue(500);
integer_field->setStringValue(std::string("five hundred"));
original_record.fields["integer_record"] = integer_field;
auto array_field = InterpretedStringArrayRecordField::createRecord();
array_field->setArrays({"first name", "second name"}, {"first value", "second value"});
original_record.fields["array_record"] = array_field;
return original_record;
}
TEST(AuditRecord, Serialization)
{
AuditRecord original_record = generateTestRecord();
boost::property_tree::ptree ptree_data = original_record.toPtree();
std::stringstream stream_data;
boost::property_tree::write_json(stream_data, ptree_data);
boost::property_tree::ptree ptree_restored_data;
boost::property_tree::read_json(stream_data, ptree_restored_data);
auto restored_record = AuditRecord::fromPtree(ptree_restored_data);
ASSERT_TRUE(restored_record);
EXPECT_EQ(original_record.time, restored_record->time);
EXPECT_EQ(original_record.milliseconds, restored_record->milliseconds);
EXPECT_EQ(original_record.serial, restored_record->serial);
EXPECT_EQ(original_record.node, restored_record->node);
EXPECT_FALSE(original_record.filename.empty());
EXPECT_TRUE(restored_record->filename.empty());
EXPECT_EQ(original_record.fields.size(), restored_record->fields.size());
for (auto iter = original_record.fields.begin(); iter != original_record.fields.end(); ++iter)
{
auto second_iter = restored_record->fields.find(iter->first);
EXPECT_TRUE(second_iter != restored_record->fields.end());
if (second_iter == restored_record->fields.end())
{
continue;
}
EXPECT_EQ(iter->second->getType(), second_iter->second->getType());
if (iter->second->getType() != second_iter->second->getType())
{
continue;
}
switch (iter->second->getType())
{
case AbstractRecordField::Type::Int:
{
auto original_field = std::dynamic_pointer_cast<IntegerRecordField>(iter->second);
auto restored_field = std::dynamic_pointer_cast<IntegerRecordField>(second_iter->second);
EXPECT_TRUE(original_field);
EXPECT_TRUE(restored_field);
if ((!original_field) || (!restored_field))
{
break;
}
EXPECT_EQ(original_field->getIntValue(), restored_field->getIntValue());
EXPECT_EQ(original_field->getStringValue(), restored_field->getStringValue());
}
break;
case AbstractRecordField::Type::String:
{
auto original_field = std::dynamic_pointer_cast<StringRecordField>(iter->second);
auto restored_field = std::dynamic_pointer_cast<StringRecordField>(second_iter->second);
EXPECT_TRUE(original_field);
EXPECT_TRUE(restored_field);
if ((!original_field) || (!restored_field))
{
break;
}
EXPECT_EQ(original_field->getStringValue(), restored_field->getStringValue());
}
break;
case AbstractRecordField::Type::InterpretedString:
{
auto original_field = std::dynamic_pointer_cast<InterpretedStringRecordField>(iter->second);
auto restored_field = std::dynamic_pointer_cast<InterpretedStringRecordField>(second_iter->second);
EXPECT_TRUE(original_field);
EXPECT_TRUE(restored_field);
if ((!original_field) || (!restored_field))
{
break;
}
EXPECT_EQ(original_field->getStringValue(), restored_field->getStringValue());
}
break;
case AbstractRecordField::Type::InterpretedStringArray:
{
auto original_field = std::dynamic_pointer_cast<InterpretedStringArrayRecordField>(iter->second);
auto restored_field = std::dynamic_pointer_cast<InterpretedStringArrayRecordField>(second_iter->second);
EXPECT_TRUE(original_field);
EXPECT_TRUE(restored_field);
if ((!original_field) || (!restored_field))
{
break;
}
auto original_names = original_field->getNamesArray();
auto original_values = original_field->getValuesArray();
auto restored_names = restored_field->getNamesArray();
auto restored_values = restored_field->getValuesArray();
EXPECT_EQ(original_names.size(), restored_names.size());
if (original_names.size() == restored_names.size())
{
auto original_iter = original_names.begin();
auto restored_iter = restored_names.begin();
for ( ; (original_iter != original_names.end()) && (restored_iter != restored_names.end()); ++original_iter, ++restored_iter)
{
EXPECT_EQ(*original_iter, *restored_iter);
}
}
EXPECT_EQ(original_values.size(), restored_values.size());
if (original_values.size() == restored_values.size())
{
auto original_iter = original_values.begin();
auto restored_iter = restored_values.begin();
for ( ; (original_iter != original_values.end()) && (restored_iter != restored_values.end()); ++original_iter, ++restored_iter)
{
EXPECT_EQ(*original_iter, *restored_iter);
}
}
}
break;
}
}
}