// SPDX-License-Identifier: GPL-2.0
/*
 * Base unit test (KUnit) API.
 *
 * Copyright (C) 2019, Google LLC.
 * Author: Brendan Higgins <brendanhiggins@google.com>
 */

#include <linux/sched/debug.h>
#include <kunit/test.h>
#include <kunit/try-catch.h>

static void kunit_set_failure(struct kunit *test)
{
	WRITE_ONCE(test->success, false);
}

static bool kunit_get_death_test(struct kunit *test)
{
	bool death_test;

	mutex_lock(&test->lock);
	death_test = test->death_test;
	mutex_unlock(&test->lock);

	return death_test;
}

static int kunit_vprintk_emit(int level, const char *fmt, va_list args)
{
	return vprintk_emit(0, level, NULL, 0, fmt, args);
}

static int kunit_printk_emit(int level, const char *fmt, ...)
{
	va_list args;
	int ret;

	va_start(args, fmt);
	ret = kunit_vprintk_emit(level, fmt, args);
	va_end(args);

	return ret;
}

static void kunit_vprintk(const struct kunit *test,
			  const char *level,
			  struct va_format *vaf)
{
	kunit_printk_emit(level[1] - '0', "\t# %s: %pV", test->name, vaf);
}

static void kunit_print_tap_version(void)
{
	static bool kunit_has_printed_tap_version;

	if (!kunit_has_printed_tap_version) {
		kunit_printk_emit(LOGLEVEL_INFO, "TAP version 14\n");
		kunit_has_printed_tap_version = true;
	}
}

static size_t kunit_test_cases_len(struct kunit_case *test_cases)
{
	struct kunit_case *test_case;
	size_t len = 0;

	for (test_case = test_cases; test_case->run_case; test_case++)
		len++;

	return len;
}

static void kunit_print_subtest_start(struct kunit_suite *suite)
{
	kunit_print_tap_version();
	kunit_printk_emit(LOGLEVEL_INFO, "\t# Subtest: %s\n", suite->name);
	kunit_printk_emit(LOGLEVEL_INFO,
			  "\t1..%zd\n",
			  kunit_test_cases_len(suite->test_cases));
}

static void kunit_print_ok_not_ok(bool should_indent,
				  bool is_ok,
				  size_t test_number,
				  const char *description)
{
	const char *indent, *ok_not_ok;

	if (should_indent)
		indent = "\t";
	else
		indent = "";

	if (is_ok)
		ok_not_ok = "ok";
	else
		ok_not_ok = "not ok";

	kunit_printk_emit(LOGLEVEL_INFO,
			  "%s%s %zd - %s\n",
			  indent, ok_not_ok, test_number, description);
}

static bool kunit_suite_has_succeeded(struct kunit_suite *suite)
{
	const struct kunit_case *test_case;

	for (test_case = suite->test_cases; test_case->run_case; test_case++)
		if (!test_case->success)
			return false;

	return true;
}

static void kunit_print_subtest_end(struct kunit_suite *suite)
{
	static size_t kunit_suite_counter = 1;

	kunit_print_ok_not_ok(false,
			      kunit_suite_has_succeeded(suite),
			      kunit_suite_counter++,
			      suite->name);
}

static void kunit_print_test_case_ok_not_ok(struct kunit_case *test_case,
					    size_t test_number)
{
	kunit_print_ok_not_ok(true,
			      test_case->success,
			      test_number,
			      test_case->name);
}

void kunit_fail(struct kunit *test, struct kunit_stream *stream)
{
	kunit_set_failure(test);
	kunit_stream_commit(stream);
}

void __noreturn kunit_abort(struct kunit *test)
{
	kunit_set_death_test(test, true);

	kunit_try_catch_throw(&test->try_catch);

	/*
	 * Throw could not abort from test.
	 *
	 * XXX: we should never reach this line! As kunit_try_catch_throw is
	 * marked __noreturn.
	 */
	WARN_ONCE(true, "Throw could not abort from test!\n");
}

void kunit_init_test(struct kunit *test, const char *name)
{
	mutex_init(&test->lock);
	INIT_LIST_HEAD(&test->resources);
	test->name = name;
	test->success = true;
	test->death_test = false;
}

/*
 * Initializes and runs test case. Does not clean up or do post validations.
 */
static void kunit_run_case_internal(struct kunit *test,
				    struct kunit_suite *suite,
				    struct kunit_case *test_case)
{
	int ret;

	if (suite->init) {
		ret = suite->init(test);
		if (ret) {
			kunit_err(test, "failed to initialize: %d\n", ret);
			kunit_set_failure(test);
			return;
		}
	}

	test_case->run_case(test);
}

static void kunit_case_internal_cleanup(struct kunit *test)
{
	kunit_cleanup(test);
}

/*
 * Performs post validations and cleanup after a test case was run.
 * XXX: Should ONLY BE CALLED AFTER kunit_run_case_internal!
 */
static void kunit_run_case_cleanup(struct kunit *test,
				   struct kunit_suite *suite)
{
	if (suite->exit)
		suite->exit(test);

