selftests/bpf: add pre bpf_prog_test_run_opts() callback for test_loader
authorEduard Zingerman <eddyz87@gmail.com>
Thu, 20 Apr 2023 23:23:16 +0000 (02:23 +0300)
committerAlexei Starovoitov <ast@kernel.org>
Thu, 20 Apr 2023 23:49:16 +0000 (16:49 -0700)
When a test case is annotated with __retval tag the test_loader engine
would use libbpf's bpf_prog_test_run_opts() to do a test run of the
program and compare retvals.

This commit allows to perform arbitrary actions on bpf object right
before test loader invokes bpf_prog_test_run_opts(). This could be
used to setup some state for program execution, e.g. fill some maps.

Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20230420232317.2181776-4-eddyz87@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/test_loader.c
tools/testing/selftests/bpf/test_progs.h

index e2a1bdc..40c9b7d 100644 (file)
@@ -590,6 +590,14 @@ void run_subtest(struct test_loader *tester,
                if (restore_capabilities(&caps))
                        goto tobj_cleanup;
 
+               if (tester->pre_execution_cb) {
+                       err = tester->pre_execution_cb(tobj);
+                       if (err) {
+                               PRINT_FAIL("pre_execution_cb failed: %d\n", err);
+                               goto tobj_cleanup;
+                       }
+               }
+
                do_prog_test_run(bpf_program__fd(tprog), &retval);
                if (retval != subspec->retval && subspec->retval != POINTER_VALUE) {
                        PRINT_FAIL("Unexpected retval: %d != %d\n", retval, subspec->retval);
index 10ba432..0ed3134 100644 (file)
@@ -424,14 +424,23 @@ int get_bpf_max_tramp_links(void);
 
 #define BPF_TESTMOD_TEST_FILE "/sys/kernel/bpf_testmod"
 
+typedef int (*pre_execution_cb)(struct bpf_object *obj);
+
 struct test_loader {
        char *log_buf;
        size_t log_buf_sz;
        size_t next_match_pos;
+       pre_execution_cb pre_execution_cb;
 
        struct bpf_object *obj;
 };
 
+static inline void test_loader__set_pre_execution_cb(struct test_loader *tester,
+                                                    pre_execution_cb cb)
+{
+       tester->pre_execution_cb = cb;
+}
+
 typedef const void *(*skel_elf_bytes_fn)(size_t *sz);
 
 extern void test_loader__run_subtests(struct test_loader *tester,