X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=tests%2Funit%2Ftest_event_rule.cpp;fp=tests%2Funit%2Ftest_event_rule.cpp;h=0fc9ec7702a44724339e5a530d19af5f71de52ae;hb=740da7d5000ca1ffdcf14bda5096bf7ccfb86bdd;hp=0000000000000000000000000000000000000000;hpb=02c3d2c2e3b27ab0bad1207c70465f84b649c816;p=lttng-tools.git diff --git a/tests/unit/test_event_rule.cpp b/tests/unit/test_event_rule.cpp new file mode 100644 index 000000000..0fc9ec770 --- /dev/null +++ b/tests/unit/test_event_rule.cpp @@ -0,0 +1,830 @@ +/* + * Unit tests for the notification API. + * + * Copyright (C) 2019 Jonathan Rajotte + * + * SPDX-License-Identifier: LGPL-2.1-only + * + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "bin/lttng/loglevel.h" + +/* For error.h. */ +int lttng_opt_quiet = 1; +int lttng_opt_verbose; +int lttng_opt_mi; + +#define NUM_TESTS 212 + +struct tracepoint_test { + enum lttng_domain_type type; + bool support_name_pattern_exclusion; +}; + +typedef const char *(*log_level_name_getter)(int log_level); + +typedef struct lttng_event_rule *(*event_rule_create)(void); +typedef enum lttng_event_rule_status (*event_rule_set_log_level)( + struct lttng_event_rule *rule, + const struct lttng_log_level_rule *log_level_rule); + +static +void test_event_rule_kernel_tracepoint(void) +{ + struct lttng_event_rule *tracepoint = NULL; + struct lttng_event_rule *tracepoint_from_buffer = NULL; + enum lttng_event_rule_status status; + const char *pattern="my_event_*"; + const char *filter="msg_id == 23 && size >= 2048"; + const char *tmp; + struct lttng_payload payload; + + diag("Testing lttng_event_rule_kernel_tracepoint."); + + lttng_payload_init(&payload); + + tracepoint = lttng_event_rule_kernel_tracepoint_create(); + ok(tracepoint, "tracepoint object."); + + status = lttng_event_rule_kernel_tracepoint_set_name_pattern(tracepoint, pattern); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "setting pattern."); + status = lttng_event_rule_kernel_tracepoint_get_name_pattern(tracepoint, &tmp); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "getting pattern."); + ok(!strncmp(pattern, tmp, strlen(pattern)), "pattern is equal."); + + status = lttng_event_rule_kernel_tracepoint_set_filter(tracepoint, filter); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "setting filter."); + status = lttng_event_rule_kernel_tracepoint_get_filter(tracepoint, &tmp); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "getting filter."); + ok(!strncmp(filter, tmp, strlen(filter)), "filter is equal."); + + ok(lttng_event_rule_serialize(tracepoint, &payload) == 0, "Serializing."); + + { + struct lttng_payload_view view = + lttng_payload_view_from_payload( + &payload, 0, -1); + + ok(lttng_event_rule_create_from_payload( + &view, &tracepoint_from_buffer) > 0, + "Deserializing."); + } + + ok(lttng_event_rule_is_equal(tracepoint, tracepoint_from_buffer), "serialized and from buffer are equal."); + + lttng_payload_reset(&payload); + lttng_event_rule_destroy(tracepoint); + lttng_event_rule_destroy(tracepoint_from_buffer); +} + +static +void test_event_rule_user_tracepoint(void) +{ + int i; + unsigned int count; + struct lttng_event_rule *tracepoint = NULL; + struct lttng_event_rule *tracepoint_from_buffer = NULL; + enum lttng_event_rule_status status; + const char *pattern="my_event_*"; + const char *filter="msg_id == 23 && size >= 2048"; + const char *tmp; + const char *name_pattern_exclusions[] = {"my_event_test1", "my_event_test2" ,"my_event_test3"}; + struct lttng_log_level_rule *log_level_rule = NULL; + const struct lttng_log_level_rule *log_level_rule_return = NULL; + struct lttng_payload payload; + + diag("Testing lttng_event_rule_user_tracepoint."); + + lttng_payload_init(&payload); + + log_level_rule = lttng_log_level_rule_exactly_create(LTTNG_LOGLEVEL_INFO); + LTTNG_ASSERT(log_level_rule); + + tracepoint = lttng_event_rule_user_tracepoint_create(); + ok(tracepoint, "user tracepoint object."); + + status = lttng_event_rule_user_tracepoint_set_name_pattern(tracepoint, pattern); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "setting pattern."); + status = lttng_event_rule_user_tracepoint_get_name_pattern(tracepoint, &tmp); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "getting pattern."); + ok(!strncmp(pattern, tmp, strlen(pattern)), "pattern is equal."); + + status = lttng_event_rule_user_tracepoint_set_filter(tracepoint, filter); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "setting filter."); + status = lttng_event_rule_user_tracepoint_get_filter(tracepoint, &tmp); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "getting filter."); + ok(!strncmp(filter, tmp, strlen(filter)), "filter is equal."); + + status = lttng_event_rule_user_tracepoint_get_log_level_rule(tracepoint, &log_level_rule_return); + ok(status == LTTNG_EVENT_RULE_STATUS_UNSET, "get unset log level rule."); + + status = lttng_event_rule_user_tracepoint_set_log_level_rule( + tracepoint, log_level_rule); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "setting log level rule."); + status = lttng_event_rule_user_tracepoint_get_log_level_rule( + tracepoint, &log_level_rule_return); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "get log level rule."); + + /* Name pattern exclusions */ + for (i = 0; i < 3; i++) { + status = lttng_event_rule_user_tracepoint_add_name_pattern_exclusion( + tracepoint, name_pattern_exclusions[i]); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, + "setting name pattern exclusions \"%s\"", + name_pattern_exclusions[i]); + } + + status = lttng_event_rule_user_tracepoint_get_name_pattern_exclusion_count( + tracepoint, &count); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, + "getting name pattern exclusion count."); + ok(count == 3, "count is %d/3", count); + + for (i = 0; i < count; i++) { + status = lttng_event_rule_user_tracepoint_get_name_pattern_exclusion_at_index( + tracepoint, i, &tmp); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, + "getting name pattern exclusion at index %d.", + i); + ok(!strncmp(name_pattern_exclusions[i], tmp, + strlen(name_pattern_exclusions[i])), + "%s == %s.", tmp, name_pattern_exclusions[i]); + } + + ok(lttng_event_rule_serialize(tracepoint, &payload) == 0, "Serializing."); + + { + struct lttng_payload_view view = + lttng_payload_view_from_payload( + &payload, 0, -1); + + ok(lttng_event_rule_create_from_payload( + &view, &tracepoint_from_buffer) > 0, + "Deserializing."); + } + + ok(lttng_event_rule_is_equal(tracepoint, tracepoint_from_buffer), "serialized and from buffer are equal."); + + lttng_payload_reset(&payload); + lttng_event_rule_destroy(tracepoint); + lttng_event_rule_destroy(tracepoint_from_buffer); + lttng_log_level_rule_destroy(log_level_rule); +} + +static void test_event_rule_syscall(void) +{ + struct lttng_event_rule *syscall = NULL; + struct lttng_event_rule *syscall_from_buffer = NULL; + enum lttng_event_rule_status status; + const char *pattern = "my_event_*"; + const char *filter = "msg_id == 23 && size >= 2048"; + const char *tmp; + struct lttng_payload payload; + + diag("Event rule syscall."); + + lttng_payload_init(&payload); + + syscall = lttng_event_rule_kernel_syscall_create(LTTNG_EVENT_RULE_KERNEL_SYSCALL_EMISSION_SITE_ENTRY); + ok(syscall, "syscall object."); + + status = lttng_event_rule_kernel_syscall_set_name_pattern(syscall, pattern); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "setting pattern."); + status = lttng_event_rule_kernel_syscall_get_name_pattern(syscall, &tmp); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "getting pattern."); + ok(!strncmp(pattern, tmp, strlen(pattern)), "pattern is equal."); + + status = lttng_event_rule_kernel_syscall_set_filter(syscall, filter); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "setting filter."); + status = lttng_event_rule_kernel_syscall_get_filter(syscall, &tmp); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "getting filter."); + ok(!strncmp(filter, tmp, strlen(filter)), "filter is equal."); + + ok(lttng_event_rule_serialize(syscall, &payload) == 0, "Serializing."); + + { + struct lttng_payload_view view = + lttng_payload_view_from_payload( + &payload, 0, -1); + + ok(lttng_event_rule_create_from_payload( + &view, &syscall_from_buffer) > 0, + "Deserializing."); + } + + ok(lttng_event_rule_is_equal(syscall, syscall_from_buffer), + "serialized and from buffer are equal."); + + lttng_payload_reset(&payload); + lttng_event_rule_destroy(syscall); + lttng_event_rule_destroy(syscall_from_buffer); +} + +static +void test_event_rule_jul_logging(void) +{ + struct lttng_event_rule *jul_logging = NULL; + struct lttng_event_rule *jul_logging_from_buffer = NULL; + enum lttng_event_rule_status status; + const char *pattern="my_event_*"; + const char *filter="msg_id == 23 && size >= 2048"; + const char *tmp; + struct lttng_log_level_rule *log_level_rule = NULL; + const struct lttng_log_level_rule *log_level_rule_return = NULL; + struct lttng_payload payload; + + diag("Testing lttng_event_rule_user_jul_logging."); + + lttng_payload_init(&payload); + + log_level_rule = lttng_log_level_rule_exactly_create(LTTNG_LOGLEVEL_INFO); + LTTNG_ASSERT(log_level_rule); + + jul_logging = lttng_event_rule_jul_logging_create(); + ok(jul_logging, "jul_logging object."); + + status = lttng_event_rule_jul_logging_set_name_pattern(jul_logging, pattern); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "setting pattern."); + status = lttng_event_rule_jul_logging_get_name_pattern(jul_logging, &tmp); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "getting pattern."); + ok(!strncmp(pattern, tmp, strlen(pattern)), "pattern is equal."); + + status = lttng_event_rule_jul_logging_set_filter(jul_logging, filter); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "setting filter."); + status = lttng_event_rule_jul_logging_get_filter(jul_logging, &tmp); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "getting filter."); + ok(!strncmp(filter, tmp, strlen(filter)), "filter is equal."); + + status = lttng_event_rule_jul_logging_get_log_level_rule(jul_logging, &log_level_rule_return); + ok(status == LTTNG_EVENT_RULE_STATUS_UNSET, "get unset log level rule."); + + status = lttng_event_rule_jul_logging_set_log_level_rule( + jul_logging, log_level_rule); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "setting log level rule."); + status = lttng_event_rule_jul_logging_get_log_level_rule( + jul_logging, &log_level_rule_return); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "get log level rule."); + + ok(lttng_event_rule_serialize(jul_logging, &payload) == 0, "Serializing."); + + { + struct lttng_payload_view view = + lttng_payload_view_from_payload( + &payload, 0, -1); + + ok(lttng_event_rule_create_from_payload( + &view, &jul_logging_from_buffer) > 0, + "Deserializing."); + } + + ok(lttng_event_rule_is_equal(jul_logging, jul_logging_from_buffer), "serialized and from buffer are equal."); + + lttng_payload_reset(&payload); + lttng_event_rule_destroy(jul_logging); + lttng_event_rule_destroy(jul_logging_from_buffer); + lttng_log_level_rule_destroy(log_level_rule); +} + +static +void test_event_rule_log4j_logging(void) +{ + struct lttng_event_rule *log4j_logging = NULL; + struct lttng_event_rule *log4j_logging_from_buffer = NULL; + enum lttng_event_rule_status status; + const char *pattern="my_event_*"; + const char *filter="msg_id == 23 && size >= 2048"; + const char *tmp; + struct lttng_log_level_rule *log_level_rule = NULL; + const struct lttng_log_level_rule *log_level_rule_return = NULL; + struct lttng_payload payload; + + diag("Testing lttng_event_rule_user_log4j_logging."); + + lttng_payload_init(&payload); + + log_level_rule = lttng_log_level_rule_exactly_create(LTTNG_LOGLEVEL_INFO); + LTTNG_ASSERT(log_level_rule); + + log4j_logging = lttng_event_rule_log4j_logging_create(); + ok(log4j_logging, "log4j_logging object."); + + status = lttng_event_rule_log4j_logging_set_name_pattern(log4j_logging, pattern); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "setting pattern."); + status = lttng_event_rule_log4j_logging_get_name_pattern(log4j_logging, &tmp); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "getting pattern."); + ok(!strncmp(pattern, tmp, strlen(pattern)), "pattern is equal."); + + status = lttng_event_rule_log4j_logging_set_filter(log4j_logging, filter); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "setting filter."); + status = lttng_event_rule_log4j_logging_get_filter(log4j_logging, &tmp); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "getting filter."); + ok(!strncmp(filter, tmp, strlen(filter)), "filter is equal."); + + status = lttng_event_rule_log4j_logging_get_log_level_rule(log4j_logging, &log_level_rule_return); + ok(status == LTTNG_EVENT_RULE_STATUS_UNSET, "get unset log level rule."); + + status = lttng_event_rule_log4j_logging_set_log_level_rule( + log4j_logging, log_level_rule); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "setting log level rule."); + status = lttng_event_rule_log4j_logging_get_log_level_rule( + log4j_logging, &log_level_rule_return); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "get log level rule."); + + ok(lttng_event_rule_serialize(log4j_logging, &payload) == 0, "Serializing."); + + { + struct lttng_payload_view view = + lttng_payload_view_from_payload( + &payload, 0, -1); + + ok(lttng_event_rule_create_from_payload( + &view, &log4j_logging_from_buffer) > 0, + "Deserializing."); + } + + ok(lttng_event_rule_is_equal(log4j_logging, log4j_logging_from_buffer), "serialized and from buffer are equal."); + + lttng_payload_reset(&payload); + lttng_event_rule_destroy(log4j_logging); + lttng_event_rule_destroy(log4j_logging_from_buffer); + lttng_log_level_rule_destroy(log_level_rule); +} + +static +void test_event_rule_python_logging(void) +{ + struct lttng_event_rule *python_logging = NULL; + struct lttng_event_rule *python_logging_from_buffer = NULL; + enum lttng_event_rule_status status; + const char *pattern="my_event_*"; + const char *filter="msg_id == 23 && size >= 2048"; + const char *tmp; + struct lttng_log_level_rule *log_level_rule = NULL; + const struct lttng_log_level_rule *log_level_rule_return = NULL; + struct lttng_payload payload; + + diag("Testing lttng_event_rule_user_python_logging."); + + lttng_payload_init(&payload); + + log_level_rule = lttng_log_level_rule_exactly_create(LTTNG_LOGLEVEL_INFO); + LTTNG_ASSERT(log_level_rule); + + python_logging = lttng_event_rule_python_logging_create(); + ok(python_logging, "python_logging object."); + + status = lttng_event_rule_python_logging_set_name_pattern(python_logging, pattern); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "setting pattern."); + status = lttng_event_rule_python_logging_get_name_pattern(python_logging, &tmp); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "getting pattern."); + ok(!strncmp(pattern, tmp, strlen(pattern)), "pattern is equal."); + + status = lttng_event_rule_python_logging_set_filter(python_logging, filter); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "setting filter."); + status = lttng_event_rule_python_logging_get_filter(python_logging, &tmp); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "getting filter."); + ok(!strncmp(filter, tmp, strlen(filter)), "filter is equal."); + + status = lttng_event_rule_python_logging_get_log_level_rule(python_logging, &log_level_rule_return); + ok(status == LTTNG_EVENT_RULE_STATUS_UNSET, "get unset log level rule."); + + status = lttng_event_rule_python_logging_set_log_level_rule( + python_logging, log_level_rule); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "setting log level rule."); + status = lttng_event_rule_python_logging_get_log_level_rule( + python_logging, &log_level_rule_return); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "get log level rule."); + + ok(lttng_event_rule_serialize(python_logging, &payload) == 0, "Serializing."); + + { + struct lttng_payload_view view = + lttng_payload_view_from_payload( + &payload, 0, -1); + + ok(lttng_event_rule_create_from_payload( + &view, &python_logging_from_buffer) > 0, + "Deserializing."); + } + + ok(lttng_event_rule_is_equal(python_logging, python_logging_from_buffer), "serialized and from buffer are equal."); + + lttng_payload_reset(&payload); + lttng_event_rule_destroy(python_logging); + lttng_event_rule_destroy(python_logging_from_buffer); + lttng_log_level_rule_destroy(log_level_rule); +} + +static void test_event_rule_userspace_probe(void) +{ + struct lttng_event_rule *uprobe = NULL; + struct lttng_event_rule *uprobe_from_buffer = NULL; + struct lttng_userspace_probe_location_lookup_method *lookup_method = + NULL; + struct lttng_userspace_probe_location *probe_location = NULL; + const struct lttng_userspace_probe_location *probe_location_tmp = NULL; + enum lttng_event_rule_status status; + + const char *probe_name = "my_probe."; + const char *tmp; + struct lttng_payload payload; + + diag("Event rule uprobe."); + + lookup_method = lttng_userspace_probe_location_lookup_method_function_elf_create(); + if (!lookup_method) { + fail("Setup error on userspace probe lookup method creation."); + goto end; + } + + probe_location = lttng_userspace_probe_location_function_create( + "/proc/self/exe", + "lttng_userspace_probe_location_tracepoint_create", + lookup_method); + if (!probe_location) { + fail("Setup error on userspace probe location creation."); + goto end; + } + + /* Ownership transferred to the probe location function object. */ + lookup_method = NULL; + + lttng_payload_init(&payload); + + uprobe = lttng_event_rule_kernel_uprobe_create(probe_location); + ok(uprobe, "uprobe event rule object creation."); + + status = lttng_event_rule_kernel_uprobe_get_location( + uprobe, &probe_location_tmp); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, + "Getting uprobe event rule location."); + ok(lttng_userspace_probe_location_is_equal( + probe_location, probe_location_tmp), + "Location is equal."); + + status = lttng_event_rule_kernel_uprobe_set_event_name(uprobe, probe_name); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, + "Setting uprobe event rule name: %s.", probe_name); + status = lttng_event_rule_kernel_uprobe_get_event_name(uprobe, &tmp); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "Getting uprobe name."); + ok(!strcmp(probe_name, tmp), "Uprobe name are equal."); + + ok(lttng_event_rule_serialize(uprobe, &payload) == 0, "Serializing."); + + { + struct lttng_payload_view view = + lttng_payload_view_from_payload( + &payload, 0, -1); + + ok(lttng_event_rule_create_from_payload( + &view, &uprobe_from_buffer) > 0, + "Deserializing."); + } + + ok(lttng_event_rule_is_equal(uprobe, uprobe_from_buffer), + "serialized and from buffer are equal."); + +end: + lttng_payload_reset(&payload); + lttng_event_rule_destroy(uprobe); + lttng_event_rule_destroy(uprobe_from_buffer); + lttng_userspace_probe_location_destroy(probe_location); + lttng_userspace_probe_location_lookup_method_destroy(lookup_method); +} + +static void test_event_rule_kernel_probe_by_location( + const struct lttng_kernel_probe_location *location) +{ + struct lttng_event_rule *kprobe = NULL; + struct lttng_event_rule *kprobe_from_buffer = NULL; + enum lttng_event_rule_status status; + const struct lttng_kernel_probe_location *_location; + + const char *probe_name = "my_probe"; + const char *tmp; + struct lttng_payload payload; + + diag("Event rule kprobe for location type %d.", + lttng_kernel_probe_location_get_type(location)); + + lttng_payload_init(&payload); + + kprobe = lttng_event_rule_kernel_kprobe_create(location); + ok(kprobe, "kprobe event rule object creation."); + + status = lttng_event_rule_kernel_kprobe_get_location(kprobe, &_location); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, + "Getting kprobe event rule location."); + ok(lttng_kernel_probe_location_is_equal(location, _location), "Locations are equal."); + + status = lttng_event_rule_kernel_kprobe_set_event_name(kprobe, probe_name); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, + "Setting kprobe event rule name: %s.", probe_name); + status = lttng_event_rule_kernel_kprobe_get_event_name(kprobe, &tmp); + ok(status == LTTNG_EVENT_RULE_STATUS_OK, "Getting kprobe name."); + ok(!strcmp(probe_name, tmp), "kprobe name are equal."); + + ok(lttng_event_rule_serialize(kprobe, &payload) == 0, "Serializing."); + + { + struct lttng_payload_view view = + lttng_payload_view_from_payload( + &payload, 0, -1); + + ok(lttng_event_rule_create_from_payload( + &view, &kprobe_from_buffer) > 0, + "Deserializing."); + } + + ok(lttng_event_rule_is_equal(kprobe, kprobe_from_buffer), + "serialized and from buffer are equal."); + + lttng_payload_reset(&payload); + lttng_event_rule_destroy(kprobe); + lttng_event_rule_destroy(kprobe_from_buffer); +} + +static void test_event_rule_kernel_probe(void) +{ + struct lttng_kernel_probe_location *address_location = NULL; + struct lttng_kernel_probe_location *symbol_location = NULL; + + address_location = lttng_kernel_probe_location_address_create(50); + symbol_location = lttng_kernel_probe_location_symbol_create("une_bonne", 50); + LTTNG_ASSERT(address_location); + LTTNG_ASSERT(symbol_location); + + test_event_rule_kernel_probe_by_location(address_location); + test_event_rule_kernel_probe_by_location(symbol_location); + + lttng_kernel_probe_location_destroy(address_location); + lttng_kernel_probe_location_destroy(symbol_location); +} + +static void test_set_event_rule_log_level_rules( + struct lttng_event_rule *event_rule, + event_rule_set_log_level set_log_level, + int log_level, + enum lttng_event_rule_status *exactly_status, + enum lttng_event_rule_status *as_severe_status) +{ + struct lttng_log_level_rule *log_level_rule; + + log_level_rule = lttng_log_level_rule_at_least_as_severe_as_create( + log_level); + LTTNG_ASSERT(log_level_rule); + + *as_severe_status = set_log_level( + event_rule, log_level_rule); + lttng_log_level_rule_destroy(log_level_rule); + + log_level_rule = lttng_log_level_rule_exactly_create(log_level); + LTTNG_ASSERT(log_level_rule); + + *exactly_status = set_log_level( + event_rule, log_level_rule); + lttng_log_level_rule_destroy(log_level_rule); +} + +static void test_event_rule_log_level_generic(enum lttng_event_rule_type event_rule_type, + log_level_name_getter get_log_level_name, + event_rule_create create_event_rule, + event_rule_set_log_level set_log_level, + const int tagged_log_level_values[], + size_t tagged_log_level_values_count, + const int valid_log_level_values[], + size_t valid_log_level_values_count, + const int invalid_log_level_values[], + size_t invalid_log_level_values_count) +{ + size_t i; + struct lttng_event_rule *rule; + enum lttng_event_rule_status er_exactly_status, er_as_severe_status; + const char *event_rule_type_str = lttng_event_rule_type_str(event_rule_type); + + + diag("Test %s event rule + log level rule", event_rule_type_str); + + rule = create_event_rule(); + LTTNG_ASSERT(rule); + + for (i = 0; i < tagged_log_level_values_count; i++) { + const int tagged_log_level_value = tagged_log_level_values[i]; + + test_set_event_rule_log_level_rules(rule, set_log_level, + tagged_log_level_value, + &er_exactly_status, &er_as_severe_status); + ok(er_exactly_status == LTTNG_EVENT_RULE_STATUS_OK, + "Log level rule \"exactly\" accepted by %s event rule: level = %s", + event_rule_type_str, + get_log_level_name( + tagged_log_level_value)); + ok(er_as_severe_status == LTTNG_EVENT_RULE_STATUS_OK, + "Log level rule \"as least as severe as\" accepted by %s event rule: level = %s", + event_rule_type_str, + get_log_level_name( + tagged_log_level_value)); + } + + for (i = 0; i < valid_log_level_values_count; i++) { + const int valid_log_level_value = valid_log_level_values[i]; + + test_set_event_rule_log_level_rules(rule, set_log_level, + valid_log_level_value, + &er_exactly_status, &er_as_severe_status); + ok(er_exactly_status == LTTNG_EVENT_RULE_STATUS_OK, + "Log level rule \"exactly\" accepted by %s event rule: level = %d", + event_rule_type_str, + valid_log_level_value); + ok(er_as_severe_status == LTTNG_EVENT_RULE_STATUS_OK, + "Log level rule \"as least as severe as\" accepted by %s event rule: level = %d", + event_rule_type_str, + valid_log_level_value); + } + + for (i = 0; i < invalid_log_level_values_count; i++) { + const int invalid_log_level_value = invalid_log_level_values[i]; + + test_set_event_rule_log_level_rules(rule, set_log_level, + invalid_log_level_value, + &er_exactly_status, &er_as_severe_status); + ok(er_exactly_status == LTTNG_EVENT_RULE_STATUS_INVALID, + "Log level rule \"exactly\" rejected by %s event rule: level = %d", + event_rule_type_str, + invalid_log_level_value); + ok(er_as_severe_status == LTTNG_EVENT_RULE_STATUS_INVALID, + "Log level rule \"as least as severe as\" rejected by %s event rule: level = %d", + event_rule_type_str, + invalid_log_level_value); + } + + lttng_event_rule_destroy(rule); +} + +static void test_event_rule_log_level_ust(void) +{ + const int tagged_log_level_values[] = { + LTTNG_LOGLEVEL_EMERG, + LTTNG_LOGLEVEL_ALERT, + LTTNG_LOGLEVEL_CRIT, + LTTNG_LOGLEVEL_ERR, + LTTNG_LOGLEVEL_WARNING, + LTTNG_LOGLEVEL_NOTICE, + LTTNG_LOGLEVEL_INFO, + LTTNG_LOGLEVEL_DEBUG_SYSTEM, + LTTNG_LOGLEVEL_DEBUG_PROGRAM, + LTTNG_LOGLEVEL_DEBUG_PROCESS, + LTTNG_LOGLEVEL_DEBUG_MODULE, + LTTNG_LOGLEVEL_DEBUG_UNIT, + LTTNG_LOGLEVEL_DEBUG_FUNCTION, + LTTNG_LOGLEVEL_DEBUG_LINE, + LTTNG_LOGLEVEL_DEBUG, + }; + const int invalid_log_level_values[] = { + -1980, + 1995, + LTTNG_LOGLEVEL_DEBUG + 1, + LTTNG_LOGLEVEL_EMERG - 1, + }; + + test_event_rule_log_level_generic(LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT, + loglevel_value_to_name, + lttng_event_rule_user_tracepoint_create, + lttng_event_rule_user_tracepoint_set_log_level_rule, + tagged_log_level_values, + ARRAY_SIZE(tagged_log_level_values), NULL, 0, + invalid_log_level_values, + ARRAY_SIZE(invalid_log_level_values)); +} + +static void test_event_rule_log_level_jul(void) +{ + const int tagged_log_level_values[] = { + LTTNG_LOGLEVEL_JUL_OFF, + LTTNG_LOGLEVEL_JUL_SEVERE, + LTTNG_LOGLEVEL_JUL_WARNING, + LTTNG_LOGLEVEL_JUL_INFO, + LTTNG_LOGLEVEL_JUL_CONFIG, + LTTNG_LOGLEVEL_JUL_FINE, + LTTNG_LOGLEVEL_JUL_FINER, + LTTNG_LOGLEVEL_JUL_FINEST, + LTTNG_LOGLEVEL_JUL_ALL, + }; + const int valid_log_level_values[] = { + 0, + -1980, + 1995 + }; + + test_event_rule_log_level_generic(LTTNG_EVENT_RULE_TYPE_JUL_LOGGING, + loglevel_jul_value_to_name, + lttng_event_rule_jul_logging_create, + lttng_event_rule_jul_logging_set_log_level_rule, + tagged_log_level_values, + ARRAY_SIZE(tagged_log_level_values), + valid_log_level_values, + ARRAY_SIZE(valid_log_level_values), NULL, 0); +} + +static void test_event_rule_log_level_log4j(void) +{ + const int tagged_log_level_values[] = { + LTTNG_LOGLEVEL_LOG4J_OFF, + LTTNG_LOGLEVEL_LOG4J_FATAL, + LTTNG_LOGLEVEL_LOG4J_ERROR, + LTTNG_LOGLEVEL_LOG4J_WARN, + LTTNG_LOGLEVEL_LOG4J_INFO, + LTTNG_LOGLEVEL_LOG4J_DEBUG, + LTTNG_LOGLEVEL_LOG4J_TRACE, + LTTNG_LOGLEVEL_LOG4J_ALL, + }; + const int valid_log_level_values[] = { + 0 + -1980, + 1995 + }; + + test_event_rule_log_level_generic(LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING, + loglevel_log4j_value_to_name, + lttng_event_rule_log4j_logging_create, + lttng_event_rule_log4j_logging_set_log_level_rule, + tagged_log_level_values, + ARRAY_SIZE(tagged_log_level_values), + valid_log_level_values, + ARRAY_SIZE(valid_log_level_values), NULL, 0); +} + +static void test_event_rule_log_level_python(void) +{ + const int tagged_log_level_values[] = { + LTTNG_LOGLEVEL_PYTHON_CRITICAL, + LTTNG_LOGLEVEL_PYTHON_ERROR, + LTTNG_LOGLEVEL_PYTHON_WARNING, + LTTNG_LOGLEVEL_PYTHON_INFO, + LTTNG_LOGLEVEL_PYTHON_DEBUG, + LTTNG_LOGLEVEL_PYTHON_NOTSET, + }; + const int valid_log_level_values[] = { + 45, + 35, + 0, + -657, + }; + + test_event_rule_log_level_generic(LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING, + loglevel_python_value_to_name, + lttng_event_rule_python_logging_create, + lttng_event_rule_python_logging_set_log_level_rule, + tagged_log_level_values, + ARRAY_SIZE(tagged_log_level_values), + valid_log_level_values, + ARRAY_SIZE(valid_log_level_values), + NULL, 0); +} + +int main(int argc, const char *argv[]) +{ + plan_tests(NUM_TESTS); + test_event_rule_kernel_tracepoint(); + test_event_rule_user_tracepoint(); + test_event_rule_syscall(); + test_event_rule_userspace_probe(); + test_event_rule_kernel_probe(); + test_event_rule_log4j_logging(); + test_event_rule_jul_logging(); + test_event_rule_python_logging(); + test_event_rule_log_level_ust(); + test_event_rule_log_level_jul(); + test_event_rule_log_level_log4j(); + test_event_rule_log_level_python(); + return exit_status(); +}