diff --git a/userspace/libsinsp/test/eventformatter.ut.cpp b/userspace/libsinsp/test/eventformatter.ut.cpp index 6d0d2b1cf0..b3e358ed24 100644 --- a/userspace/libsinsp/test/eventformatter.ut.cpp +++ b/userspace/libsinsp/test/eventformatter.ut.cpp @@ -50,9 +50,11 @@ class sinsp_formatter_test : public sinsp_with_test_input } void format(const std::string& fmt, - sinsp_evt_formatter::output_format of = sinsp_evt_formatter::output_format::OF_NORMAL) + sinsp_evt_formatter::output_format of = sinsp_evt_formatter::output_format::OF_NORMAL, + bool resolve_transformers = true) { sinsp_evt_formatter f(&m_inspector, fmt, m_filter_list); + f.set_resolve_transformed_fields(resolve_transformers); auto evt = generate_getcwd_failed_entry_event(); f.get_field_names(m_last_field_names); auto r1 = f.resolve_tokens(evt, m_last_field_values); @@ -250,3 +252,145 @@ TEST_F(sinsp_formatter_test, multiple_fields_with_args_no_blank) EXPECT_EQ(m_last_field_values["proc.aname[0]"], "init"); EXPECT_EQ(m_last_field_values["proc.apid[0]"], "1"); } + +TEST_F(sinsp_formatter_test, invalid_transformers) +{ + ASSERT_THROW(format("start %some_transformer(proc.aname) end"), sinsp_exception); + ASSERT_THROW(format("start %val(proc.aname) end"), sinsp_exception); + ASSERT_THROW(format("start %(proc.aname) end"), sinsp_exception); + ASSERT_THROW(format("start %toupper(proc.aname"), sinsp_exception); + ASSERT_THROW(format("start %toupper(tolower)"), sinsp_exception); + ASSERT_THROW(format("start %toupper(tolower(proc.aname"), sinsp_exception); + ASSERT_THROW(format("start %toupper(tolower(proc.aname)"), sinsp_exception); + ASSERT_THROW(format("start %toupper(val(proc.aname))"), sinsp_exception); + ASSERT_THROW(format("start %toupper(val(proc.aname)"), sinsp_exception); + ASSERT_THROW(format("start %touper("), sinsp_exception); + ASSERT_THROW(format("start %("), sinsp_exception); + ASSERT_THROW(format("start %toupper(evt.num) end"), sinsp_exception); // wrong type + + // note: whitespaces are not allowed between transformers + ASSERT_THROW(format("start %toupper (proc.name) end"), sinsp_exception); + ASSERT_THROW(format("start %toupper( proc.name) end"), sinsp_exception); + ASSERT_THROW(format("start %toupper(proc.name ) end"), sinsp_exception); + ASSERT_THROW(format("start %toupper( proc.name ) end"), sinsp_exception); + ASSERT_THROW(format("start %toupper( tolower(proc.name)) end"), sinsp_exception); + ASSERT_THROW(format("start %toupper( tolower( proc.name)) end"), sinsp_exception); + ASSERT_THROW(format("start %toupper( tolower( proc.name )) end"), sinsp_exception); + ASSERT_THROW(format("start %toupper( tolower( proc.name ) ) end"), sinsp_exception); +} + +TEST_F(sinsp_formatter_test, field_with_transformer) +{ + format("start %toupper(proc.name) end"); + EXPECT_EQ(m_last_res, true); + EXPECT_EQ(m_last_output, "start INIT end"); + EXPECT_EQ(m_last_field_values.size(), 2) << pretty_print(m_last_field_values); + EXPECT_EQ(m_last_field_values["proc.name"], "init"); + EXPECT_EQ(m_last_field_values["toupper(proc.name)"], "INIT"); +} + +TEST_F(sinsp_formatter_test, field_with_transformer_excluded) +{ + auto of = sinsp_evt_formatter::output_format::OF_NORMAL; + format("start %toupper(proc.name) end", of, false); + EXPECT_EQ(m_last_res, true); + EXPECT_EQ(m_last_output, "start INIT end"); + EXPECT_EQ(m_last_field_values.size(), 1) << pretty_print(m_last_field_values); + EXPECT_EQ(m_last_field_values["proc.name"], "init"); +} + +TEST_F(sinsp_formatter_test, field_with_transformer_excluded_json) +{ + auto of = sinsp_evt_formatter::output_format::OF_JSON; + format("start %toupper(proc.name) end", of, false); + EXPECT_EQ(m_last_res, true); + EXPECT_EQ(m_last_output, "{\"proc.name\":\"init\"}"); + EXPECT_EQ(m_last_field_values.size(), 1) << pretty_print(m_last_field_values); + EXPECT_EQ(m_last_field_values["proc.name"], "init"); +} + +TEST_F(sinsp_formatter_test, field_with_transformer_and_arg) +{ + format("start %toupper(evt.arg[1]) end"); + EXPECT_EQ(m_last_res, true); + EXPECT_EQ(m_last_output, "start /TEST/DIR end"); + EXPECT_EQ(m_last_field_values.size(), 2) << pretty_print(m_last_field_values); + EXPECT_EQ(m_last_field_values["evt.arg[1]"], "/test/dir"); + EXPECT_EQ(m_last_field_values["toupper(evt.arg[1])"], "/TEST/DIR"); +} + +TEST_F(sinsp_formatter_test, field_with_nested_transformer) +{ + format("start %tolower(toupper(proc.name)) end"); + EXPECT_EQ(m_last_res, true); + EXPECT_EQ(m_last_output, "start init end"); + EXPECT_EQ(m_last_field_values.size(), 2) << pretty_print(m_last_field_values); + EXPECT_EQ(m_last_field_values["proc.name"], "init"); + EXPECT_EQ(m_last_field_values["tolower(toupper(proc.name))"], "init"); +} + +TEST_F(sinsp_formatter_test, field_with_nested_transformer_and_arg) +{ + format("start %tolower(toupper(evt.arg[1])) end"); + EXPECT_EQ(m_last_res, true); + EXPECT_EQ(m_last_output, "start /test/dir end"); + EXPECT_EQ(m_last_field_values.size(), 2) << pretty_print(m_last_field_values); + EXPECT_EQ(m_last_field_values["evt.arg[1]"], "/test/dir"); + EXPECT_EQ(m_last_field_values["tolower(toupper(evt.arg[1]))"], "/test/dir"); +} + +TEST_F(sinsp_formatter_test, multiple_fields_with_transformer) +{ + format("start %toupper(proc.name) %toupper(evt.arg.path) end"); + EXPECT_EQ(m_last_res, true); + EXPECT_EQ(m_last_output, "start INIT /TEST/DIR end"); + EXPECT_EQ(m_last_field_values.size(), 4) << pretty_print(m_last_field_values); + EXPECT_EQ(m_last_field_values["proc.name"], "init"); + EXPECT_EQ(m_last_field_values["evt.arg.path"], "/test/dir"); + EXPECT_EQ(m_last_field_values["toupper(proc.name)"], "INIT"); + EXPECT_EQ(m_last_field_values["toupper(evt.arg.path)"], "/TEST/DIR"); +} + +TEST_F(sinsp_formatter_test, multiple_fields_with_transformer_json) +{ + format("start %toupper(proc.name) %toupper(evt.arg.path) end", sinsp_evt_formatter::output_format::OF_JSON); + EXPECT_EQ(m_last_res, true); + EXPECT_EQ(m_last_output, "{\"evt.arg.path\":\"/test/dir\",\"proc.name\":\"init\",\"toupper(evt.arg.path)\":\"/TEST/DIR\",\"toupper(proc.name)\":\"INIT\"}"); + EXPECT_EQ(m_last_field_values.size(), 4) << pretty_print(m_last_field_values); + EXPECT_EQ(m_last_field_values["proc.name"], "init"); + EXPECT_EQ(m_last_field_values["evt.arg.path"], "/test/dir"); + EXPECT_EQ(m_last_field_values["toupper(proc.name)"], "INIT"); + EXPECT_EQ(m_last_field_values["toupper(evt.arg.path)"], "/TEST/DIR"); +} + +TEST_F(sinsp_formatter_test, multiple_fields_with_transformer_no_blank) +{ + format("start%toupper(proc.name)and%toupper(evt.arg.path)end"); + EXPECT_EQ(m_last_res, true); + EXPECT_EQ(m_last_output, "startINITand/TEST/DIRend"); + EXPECT_EQ(m_last_field_values.size(), 4) << pretty_print(m_last_field_values); + EXPECT_EQ(m_last_field_values["proc.name"], "init"); + EXPECT_EQ(m_last_field_values["evt.arg.path"], "/test/dir"); + EXPECT_EQ(m_last_field_values["toupper(proc.name)"], "INIT"); + EXPECT_EQ(m_last_field_values["toupper(evt.arg.path)"], "/TEST/DIR"); +} + +TEST_F(sinsp_formatter_test, lenght_shorter_with_transformer) +{ + format("start %2toupper(proc.name) end"); + EXPECT_EQ(m_last_res, true); + EXPECT_EQ(m_last_output, "start IN end"); + EXPECT_EQ(m_last_field_values.size(), 2) << pretty_print(m_last_field_values); + EXPECT_EQ(m_last_field_values["proc.name"], "init"); + EXPECT_EQ(m_last_field_values["toupper(proc.name)"], "INIT"); +} + +TEST_F(sinsp_formatter_test, lenght_larger_with_transformer) +{ + format("start %10toupper(proc.name) end"); + EXPECT_EQ(m_last_res, true); + EXPECT_EQ(m_last_output, "start INIT end"); + EXPECT_EQ(m_last_field_values.size(), 2) << pretty_print(m_last_field_values); + EXPECT_EQ(m_last_field_values["proc.name"], "init"); + EXPECT_EQ(m_last_field_values["toupper(proc.name)"], "INIT"); +}