From e41c2de552d2c28f5102eb745d594cdcf4ec0e82 Mon Sep 17 00:00:00 2001 From: Leonardo Grasso Date: Tue, 17 Mar 2026 13:53:58 +0100 Subject: [PATCH] chore(unit_tests/engine): capture feature testing Signed-off-by: Leonardo Grasso --- unit_tests/engine/test_rule_loader.cpp | 279 +++++++++++++++++++++++++ unit_tests/falco/test_capture.cpp | 50 +++++ 2 files changed, 329 insertions(+) diff --git a/unit_tests/engine/test_rule_loader.cpp b/unit_tests/engine/test_rule_loader.cpp index 6f389869..a66b34db 100644 --- a/unit_tests/engine/test_rule_loader.cpp +++ b/unit_tests/engine/test_rule_loader.cpp @@ -1516,3 +1516,282 @@ TEST_F(test_falco_engine, no_deprecated_field_warning_in_output) { ASSERT_FALSE(check_warning_message("evt.dir")) << m_load_result_string; EXPECT_EQ(num_rules_for_ruleset(), 1); } + +// Capture field tests + +TEST_F(test_falco_engine, rule_capture_enabled) { + std::string rules_content = R"END( +- rule: test_rule + desc: test rule + condition: evt.type = close + output: user=%user.name + priority: WARNING + capture: true +)END"; + + std::string rule_name = "test_rule"; + ASSERT_TRUE(load_rules(rules_content, "rules.yaml")) << m_load_result_string; + ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation(); + + auto rule_description = m_engine->describe_rule(&rule_name, {}); + ASSERT_EQ(rule_description["rules"][0]["info"]["capture"].template get(), true); +} + +TEST_F(test_falco_engine, rule_capture_disabled_by_default) { + std::string rules_content = R"END( +- rule: test_rule + desc: test rule + condition: evt.type = close + output: user=%user.name + priority: INFO +)END"; + + std::string rule_name = "test_rule"; + ASSERT_TRUE(load_rules(rules_content, "rules.yaml")) << m_load_result_string; + ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation(); + + auto rule_description = m_engine->describe_rule(&rule_name, {}); + ASSERT_EQ(rule_description["rules"][0]["info"]["capture"].template get(), false); + ASSERT_EQ(rule_description["rules"][0]["info"]["capture_duration"].template get(), + 0u); + ASSERT_EQ(rule_description["rules"][0]["info"]["capture_events"].template get(), 0u); + ASSERT_EQ(rule_description["rules"][0]["info"]["capture_filesize"].template get(), + 0u); +} + +TEST_F(test_falco_engine, rule_capture_duration) { + std::string rules_content = R"END( +- rule: test_rule + desc: test rule + condition: evt.type = close + output: user=%user.name + priority: WARNING + capture: true + capture_duration: 10000 +)END"; + + std::string rule_name = "test_rule"; + ASSERT_TRUE(load_rules(rules_content, "rules.yaml")) << m_load_result_string; + ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation(); + + auto rule_description = m_engine->describe_rule(&rule_name, {}); + ASSERT_EQ(rule_description["rules"][0]["info"]["capture_duration"].template get(), + 10000u); +} + +TEST_F(test_falco_engine, rule_capture_events) { + std::string rules_content = R"END( +- rule: test_rule + desc: test rule + condition: evt.type = close + output: user=%user.name + priority: WARNING + capture: true + capture_events: 25000 +)END"; + + std::string rule_name = "test_rule"; + ASSERT_TRUE(load_rules(rules_content, "rules.yaml")) << m_load_result_string; + ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation(); + + auto rule_description = m_engine->describe_rule(&rule_name, {}); + ASSERT_EQ(rule_description["rules"][0]["info"]["capture_events"].template get(), + 25000u); +} + +TEST_F(test_falco_engine, rule_capture_filesize) { + std::string rules_content = R"END( +- rule: test_rule + desc: test rule + condition: evt.type = close + output: user=%user.name + priority: WARNING + capture: true + capture_filesize: 80000 +)END"; + + std::string rule_name = "test_rule"; + ASSERT_TRUE(load_rules(rules_content, "rules.yaml")) << m_load_result_string; + ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation(); + + auto rule_description = m_engine->describe_rule(&rule_name, {}); + ASSERT_EQ(rule_description["rules"][0]["info"]["capture_filesize"].template get(), + 80000u); +} + +TEST_F(test_falco_engine, rule_capture_all_fields) { + std::string rules_content = R"END( +- rule: test_rule + desc: test rule + condition: evt.type = close + output: user=%user.name + priority: WARNING + capture: true + capture_duration: 5000 + capture_events: 10000 + capture_filesize: 2048 +)END"; + + std::string rule_name = "test_rule"; + ASSERT_TRUE(load_rules(rules_content, "rules.yaml")) << m_load_result_string; + ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation(); + + auto rule_description = m_engine->describe_rule(&rule_name, {}); + ASSERT_EQ(rule_description["rules"][0]["info"]["capture"].template get(), true); + ASSERT_EQ(rule_description["rules"][0]["info"]["capture_duration"].template get(), + 5000u); + ASSERT_EQ(rule_description["rules"][0]["info"]["capture_events"].template get(), + 10000u); + ASSERT_EQ(rule_description["rules"][0]["info"]["capture_filesize"].template get(), + 2048u); +} + +TEST_F(test_falco_engine, rule_override_capture_replace) { + std::string rules_content = R"END( +- rule: test_rule + desc: test rule + condition: evt.type = close + output: user=%user.name + priority: WARNING + capture: true + +- rule: test_rule + capture: false + override: + capture: replace +)END"; + + std::string rule_name = "test_rule"; + ASSERT_TRUE(load_rules(rules_content, "rules.yaml")) << m_load_result_string; + ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation(); + + auto rule_description = m_engine->describe_rule(&rule_name, {}); + ASSERT_EQ(rule_description["rules"][0]["info"]["capture"].template get(), false); +} + +TEST_F(test_falco_engine, rule_override_capture_duration_replace) { + std::string rules_content = R"END( +- rule: test_rule + desc: test rule + condition: evt.type = close + output: user=%user.name + priority: WARNING + capture: true + capture_duration: 5000 + +- rule: test_rule + capture_duration: 15000 + override: + capture_duration: replace +)END"; + + std::string rule_name = "test_rule"; + ASSERT_TRUE(load_rules(rules_content, "rules.yaml")) << m_load_result_string; + ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation(); + + auto rule_description = m_engine->describe_rule(&rule_name, {}); + ASSERT_EQ(rule_description["rules"][0]["info"]["capture_duration"].template get(), + 15000u); +} + +TEST_F(test_falco_engine, rule_override_capture_events_replace) { + std::string rules_content = R"END( +- rule: test_rule + desc: test rule + condition: evt.type = close + output: user=%user.name + priority: WARNING + capture_events: 1000 + +- rule: test_rule + capture_events: 5000 + override: + capture_events: replace +)END"; + + std::string rule_name = "test_rule"; + ASSERT_TRUE(load_rules(rules_content, "rules.yaml")) << m_load_result_string; + ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation(); + + auto rule_description = m_engine->describe_rule(&rule_name, {}); + ASSERT_EQ(rule_description["rules"][0]["info"]["capture_events"].template get(), + 5000u); +} + +TEST_F(test_falco_engine, rule_override_capture_filesize_replace) { + std::string rules_content = R"END( +- rule: test_rule + desc: test rule + condition: evt.type = close + output: user=%user.name + priority: WARNING + capture_filesize: 1024 + +- rule: test_rule + capture_filesize: 4096 + override: + capture_filesize: replace +)END"; + + std::string rule_name = "test_rule"; + ASSERT_TRUE(load_rules(rules_content, "rules.yaml")) << m_load_result_string; + ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation(); + + auto rule_description = m_engine->describe_rule(&rule_name, {}); + ASSERT_EQ(rule_description["rules"][0]["info"]["capture_filesize"].template get(), + 4096u); +} + +TEST_F(test_falco_engine, rule_capture_events_wrong_type) { + std::string rules_content = R"END( +- rule: test_rule + desc: test rule + condition: evt.type = close + output: user=%user.name + priority: INFO + capture_events: "not_a_number" +)END"; + + // String value for an integer field causes a load error + ASSERT_FALSE(load_rules(rules_content, "rules.yaml")); +} + +TEST_F(test_falco_engine, rule_capture_filesize_wrong_type) { + std::string rules_content = R"END( +- rule: test_rule + desc: test rule + condition: evt.type = close + output: user=%user.name + priority: INFO + capture_filesize: "not_a_number" +)END"; + + ASSERT_FALSE(load_rules(rules_content, "rules.yaml")); +} + +TEST_F(test_falco_engine, rule_capture_duration_wrong_type) { + std::string rules_content = R"END( +- rule: test_rule + desc: test rule + condition: evt.type = close + output: user=%user.name + priority: INFO + capture_duration: "not_a_number" +)END"; + + ASSERT_FALSE(load_rules(rules_content, "rules.yaml")); +} + +TEST_F(test_falco_engine, rule_capture_wrong_type) { + std::string rules_content = R"END( +- rule: test_rule + desc: test rule + condition: evt.type = close + output: user=%user.name + priority: INFO + capture: "yes" +)END"; + + ASSERT_TRUE(load_rules(rules_content, "rules.yaml")); + ASSERT_VALIDATION_STATUS(yaml_helper::validation_failed) << m_load_result->schema_validation(); +} diff --git a/unit_tests/falco/test_capture.cpp b/unit_tests/falco/test_capture.cpp index 1bf2d4e7..1f220a8f 100644 --- a/unit_tests/falco/test_capture.cpp +++ b/unit_tests/falco/test_capture.cpp @@ -79,6 +79,8 @@ plugins: EXPECT_EQ(config.m_capture_path_prefix, "/tmp/falco"); EXPECT_EQ(config.m_capture_mode, capture_mode_t::RULES); EXPECT_EQ(config.m_capture_default_duration_ns, 5000 * 1000000LL); // 5 seconds in ns + EXPECT_EQ(config.m_capture_default_events, 0u); + EXPECT_EQ(config.m_capture_default_filesize_kb, 0u); } TEST(Capture, capture_config_enabled_rules_mode) { @@ -132,3 +134,51 @@ capture: // Should throw an exception for invalid mode EXPECT_THROW(res = config.init_from_content(config_content, {}), std::logic_error); } + +TEST(Capture, capture_config_with_events_limit) { + std::string config_content = R"( +capture: + enabled: true + default_events: 50000 +)"; + + falco_configuration config; + config_loaded_res res; + ASSERT_NO_THROW(res = config.init_from_content(config_content, {})); + + EXPECT_EQ(config.m_capture_default_events, 50000u); + EXPECT_EQ(config.m_capture_default_filesize_kb, 0u); +} + +TEST(Capture, capture_config_with_filesize_limit) { + std::string config_content = R"( +capture: + enabled: true + default_filesize: 10240 +)"; + + falco_configuration config; + config_loaded_res res; + ASSERT_NO_THROW(res = config.init_from_content(config_content, {})); + + EXPECT_EQ(config.m_capture_default_events, 0u); + EXPECT_EQ(config.m_capture_default_filesize_kb, 10240u); +} + +TEST(Capture, capture_config_with_all_limits) { + std::string config_content = R"( +capture: + enabled: true + default_duration: 15000 + default_events: 25000 + default_filesize: 80000 +)"; + + falco_configuration config; + config_loaded_res res; + ASSERT_NO_THROW(res = config.init_from_content(config_content, {})); + + EXPECT_EQ(config.m_capture_default_duration_ns, 15000 * 1000000LL); + EXPECT_EQ(config.m_capture_default_events, 25000u); + EXPECT_EQ(config.m_capture_default_filesize_kb, 80000u); +}