	kunit_case_internal_cleanup(test);
}

/*
 * Handles an unexpected crash in a test case.
 */
static void kunit_handle_test_crash(struct kunit *test,
				   struct kunit_suite *suite,
				   struct kunit_case *test_case)
{
	kunit_err(test, "kunit test case crashed!");
	/*
	 * TODO(brendanhiggins@google.com): This prints the stack trace up
	 * through this frame, not up to the frame that caused the crash.
	 */
	show_stack(NULL, NULL);

	kunit_case_internal_cleanup(test);
}

struct kunit_try_catch_context {
	struct kunit *test;
	struct kunit_suite *suite;
	struct kunit_case *test_case;
};

static void kunit_try_run_case(void *data)
{
	struct kunit_try_catch_context *ctx = data;
	struct kunit *test = ctx->test;
	struct kunit_suite *suite = ctx->suite;
	struct kunit_case *test_case = ctx->test_case;

	/*
	 * kunit_run_case_internal may encounter a fatal error; if it does,
	 * abort will be called, this thread will exit, and finally the parent
	 * thread will resume control and handle any necessary clean up.
	 */
	kunit_run_case_internal(test, suite, test_case);
	/* This line may never be reached. */
	kunit_run_case_cleanup(test, suite);
}

static void kunit_catch_run_case(void *data)
{
	struct kunit_try_catch_context *ctx = data;
	struct kunit *test = ctx->test;
	struct kunit_suite *suite = ctx->suite;
	struct kunit_case *test_case = ctx->test_case;
	int try_exit_code = kunit_try_catch_get_result(&test->try_catch);

	if (try_exit_code) {
		kunit_set_failure(test);
		/*
		 * Test case could not finish, we have no idea what state it is
		 * in, so don't do clean up.
		 */
		if (try_exit_code == -ETIMEDOUT)
			kunit_err(test, "test case timed out\n");
		/*
		 * Unknown internal error occurred preventing test case from
		 * running, so there is nothing to clean up.
		 */
		else
			kunit_err(test, "internal error occurred preventing test case from running: %d\n",
				  try_exit_code);
		return;
	}

	if (kunit_get_death_test(test)) {
		/*
		 * EXPECTED DEATH: kunit_run_case_internal encountered
		 * anticipated fatal error. Everything should be in a safe
		 * state.
		 */
		kunit_run_case_cleanup(test, suite);
	} else {
		/*
		 * UNEXPECTED DEATH: kunit_run_case_internal encountered an
		 * unanticipated fatal error. We have no idea what the state of
		 * the test case is in.
		 */
		kunit_handle_test_crash(test, suite, test_case);
		kunit_set_failure(test);
	}
}

/*
 * Performs all logic to run a test case. It also catches most errors that
 * occurs in a test case and reports them as failures.
 */
static void kunit_run_case_catch_errors(struct kunit_suite *suite,
					struct kunit_case *test_case)
{
	struct kunit_try_catch_context context;
	struct kunit_try_catch *try_catch;
	struct kunit test;

	kunit_init_test(&test, test_case->name);
	try_catch = &test.try_catch;

	kunit_try_catch_init(try_catch,
			     &test,
			     kunit_try_run_case,
			     kunit_catch_run_case);
	context.test = &test;
	context.suite = suite;
	context.test_case = test_case;
	kunit_try_catch_run(try_catch, &context);

	test_case->success = test.success;
}

int kunit_run_tests(struct kunit_suite *suite)
{
	struct kunit_case *test_case;
	size_t test_case_count = 1;

	kunit_print_subtest_start(suite);

	for (test_case = suite->test_cases; test_case->run_case; test_case++) {
		kunit_run_case_catch_errors(suite, test_case);
		kunit_print_test_case_ok_not_ok(test_case, test_case_count++);
	}

	kunit_print_subtest_end(suite);

	return 0;
}

struct kunit_resource *kunit_alloc_resource(struct kunit *test,
					    kunit_resource_init_t init,
					    kunit_resource_free_t free,
					    void *context)
{
	struct kunit_resource *res;
	int ret;

	res = kzalloc(sizeof(*res), GFP_KERNEL);
	if (!res)
		return NULL;

	ret = init(res, context);
	if (ret)
		return NULL;

	res->free = free;
	mutex_lock(&test->lock);
	list_add_tail(&res->node, &test->resources);
	mutex_unlock(&test->lock);

	return res;
}

void kunit_free_resource(struct kunit *test, struct kunit_resource *res)
{
	res->free(res);
	list_del(&res->node);
	kfree(res);
}

struct kunit_kmalloc_params {
	size_t size;
	gfp_t gfp;
};

static int kunit_kmalloc_init(struct kunit_resource *res, void *context)
{
	struct kunit_kmalloc_params *params = context;

	res->allocation = kmalloc(params->size, params->gfp);
	if (!res->allocation)
		return -ENOMEM;

	return 0;
}

static void kunit_kmalloc_free(struct kunit_resource *res)
{
	kfree(res->allocation);
}

