tools/bpf: add bpffs pretty print btf test for hash/lru_hash maps

Pretty print tests for hash/lru_hash maps are added in test_btf.c.
The btf type blob is the same as pretty print array map test.
The test result:
  $ mount -t bpf bpf /sys/fs/bpf
  $ ./test_btf -p
    BTF pretty print array......OK
    BTF pretty print hash......OK
    BTF pretty print lru hash......OK
    PASS:3 SKIP:0 FAIL:0

Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
This commit is contained in:
Yonghong Song 2018-08-09 08:55:21 -07:00 committed by Daniel Borkmann
parent 699c86d6ec
commit af2a81dab4

View file

@ -131,6 +131,8 @@ struct btf_raw_test {
__u32 max_entries; __u32 max_entries;
bool btf_load_err; bool btf_load_err;
bool map_create_err; bool map_create_err;
bool ordered_map;
bool lossless_map;
int hdr_len_delta; int hdr_len_delta;
int type_off_delta; int type_off_delta;
int str_off_delta; int str_off_delta;
@ -2093,8 +2095,7 @@ struct pprint_mapv {
} aenum; } aenum;
}; };
static struct btf_raw_test pprint_test = { static struct btf_raw_test pprint_test_template = {
.descr = "BTF pretty print test #1",
.raw_types = { .raw_types = {
/* unsighed char */ /* [1] */ /* unsighed char */ /* [1] */
BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1), BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
@ -2146,8 +2147,6 @@ static struct btf_raw_test pprint_test = {
}, },
.str_sec = "\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum", .str_sec = "\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum",
.str_sec_size = sizeof("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum"), .str_sec_size = sizeof("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum"),
.map_type = BPF_MAP_TYPE_ARRAY,
.map_name = "pprint_test",
.key_size = sizeof(unsigned int), .key_size = sizeof(unsigned int),
.value_size = sizeof(struct pprint_mapv), .value_size = sizeof(struct pprint_mapv),
.key_type_id = 3, /* unsigned int */ .key_type_id = 3, /* unsigned int */
@ -2155,6 +2154,40 @@ static struct btf_raw_test pprint_test = {
.max_entries = 128 * 1024, .max_entries = 128 * 1024,
}; };
static struct btf_pprint_test_meta {
const char *descr;
enum bpf_map_type map_type;
const char *map_name;
bool ordered_map;
bool lossless_map;
} pprint_tests_meta[] = {
{
.descr = "BTF pretty print array",
.map_type = BPF_MAP_TYPE_ARRAY,
.map_name = "pprint_test_array",
.ordered_map = true,
.lossless_map = true,
},
{
.descr = "BTF pretty print hash",
.map_type = BPF_MAP_TYPE_HASH,
.map_name = "pprint_test_hash",
.ordered_map = false,
.lossless_map = true,
},
{
.descr = "BTF pretty print lru hash",
.map_type = BPF_MAP_TYPE_LRU_HASH,
.map_name = "pprint_test_lru_hash",
.ordered_map = false,
.lossless_map = false,
},
};
static void set_pprint_mapv(struct pprint_mapv *v, uint32_t i) static void set_pprint_mapv(struct pprint_mapv *v, uint32_t i)
{ {
v->ui32 = i; v->ui32 = i;
@ -2166,10 +2199,12 @@ static void set_pprint_mapv(struct pprint_mapv *v, uint32_t i)
v->aenum = i & 0x03; v->aenum = i & 0x03;
} }
static int test_pprint(void) static int do_test_pprint(void)
{ {
const struct btf_raw_test *test = &pprint_test; const struct btf_raw_test *test = &pprint_test_template;
struct bpf_create_map_attr create_attr = {}; struct bpf_create_map_attr create_attr = {};
unsigned int key, nr_read_elems;
bool ordered_map, lossless_map;
int map_fd = -1, btf_fd = -1; int map_fd = -1, btf_fd = -1;
struct pprint_mapv mapv = {}; struct pprint_mapv mapv = {};
unsigned int raw_btf_size; unsigned int raw_btf_size;
@ -2178,7 +2213,6 @@ static int test_pprint(void)
char pin_path[255]; char pin_path[255];
size_t line_len = 0; size_t line_len = 0;
char *line = NULL; char *line = NULL;
unsigned int key;
uint8_t *raw_btf; uint8_t *raw_btf;
ssize_t nread; ssize_t nread;
int err, ret; int err, ret;
@ -2251,14 +2285,18 @@ static int test_pprint(void)
goto done; goto done;
} }
key = 0; nr_read_elems = 0;
ordered_map = test->ordered_map;
lossless_map = test->lossless_map;
do { do {
ssize_t nexpected_line; ssize_t nexpected_line;
unsigned int next_key;
set_pprint_mapv(&mapv, key); next_key = ordered_map ? nr_read_elems : atoi(line);
set_pprint_mapv(&mapv, next_key);
nexpected_line = snprintf(expected_line, sizeof(expected_line), nexpected_line = snprintf(expected_line, sizeof(expected_line),
"%u: {%u,0,%d,0x%x,0x%x,0x%x,{%lu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s}\n", "%u: {%u,0,%d,0x%x,0x%x,0x%x,{%lu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s}\n",
key, next_key,
mapv.ui32, mapv.si32, mapv.ui32, mapv.si32,
mapv.unused_bits2a, mapv.bits28, mapv.unused_bits2b, mapv.unused_bits2a, mapv.bits28, mapv.unused_bits2b,
mapv.ui64, mapv.ui64,
@ -2281,11 +2319,12 @@ static int test_pprint(void)
} }
nread = getline(&line, &line_len, pin_file); nread = getline(&line, &line_len, pin_file);
} while (++key < test->max_entries && nread > 0); } while (++nr_read_elems < test->max_entries && nread > 0);
if (CHECK(key < test->max_entries, if (lossless_map &&
"Unexpected EOF. key:%u test->max_entries:%u", CHECK(nr_read_elems < test->max_entries,
key, test->max_entries)) { "Unexpected EOF. nr_read_elems:%u test->max_entries:%u",
nr_read_elems, test->max_entries)) {
err = -1; err = -1;
goto done; goto done;
} }
@ -2314,6 +2353,24 @@ static int test_pprint(void)
return err; return err;
} }
static int test_pprint(void)
{
unsigned int i;
int err = 0;
for (i = 0; i < ARRAY_SIZE(pprint_tests_meta); i++) {
pprint_test_template.descr = pprint_tests_meta[i].descr;
pprint_test_template.map_type = pprint_tests_meta[i].map_type;
pprint_test_template.map_name = pprint_tests_meta[i].map_name;
pprint_test_template.ordered_map = pprint_tests_meta[i].ordered_map;
pprint_test_template.lossless_map = pprint_tests_meta[i].lossless_map;
err |= count_result(do_test_pprint());
}
return err;
}
static void usage(const char *cmd) static void usage(const char *cmd)
{ {
fprintf(stderr, "Usage: %s [-l] [[-r test_num (1 - %zu)] | [-g test_num (1 - %zu)] | [-f test_num (1 - %zu)] | [-p]]\n", fprintf(stderr, "Usage: %s [-l] [[-r test_num (1 - %zu)] | [-g test_num (1 - %zu)] | [-f test_num (1 - %zu)] | [-p]]\n",
@ -2409,7 +2466,7 @@ int main(int argc, char **argv)
err |= test_file(); err |= test_file();
if (args.pprint_test) if (args.pprint_test)
err |= count_result(test_pprint()); err |= test_pprint();
if (args.raw_test || args.get_info_test || args.file_test || if (args.raw_test || args.get_info_test || args.file_test ||
args.pprint_test) args.pprint_test)