Add serialization test
This commit is contained in:
parent
bb98d8809a
commit
6fc2fe5320
@ -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
206
test_audit_record.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user