Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.13.7.
  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
 18void btf_dump_printf(void *ctx, const char *fmt, va_list args)
 19{
 20	vfprintf(ctx, fmt, args);
 21}
 22
 23struct 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
 36static 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
 53done:
 54	btf_dump__free(d);
 55	return err;
 56}
 57
 58int 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
129done:
130	btf__free(btf);
131	return err;
132}
133
134int 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}