aboutsummaryrefslogtreecommitdiff
path: root/components/service/test_runner/provider/backend/simple_c/simple_c_test_runner.c
diff options
context:
space:
mode:
Diffstat (limited to 'components/service/test_runner/provider/backend/simple_c/simple_c_test_runner.c')
-rw-r--r--components/service/test_runner/provider/backend/simple_c/simple_c_test_runner.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/components/service/test_runner/provider/backend/simple_c/simple_c_test_runner.c b/components/service/test_runner/provider/backend/simple_c/simple_c_test_runner.c
new file mode 100644
index 000000000..0ab190c5d
--- /dev/null
+++ b/components/service/test_runner/provider/backend/simple_c/simple_c_test_runner.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <service/test_runner/provider/test_runner_backend.h>
+#include <service/test_runner/provider/test_runner_provider.h>
+#include "simple_c_test_runner.h"
+#include <string.h>
+
+
+/* Private defines */
+#define SIMPLE_C_TEST_GROUP_LIMIT (50)
+
+/**
+ * The simple_c test runner specialises the base test_runner_backend
+ * to add a regsitry of registered test groups.
+ */
+static struct simple_c_test_runner
+{
+ struct test_runner_backend base_backend;
+ size_t num_groups;
+ const struct simple_c_test_group *groups[SIMPLE_C_TEST_GROUP_LIMIT];
+} the_test_runner;
+
+/* Concrete test_runner_backed functions */
+static size_t count_tests(const struct test_spec *spec);
+static int run_tests(const struct test_spec *spec,
+ struct test_summary *summary, struct test_result *results, size_t result_limit);
+static void list_tests(const struct test_spec *spec,
+ struct test_summary *summary, struct test_result *results, size_t result_limit);
+
+
+void simple_c_test_runner_init(struct test_runner_provider *frontend)
+{
+ /* Initialise base test_runner_backend */
+ the_test_runner.base_backend.count_tests = count_tests;
+ the_test_runner.base_backend.run_tests = run_tests;
+ the_test_runner.base_backend.list_tests = list_tests;
+ the_test_runner.base_backend.next = NULL;
+
+ /* Registry initially empty */
+ the_test_runner.num_groups = 0;
+
+ test_runner_provider_register_backend(frontend, &the_test_runner.base_backend);
+}
+
+void simple_c_test_runner_register_group(const struct simple_c_test_group *test_group)
+{
+ if (the_test_runner.num_groups < SIMPLE_C_TEST_GROUP_LIMIT) {
+
+ the_test_runner.groups[the_test_runner.num_groups] = test_group;
+ ++the_test_runner.num_groups;
+ }
+}
+
+static bool does_qualify(const char *spec_string, const char *test_string)
+{
+ return ((strlen(spec_string) == 0) || (strcmp(spec_string, test_string) == 0));
+}
+
+static int test_iterate(const struct test_spec *spec, bool list_only,
+ struct test_summary *summary, struct test_result *results, size_t result_limit)
+{
+ summary->num_tests = 0;
+ summary->num_results = 0;
+ summary->num_passed = 0;
+ summary->num_failed = 0;
+
+ for (size_t group_index = 0; group_index < the_test_runner.num_groups; ++group_index) {
+
+ const struct simple_c_test_group *test_group = the_test_runner.groups[group_index];
+
+ if (does_qualify(spec->group, test_group->group)) {
+
+ for (size_t test_index = 0; test_index < test_group->num_test_cases; ++test_index) {
+
+ const struct simple_c_test_case *test_case = &test_group->test_cases[test_index];
+
+ if (does_qualify(spec->name, test_case->name)) {
+
+ enum test_run_state run_state = TEST_RUN_STATE_NOT_RUN;
+
+ /* Run the qualifying test case if we're not just listing tests */
+ if (!list_only) {
+
+ if (test_case->test_func()) {
+
+ run_state = TEST_RUN_STATE_PASSED;
+ ++summary->num_passed;
+ }
+ else {
+
+ run_state = TEST_RUN_STATE_FAILED;
+ ++summary->num_failed;
+ }
+ }
+
+ /* Update result object if capacity - common for listing and running tests */
+ if (summary->num_tests < result_limit) {
+
+ struct test_result *new_result = &results[summary->num_results];
+
+ new_result->run_state = run_state;
+ new_result->fail_line = 0;
+ strcpy(new_result->group, test_group->group);
+ strcpy(new_result->name, test_case->name);
+
+ ++summary->num_results;
+ }
+
+ ++summary->num_tests;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+static size_t count_tests(const struct test_spec *spec)
+{
+ size_t count = 0;
+
+ for (int group_index = 0; group_index < the_test_runner.num_groups; ++group_index) {
+
+ count += the_test_runner.groups[group_index]->num_test_cases;
+ }
+
+ return count;
+}
+
+static int run_tests(const struct test_spec *spec,
+ struct test_summary *summary, struct test_result *results, size_t result_limit)
+{
+ return test_iterate(spec, false, summary, results, result_limit);
+}
+
+static void list_tests(const struct test_spec *spec,
+ struct test_summary *summary, struct test_result *results, size_t result_limit)
+{
+ test_iterate(spec, true, summary, results, result_limit);
+} \ No newline at end of file