diff --git a/unit_tests/engine/test_filter_evttype_resolver.cpp b/unit_tests/engine/test_filter_evttype_resolver.cpp new file mode 100644 index 00000000..aaf83805 --- /dev/null +++ b/unit_tests/engine/test_filter_evttype_resolver.cpp @@ -0,0 +1,119 @@ +/* +Copyright (C) 2023 The Falco Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include +#include +#include + +std::set get_filter_set(const string &fltstr) +{ + set actual; + auto f = libsinsp::filter::parser(fltstr).parse(); + filter_evttype_resolver().evttypes(f.get(), actual); + return actual; +} + +std::set get_set_difference(std::set exclude_set = {}) +{ + std::set set_difference = {}; + + /* Not considering GENERIC_E GENERIC_X */ + for(uint32_t i = 2; i < PPM_EVENT_MAX; i++) + { + /* Skip events that are unused. */ + if(sinsp::is_unused_event(i)) + { + continue; + } + + if(exclude_set.find(i) == exclude_set.end()) + { + set_difference.insert(i); + } + } + return set_difference; +} + +TEST(EvtTypeResolver, check_openat) +{ + std::set openat_only{ + PPME_SYSCALL_OPENAT_E, PPME_SYSCALL_OPENAT_X, + PPME_SYSCALL_OPENAT_2_E, PPME_SYSCALL_OPENAT_2_X}; + + std::set not_openat = get_set_difference(openat_only); + + /* `openat_only` */ + ASSERT_EQ(get_filter_set("evt.type=openat"), openat_only); + ASSERT_EQ(get_filter_set("evt.type = openat"), openat_only); + ASSERT_EQ(get_filter_set("not evt.type != openat"), openat_only); + ASSERT_EQ(get_filter_set("not not evt.type = openat"), openat_only); + ASSERT_EQ(get_filter_set("not not not not evt.type = openat"), openat_only); + ASSERT_EQ(get_filter_set("evt.type in (openat)"), openat_only); + ASSERT_EQ(get_filter_set("not (not evt.type=openat)"), openat_only); + ASSERT_EQ(get_filter_set("evt.type=openat and proc.name=nginx"), openat_only); + ASSERT_EQ(get_filter_set("evt.type=openat and not proc.name=nginx"), openat_only); + ASSERT_EQ(get_filter_set("evt.type=openat and (proc.name=nginx)"), openat_only); + ASSERT_EQ(get_filter_set("evt.type=openat and not (evt.type=close and proc.name=nginx)"), openat_only); + + /* `not_openat` */ + ASSERT_EQ(get_filter_set("evt.type!=openat"), not_openat); + ASSERT_EQ(get_filter_set("not not not evt.type = openat"), not_openat); + ASSERT_EQ(get_filter_set("not evt.type=openat"), not_openat); + ASSERT_EQ(get_filter_set("evt.type=close or not (evt.type=openat and proc.name=nginx)"), not_openat); +} + +TEST(EvtTypeResolver, check_openat_or_close) +{ + std::set openat_close_only{ + PPME_SYSCALL_OPENAT_E, PPME_SYSCALL_OPENAT_X, + PPME_SYSCALL_OPENAT_2_E, PPME_SYSCALL_OPENAT_2_X, + PPME_SYSCALL_CLOSE_E, PPME_SYSCALL_CLOSE_X}; + + std::set not_openat_close = get_set_difference(openat_close_only); + + /* `openat_close_only` */ + ASSERT_EQ(get_filter_set("evt.type in (openat, close)"), openat_close_only); + ASSERT_EQ(get_filter_set("evt.type=openat or evt.type=close"), openat_close_only); + ASSERT_EQ(get_filter_set("evt.type=openat or (evt.type=close and proc.name=nginx)"), openat_close_only); + ASSERT_EQ(get_filter_set("evt.type=close or (evt.type=openat and proc.name=nginx)"), openat_close_only); + + /* not `not_openat_close` */ + ASSERT_EQ(get_filter_set("not evt.type in (openat, close)"), not_openat_close); + ASSERT_EQ(get_filter_set("not not not evt.type in (openat, close)"), not_openat_close); + ASSERT_EQ(get_filter_set("evt.type!=openat and evt.type!=close"), not_openat_close); +} + +TEST(EvtTypeResolver, check_all_events) +{ + /* Computed as a difference of the empty set */ + std::set all_events = get_set_difference(); + + ASSERT_EQ(get_filter_set("evt.type!=openat or evt.type!=close"), all_events); + ASSERT_EQ(get_filter_set("proc.name=nginx"), all_events); + ASSERT_EQ(get_filter_set("evt.type=openat or proc.name=nginx"), all_events); + ASSERT_EQ(get_filter_set("evt.type=openat or (proc.name=nginx)"), all_events); + ASSERT_EQ(get_filter_set("(evt.type=openat) or proc.name=nginx"), all_events); +} + +TEST(EvtTypeResolver, check_no_events) +{ + std::set no_events = {}; + + ASSERT_EQ(get_filter_set("evt.type=close and evt.type=openat"), no_events); + ASSERT_EQ(get_filter_set("evt.type=openat and (evt.type=close and proc.name=nginx)"), no_events); + ASSERT_EQ(get_filter_set("evt.type=openat and (evt.type=close)"), no_events); +}