[igt-dev] [PATCH i-g-t 1/3] runner: Use Jansson in resultgen instead of json-c

Ryszard Knop ryszard.knop at intel.com
Wed Aug 10 13:55:28 UTC 2022


The json-c library has a hard limit of 2GB of its output. While normally
it's not a problem, some very verbose edge cases make the results.json
output go past that limit.

Jansson has a similar API, can work with files over 2GB and, according
to JSON library and benchmarks, is slightly slower but uses less RAM to
serialize its output. Jansson 2.12+ (released in 2018) is required.

This commit also updates tests to use Jansson, but they need data fixups
to pass (in the next commit).

Signed-off-by: Ryszard Knop <ryszard.knop at intel.com>
---
 runner/meson.build         |  12 +-
 runner/resultgen.c         | 349 +++++++++++++++++--------------------
 runner/resultgen.h         |   2 +-
 runner/runner_json_tests.c | 129 +++++---------
 runner/runner_tests.c      |  60 +++----
 5 files changed, 247 insertions(+), 305 deletions(-)

diff --git a/runner/meson.build b/runner/meson.build
index c3927af5..4e25f70a 100644
--- a/runner/meson.build
+++ b/runner/meson.build
@@ -13,8 +13,8 @@ results_sources = [ 'results.c' ]
 runner_test_sources = [ 'runner_tests.c' ]
 runner_json_test_sources = [ 'runner_json_tests.c' ]
 
-jsonc = dependency('json-c', required: build_runner)
-runner_deps = [jsonc, glib]
+jansson = dependency('jansson', required: build_runner, version: '>=2.12')
+runner_deps = [jansson, glib]
 runner_c_args = []
 
 liboping = dependency('liboping', required: get_option('oping'))
@@ -23,11 +23,11 @@ if liboping.found()
 	runner_c_args += '-DHAVE_OPING=1'
 endif
 
-if not build_tests and jsonc.found()
+if not build_tests and jansson.found()
 	error('Building test runner requires building tests')
 endif
 
-if jsonc.found()
+if jansson.found()
 	subdir('testdata')
 
 	runnerlib = static_library('igt_runner', runnerlib_sources,
@@ -60,14 +60,14 @@ if jsonc.found()
 				 c_args : '-DTESTDATA_DIRECTORY="@0@"'.format(testdata_dir),
 				 link_with : runnerlib,
 				 install : false,
-				 dependencies : [igt_deps, jsonc])
+				 dependencies : [igt_deps, jansson])
 	test('runner', runner_test, timeout : 300)
 
 	runner_json_test = executable('runner_json_test', runner_json_test_sources,
 				      c_args : '-DJSON_TESTS_DIRECTORY="@0@"'.format(join_paths(meson.current_source_dir(), 'json_tests_data')),
 				      link_with : runnerlib,
 				      install : false,
-				      dependencies : [igt_deps, jsonc])
+				      dependencies : [igt_deps, jansson])
 	test('runner_json', runner_json_test, timeout : 300)
 
 	build_info += 'Build test runner: true'
diff --git a/runner/resultgen.c b/runner/resultgen.c
index 479d6d4f..eda31267 100644
--- a/runner/resultgen.c
+++ b/runner/resultgen.c
@@ -5,10 +5,9 @@
 #include <string.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
-#include <sys/types.h>
 #include <unistd.h>
 
-#include <json.h>
+#include <jansson.h>
 
 #include "igt_aux.h"
 #include "igt_core.h"
@@ -40,9 +39,9 @@ struct subtest_list
 
 struct results
 {
-	struct json_object *tests;
-	struct json_object *totals;
-	struct json_object *runtimes;
+	struct json_t *tests;
+	struct json_t *totals;
+	struct json_t *runtimes;
 };
 
 static void add_dynamic_subtest(struct subtest *subtest, char *dynamic)
@@ -257,61 +256,54 @@ static void parse_subtest_result(const char *subtest,
 	parse_result_string(resultstring, linelen - (resultstring - line), result, time);
 }
 
-static struct json_object *get_or_create_json_object(struct json_object *base,
-						     const char *key)
+static struct json_t *get_or_create_json_object(struct json_t *base, const char *key)
 {
-	struct json_object *ret;
+	struct json_t *ret = json_object_get(base, key);
 
-	if (json_object_object_get_ex(base, key, &ret))
+	if (ret)
 		return ret;
 
-	ret = json_object_new_object();
-	json_object_object_add(base, key, ret);
+	ret = json_object();
+	json_object_set_new(base, key, ret);
 
 	return ret;
 }
 
-static void set_result(struct json_object *obj, const char *result)
+static void set_result(struct json_t *obj, const char *result)
 {
-	if (result)
-		json_object_object_add(obj, "result",
-				       json_object_new_string(result));
+	if (!result)
+		return;
+
+	json_object_set_new(obj, "result", json_string(result));
 }
 
-static void add_runtime(struct json_object *obj, double time)
+static void add_runtime(struct json_t *obj, double time)
 {
 	double oldtime;
-	struct json_object *timeobj = get_or_create_json_object(obj, "time");
-	struct json_object *oldend;
+	struct json_t *timeobj = get_or_create_json_object(obj, "time");
+	struct json_t *oldend;
 
-	json_object_object_add(timeobj, "__type__",
-			       json_object_new_string("TimeAttribute"));
-	json_object_object_add(timeobj, "start",
-			       json_object_new_double(0.0));
+	json_object_set_new(timeobj, "__type__", json_string("TimeAttribute"));
+	json_object_set_new(timeobj, "start", json_real(0.0));
 
-	if (!json_object_object_get_ex(timeobj, "end", &oldend)) {
-		json_object_object_add(timeobj, "end",
-				       json_object_new_double(time));
+	if (!(oldend = json_object_get(timeobj, "end"))) {
+		json_object_set_new(timeobj, "end", json_real(time));
 		return;
 	}
 
 	/* Add the runtime to the existing runtime. */
-	oldtime = json_object_get_double(oldend);
+	oldtime = json_real_value(oldend);
 	time += oldtime;
-	json_object_object_add(timeobj, "end",
-			       json_object_new_double(time));
+	json_object_set_new(timeobj, "end", json_real(time));
 }
 
-static void set_runtime(struct json_object *obj, double time)
+static void set_runtime(struct json_t *obj, double time)
 {
-	struct json_object *timeobj = get_or_create_json_object(obj, "time");
-
-	json_object_object_add(timeobj, "__type__",
-			       json_object_new_string("TimeAttribute"));
-	json_object_object_add(timeobj, "start",
-			       json_object_new_double(0.0));
-	json_object_object_add(timeobj, "end",
-			       json_object_new_double(time));
+	struct json_t *timeobj = get_or_create_json_object(obj, "time");
+
+	json_object_set_new(timeobj, "__type__", json_string("TimeAttribute"));
+	json_object_set_new(timeobj, "start", json_real(0.0));
+	json_object_set_new(timeobj, "end", json_real(time));
 }
 
 struct match_item
@@ -396,7 +388,7 @@ static bool is_subtest_result_line(const char *needle, const char *line, const c
 	if (line >= bufend || *line++ != ':')
 		return false;
 
-	if (line >= bufend || *line++ != ' ')
+	if (line >= bufend || *line != ' ')
 		return false;
 
 	return true;
@@ -407,9 +399,9 @@ static void free_matches(struct matches *matches)
 	free(matches->items);
 }
 
-static struct json_object *new_escaped_json_string(const char *buf, size_t len)
+static struct json_t *escaped_json_stringn(const char *buf, size_t len)
 {
-	struct json_object *obj;
+	struct json_t *obj;
 	char *str = NULL;
 	size_t strsize = 0;
 	size_t i;
@@ -435,19 +427,18 @@ static struct json_object *new_escaped_json_string(const char *buf, size_t len)
 		}
 	}
 
