From a8657a46bb876b2b607cd7551c90b4ff4127727e Mon Sep 17 00:00:00 2001 From: nikotian Date: Wed, 4 Nov 2020 20:54:46 +0100 Subject: [PATCH] Unit tests for chrome trace converter --- client/chrome_trace_converter.cpp | 4 +- client/chrome_trace_converter.hpp | 3 +- tests/client/CMakeLists.txt | 1 + tests/client/test_chrome_trace_converter.cpp | 337 +++++++++++++++++++ 4 files changed, 343 insertions(+), 2 deletions(-) create mode 100644 tests/client/test_chrome_trace_converter.cpp diff --git a/client/chrome_trace_converter.cpp b/client/chrome_trace_converter.cpp index e5cfb9d8..2500f64a 100644 --- a/client/chrome_trace_converter.cpp +++ b/client/chrome_trace_converter.cpp @@ -12,6 +12,8 @@ namespace HawkTracer namespace client { +const std::string ChromeTraceConverter::HEADER = "{\"traceEvents\": ["; + ChromeTraceConverter::~ChromeTraceConverter() { stop(); @@ -23,7 +25,7 @@ bool ChromeTraceConverter::init(const std::string& file_name) _file.open(file_name); if (_file.is_open()) { - _file << "{\"traceEvents\": ["; + _file << HEADER; return true; } return false; diff --git a/client/chrome_trace_converter.hpp b/client/chrome_trace_converter.hpp index 4672119e..4415cf0a 100644 --- a/client/chrome_trace_converter.hpp +++ b/client/chrome_trace_converter.hpp @@ -17,10 +17,11 @@ class ChromeTraceConverter : public Converter public: ~ChromeTraceConverter() override; + static const std::string HEADER; + bool init(const std::string& file_name) override; void process_event(const parser::Event& event) override; void stop() override; - private: static std::string _get_args(const parser::Event& event); static std::string _get_json_value(const parser::Event::Value& value); diff --git a/tests/client/CMakeLists.txt b/tests/client/CMakeLists.txt index df0ef117..df36f60e 100644 --- a/tests/client/CMakeLists.txt +++ b/tests/client/CMakeLists.txt @@ -1,6 +1,7 @@ set(HAWKTRACER_GTEST_TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/test_call_graph.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_file_loader.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_chrome_trace_converter.cpp ${HAWKTRACER_GTEST_TEST_SOURCES} PARENT_SCOPE) diff --git a/tests/client/test_chrome_trace_converter.cpp b/tests/client/test_chrome_trace_converter.cpp new file mode 100644 index 00000000..3b1ea8f9 --- /dev/null +++ b/tests/client/test_chrome_trace_converter.cpp @@ -0,0 +1,337 @@ +#include + +#include + +#include +#include +#include + +#include + +using HawkTracer::client::ChromeTraceConverter; +using HawkTracer::parser::EventKlass; +using HawkTracer::parser::Event; +using HawkTracer::parser::FieldType; +using HawkTracer::parser::FieldTypeId; +using HawkTracer::parser::EventKlassField; + +namespace { + static const std::string file_name = "test.log"; +} + +class TestChromeTraceConverter : public ::testing::Test +{ + protected: + void SetUp() override + { + trace_converter = std::make_shared(); + trace_converter->init(file_name); + + klass_info = std::make_shared("klass_info", 2); + klass_value = std::make_shared("klass_name", 1); + + duration_field = std::make_shared("duration", "field_type", FieldTypeId::UINT64); + info_field = std::make_shared("info_klass_id", "field_type", FieldTypeId::UINT32); + name_field = std::make_shared("name", "field_type", FieldTypeId::STRING); + label_field = std::make_shared("label", "field_type", FieldTypeId::STRING); + mapping_field = std::make_shared("event_klass_name", "field_type", FieldTypeId::STRING); + thread_field = std::make_shared("thread_id", "field_type", FieldTypeId::UINT32); + timestamp_field = std::make_shared("timestamp", "field_type", FieldTypeId::UINT64); + + first_field = std::make_shared("1st", "field_type", FieldTypeId::STRING); + second_field = std::make_shared("2nd", "field_type", FieldTypeId::STRING); + + } + + void SetMappingField(Event &event) + { + char* value = (char*)malloc(22); strncpy(value, "HT_StringMappingEvent", 22); + event.set_value(mapping_field.get(), value); + } + + std::shared_ptr trace_converter; + + std::shared_ptr klass_info; + std::shared_ptr klass_value; + + std::shared_ptr duration_field; + std::shared_ptr info_field; + std::shared_ptr label_field; + std::shared_ptr mapping_field; + std::shared_ptr name_field; + std::shared_ptr thread_field; + std::shared_ptr timestamp_field; + + std::shared_ptr first_field; + std::shared_ptr second_field; + + FieldType value_field; +}; + +std::string GetFileContents(const std::string file) +{ + std::ifstream file_handle(file, std::ios::in | std::ios::binary); + std::ostringstream header; + header << file_handle.rdbuf(); + return header.str(); +} + +TEST_F(TestChromeTraceConverter, CheckFileAfterOpenButNoEvents) +{ + trace_converter->stop(); + + std::string expected = ChromeTraceConverter::HEADER; + expected.append("]}"); + + EXPECT_EQ(expected, GetFileContents(file_name)); +} + +TEST_F(TestChromeTraceConverter, CheckWhenEmptyEventProcessed) +{ + Event event(klass_value); + trace_converter->process_event(event); + trace_converter->stop(); + + std::string expected = ChromeTraceConverter::HEADER; + expected.append("]}"); + + EXPECT_EQ(expected, GetFileContents(file_name)); +} + +TEST_F(TestChromeTraceConverter, CheckWhenOnlyTimeStampAdded) +{ + Event event(klass_value); + + value_field.f_UINT64 = 12987; + event.set_value(timestamp_field.get(), value_field); + + trace_converter->process_event(event); + trace_converter.reset(); + + std::string expected = ChromeTraceConverter::HEADER; + expected.append("]}"); + + EXPECT_EQ(expected, GetFileContents(file_name)); +} + +TEST_F(TestChromeTraceConverter, CheckWhenNameTimeStampAdded) +{ + Event event(klass_info); + SetMappingField(event); + + // Set info field + event.set_value(info_field.get(), 123); + + //Process event + trace_converter->process_event(event); + + Event event_value(klass_value); + // Add timestamp + value_field.f_UINT64 = 15987; + event_value.set_value(timestamp_field.get(), value_field); + + // Add name + char* name_value = (char*)malloc(6); strncpy(name_value, "first", 6); + event_value.set_value(name_field.get(), name_value); + + trace_converter->process_event(event_value); + + std::string expected = ChromeTraceConverter::HEADER; + expected.append("{\"name\": \"first\", \"ph\": \"X\", \"ts\": 15, \"dur\": 0, \"pid\": 0, \"tid\": 0, \"args\": {\"name\": \"first\"}}]}"); + trace_converter.reset(); + + EXPECT_EQ(expected, GetFileContents(file_name)); +} + +TEST_F(TestChromeTraceConverter, CheckWhenLabelTimeStampAdded) +{ + Event event(klass_info); + SetMappingField(event); + + // Set info field + event.set_value(info_field.get(), 456); + + // Process event + trace_converter->process_event(event); + + Event event_value(klass_value); + + // Add Timestamp + value_field.f_UINT64 = 16987; + event_value.set_value(timestamp_field.get(), value_field); + + // Add label + char* label_value = (char*)malloc(6); strncpy(label_value, "second", 6); + event_value.set_value(label_field.get(), label_value); + + trace_converter->process_event(event_value); + + std::string expected = ChromeTraceConverter::HEADER; + expected.append("{\"name\": \"second\", \"ph\": \"X\", \"ts\": 16, \"dur\": 0, \"pid\": 0, \"tid\": 0, \"args\": {}}]}"); + trace_converter.reset(); + + EXPECT_EQ(expected, GetFileContents(file_name)); +} + +TEST_F(TestChromeTraceConverter, CheckWhenNameAndDurationAdded) +{ + Event event(klass_info); + SetMappingField(event); + + // Set info field + event.set_value(info_field.get(), 789); + + // Process event + trace_converter->process_event(event); + + Event event_value(klass_value); + + // Add timestamp + value_field.f_UINT64 = 16987; + event_value.set_value(timestamp_field.get(), value_field); + + // Add name + char* name_value = (char*)malloc(6); strncpy(name_value, "third", 6); + event_value.set_value(name_field.get(), name_value); + + // Add duration + value_field.f_UINT64 = 20000; + event_value.set_value(duration_field.get(), value_field); + + // Add thread id + value_field.f_UINT32 = 200; + event_value.set_value(thread_field.get(), value_field); + + trace_converter->process_event(event_value); + + std::string expected = ChromeTraceConverter::HEADER; + expected.append("{\"name\": \"third\", \"ph\": \"X\", \"ts\": 16, \"dur\": 20, \"pid\": 0, \"tid\": 200, \"args\": {\"name\": \"third\"}}]}"); + trace_converter.reset(); + + EXPECT_EQ(expected, GetFileContents(file_name)); +} + +TEST_F(TestChromeTraceConverter, CheckWhenLabelAndDurationAdded) +{ + Event event(klass_info); + SetMappingField(event); + + // Add info + event.set_value(info_field.get(), 123); + + trace_converter->process_event(event); + + Event event_value(klass_value); + + // Add timestamp + value_field.f_UINT64 = 16987; + event_value.set_value(timestamp_field.get(), value_field); + + // Add label + char* label_value = (char*)malloc(6); strncpy(label_value, "second", 6); + event_value.set_value(label_field.get(), label_value); + + // Add duration + value_field.f_UINT64 = 20000; + event_value.set_value(duration_field.get(), value_field); + + // Add thread id + value_field.f_UINT32 = 200; + event_value.set_value(thread_field.get(), value_field); + + trace_converter->process_event(event_value); + + std::string expected = ChromeTraceConverter::HEADER; + expected.append("{\"name\": \"second\", \"ph\": \"X\", \"ts\": 16, \"dur\": 20, \"pid\": 0, \"tid\": 200, \"args\": {}}]}"); + trace_converter.reset(); + + EXPECT_EQ(expected, GetFileContents(file_name)); +} + +TEST_F(TestChromeTraceConverter, CheckWithNameAndMultipleArgsAdded) +{ + Event event(klass_info); + SetMappingField(event); + + // Add info + event.set_value(info_field.get(), 456); + + trace_converter->process_event(event); + + Event event_value(klass_value); + + // Add timestamp + value_field.f_UINT64 = 26987; + event_value.set_value(timestamp_field.get(), value_field); + + // Add name + char* name_value = (char*)malloc(6); strncpy(name_value, "third", 6); + event_value.set_value(name_field.get(), name_value); + + // Add duration + value_field.f_UINT64 = 30000; + event_value.set_value(duration_field.get(), value_field); + + // Add thread id + value_field.f_UINT32 = 300; + event_value.set_value(thread_field.get(), value_field); + + // Add first argument + char* first_value = (char*)malloc(6); strncpy(first_value, "Alpha", 6); + event_value.set_value(first_field.get(), first_value); + + // Add second argument + char* second_value = (char*)malloc(5); strncpy(second_value, "Beta", 5); + event_value.set_value(second_field.get(), second_value); + + trace_converter->process_event(event_value); + std::string expected = ChromeTraceConverter::HEADER; + expected.append("{\"name\": \"third\", \"ph\": \"X\", \"ts\": 26, \"dur\": 30, \"pid\": 0, \"tid\": 300, \"args\": {\"2nd\": \"Beta\",\"1st\": \"Alpha\",\"name\": \"third\"}}]}"); + trace_converter.reset(); + + EXPECT_EQ(expected, GetFileContents(file_name)); +} + +TEST_F(TestChromeTraceConverter, CheckWithLabelAndMultipleArgsAdded) +{ + Event event(klass_info); + SetMappingField(event); + + // Add info + event.set_value(info_field.get(), 456); + + trace_converter->process_event(event); + + Event event_value(klass_value); + + // Add timestamp + value_field.f_UINT64 = 26987; + event_value.set_value(timestamp_field.get(), value_field); + + // Add label + char* label_value = (char*)malloc(6); strncpy(label_value, "fourth", 6); + event_value.set_value(name_field.get(), label_value); + + // Add duration + value_field.f_UINT64 = 30000; + event_value.set_value(duration_field.get(), value_field); + + // Add thread id + value_field.f_UINT32 = 300; + event_value.set_value(thread_field.get(), value_field); + + // Add first argument + char* first_value = (char*)malloc(6); strncpy(first_value, "Alpha", 6); + event_value.set_value(first_field.get(), first_value); + + // Add second argument + char* second_value = (char*)malloc(5); strncpy(second_value, "Beta", 5); + event_value.set_value(second_field.get(), second_value); + + trace_converter->process_event(event_value); + std::string expected = ChromeTraceConverter::HEADER; + expected.append("{\"name\": \"fourth\", \"ph\": \"X\", \"ts\": 26, \"dur\": 30, \"pid\": 0, \"tid\": 300, \"args\": {\"2nd\": \"Beta\",\"1st\": \"Alpha\",\"name\": \"fourth\"}}]}"); + trace_converter.reset(); + + EXPECT_EQ(expected, GetFileContents(file_name)); +}