root/tools/testing/selftests/bpf/test_btf_dump.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. btf_dump_printf
  2. btf_dump_all_types
  3. test_btf_dump_case
  4. main

   1 #include <stdio.h>
   2 #include <stdlib.h>
   3 #include <string.h>
   4 #include <unistd.h>
   5 #include <errno.h>
   6 #include <linux/err.h>
   7 #include <btf.h>
   8 
   9 #define CHECK(condition, format...) ({                                  \
  10         int __ret = !!(condition);                                      \
  11         if (__ret) {                                                    \
  12                 fprintf(stderr, "%s:%d:FAIL ", __func__, __LINE__);     \
  13                 fprintf(stderr, format);                                \
  14         }                                                               \
  15         __ret;                                                          \
  16 })
  17 
  18 void btf_dump_printf(void *ctx, const char *fmt, va_list args)
  19 {
  20         vfprintf(ctx, fmt, args);
  21 }
  22 
  23 struct btf_dump_test_case {
  24         const char *name;
  25         struct btf_dump_opts opts;
  26 } btf_dump_test_cases[] = {
  27         {.name = "btf_dump_test_case_syntax", .opts = {}},
  28         {.name = "btf_dump_test_case_ordering", .opts = {}},
  29         {.name = "btf_dump_test_case_padding", .opts = {}},
  30         {.name = "btf_dump_test_case_packing", .opts = {}},
  31         {.name = "btf_dump_test_case_bitfields", .opts = {}},
  32         {.name = "btf_dump_test_case_multidim", .opts = {}},
  33         {.name = "btf_dump_test_case_namespacing", .opts = {}},
  34 };
  35 
  36 static int btf_dump_all_types(const struct btf *btf,
  37                               const struct btf_dump_opts *opts)
  38 {
  39         size_t type_cnt = btf__get_nr_types(btf);
  40         struct btf_dump *d;
  41         int err = 0, id;
  42 
  43         d = btf_dump__new(btf, NULL, opts, btf_dump_printf);
  44         if (IS_ERR(d))
  45                 return PTR_ERR(d);
  46 
  47         for (id = 1; id <= type_cnt; id++) {
  48                 err = btf_dump__dump_type(d, id);
  49                 if (err)
  50                         goto done;
  51         }
  52 
  53 done:
  54         btf_dump__free(d);
  55         return err;
  56 }
  57 
  58 int test_btf_dump_case(int n, struct btf_dump_test_case *test_case)
  59 {
  60         char test_file[256], out_file[256], diff_cmd[1024];
  61         struct btf *btf = NULL;
  62         int err = 0, fd = -1;
  63         FILE *f = NULL;
  64 
  65         fprintf(stderr, "Test case #%d (%s): ", n, test_case->name);
  66 
  67         snprintf(test_file, sizeof(test_file), "%s.o", test_case->name);
  68 
  69         btf = btf__parse_elf(test_file, NULL);
  70         if (CHECK(IS_ERR(btf),
  71             "failed to load test BTF: %ld\n", PTR_ERR(btf))) {
  72                 err = -PTR_ERR(btf);
  73                 btf = NULL;
  74                 goto done;
  75         }
  76 
  77         snprintf(out_file, sizeof(out_file),
  78                  "/tmp/%s.output.XXXXXX", test_case->name);
  79         fd = mkstemp(out_file);
  80         if (CHECK(fd < 0, "failed to create temp output file: %d\n", fd)) {
  81                 err = fd;
  82                 goto done;
  83         }
  84         f = fdopen(fd, "w");
  85         if (CHECK(f == NULL, "failed to open temp output file: %s(%d)\n",
  86                   strerror(errno), errno)) {
  87                 close(fd);
  88                 goto done;
  89         }
  90 
  91         test_case->opts.ctx = f;
  92         err = btf_dump_all_types(btf, &test_case->opts);
  93         fclose(f);
  94         close(fd);
  95         if (CHECK(err, "failure during C dumping: %d\n", err)) {
  96                 goto done;
  97         }
  98 
  99         snprintf(test_file, sizeof(test_file), "progs/%s.c", test_case->name);
 100         if (access(test_file, R_OK) == -1)
 101                 /*
 102                  * When the test is run with O=, kselftest copies TEST_FILES
 103                  * without preserving the directory structure.
 104                  */
 105                 snprintf(test_file, sizeof(test_file), "%s.c",
 106                         test_case->name);
 107         /*
 108          * Diff test output and expected test output, contained between
 109          * START-EXPECTED-OUTPUT and END-EXPECTED-OUTPUT lines in test case.
 110          * For expected output lines, everything before '*' is stripped out.
 111          * Also lines containing comment start and comment end markers are
 112          * ignored. 
 113          */
 114         snprintf(diff_cmd, sizeof(diff_cmd),
 115                  "awk '/START-EXPECTED-OUTPUT/{out=1;next} "
 116                  "/END-EXPECTED-OUTPUT/{out=0} "
 117                  "/\\/\\*|\\*\\//{next} " /* ignore comment start/end lines */
 118                  "out {sub(/^[ \\t]*\\*/, \"\"); print}' '%s' | diff -u - '%s'",
 119                  test_file, out_file);
 120         err = system(diff_cmd);
 121         if (CHECK(err,
 122                   "differing test output, output=%s, err=%d, diff cmd:\n%s\n",
 123                   out_file, err, diff_cmd))
 124                 goto done;
 125 
 126         remove(out_file);
 127         fprintf(stderr, "OK\n");
 128 
 129 done:
 130         btf__free(btf);
 131         return err;
 132 }
 133 
 134 int main() {
 135         int test_case_cnt, i, err, failed = 0;
 136 
 137         test_case_cnt = sizeof(btf_dump_test_cases) /
 138                         sizeof(btf_dump_test_cases[0]);
 139 
 140         for (i = 0; i < test_case_cnt; i++) {
 141                 err = test_btf_dump_case(i, &btf_dump_test_cases[i]);
 142                 if (err)
 143                         failed++;
 144         }
 145 
 146         fprintf(stderr, "%d tests succeeded, %d tests failed.\n",
 147                 test_case_cnt - failed, failed);
 148 
 149         return failed;
 150 }

/* [<][>][^][v][top][bottom][index][help] */