Test cases for btf_dump__dump_one_type() and company: - peek a type, save it's dependencies to the emit queue, print the content of the emit queue, expect only relevant dependencies; - print a forward declaration for a single type, expect no dependencies in the output; - print a full dependencies for a type, expect no dependencies in the output. Signed-off-by: Eduard Zingerman <eddyz87@xxxxxxxxx> --- .../selftests/bpf/prog_tests/btf_dump.c | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/tools/testing/selftests/bpf/prog_tests/btf_dump.c b/tools/testing/selftests/bpf/prog_tests/btf_dump.c index e9ea38aa8248..04f32472e221 100644 --- a/tools/testing/selftests/bpf/prog_tests/btf_dump.c +++ b/tools/testing/selftests/bpf/prog_tests/btf_dump.c @@ -255,6 +255,90 @@ static void test_btf_dump_incremental(void) btf__free(btf); } +static void test_btf_dump_emit_queue(void) +{ + struct btf_dump_emit_queue_item *items; + struct btf_dump *d = NULL; + struct btf *btf = NULL; + u32 union_simple; + int err, i, cnt; + + btf = btf__parse_elf("btf_dump_test_case_syntax.bpf.o", NULL); + if (!ASSERT_OK_PTR(btf, "btf_parse_elf")) { + err = -PTR_ERR(btf); + btf = NULL; + goto err_out; + } + + union_simple = btf__find_by_name_kind(btf, "union_simple", BTF_KIND_UNION); + ASSERT_GT(union_simple, 0, "'union_simple' id"); + + dump_buf_file = open_memstream(&dump_buf, &dump_buf_sz); + if (!ASSERT_OK_PTR(dump_buf_file, "dump_memstream")) + return; + d = btf_dump__new(btf, btf_dump_printf, dump_buf_file, NULL); + if (!ASSERT_OK(libbpf_get_error(d), "btf_dump__new")) + goto err_out; + + err = btf_dump__order_type(d, union_simple); + ASSERT_OK(err, "order type 'union_simple'"); + cnt = btf_dump__emit_queue_cnt(d); + items = btf_dump__emit_queue(d); + for (i = 1; i < cnt; i++) { + err = btf_dump__dump_one_type(d, items[i].id, items[i].fwd); + if (err > 0) + fprintf(dump_buf_file, ";\n\n"); + } + + fflush(dump_buf_file); + dump_buf[dump_buf_sz] = 0; + + ASSERT_STREQ(dump_buf, +"union union_empty {};\n" +"\n" +"union union_simple {\n" +" void *ptr;\n" +" int num;\n" +" int_t num2;\n" +" union union_empty u;\n" +"};\n\n", "c_dump1"); + + btf_dump__free(d); + d = btf_dump__new(btf, btf_dump_printf, dump_buf_file, NULL); + if (!ASSERT_OK(libbpf_get_error(d), "btf_dump__new")) { + d = NULL; + goto err_out; + } + err = btf_dump__order_type(d, union_simple); + ASSERT_OK(err, "order type 'union_simple'"); + + rewind(dump_buf_file); + btf_dump__dump_one_type(d, union_simple, true); + fflush(dump_buf_file); + dump_buf[dump_buf_sz] = 0; + + ASSERT_STREQ(dump_buf, "union union_simple", "c_dump2"); + + rewind(dump_buf_file); + btf_dump__dump_one_type(d, union_simple, false); + fflush(dump_buf_file); + dump_buf[dump_buf_sz] = 0; + + ASSERT_STREQ(dump_buf, +"union union_simple {\n" +" void *ptr;\n" +" int num;\n" +" int_t num2;\n" +" union union_empty u;\n" +"}", "c_dump3"); + +err_out: + fclose(dump_buf_file); + free(dump_buf); + btf_dump__free(d); + btf__free(btf); +} + #define STRSIZE 4096 static void btf_dump_snprintf(void *ctx, const char *fmt, va_list args) @@ -873,6 +957,8 @@ void test_btf_dump() { } if (test__start_subtest("btf_dump: incremental")) test_btf_dump_incremental(); + if (test__start_subtest("btf_dump: emit queue")) + test_btf_dump_emit_queue(); btf = libbpf_find_kernel_btf(); if (!ASSERT_OK_PTR(btf, "no kernel BTF found")) -- 2.34.1