-	obj = json_object_new_string_len(str, strsize);
+	obj = json_stringn(str, strsize);
 	free(str);
 
 	return obj;
 }
 
-static void add_igt_version(struct json_object *testobj,
+static void add_igt_version(struct json_t *testobj,
 			    const char *igt_version,
 			    size_t igt_version_len)
 {
 	if (igt_version)
-		json_object_object_add(testobj, "igt-version",
-				       new_escaped_json_string(igt_version, igt_version_len));
+		json_object_set_new(testobj, "igt-version", escaped_json_stringn(igt_version, igt_version_len));
 }
 
 enum subtest_find_pattern {
@@ -603,7 +594,7 @@ static void process_dynamic_subtest_output(const char *piglit_name,
 					   const char *beg,
 					   const char *end,
 					   const char *key,
-					   struct json_object *tests,
+					   struct json_t *tests,
 					   struct subtest *subtest)
 {
 	size_t k;
@@ -620,7 +611,7 @@ static void process_dynamic_subtest_output(const char *piglit_name,
 	}
 
 	for (k = begin_idx + 1; k < result_idx; k++) {
-		struct json_object *current_dynamic_test = NULL;
+		struct json_t *current_dynamic_test = NULL;
 		int dyn_result_idx;
 		char dynamic_name[256];
 		char dynamic_piglit_name[256];
@@ -644,11 +635,10 @@ static void process_dynamic_subtest_output(const char *piglit_name,
 		add_dynamic_subtest(subtest, strdup(dynamic_name));
 		current_dynamic_test = get_or_create_json_object(tests, dynamic_piglit_name);
 
-		json_object_object_add(current_dynamic_test, key,
-				       new_escaped_json_string(dynbeg, dynend - dynbeg));
+		json_object_set_new(current_dynamic_test, key, escaped_json_stringn(dynbeg, dynend - dynbeg));
 		add_igt_version(current_dynamic_test, igt_version, igt_version_len);
 
-		if (!json_object_object_get_ex(current_dynamic_test, "result", NULL)) {
+		if (!json_object_get(current_dynamic_test, "result")) {
 			const char *dynresulttext;
 			double dyntime;
 
@@ -667,11 +657,11 @@ static void process_dynamic_subtest_output(const char *piglit_name,
 			 * attribute this status to our subsubtest.
 			 */
 			if (!strcmp(dynresulttext, "incomplete")) {
-				struct json_object *parent_subtest;
+				struct json_t *parent_subtest;
 
-				if (json_object_object_get_ex(tests, piglit_name, &parent_subtest) &&
-				    json_object_object_get_ex(parent_subtest, "result", &parent_subtest)) {
-					const char *resulttext = json_object_get_string(parent_subtest);
+				if ((parent_subtest = json_object_get(tests, piglit_name)) &&
+				    (parent_subtest = json_object_get(parent_subtest, "result"))) {
+					const char *resulttext = json_string_value(parent_subtest);
 
 					if (!strcmp(resulttext, "abort") ||
 					    !strcmp(resulttext, "notrun"))
@@ -687,14 +677,14 @@ static void process_dynamic_subtest_output(const char *piglit_name,
 
 static bool fill_from_output(int fd, const char *binary, const char *key,
 			     struct subtest_list *subtests,
-			     struct json_object *tests)
+			     struct json_t *tests)
 {
 	char *buf, *bufend, *nullchr;
 	struct stat statbuf;
 	char piglit_name[256];
 	char *igt_version = NULL;
 	size_t igt_version_len = 0;
-	struct json_object *current_test = NULL;
+	struct json_t *current_test = NULL;
 	struct match_needle needles[] = {
 		{ STARTING_SUBTEST, NULL },
 		{ SUBTEST_RESULT, is_subtest_result_line },
@@ -738,8 +728,7 @@ static bool fill_from_output(int fd, const char *binary, const char *key,
 		generate_piglit_name(binary, NULL, piglit_name, sizeof(piglit_name));
 		current_test = get_or_create_json_object(tests, piglit_name);
 
-		json_object_object_add(current_test, key,
-				       new_escaped_json_string(buf, statbuf.st_size));
+		json_object_set_new(current_test, key, escaped_json_stringn(buf, statbuf.st_size));
 		add_igt_version(current_test, igt_version, igt_version_len);
 
 		return true;
@@ -762,12 +751,11 @@ static bool fill_from_output(int fd, const char *binary, const char *key,
 		beg = find_subtest_begin_limit(matches, begin_idx, result_idx, buf, bufend);
 		end = find_subtest_end_limit(matches, begin_idx, result_idx, buf, bufend);
 
-		json_object_object_add(current_test, key,
-				       new_escaped_json_string(beg, end - beg));
+		json_object_set_new(current_test, key, escaped_json_stringn(beg, end - beg));
 
 		add_igt_version(current_test, igt_version, igt_version_len);
 
-		if (!json_object_object_get_ex(current_test, "result", NULL)) {
+		if (!json_object_get(current_test, "result")) {
 			parse_subtest_result(subtests->subs[i].name,
 					     SUBTEST_RESULT,
 					     &resulttext, &time,
@@ -917,24 +905,22 @@ static void generate_formatted_dmesg_line(char *message,
 	*f = '\0';
 }
 
-static void add_dmesg(struct json_object *obj,
+static void add_dmesg(struct json_t *obj,
 		      const char *dmesg, size_t dmesglen,
 		      const char *warnings, size_t warningslen)
 {
-	json_object_object_add(obj, "dmesg",
-			       new_escaped_json_string(dmesg, dmesglen));
+	json_object_set_new(obj, "dmesg", escaped_json_stringn(dmesg, dmesglen));
 
-	if (warnings) {
-		json_object_object_add(obj, "dmesg-warnings",
-				       new_escaped_json_string(warnings, warningslen));
-	}
+	if (warnings)
+		json_object_set_new(obj, "dmesg-warnings",
+				    escaped_json_stringn(warnings, warningslen));
 }
 
-static void add_empty_dmesgs_where_missing(struct json_object *tests,
+static void add_empty_dmesgs_where_missing(struct json_t *tests,
 					   char *binary,
 					   struct subtest_list *subtests)
 {
-	struct json_object *current_test;
+	struct json_t *current_test;
 	char piglit_name[256];
 	char dynamic_piglit_name[256];
 	size_t i, k;
@@ -942,7 +928,7 @@ static void add_empty_dmesgs_where_missing(struct json_object *tests,
 	for (i = 0; i < subtests->size; i++) {
 		generate_piglit_name(binary, subtests->subs[i].name, piglit_name, sizeof(piglit_name));
 		current_test = get_or_create_json_object(tests, piglit_name);
-		if (!json_object_object_get_ex(current_test, "dmesg", NULL)) {
+		if (!json_object_get(current_test, "dmesg")) {
 			add_dmesg(current_test, "", 0, NULL, 0);
 		}
 
@@ -950,7 +936,7 @@ static void add_empty_dmesgs_where_missing(struct json_object *tests,
 			generate_piglit_name_for_dynamic(piglit_name, subtests->subs[i].dynamic_names[k],
 							 dynamic_piglit_name, sizeof(dynamic_piglit_name));
 			current_test = get_or_create_json_object(tests, dynamic_piglit_name);
-			if (!json_object_object_get_ex(current_test, "dmesg", NULL)) {
+			if (!json_object_get(current_test, "dmesg")) {
 				add_dmesg(current_test, "", 0, NULL, 0);
 			}
 		}
@@ -962,7 +948,7 @@ static bool fill_from_dmesg(int fd,
 			    struct settings *settings,
 			    char *binary,
 			    struct subtest_list *subtests,
-			    struct json_object *tests)
+			    struct json_t *tests)
 {
 	char *line = NULL;
 	char *warnings = NULL, *dynamic_warnings = NULL;
@@ -970,8 +956,8 @@ static bool fill_from_dmesg(int fd,
 	size_t linelen = 0;
 	size_t warningslen = 0, dynamic_warnings_len = 0;
 	size_t dmesglen = 0, dynamic_dmesg_len = 0;
-	struct json_object *current_test = NULL;
-	struct json_object *current_dynamic_test = NULL;
+	struct json_t *current_test = NULL;
+	struct json_t *current_dynamic_test = NULL;
 	FILE *f = fdopen(fd, "r");
 	char piglit_name[256];
 	char dynamic_piglit_name[256];
@@ -1135,15 +1121,15 @@ static void fill_from_journal(int fd,
 	char timeoutline[] = "timeout:";
 	int exitcode = INCOMPLETE_EXITCODE;
 	bool has_timeout = false;
-	struct json_object *tests = results->tests;
-	struct json_object *runtimes = results->runtimes;
+	struct json_t *tests = results->tests;
+	struct json_t *runtimes = results->runtimes;
 
 	while ((read = getline(&line, &linelen, f)) > 0) {
 		if (read >= strlen(exitline) && !memcmp(line, exitline, strlen(exitline))) {
 			char *p = strchr(line, '(');
 			char piglit_name[256];
 			double time = 0.0;
-			struct json_object *obj;
+			struct json_t *obj;
 
 			exitcode = atoi(line + strlen(exitline));
 
@@ -1168,7 +1154,7 @@ static void fill_from_journal(int fd,
 				char piglit_name[256];
 				char *p = strchr(line, '(');
 				double time = 0.0;
-				struct json_object *obj;
+				struct json_t *obj;
 
 				generate_piglit_name(entry->binary, last_subtest, piglit_name, sizeof(piglit_name));
 				obj = get_or_create_json_object(tests, piglit_name);
@@ -1194,7 +1180,7 @@ static void fill_from_journal(int fd,
 	if (subtests->size && (exitcode == IGT_EXIT_ABORT || exitcode == GRACEFUL_EXITCODE)) {
 		char *last_subtest = subtests->subs[subtests->size - 1].name;
 		char subtest_piglit_name[256];
-		struct json_object *subtest_obj;
+		struct json_t *subtest_obj;
 
 		generate_piglit_name(entry->binary, last_subtest, subtest_piglit_name, sizeof(subtest_piglit_name));
 		subtest_obj = get_or_create_json_object(tests, subtest_piglit_name);
@@ -1205,7 +1191,7 @@ static void fill_from_journal(int fd,
 	if (subtests->size == 0) {
 		char *subtestname = NULL;
 		char piglit_name[256];
-		struct json_object *obj;
+		struct json_t *obj;
 		const char *result = has_timeout ? "timeout" : result_from_exitcode(exitcode);
 
 		/*
@@ -1251,7 +1237,7 @@ static bool result_is_requested(struct job_list_entry *entry,
 static void prune_subtests(struct settings *settings,
 			   struct job_list_entry *entry,
 			   struct subtest_list *subtests,
-			   struct json_object *tests)
+			   struct json_t *tests)
 {
 	char piglit_name[256];
 	char dynamic_piglit_name[256];
@@ -1265,7 +1251,7 @@ static void prune_subtests(struct settings *settings,
 
 		if (settings->prune_mode == PRUNE_KEEP_DYNAMIC) {
 			if (subtests->subs[i].dynamic_size)
-				json_object_object_del(tests, piglit_name);
+				json_object_del(tests, piglit_name);
 
 			continue;
 		}
@@ -1274,7 +1260,7 @@ static void prune_subtests(struct settings *settings,
 
 		if (settings->prune_mode == PRUNE_KEEP_REQUESTED &&
 		    !result_is_requested(entry, subtests->subs[i].name, NULL)) {
-			json_object_object_del(tests, piglit_name);
+			json_object_del(tests, piglit_name);
 		}
 
 		for (k = 0; k < subtests->subs[i].dynamic_size; k++) {
@@ -1283,7 +1269,7 @@ static void prune_subtests(struct settings *settings,
 			     !result_is_requested(entry, subtests->subs[i].name, subtests->subs[i].dynamic_names[k]))) {
 				generate_piglit_name_for_dynamic(piglit_name, subtests->subs[i].dynamic_names[k],
 								 dynamic_piglit_name, sizeof(dynamic_piglit_name));
-				json_object_object_del(tests, dynamic_piglit_name);
+				json_object_del(tests, dynamic_piglit_name);
 			}
 		}
 	}
@@ -1313,40 +1299,41 @@ static bool stderr_contains_warnings(const char *beg, const char *end)
 	return false;
 }
 
-static bool json_field_has_data(struct json_object *obj, const char *key)
+static bool json_field_has_data(struct json_t *obj, const char *key)
 {
-	struct json_object *field;
+	struct json_t *field;
 
-	if (json_object_object_get_ex(obj, key, &field))
-		return strcmp(json_object_get_string(field), "");
+	if ((field = json_object_get(obj, key)))
+		return strcmp(json_string_value(field), "");
 
 	return false;
 }
 
-static void override_completely_empty_results(struct json_object *obj)
+static void override_completely_empty_results(struct json_t *obj)
 {
 	if (json_field_has_data(obj, "out") ||
 	    json_field_has_data(obj, "err") ||
 	    json_field_has_data(obj, "dmesg"))
 		return;
 
-	json_object_object_add(obj, "out",
-			       json_object_new_string("This test didn't produce any output. "
-						      "The machine probably rebooted ungracefully.\n"));
+	json_object_set_new(obj, "out", json_string("This test didn't produce any output. "
+						    "The machine probably rebooted ungracefully.\n"));
 	set_result(obj, "incomplete");
 }
 
-static void override_result_single(struct json_object *obj)
+static void override_result_single(struct json_t *obj)
 {
 	const char *errtext = "", *result = "";
-	struct json_object *textobj;
+	struct json_t *textobj;
 	bool dmesgwarns = false;
 
-	if (json_object_object_get_ex(obj, "err", &textobj))
-		errtext = json_object_get_string(textobj);
-	if (json_object_object_get_ex(obj, "result", &textobj))
-		result = json_object_get_string(textobj);
-	if (json_object_object_get_ex(obj, "dmesg-warnings", &textobj))
+	if ((textobj = json_object_get(obj, "err")))
+		errtext = json_string_value(textobj);
+
+	if ((textobj = json_object_get(obj, "result")))
+		result = json_string_value(textobj);
+
+	if (json_object_get(obj, "dmesg-warnings"))
 		dmesgwarns = true;
 
 	if (!strcmp(result, "pass") &&
@@ -1368,9 +1355,9 @@ static void override_result_single(struct json_object *obj)
 
 static void override_results(char *binary,
 			     struct subtest_list *subtests,
-			     struct json_object *tests)
+			     struct json_t *tests)
 {
-	struct json_object *obj;
+	struct json_t *obj;
 	char piglit_name[256];
 	char dynamic_piglit_name[256];
 	size_t i, k;
@@ -1396,52 +1383,50 @@ static void override_results(char *binary,
 	}
 }
 
-static struct json_object *get_totals_object(struct json_object *totals,
-					     const char *key)
+static struct json_t *get_totals_object(struct json_t *totals, const char *key)
 {
-	struct json_object *obj = NULL;
+	struct json_t *obj = NULL;
 
-	if (json_object_object_get_ex(totals, key, &obj))
+	if ((obj = json_object_get(totals, key)))
 		return obj;
 
-	obj = json_object_new_object();
-	json_object_object_add(totals, key, obj);
-
-	json_object_object_add(obj, "crash", json_object_new_int(0));
-	json_object_object_add(obj, "pass", json_object_new_int(0));
-	json_object_object_add(obj, "dmesg-fail", json_object_new_int(0));
-	json_object_object_add(obj, "dmesg-warn", json_object_new_int(0));
-	json_object_object_add(obj, "skip", json_object_new_int(0));
-	json_object_object_add(obj, "incomplete", json_object_new_int(0));
-	json_object_object_add(obj, "abort", json_object_new_int(0));
-	json_object_object_add(obj, "timeout", json_object_new_int(0));
-	json_object_object_add(obj, "notrun", json_object_new_int(0));
-	json_object_object_add(obj, "fail", json_object_new_int(0));
-	json_object_object_add(obj, "warn", json_object_new_int(0));
+	obj = json_object();
+	json_object_set_new(totals, key, obj);
+
+	json_object_set_new(obj, "crash", json_integer(0));
+	json_object_set_new(obj, "pass", json_integer(0));
+	json_object_set_new(obj, "dmesg-fail", json_integer(0));
+	json_object_set_new(obj, "dmesg-warn", json_integer(0));
+	json_object_set_new(obj, "skip", json_integer(0));
+	json_object_set_new(obj, "incomplete", json_integer(0));
+	json_object_set_new(obj, "abort", json_integer(0));
+	json_object_set_new(obj, "timeout", json_integer(0));
+	json_object_set_new(obj, "notrun", json_integer(0));
+	json_object_set_new(obj, "fail", json_integer(0));
+	json_object_set_new(obj, "warn", json_integer(0));
 
 	return obj;
 }
 
-static void add_result_to_totals(struct json_object *totals,
-				 const char *result)
+static void add_result_to_totals(struct json_t *totals, const char *result)
 {
-	json_object *numobj = NULL;
-	int old;
+	struct json_t *numobj = NULL;
+	json_int_t old;
 
-	if (!json_object_object_get_ex(totals, result, &numobj)) {
+	if (!(numobj = json_object_get(totals, result))) {
 		fprintf(stderr, "Warning: Totals object without count for %s\n", result);
 		return;
 	}
 
-	old = json_object_get_int(numobj);
-	json_object_object_add(totals, result, json_object_new_int(old + 1));
+	old = json_integer_value(numobj);
+	json_object_set_new(totals, result, json_integer(old + 1));
 }
 
 static void add_to_totals(const char *binary,
 			  struct subtest_list *subtests,
 			  struct results *results)
 {
-	struct json_object *test, *resultobj, *emptystrtotal, *roottotal, *binarytotal;
+	struct json_t *test, *resultobj, *emptystrtotal, *roottotal, *binarytotal;
 	char piglit_name[256];
 	char dynamic_piglit_name[256];
 	const char *result;
@@ -1454,11 +1439,12 @@ static void add_to_totals(const char *binary,
 
 	if (subtests->size == 0) {
 		test = get_or_create_json_object(results->tests, piglit_name);
-		if (!json_object_object_get_ex(test, "result", &resultobj)) {
+		if (!(resultobj = json_object_get(test, "result"))) {
 			fprintf(stderr, "Warning: No results set for %s\n", piglit_name);
 			return;
 		}
-		result = json_object_get_string(resultobj);
+
+		result = json_string_value(resultobj);
 		add_result_to_totals(emptystrtotal, result);
 		add_result_to_totals(roottotal, result);
 		add_result_to_totals(binarytotal, result);
@@ -1468,12 +1454,13 @@ static void add_to_totals(const char *binary,
 	for (i = 0; i < subtests->size; i++) {
 		generate_piglit_name(binary, subtests->subs[i].name, piglit_name, sizeof(piglit_name));
 
-		if (json_object_object_get_ex(results->tests, piglit_name, &test)) {
-			if (!json_object_object_get_ex(test, "result", &resultobj)) {
+		if ((test = json_object_get(results->tests, piglit_name))) {
+			if (!(resultobj = json_object_get(test, "result"))) {
 				fprintf(stderr, "Warning: No results set for %s\n", piglit_name);
 				return;
 			}
-			result = json_object_get_string(resultobj);
+
+			result = json_string_value(resultobj);
 			add_result_to_totals(emptystrtotal, result);
 			add_result_to_totals(roottotal, result);
 			add_result_to_totals(binarytotal, result);
@@ -1483,12 +1470,13 @@ static void add_to_totals(const char *binary,
 			generate_piglit_name_for_dynamic(piglit_name, subtests->subs[i].dynamic_names[k],
 							 dynamic_piglit_name, sizeof(dynamic_piglit_name));
 
-			if (json_object_object_get_ex(results->tests, dynamic_piglit_name, &test)) {
-				if (!json_object_object_get_ex(test, "result", &resultobj)) {
+			if ((test = json_object_get(results->tests, dynamic_piglit_name))) {
+				if (!(resultobj = json_object_get(test, "result"))) {
 					fprintf(stderr, "Warning: No results set for %s\n", dynamic_piglit_name);
 					return;
 				}
-				result = json_object_get_string(resultobj);
+
+				result = json_string_value(resultobj);
 				add_result_to_totals(emptystrtotal, result);
 				add_result_to_totals(roottotal, result);
 				add_result_to_totals(binarytotal, result);
@@ -1542,7 +1530,7 @@ static void try_add_notrun_results(const struct job_list_entry *entry,
 				   struct results *results)
 {
 	struct subtest_list subtests = {};
-	struct json_object *current_test;
+	struct json_t *current_test;
 	size_t i;
 
 	if (entry->subtest_count == 0) {
@@ -1553,10 +1541,10 @@ static void try_add_notrun_results(const struct job_list_entry *entry,
 			return;
 		generate_piglit_name(entry->binary, NULL, piglit_name, sizeof(piglit_name));
 		current_test = get_or_create_json_object(results->tests, piglit_name);
-		json_object_object_add(current_test, "out", json_object_new_string(""));
-		json_object_object_add(current_test, "err", json_object_new_string(""));
-		json_object_object_add(current_test, "dmesg", json_object_new_string(""));
-		json_object_object_add(current_test, "result", json_object_new_string("notrun"));
+		json_object_set_new(current_test, "out", json_string(""));
+		json_object_set_new(current_test, "err", json_string(""));
+		json_object_set_new(current_test, "dmesg", json_string(""));
+		json_object_set_new(current_test, "result", json_string("notrun"));
 	}
 
 	for (i = 0; i < entry->subtest_count; i++) {
@@ -1564,10 +1552,10 @@ static void try_add_notrun_results(const struct job_list_entry *entry,
 
 		generate_piglit_name(entry->binary, entry->subtests[i], piglit_name, sizeof(piglit_name));
 		current_test = get_or_create_json_object(results->tests, piglit_name);
-		json_object_object_add(current_test, "out", json_object_new_string(""));
-		json_object_object_add(current_test, "err", json_object_new_string(""));
-		json_object_object_add(current_test, "dmesg", json_object_new_string(""));
-		json_object_object_add(current_test, "result", json_object_new_string("notrun"));
+		json_object_set_new(current_test, "out", json_string(""));
+		json_object_set_new(current_test, "err", json_string(""));
+		json_object_set_new(current_test, "dmesg", json_string(""));
+		json_object_set_new(current_test, "result", json_string("notrun"));
 		add_subtest(&subtests, strdup(entry->subtests[i]));
 	}
 
@@ -1575,22 +1563,22 @@ static void try_add_notrun_results(const struct job_list_entry *entry,
 	free_subtests(&subtests);
 }
 
-static void create_result_root_nodes(struct json_object *root,
+static void create_result_root_nodes(struct json_t *root,
 				     struct results *results)
 {
-	results->tests = json_object_new_object();
-	json_object_object_add(root, "tests", results->tests);
-	results->totals = json_object_new_object();
-	json_object_object_add(root, "totals", results->totals);
-	results->runtimes = json_object_new_object();
-	json_object_object_add(root, "runtimes", results->runtimes);
+	results->tests = json_object();
+	json_object_set_new(root, "tests", results->tests);
+	results->totals = json_object();
+	json_object_set_new(root, "totals", results->totals);
+	results->runtimes = json_object();
+	json_object_set_new(root, "runtimes", results->runtimes);
 }
 
-struct json_object *generate_results_json(int dirfd)
+struct json_t *generate_results_json(int dirfd)
 {
 	struct settings settings;
 	struct job_list job_list;
-	struct json_object *obj, *elapsed;
+	struct json_t *obj, *elapsed;
 	struct results results;
 	int testdirfd, fd;
 	size_t i;
@@ -1608,13 +1596,12 @@ struct json_object *generate_results_json(int dirfd)
 		return NULL;
 	}
 
-	obj = json_object_new_object();
-	json_object_object_add(obj, "__type__", json_object_new_string("TestrunResult"));
-	json_object_object_add(obj, "results_version", json_object_new_int(10));
-	json_object_object_add(obj, "name",
-			       settings.name ?
-			       json_object_new_string(settings.name) :
-			       json_object_new_string(""));
+	obj = json_object();
+	json_object_set_new(obj, "__type__", json_string("TestrunResult"));
+	json_object_set_new(obj, "results_version", json_integer(10));
+	json_object_set_new(obj, "name", settings.name ?
+					 json_string(settings.name) :
+					 json_string(""));
 
 	if ((fd = openat(dirfd, "uname.txt", O_RDONLY)) >= 0) {
 		char buf[128];
@@ -1623,26 +1610,25 @@ struct json_object *generate_results_json(int dirfd)
 		if (r > 0 && buf[r - 1] == '\n')
 			r--;
 
-		json_object_object_add(obj, "uname",
-				       new_escaped_json_string(buf, r));
+		json_object_set_new(obj, "uname", escaped_json_stringn(buf, r));
 		close(fd);
 	}
 
-	elapsed = json_object_new_object();
-	json_object_object_add(elapsed, "__type__", json_object_new_string("TimeAttribute"));
+	elapsed = json_object();
+	json_object_set_new(elapsed, "__type__", json_string("TimeAttribute"));
 	if ((fd = openat(dirfd, "starttime.txt", O_RDONLY)) >= 0) {
 		char buf[128] = {};
 		read(fd, buf, sizeof(buf));
-		json_object_object_add(elapsed, "start", json_object_new_double(atof(buf)));
+		json_object_set_new(elapsed, "start", json_real(atof(buf)));
 		close(fd);
 	}
 	if ((fd = openat(dirfd, "endtime.txt", O_RDONLY)) >= 0) {
 		char buf[128] = {};
 		read(fd, buf, sizeof(buf));
-		json_object_object_add(elapsed, "end", json_object_new_double(atof(buf)));
+		json_object_set_new(elapsed, "end", json_real(atof(buf)));
 		close(fd);
 	}
-	json_object_object_add(obj, "time_elapsed", elapsed);
+	json_object_set_new(obj, "time_elapsed", elapsed);
 
 	create_result_root_nodes(obj, &results);
 
@@ -1679,21 +1665,17 @@ struct json_object *generate_results_json(int dirfd)
 		char buf[4096];
 		char piglit_name[] = "igt at runner@aborted";
 		struct subtest_list abortsub = {};
-		struct json_object *aborttest = get_or_create_json_object(results.tests, piglit_name);
+		struct json_t *aborttest = get_or_create_json_object(results.tests, piglit_name);
 		ssize_t s;
 
 		add_subtest(&abortsub, strdup("aborted"));
 
 		s = read(fd, buf, sizeof(buf));
 
-		json_object_object_add(aborttest, "out",
-				       new_escaped_json_string(buf, s));
-		json_object_object_add(aborttest, "err",
-				       json_object_new_string(""));
-		json_object_object_add(aborttest, "dmesg",
-				       json_object_new_string(""));
-		json_object_object_add(aborttest, "result",
-				       json_object_new_string("fail"));
+		json_object_set_new(aborttest, "out", escaped_json_stringn(buf, s));
+		json_object_set_new(aborttest, "err", json_string(""));
+		json_object_set_new(aborttest, "dmesg", json_string(""));
+		json_object_set_new(aborttest, "result", json_string("fail"));
 
 		add_to_totals("runner", &abortsub, &results);
 
@@ -1709,9 +1691,8 @@ struct json_object *generate_results_json(int dirfd)
 
 bool generate_results(int dirfd)
 {
-	struct json_object *obj = generate_results_json(dirfd);
-	const char *json_string;
-	int resultsfd;
+	struct json_t *obj = generate_results_json(dirfd);
+	int resultsfd, status;
 
 	if (obj == NULL)
 		return false;
@@ -1722,23 +1703,19 @@ bool generate_results(int dirfd)
 		return false;
 	}
 
-	json_string = json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PRETTY);
+	status = json_dumpfd(obj, resultsfd, JSON_INDENT(4));
 
-	if (json_string == NULL) {
+	if (status != 0) {
 		fprintf(stderr, "resultgen: Failed to create json representation of the results.\n");
 		fprintf(stderr, "           This usually means that the results are too big\n");
 		fprintf(stderr, "           to fit in the memory as the text representation\n");
 		fprintf(stderr, "           is being created.\n\n");
 		fprintf(stderr, "           Either something was spamming the logs or your\n");
 		fprintf(stderr, "           system is very low on free mem.\n");
-
-		close(resultsfd);
-		return false;
 	}
 
-	write(resultsfd, json_string, strlen(json_string));
 	close(resultsfd);
-	return true;
+	return status == 0;
 }
 
 bool generate_results_path(char *resultspath)
diff --git a/runner/resultgen.h b/runner/resultgen.h
index ab0bf108..3bc3bafe 100644
--- a/runner/resultgen.h
+++ b/runner/resultgen.h
@@ -6,6 +6,6 @@
 bool generate_results(int dirfd);
 bool generate_results_path(char *resultspath);
 
-struct json_object *generate_results_json(int dirfd);
+struct json_t *generate_results_json(int dirfd);
 
 #endif
diff --git a/runner/runner_json_tests.c b/runner/runner_json_tests.c
index 7253c906..9f487855 100644
--- a/runner/runner_json_tests.c
+++ b/runner/runner_json_tests.c
@@ -2,122 +2,85 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 
-#include <json.h>
+#include <jansson.h>
 
 #include "igt.h"
 #include "resultgen.h"
 
 static char testdatadir[] = JSON_TESTS_DIRECTORY;
 
-static struct json_object *read_json(int fd)
-{
-	struct json_object *obj;
-	struct json_tokener *tok = json_tokener_new();
-	enum json_tokener_error err;
-	char buf[512];
-	ssize_t s;
-
-	do {
-		s = read(fd, buf, sizeof(buf));
-		obj = json_tokener_parse_ex(tok, buf, s);
-	} while ((err = json_tokener_get_error(tok)) == json_tokener_continue);
-
-	igt_assert_eq(err, json_tokener_success);
-
-	json_tokener_free(tok);
-	return obj;
-}
-
-static void compare(struct json_object *one,
-		    struct json_object *two);
+static void compare(struct json_t *one,
+		    struct json_t *two);
 
-static void compare_objects(struct json_object *one,
-			    struct json_object *two)
+static void compare_objects(struct json_t *one, struct json_t *two)
 {
-	json_object_iter iter;
-	struct json_object *subobj;
-
-	json_object_object_foreachC(one, iter) {
-		igt_debug("Key %s\n", iter.key);
-
-		igt_assert(json_object_object_get_ex(two, iter.key, &subobj));
+	const char *key;
+	json_t *one_value, *two_value;
 
-		compare(iter.val, subobj);
+	json_object_foreach(one, key, one_value) {
+		igt_debug("Key %s\n", key);
+		igt_assert(two_value = json_object_get(two, key));
+		compare(one_value, two_value);
 	}
 }
 
-static void compare_arrays(struct json_object *one,
-			   struct json_object *two)
+static void compare_arrays(struct json_t *one, struct json_t *two)
 {
-	size_t i;
-
-	for (i = 0; i < json_object_array_length(one); i++) {
+	for (size_t i = 0; i < json_array_size(one); i++) {
 		igt_debug("Array index %zd\n", i);
-		compare(json_object_array_get_idx(one, i),
-			json_object_array_get_idx(two, i));
+		compare(json_array_get(one, i),
+		        json_array_get(two, i));
 	}
 }
 
-static bool compatible_types(struct json_object *one,
-			     struct json_object *two)
+static bool compatible_types(struct json_t *one, struct json_t *two)
 {
 	/*
-	 * A double of value 0.0 gets written as "0", which gets read
-	 * as an int.
+	 * Numbers should be compatible with each other. A double of
+	 * value 0.0 gets written as "0", which gets read as an int.
 	 */
-	json_type onetype = json_object_get_type(one);
-	json_type twotype = json_object_get_type(two);
-
-	switch (onetype) {
-	case json_type_boolean:
-	case json_type_string:
-	case json_type_object:
-	case json_type_array:
-	case json_type_null:
-		return onetype == twotype;
-		break;
-	case json_type_double:
-	case json_type_int:
-		return twotype == json_type_double || twotype == json_type_int;
-		break;
-	}
+	if (json_is_number(one))
+		return json_is_number(two);
+
+	if (json_is_boolean(one))
+		return json_is_boolean(two);
 
-	igt_assert(!"Cannot be reached");
-	return false;
+	return json_typeof(one) == json_typeof(two);
 }
 
-static void compare(struct json_object *one,
-		    struct json_object *two)
+static void compare(struct json_t *one,
+		    struct json_t *two)
 {
 	igt_assert(compatible_types(one, two));
 
-	switch (json_object_get_type(one)) {
-	case json_type_boolean:
-		igt_assert_eq(json_object_get_boolean(one), json_object_get_boolean(two));
+	switch (json_typeof(one)) {
+	case JSON_NULL:
+	case JSON_TRUE:
+	case JSON_FALSE:
+		/* These values are singletons: */
+		igt_assert(one == two);
 		break;
-	case json_type_double:
-	case json_type_int:
+	case JSON_REAL:
+	case JSON_INTEGER:
 		/*
 		 * A double of value 0.0 gets written as "0", which
 		 * gets read as an int. Both yield 0.0 with
 		 * json_object_get_double(). Comparing doubles with ==
 		 * considered crazy but it's good enough.
 		 */
-		igt_assert(json_object_get_double(one) == json_object_get_double(two));
+		igt_assert_eq_double(json_number_value(one), json_number_value(two));
 		break;
-	case json_type_string:
-		igt_assert(!strcmp(json_object_get_string(one), json_object_get_string(two)));
+	case JSON_STRING:
+		igt_assert(!strcmp(json_string_value(one), json_string_value(two)));
 		break;
-	case json_type_object:
-		igt_assert_eq(json_object_object_length(one), json_object_object_length(two));
+	case JSON_OBJECT:
+		igt_assert_eq(json_object_size(one), json_object_size(two));
 		compare_objects(one, two);
 		break;
-	case json_type_array:
-		igt_assert_eq(json_object_array_length(one), json_object_array_length(two));
+	case JSON_ARRAY:
+		igt_assert_eq(json_array_size(one), json_array_size(two));
 		compare_arrays(one, two);
 		break;
-	case json_type_null:
-		break;
 	default:
 		igt_assert(!"Cannot be reached");
 	}
@@ -127,7 +90,8 @@ static void run_results_and_compare(int dirfd, const char *dirname)
 {
 	int testdirfd = openat(dirfd, dirname, O_RDONLY | O_DIRECTORY);
 	int reference;
-	struct json_object *resultsobj, *referenceobj;
+	struct json_t *resultsobj, *referenceobj;
+	struct json_error_t error;
 
 	igt_assert_fd(testdirfd);
 
@@ -137,14 +101,15 @@ static void run_results_and_compare(int dirfd, const char *dirname)
 	close(testdirfd);
 
 	igt_assert_fd(reference);
-	referenceobj = read_json(reference);
+	referenceobj = json_loadfd(reference, 0, &error);
 	close(reference);
-	igt_assert(referenceobj != NULL);
+	igt_assert_f(referenceobj != NULL, "JSON loading error for %s/%s:%d:%d - %s\n",
+		     dirname, "reference.json", error.line, error.column, error.text);
 
 	igt_debug("Root object\n");
 	compare(resultsobj, referenceobj);
-	igt_assert_eq(json_object_put(resultsobj), 1);
-	igt_assert_eq(json_object_put(referenceobj), 1);
+	json_decref(resultsobj);
+	json_decref(referenceobj);
 }
 
 static const char *dirnames[] = {
diff --git a/runner/runner_tests.c b/runner/runner_tests.c
index 8fe86978..e36ab103 100644
--- a/runner/runner_tests.c
+++ b/runner/runner_tests.c
@@ -4,7 +4,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-#include <json.h>
+#include <jansson.h>
 
 #include "igt.h"
 
@@ -33,20 +33,20 @@ static const char testdatadir[] = TESTDATA_DIRECTORY;
 /* The total number of test binaries in runner/testdata/ */
 #define NUM_TESTDATA_BINARIES 8
 
-static const char *igt_get_result(struct json_object *tests, const char* testname)
+static const char *igt_get_result(struct json_t *tests, const char* testname)
 {
-	struct json_object *obj;
+	struct json_t *obj;
 
-	igt_assert(json_object_object_get_ex(tests, testname, &obj));
-	igt_assert(json_object_object_get_ex(obj, "result", &obj));
+	igt_assert(obj = json_object_get(tests, testname));
+	igt_assert(obj = json_object_get(obj, "result"));
 
-	return json_object_get_string(obj);
+	return json_string_value(obj);
 }
 
-static void igt_assert_no_result_for(struct json_object *tests, const char* testname)
+static void igt_assert_no_result_for(struct json_t *tests, const char* testname)
 {
-	struct json_object *obj;
-	igt_assert(!json_object_object_get_ex(tests, testname, &obj));
+	struct json_t *obj;
+	igt_assert(!(obj = json_object_get(tests, testname)));
 }
 
 
@@ -1552,7 +1552,7 @@ igt_main
 
 		igt_subtest("dynamic-subtests-in-testlist") {
 			struct execute_state state;
-			struct json_object *results, *tests;
+			struct json_t *results, *tests;
 			const char *argv[] = { "runner",
 					       "--allow-non-root",
 					       "--test-list", filename,
@@ -1574,7 +1574,7 @@ igt_main
 			igt_assert_f((results = generate_results_json(dirfd)) != NULL,
 				     "Results parsing failed\n");
 
-			igt_assert(json_object_object_get_ex(results, "tests", &tests));
+			igt_assert(tests = json_object_get(results, "tests"));
 
 			/* Check that the dynamic subtest we didn't request is not reported */
 			igt_assert_no_result_for(tests, "igt at dynamic@dynamic-subtest at failing");
@@ -1582,7 +1582,7 @@ igt_main
 			/* Check that the dynamic subtest we did request is */
 			igt_assert_eqstr(igt_get_result(tests, "igt at dynamic@dynamic-subtest at passing"), "pass");
 
-			igt_assert_eq(json_object_put(results), 1);
+			json_decref(results);
 		}
 
 		igt_fixture {
@@ -1608,7 +1608,7 @@ igt_main
 
 		igt_subtest("dynamic-subtest-failure-should-not-cause-warn") {
 			struct execute_state state;
-			struct json_object *results, *tests;
+			struct json_t *results, *tests;
 			const char *argv[] = { "runner",
 					       "--allow-non-root",
 					       "-t", "^dynamic$",
@@ -1626,11 +1626,11 @@ igt_main
 			igt_assert_f((results = generate_results_json(dirfd)) != NULL,
 				     "Results parsing failed\n");
 
-			igt_assert(json_object_object_get_ex(results, "tests", &tests));
+			igt_assert(tests = json_object_get(results, "tests"));
 
 			igt_assert_eqstr(igt_get_result(tests, "igt at dynamic@dynamic-subtest at passing"), "pass");
 
-			igt_assert_eq(json_object_put(results), 1);
+			json_decref(results);
 		}
 
 		igt_fixture {
@@ -1654,7 +1654,7 @@ igt_main
 
 		igt_subtest("execute-abort-simple") {
 			struct execute_state state;
-			struct json_object *results, *tests;
+			struct json_t *results, *tests;
 			const char *argv[] = { "runner",
 					       "--allow-non-root",
 					       "-t", "^abort-simple$",
@@ -1672,11 +1672,11 @@ igt_main
 			igt_assert_f((results = generate_results_json(dirfd)) != NULL,
 				     "Results parsing failed\n");
 
-			igt_assert(json_object_object_get_ex(results, "tests", &tests));
+			igt_assert(tests = json_object_get(results, "tests"));
 
 			igt_assert_eqstr(igt_get_result(tests, "igt at abort-simple"), "abort");
 
-			igt_assert_eq(json_object_put(results), 1);
+			json_decref(results);
 		}
 
 		igt_fixture {
@@ -1702,7 +1702,7 @@ igt_main
 
 			igt_subtest_f("execute-abort%s", multiple ? "-multiple" : "") {
 				struct execute_state state;
-				struct json_object *results, *tests;
+				struct json_t *results, *tests;
 				const char *argv[] = { "runner",
 						       "--allow-non-root",
 						       "-t", "^abort$",
@@ -1721,7 +1721,7 @@ igt_main
 				igt_assert_f((results = generate_results_json(dirfd)) != NULL,
 					     "Results parsing failed\n");
 
-				igt_assert(json_object_object_get_ex(results, "tests", &tests));
+				igt_assert(tests = json_object_get(results, "tests"));
 
 				igt_assert_eqstr(igt_get_result(tests, "igt at abort@a-subtest"), "pass");
 				igt_assert_eqstr(igt_get_result(tests, "igt at abort@b-subtest"), "abort");
@@ -1731,7 +1731,7 @@ igt_main
 				else
 					igt_assert_eqstr(igt_get_result(tests, "igt at abort@c-subtest"), "notrun");
 
-				igt_assert_eq(json_object_put(results), 1);
+				json_decref(results);
 			}
 
 			igt_fixture {
@@ -1758,7 +1758,7 @@ igt_main
 
 			igt_subtest_f("execute-abort-fixture%s", multiple ? "-multiple" : "") {
 				struct execute_state state;
-				struct json_object *results, *tests;
+				struct json_t *results, *tests;
 				const char *argv[] = { "runner", multiple ? "--multiple-mode" : "--sync",
 						       "--allow-non-root",
 						       "-t", "^abort-fixture$",
@@ -1776,7 +1776,7 @@ igt_main
 				igt_assert_f((results = generate_results_json(dirfd)) != NULL,
 					     "Results parsing failed\n");
 
-				igt_assert(json_object_object_get_ex(results, "tests", &tests));
+				igt_assert(tests = json_object_get(results, "tests"));
 
 				if (multiple) {
 					/*
@@ -1791,7 +1791,7 @@ igt_main
 					igt_assert_eqstr(igt_get_result(tests, "igt at abort-fixture@b-subtest"), "notrun");
 				}
 
-				igt_assert_eq(json_object_put(results), 1);
+				json_decref(results);
 			}
 
 			igt_fixture {
@@ -1825,7 +1825,7 @@ igt_main
 
 			igt_subtest_f("execute-abort-fixture-testlist%s", multiple ? "-multiple" : "") {
 				struct execute_state state;
-				struct json_object *results, *tests;
+				struct json_t *results, *tests;
 				const char *argv[] = { "runner", multiple ? "--multiple-mode" : "--sync",
 						       "--allow-non-root",
 						       "--test-list", filename,
@@ -1843,7 +1843,7 @@ igt_main
 				igt_assert_f((results = generate_results_json(dirfd)) != NULL,
 					     "Results parsing failed\n");
 
-				igt_assert(json_object_object_get_ex(results, "tests", &tests));
+				igt_assert(tests = json_object_get(results, "tests"));
 
 				if (multiple) /* multiple mode = no notruns */
 					igt_assert_no_result_for(tests, "igt at abort-fixture@a-subtest");
@@ -1853,7 +1853,7 @@ igt_main
 
 				igt_assert_eqstr(igt_get_result(tests, "igt at abort-fixture@b-subtest"), "abort");
 
-				igt_assert_eq(json_object_put(results), 1);
+				json_decref(results);
 			}
 
 			igt_fixture {
@@ -1881,7 +1881,7 @@ igt_main
 
 			igt_subtest_f("execute-abort-dynamic%s", multiple ? "-multiple" : "") {
 				struct execute_state state;
-				struct json_object *results, *tests;
+				struct json_t *results, *tests;
 				const char *argv[] = { "runner", multiple ? "--multiple-mode" : "--sync",
 						       "--allow-non-root",
 						       "-t", "^abort-dynamic$",
@@ -1899,7 +1899,7 @@ igt_main
 				igt_assert_f((results = generate_results_json(dirfd)) != NULL,
 					     "Results parsing failed\n");
 
-				igt_assert(json_object_object_get_ex(results, "tests", &tests));
+				igt_assert(tests = json_object_get(results, "tests"));
 
 				igt_assert_eqstr(igt_get_result(tests, "igt at abort-dynamic@a-subtest at dynamic-1"), "pass");
 				igt_assert_eqstr(igt_get_result(tests, "igt at abort-dynamic@b-subtest at dynamic-1"), "pass");
@@ -1912,7 +1912,7 @@ igt_main
 				else
 					igt_assert_eqstr(igt_get_result(tests, "igt at abort-dynamic@c-subtest"), "notrun");
 
-				igt_assert_eq(json_object_put(results), 1);
+				json_decref(results);
 			}
 
 			igt_fixture {
-- 
2.37.1



More information about the igt-dev mailing list