void *kunit_kmalloc(struct kunit *test, size_t size, gfp_t gfp)
{
	struct kunit_kmalloc_params params;
	struct kunit_resource *res;

	params.size = size;
	params.gfp = gfp;

	res = kunit_alloc_resource(test,
				   kunit_kmalloc_init,
				   kunit_kmalloc_free,
				   &params);

	if (res)
		return res->allocation;

	return NULL;
}

void kunit_cleanup(struct kunit *test)
{
	struct kunit_resource *resource, *resource_safe;

	mutex_lock(&test->lock);
	/*
	 * test->resources is a stack - each allocation must be freed in the
	 * reverse order from which it was added since one resource may depend
	 * on another for its entire lifetime.
	 */
	list_for_each_entry_safe_reverse(resource,
					 resource_safe,
					 &test->resources,
					 node) {
		kunit_free_resource(test, resource);
	}
	mutex_unlock(&test->lock);
}

void kunit_printk(const char *level,
		  const struct kunit *test,
		  const char *fmt, ...)
{
	struct va_format vaf;
	va_list args;

	va_start(args, fmt);

	vaf.fmt = fmt;
	vaf.va = &args;

	kunit_vprintk(test, level, &vaf);

	va_end(args);
}

void kunit_expect_binary_msg(struct kunit *test,
			     long long left, const char *left_name,
			     long long right, const char *right_name,
			     bool compare_result,
			     const char *compare_name,
			     const char *file,
			     const char *line,
			     const char *fmt, ...)
{
	struct kunit_stream *stream = kunit_expect_start(test, file, line);
	struct va_format vaf;
	va_list args;

	kunit_stream_add(stream,
			 "Expected %s %s %s, but\n",
			 left_name, compare_name, right_name);
	kunit_stream_add(stream, "\t\t%s == %lld\n", left_name, left);
	kunit_stream_add(stream, "\t\t%s == %lld", right_name, right);

	if (fmt) {
		va_start(args, fmt);

		vaf.fmt = fmt;
		vaf.va = &args;

		kunit_stream_add(stream, "\n%pV", &vaf);

		va_end(args);
	}

	kunit_expect_end(test, compare_result, stream);
}

void kunit_expect_ptr_binary_msg(struct kunit *test,
				 void *left, const char *left_name,
				 void *right, const char *right_name,
				 bool compare_result,
				 const char *compare_name,
				 const char *file,
				 const char *line,
				 const char *fmt, ...)
{
	struct kunit_stream *stream = kunit_expect_start(test, file, line);
	struct va_format vaf;
	va_list args;

	kunit_stream_add(stream,
			 "Expected %s %s %s, but\n",
			 left_name, compare_name, right_name);
	kunit_stream_add(stream, "\t\t%s == %pK\n", left_name, left);
	kunit_stream_add(stream, "\t\t%s == %pK", right_name, right);

	if (fmt) {
		va_start(args, fmt);

		vaf.fmt = fmt;
		vaf.va = &args;

		kunit_stream_add(stream, "\n%pV", &vaf);

		va_end(args);
	}

	kunit_expect_end(test, compare_result, stream);
}

void kunit_assert_binary_msg(struct kunit *test,
			     long long left, const char *left_name,
			     long long right, const char *right_name,
			     bool compare_result,
			     const char *compare_name,
			     const char *file,
			     const char *line,
			     const char *fmt, ...)
{
	struct kunit_stream *stream = kunit_assert_start(test, file, line);
	struct va_format vaf;
	va_list args;

	kunit_stream_add(stream,
			 "Asserted %s %s %s, but\n",
			 left_name, compare_name, right_name);
	kunit_stream_add(stream, "\t\t%s == %lld\n", left_name, left);
	kunit_stream_add(stream, "\t\t%s == %lld\n", right_name, right);

	if (fmt) {
		va_start(args, fmt);

		vaf.fmt = fmt;
		vaf.va = &args;

		kunit_stream_add(stream, "\n%pV", &vaf);

		va_end(args);
	}

	kunit_assert_end(test, compare_result, stream);
}

void kunit_assert_ptr_binary_msg(struct kunit *test,
				 void *left, const char *left_name,
				 void *right, const char *right_name,
				 bool compare_result,
				 const char *compare_name,
				 const char *file,
				 const char *line,
				 const char *fmt, ...)
{
	struct kunit_stream *stream = kunit_assert_start(test, file, line);
	struct va_format vaf;
	va_list args;

	kunit_stream_add(stream,
			 "Asserted %s %s %s, but\n",
			 left_name, compare_name, right_name);
	kunit_stream_add(stream, "\t\t%s == %pK\n", left_name, left);
	kunit_stream_add(stream, "\t\t%s == %pK", right_name, right);

	if (fmt) {
		va_start(args, fmt);

		vaf.fmt = fmt;
		vaf.va = &args;

		kunit_stream_add(stream, "\n%pV", &vaf);

		va_end(args);
	}

	kunit_assert_end(test, compare_result, stream);
}
