Add serialization test

This commit is contained in:
Aleksei Nikiforov 2020-01-16 11:45:25 +03:00
parent bb98d8809a
commit 6fc2fe5320
2 changed files with 214 additions and 0 deletions

View File

@ -15,6 +15,8 @@ find_package(Boost REQUIRED COMPONENTS filesystem)
find_package(ClickhouseCpp REQUIRED) find_package(ClickhouseCpp REQUIRED)
pkg_check_modules(AUPARSE auparse REQUIRED) pkg_check_modules(AUPARSE auparse REQUIRED)
include(GoogleTest)
include_directories(${Boost_INCLUDE_DIRS} ${AUPARSE_INCLUDE_DIRS}) include_directories(${Boost_INCLUDE_DIRS} ${AUPARSE_INCLUDE_DIRS})
set(SOURCES set(SOURCES
@ -32,9 +34,15 @@ set(HEADERS
utils.hpp utils.hpp
) )
enable_testing()
add_executable( auditd-plugin-clickhouse ${SOURCES} ${HEADERS} ) add_executable( auditd-plugin-clickhouse ${SOURCES} ${HEADERS} )
target_link_libraries( auditd-plugin-clickhouse ${CLICKHOUSECPP_LIBRARIES} ${AUPARSE_LIBRARIES} Threads::Threads Boost::filesystem ) target_link_libraries( auditd-plugin-clickhouse ${CLICKHOUSECPP_LIBRARIES} ${AUPARSE_LIBRARIES} Threads::Threads Boost::filesystem )
add_executable( test-audit-record test_audit_record.cpp auditd-record.cpp logging.cpp utils.cpp auditd-record.hpp logging.hpp utils.hpp )
target_link_libraries( test-audit-record ${CLICKHOUSECPP_LIBRARIES} ${AUPARSE_LIBRARIES} gtest gtest_main )
add_test( NAME test-audit-record COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test-audit-record )
install(TARGETS auditd-plugin-clickhouse RUNTIME DESTINATION ${BIN_INSTALL_LIBEXEC} ) install(TARGETS auditd-plugin-clickhouse RUNTIME DESTINATION ${BIN_INSTALL_LIBEXEC} )
install(FILES auditd-plugin-clickhouse.conf DESTINATION ${SYSCONF_INSTALL_DIR}/audisp/plugins.d ) install(FILES auditd-plugin-clickhouse.conf DESTINATION ${SYSCONF_INSTALL_DIR}/audisp/plugins.d )
install(FILES auditd-clickhouse.conf auditd-clickhouse-datatypes.json DESTINATION ${SYSCONF_INSTALL_DIR}/audisp ) install(FILES auditd-clickhouse.conf auditd-clickhouse-datatypes.json DESTINATION ${SYSCONF_INSTALL_DIR}/audisp )

206
test_audit_record.cpp Normal file
View File

@ -0,0 +1,206 @@
/*
* 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_record");
string_field->setStringValue(std::string("string_record_value"));
original_record.fields[string_field->getName()] = string_field;
auto integer_field = IntegerRecordField::createRecord("integer_record");
integer_field->setIntValue(500);
integer_field->setStringValue(std::string("five hundred"));
original_record.fields[integer_field->getName()] = integer_field;
auto array_field = InterpretedStringArrayRecordField::createRecord("array_record");
array_field->setArrays({"first name", "second name"}, {"first value", "second value"});
original_record.fields[array_field->getName()] = 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);
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;
}
EXPECT_EQ(iter->second->getName(), second_iter->second->getName());
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;
}
}
}