Blob Blame History Raw
From: Yonghong Song <yhs@fb.com>
Date: Thu, 9 Aug 2018 08:55:21 -0700
Subject: tools/bpf: add bpffs pretty print btf test for hash/lru_hash maps
Patch-mainline: v4.19-rc1
Git-commit: af2a81dab44758de0b94679615ea75e8ee30aace
References: bsc#1109837

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>
Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
 tools/testing/selftests/bpf/test_btf.c |   87 +++++++++++++++++++++++++++------
 1 file changed, 72 insertions(+), 15 deletions(-)

--- a/tools/testing/selftests/bpf/test_btf.c
+++ b/tools/testing/selftests/bpf/test_btf.c
@@ -131,6 +131,8 @@ struct btf_raw_test {
 	__u32 max_entries;
 	bool btf_load_err;
 	bool map_create_err;
+	bool ordered_map;
+	bool lossless_map;
 	int hdr_len_delta;
 	int type_off_delta;
 	int str_off_delta;
@@ -2093,8 +2095,7 @@ struct pprint_mapv {
 	} aenum;
 };
 
-static struct btf_raw_test pprint_test = {
-	.descr = "BTF pretty print test #1",
+static struct btf_raw_test pprint_test_template = {
 	.raw_types = {
 		/* unsighed char */			/* [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_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),
 	.value_size = sizeof(struct pprint_mapv),
 	.key_type_id = 3,	/* unsigned int */
@@ -2155,6 +2154,40 @@ static struct btf_raw_test pprint_test =
 	.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)
 {
 	v->ui32 = i;
@@ -2166,10 +2199,12 @@ static void set_pprint_mapv(struct pprin
 	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 = {};
+	unsigned int key, nr_read_elems;
+	bool ordered_map, lossless_map;
 	int map_fd = -1, btf_fd = -1;
 	struct pprint_mapv mapv = {};
 	unsigned int raw_btf_size;
@@ -2178,7 +2213,6 @@ static int test_pprint(void)
 	char pin_path[255];
 	size_t line_len = 0;
 	char *line = NULL;
-	unsigned int key;
 	uint8_t *raw_btf;
 	ssize_t nread;
 	int err, ret;
@@ -2251,14 +2285,18 @@ static int test_pprint(void)
 		goto done;
 	}
 
-	key = 0;
+	nr_read_elems = 0;
+	ordered_map = test->ordered_map;
+	lossless_map = test->lossless_map;
 	do {
 		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),
 					  "%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.unused_bits2a, mapv.bits28, mapv.unused_bits2b,
 					  mapv.ui64,
@@ -2281,11 +2319,12 @@ static int test_pprint(void)
 		}
 
 		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,
-		  "Unexpected EOF. key:%u test->max_entries:%u",
-		  key, test->max_entries)) {
+	if (lossless_map &&
+	    CHECK(nr_read_elems < test->max_entries,
+		  "Unexpected EOF. nr_read_elems:%u test->max_entries:%u",
+		  nr_read_elems, test->max_entries)) {
 		err = -1;
 		goto done;
 	}
@@ -2314,6 +2353,24 @@ done:
 	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)
 {
 	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();
 
 	if (args.pprint_test)
-		err |= count_result(test_pprint());
+		err |= test_pprint();
 
 	if (args.raw_test || args.get_info_test || args.file_test ||
 	    args.pprint_test)