xref: /aosp_15_r20/external/igt-gpu-tools/runner/runner_json_tests.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker #include <sys/types.h>
2*d83cc019SAndroid Build Coastguard Worker #include <sys/stat.h>
3*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
4*d83cc019SAndroid Build Coastguard Worker 
5*d83cc019SAndroid Build Coastguard Worker #include <json.h>
6*d83cc019SAndroid Build Coastguard Worker 
7*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
8*d83cc019SAndroid Build Coastguard Worker #include "resultgen.h"
9*d83cc019SAndroid Build Coastguard Worker 
10*d83cc019SAndroid Build Coastguard Worker static char testdatadir[] = JSON_TESTS_DIRECTORY;
11*d83cc019SAndroid Build Coastguard Worker 
read_json(int fd)12*d83cc019SAndroid Build Coastguard Worker static struct json_object *read_json(int fd)
13*d83cc019SAndroid Build Coastguard Worker {
14*d83cc019SAndroid Build Coastguard Worker 	struct json_object *obj;
15*d83cc019SAndroid Build Coastguard Worker 	struct json_tokener *tok = json_tokener_new();
16*d83cc019SAndroid Build Coastguard Worker 	enum json_tokener_error err;
17*d83cc019SAndroid Build Coastguard Worker 	char buf[512];
18*d83cc019SAndroid Build Coastguard Worker 	ssize_t s;
19*d83cc019SAndroid Build Coastguard Worker 
20*d83cc019SAndroid Build Coastguard Worker 	do {
21*d83cc019SAndroid Build Coastguard Worker 		s = read(fd, buf, sizeof(buf));
22*d83cc019SAndroid Build Coastguard Worker 		obj = json_tokener_parse_ex(tok, buf, s);
23*d83cc019SAndroid Build Coastguard Worker 	} while ((err = json_tokener_get_error(tok)) == json_tokener_continue);
24*d83cc019SAndroid Build Coastguard Worker 
25*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(err, json_tokener_success);
26*d83cc019SAndroid Build Coastguard Worker 
27*d83cc019SAndroid Build Coastguard Worker 	json_tokener_free(tok);
28*d83cc019SAndroid Build Coastguard Worker 	return obj;
29*d83cc019SAndroid Build Coastguard Worker }
30*d83cc019SAndroid Build Coastguard Worker 
31*d83cc019SAndroid Build Coastguard Worker static void compare(struct json_object *one,
32*d83cc019SAndroid Build Coastguard Worker 		    struct json_object *two);
33*d83cc019SAndroid Build Coastguard Worker 
compare_objects(struct json_object * one,struct json_object * two)34*d83cc019SAndroid Build Coastguard Worker static void compare_objects(struct json_object *one,
35*d83cc019SAndroid Build Coastguard Worker 			    struct json_object *two)
36*d83cc019SAndroid Build Coastguard Worker {
37*d83cc019SAndroid Build Coastguard Worker 	json_object_iter iter;
38*d83cc019SAndroid Build Coastguard Worker 	struct json_object *subobj;
39*d83cc019SAndroid Build Coastguard Worker 
40*d83cc019SAndroid Build Coastguard Worker 	json_object_object_foreachC(one, iter) {
41*d83cc019SAndroid Build Coastguard Worker 		igt_debug("Key %s\n", iter.key);
42*d83cc019SAndroid Build Coastguard Worker 
43*d83cc019SAndroid Build Coastguard Worker 		igt_assert(json_object_object_get_ex(two, iter.key, &subobj));
44*d83cc019SAndroid Build Coastguard Worker 
45*d83cc019SAndroid Build Coastguard Worker 		compare(iter.val, subobj);
46*d83cc019SAndroid Build Coastguard Worker 	}
47*d83cc019SAndroid Build Coastguard Worker }
48*d83cc019SAndroid Build Coastguard Worker 
compare_arrays(struct json_object * one,struct json_object * two)49*d83cc019SAndroid Build Coastguard Worker static void compare_arrays(struct json_object *one,
50*d83cc019SAndroid Build Coastguard Worker 			   struct json_object *two)
51*d83cc019SAndroid Build Coastguard Worker {
52*d83cc019SAndroid Build Coastguard Worker 	size_t i;
53*d83cc019SAndroid Build Coastguard Worker 
54*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < json_object_array_length(one); i++) {
55*d83cc019SAndroid Build Coastguard Worker 		igt_debug("Array index %zd\n", i);
56*d83cc019SAndroid Build Coastguard Worker 		compare(json_object_array_get_idx(one, i),
57*d83cc019SAndroid Build Coastguard Worker 			json_object_array_get_idx(two, i));
58*d83cc019SAndroid Build Coastguard Worker 	}
59*d83cc019SAndroid Build Coastguard Worker }
60*d83cc019SAndroid Build Coastguard Worker 
compatible_types(struct json_object * one,struct json_object * two)61*d83cc019SAndroid Build Coastguard Worker static bool compatible_types(struct json_object *one,
62*d83cc019SAndroid Build Coastguard Worker 			     struct json_object *two)
63*d83cc019SAndroid Build Coastguard Worker {
64*d83cc019SAndroid Build Coastguard Worker 	/*
65*d83cc019SAndroid Build Coastguard Worker 	 * A double of value 0.0 gets written as "0", which gets read
66*d83cc019SAndroid Build Coastguard Worker 	 * as an int.
67*d83cc019SAndroid Build Coastguard Worker 	 */
68*d83cc019SAndroid Build Coastguard Worker 	json_type onetype = json_object_get_type(one);
69*d83cc019SAndroid Build Coastguard Worker 	json_type twotype = json_object_get_type(two);
70*d83cc019SAndroid Build Coastguard Worker 
71*d83cc019SAndroid Build Coastguard Worker 	switch (onetype) {
72*d83cc019SAndroid Build Coastguard Worker 	case json_type_boolean:
73*d83cc019SAndroid Build Coastguard Worker 	case json_type_string:
74*d83cc019SAndroid Build Coastguard Worker 	case json_type_object:
75*d83cc019SAndroid Build Coastguard Worker 	case json_type_array:
76*d83cc019SAndroid Build Coastguard Worker 	case json_type_null:
77*d83cc019SAndroid Build Coastguard Worker 		return onetype == twotype;
78*d83cc019SAndroid Build Coastguard Worker 		break;
79*d83cc019SAndroid Build Coastguard Worker 	case json_type_double:
80*d83cc019SAndroid Build Coastguard Worker 	case json_type_int:
81*d83cc019SAndroid Build Coastguard Worker 		return twotype == json_type_double || twotype == json_type_int;
82*d83cc019SAndroid Build Coastguard Worker 		break;
83*d83cc019SAndroid Build Coastguard Worker 	}
84*d83cc019SAndroid Build Coastguard Worker 
85*d83cc019SAndroid Build Coastguard Worker 	igt_assert(!"Cannot be reached");
86*d83cc019SAndroid Build Coastguard Worker 	return false;
87*d83cc019SAndroid Build Coastguard Worker }
88*d83cc019SAndroid Build Coastguard Worker 
compare(struct json_object * one,struct json_object * two)89*d83cc019SAndroid Build Coastguard Worker static void compare(struct json_object *one,
90*d83cc019SAndroid Build Coastguard Worker 		    struct json_object *two)
91*d83cc019SAndroid Build Coastguard Worker {
92*d83cc019SAndroid Build Coastguard Worker 	igt_assert(compatible_types(one, two));
93*d83cc019SAndroid Build Coastguard Worker 
94*d83cc019SAndroid Build Coastguard Worker 	switch (json_object_get_type(one)) {
95*d83cc019SAndroid Build Coastguard Worker 	case json_type_boolean:
96*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(json_object_get_boolean(one), json_object_get_boolean(two));
97*d83cc019SAndroid Build Coastguard Worker 		break;
98*d83cc019SAndroid Build Coastguard Worker 	case json_type_double:
99*d83cc019SAndroid Build Coastguard Worker 	case json_type_int:
100*d83cc019SAndroid Build Coastguard Worker 		/*
101*d83cc019SAndroid Build Coastguard Worker 		 * A double of value 0.0 gets written as "0", which
102*d83cc019SAndroid Build Coastguard Worker 		 * gets read as an int. Both yield 0.0 with
103*d83cc019SAndroid Build Coastguard Worker 		 * json_object_get_double(). Comparing doubles with ==
104*d83cc019SAndroid Build Coastguard Worker 		 * considered crazy but it's good enough.
105*d83cc019SAndroid Build Coastguard Worker 		 */
106*d83cc019SAndroid Build Coastguard Worker 		igt_assert(json_object_get_double(one) == json_object_get_double(two));
107*d83cc019SAndroid Build Coastguard Worker 		break;
108*d83cc019SAndroid Build Coastguard Worker 	case json_type_string:
109*d83cc019SAndroid Build Coastguard Worker 		igt_assert(!strcmp(json_object_get_string(one), json_object_get_string(two)));
110*d83cc019SAndroid Build Coastguard Worker 		break;
111*d83cc019SAndroid Build Coastguard Worker 	case json_type_object:
112*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(json_object_object_length(one), json_object_object_length(two));
113*d83cc019SAndroid Build Coastguard Worker 		compare_objects(one, two);
114*d83cc019SAndroid Build Coastguard Worker 		break;
115*d83cc019SAndroid Build Coastguard Worker 	case json_type_array:
116*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(json_object_array_length(one), json_object_array_length(two));
117*d83cc019SAndroid Build Coastguard Worker 		compare_arrays(one, two);
118*d83cc019SAndroid Build Coastguard Worker 		break;
119*d83cc019SAndroid Build Coastguard Worker 	case json_type_null:
120*d83cc019SAndroid Build Coastguard Worker 		break;
121*d83cc019SAndroid Build Coastguard Worker 	default:
122*d83cc019SAndroid Build Coastguard Worker 		igt_assert(!"Cannot be reached");
123*d83cc019SAndroid Build Coastguard Worker 	}
124*d83cc019SAndroid Build Coastguard Worker }
125*d83cc019SAndroid Build Coastguard Worker 
run_results_and_compare(int dirfd,const char * dirname)126*d83cc019SAndroid Build Coastguard Worker static void run_results_and_compare(int dirfd, const char *dirname)
127*d83cc019SAndroid Build Coastguard Worker {
128*d83cc019SAndroid Build Coastguard Worker 	int testdirfd = openat(dirfd, dirname, O_RDONLY | O_DIRECTORY);
129*d83cc019SAndroid Build Coastguard Worker 	int reference;
130*d83cc019SAndroid Build Coastguard Worker 	struct json_object *resultsobj, *referenceobj;
131*d83cc019SAndroid Build Coastguard Worker 
132*d83cc019SAndroid Build Coastguard Worker 	igt_assert_fd(testdirfd);
133*d83cc019SAndroid Build Coastguard Worker 
134*d83cc019SAndroid Build Coastguard Worker 	igt_assert((resultsobj = generate_results_json(testdirfd)) != NULL);
135*d83cc019SAndroid Build Coastguard Worker 
136*d83cc019SAndroid Build Coastguard Worker 	reference = openat(testdirfd, "reference.json", O_RDONLY);
137*d83cc019SAndroid Build Coastguard Worker 	close(testdirfd);
138*d83cc019SAndroid Build Coastguard Worker 
139*d83cc019SAndroid Build Coastguard Worker 	igt_assert_fd(reference);
140*d83cc019SAndroid Build Coastguard Worker 	referenceobj = read_json(reference);
141*d83cc019SAndroid Build Coastguard Worker 	close(reference);
142*d83cc019SAndroid Build Coastguard Worker 	igt_assert(referenceobj != NULL);
143*d83cc019SAndroid Build Coastguard Worker 
144*d83cc019SAndroid Build Coastguard Worker 	igt_debug("Root object\n");
145*d83cc019SAndroid Build Coastguard Worker 	compare(resultsobj, referenceobj);
146*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(json_object_put(resultsobj), 1);
147*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(json_object_put(referenceobj), 1);
148*d83cc019SAndroid Build Coastguard Worker }
149*d83cc019SAndroid Build Coastguard Worker 
150*d83cc019SAndroid Build Coastguard Worker static const char *dirnames[] = {
151*d83cc019SAndroid Build Coastguard Worker 	"normal-run",
152*d83cc019SAndroid Build Coastguard Worker 	"warnings",
153*d83cc019SAndroid Build Coastguard Worker 	"warnings-with-dmesg-warns",
154*d83cc019SAndroid Build Coastguard Worker 	"piglit-style-dmesg",
155*d83cc019SAndroid Build Coastguard Worker 	"incomplete-before-any-subtests",
156*d83cc019SAndroid Build Coastguard Worker 	"dmesg-results",
157*d83cc019SAndroid Build Coastguard Worker 	"aborted-on-boot",
158*d83cc019SAndroid Build Coastguard Worker 	"aborted-after-a-test",
159*d83cc019SAndroid Build Coastguard Worker 	"dmesg-escapes",
160*d83cc019SAndroid Build Coastguard Worker 	"notrun-results",
161*d83cc019SAndroid Build Coastguard Worker 	"notrun-results-multiple-mode",
162*d83cc019SAndroid Build Coastguard Worker 	"dmesg-warn-level",
163*d83cc019SAndroid Build Coastguard Worker 	"dmesg-warn-level-piglit-style",
164*d83cc019SAndroid Build Coastguard Worker 	"dmesg-warn-level-one-piglit-style"
165*d83cc019SAndroid Build Coastguard Worker };
166*d83cc019SAndroid Build Coastguard Worker 
167*d83cc019SAndroid Build Coastguard Worker igt_main
168*d83cc019SAndroid Build Coastguard Worker {
169*d83cc019SAndroid Build Coastguard Worker 	int dirfd = open(testdatadir, O_RDONLY | O_DIRECTORY);
170*d83cc019SAndroid Build Coastguard Worker 	size_t i;
171*d83cc019SAndroid Build Coastguard Worker 
172*d83cc019SAndroid Build Coastguard Worker 	igt_assert_fd(dirfd);
173*d83cc019SAndroid Build Coastguard Worker 
174*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(dirnames); i++) {
igt_subtest(dirnames[i])175*d83cc019SAndroid Build Coastguard Worker 		igt_subtest(dirnames[i]) {
176*d83cc019SAndroid Build Coastguard Worker 			run_results_and_compare(dirfd, dirnames[i]);
177*d83cc019SAndroid Build Coastguard Worker 		}
178*d83cc019SAndroid Build Coastguard Worker 	}
179*d83cc019SAndroid Build Coastguard Worker }
180