@@ -403,6 +403,100 @@ static struct tracefs_dynevent **get_dynevents_check(enum tracefs_dynevent_type
return devents;
}
+
+struct test_synth {
+ char *name;
+ char *start_system;
+ char *start_event;
+ char *end_system;
+ char *end_event;
+ char *start_match_field;
+ char *end_match_field;
+ char *match_name;
+};
+
+static void test_synth_compare(struct test_synth *synth, struct tracefs_dynevent **devents)
+{
+ enum tracefs_dynevent_type stype;
+ char *format;
+ char *event;
+ int i;
+
+ for (i = 0; devents && devents[i]; i++) {
+ stype = tracefs_dynevent_info(devents[i], NULL,
+ &event, NULL, NULL, &format);
+ CU_TEST(stype == TRACEFS_DYNEVENT_SYNTH);
+ CU_TEST(strcmp(event, synth[i].name) == 0);
+ if (synth[i].match_name) {
+ CU_TEST(strstr(format, synth[i].match_name) != NULL);
+ }
+ }
+ CU_TEST(devents[i] == NULL);
+}
+
+static void test_instance_syntetic(struct tracefs_instance *instance)
+{
+ struct test_synth sevents[] = {
+ {"synth_1", "sched", "sched_waking", "sched", "sched_switch", "pid", "next_pid", "pid_match"},
+ {"synth_2", "syscalls", "sys_enter_openat2", "syscalls", "sys_exit_openat2", "__syscall_nr", "__syscall_nr", "nr_match"},
+ };
+ int sevents_count = sizeof(sevents) / sizeof((sevents)[0]);
+ struct tracefs_dynevent **devents;
+ struct tracefs_synth **synth;
+ struct tep_handle *tep;
+ int ret;
+ int i;
+
+ synth = calloc(sevents_count + 1, sizeof(*synth));
+
+ tep = tracefs_local_events(NULL);
+ CU_TEST(tep != NULL);
+
+ /* kprobes APIs */
+ ret = tracefs_dynevent_destroy_all(TRACEFS_DYNEVENT_SYNTH, true);
+ CU_TEST(ret == 0);
+ get_dynevents_check(TRACEFS_DYNEVENT_SYNTH, 0);
+
+ for (i = 0; i < sevents_count; i++) {
+ synth[i] = tracefs_synth_alloc(tep, sevents[i].name,
+ sevents[i].start_system, sevents[i].start_event,
+ sevents[i].end_system, sevents[i].end_event,
+ sevents[i].start_match_field, sevents[i].end_match_field,
+ sevents[i].match_name);
+ CU_TEST(synth[i] != NULL);
+ }
+
+ get_dynevents_check(TRACEFS_DYNEVENT_SYNTH, 0);
+
+ for (i = 0; i < sevents_count; i++) {
+ ret = tracefs_synth_create(synth[i]);
+ CU_TEST(ret == 0);
+ }
+
+ devents = get_dynevents_check(TRACEFS_DYNEVENT_SYNTH, sevents_count);
+ CU_TEST(devents != NULL);
+ test_synth_compare(sevents, devents);
+ tracefs_dynevent_list_free(devents);
+
+ for (i = 0; i < sevents_count; i++) {
+ ret = tracefs_synth_destroy(synth[i]);
+ CU_TEST(ret == 0);
+ }
+
+ get_dynevents_check(TRACEFS_DYNEVENT_SYNTH, 0);
+
+ for (i = 0; i < sevents_count; i++)
+ tracefs_synth_free(synth[i]);
+
+ tep_free(tep);
+ free(synth);
+}
+
+static void test_synthetic(void)
+{
+ test_instance_syntetic(test_instance);
+}
+
static void test_trace_file(void)
{
const char *tmp = get_rand_str();
@@ -1525,4 +1619,5 @@ void test_tracefs_lib(void)
CU_add_test(suite, "ftrace marker",
test_ftrace_marker);
CU_add_test(suite, "kprobes", test_kprobes);
+ CU_add_test(suite, "syntetic events", test_synthetic);
}
All tracefs library APIs should be covered in the unit test. There is unit test section for the tracefs_sql* set of APIs, which use synthetic events internally, but no tests for the tracefs_synthetic* APIs. An initial unit test section is added for tracefs_synthetic* APIs. Not all APIs are covered, that section should be extended. Unit tests for basic tracefs_synthetic* APIs are added, to test the changes related to dynamic events code in the library, related to synthetic events. Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com> --- utest/tracefs-utest.c | 95 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+)