blob: 4a3f0df95dd62dc3935a7d1fa9382f87fd0fb08d [file] [log] [blame]
Andrew Scull18834872018-10-12 11:48:09 +01001/*
Andrew Walbran692b3252019-03-07 15:51:31 +00002 * Copyright 2018 The Hafnium Authors.
Andrew Scull18834872018-10-12 11:48:09 +01003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andrew Walbranbc342d42019-02-05 16:56:02 +000017#include "hftest_common.h"
Andrew Scullbc7189d2018-08-14 09:35:13 +010018
Andrew Scullf0551c82018-12-15 20:38:47 +000019#include "hf/arch/vm/power_mgmt.h"
20
Andrew Scullbc7189d2018-08-14 09:35:13 +010021#include "hf/memiter.h"
Andrew Scull8d9e1212019-04-05 13:52:55 +010022#include "hf/std.h"
Andrew Scullbc7189d2018-08-14 09:35:13 +010023
Andrew Walbranbc342d42019-02-05 16:56:02 +000024#include "hftest.h"
Andrew Scullbc7189d2018-08-14 09:35:13 +010025
26HFTEST_ENABLE();
27
Andrew Walbranbc342d42019-02-05 16:56:02 +000028static struct hftest_test hftest_constructed[HFTEST_MAX_TESTS];
29static size_t hftest_count;
30static struct hftest_test *hftest_list;
Andrew Scullbc7189d2018-08-14 09:35:13 +010031
Andrew Scullf0551c82018-12-15 20:38:47 +000032static struct hftest_context global_context;
33
34struct hftest_context *hftest_get_context(void)
35{
36 return &global_context;
37}
38
Andrew Walbranbc342d42019-02-05 16:56:02 +000039/**
40 * Adds the given test information to the global list, to be used by
41 * `hftest_use_registered_list`.
42 */
43void hftest_register(struct hftest_test test)
Andrew Scullbc7189d2018-08-14 09:35:13 +010044{
Andrew Walbranbc342d42019-02-05 16:56:02 +000045 if (hftest_count < HFTEST_MAX_TESTS) {
46 hftest_constructed[hftest_count++] = test;
47 } else {
Andrew Walbran78a63b72019-03-18 17:28:22 +000048 HFTEST_FAIL(true, "Too many tests");
Andrew Walbranbc342d42019-02-05 16:56:02 +000049 }
50}
51
52/**
53 * Uses the list of tests registered by `hftest_register(...)` as the ones to
54 * run.
55 */
56void hftest_use_registered_list(void)
57{
58 hftest_list = hftest_constructed;
59}
60
61/**
62 * Uses the given list of tests as the ones to run.
63 */
64void hftest_use_list(struct hftest_test list[], size_t count)
65{
66 hftest_list = list;
67 hftest_count = count;
68}
69
70/**
71 * Writes out a JSON structure describing the available tests.
72 */
73void hftest_json(void)
74{
Andrew Scullbc7189d2018-08-14 09:35:13 +010075 const char *suite = NULL;
Andrew Walbranbc342d42019-02-05 16:56:02 +000076 size_t i;
Andrew Scullbc7189d2018-08-14 09:35:13 +010077 size_t suites_in_image = 0;
78 size_t tests_in_suite = 0;
79
80 HFTEST_LOG("{");
81 HFTEST_LOG(" \"suites\": [");
Andrew Walbranbc342d42019-02-05 16:56:02 +000082 for (i = 0; i < hftest_count; ++i) {
83 struct hftest_test *test = &hftest_list[i];
Andrew Scullbc7189d2018-08-14 09:35:13 +010084 if (test->suite != suite) {
85 /* Close out previously open suite. */
86 if (tests_in_suite) {
87 HFTEST_LOG(" ]");
88 HFTEST_LOG(" },");
89 }
90 /* Move onto new suite. */
91 ++suites_in_image;
92 suite = test->suite;
93 tests_in_suite = 0;
94 HFTEST_LOG(" {");
95 HFTEST_LOG(" \"name\": \"%s\",", test->suite);
96 }
97 if (test->kind == HFTEST_KIND_SET_UP) {
98 HFTEST_LOG(" \"setup\": true,");
99 }
100 if (test->kind == HFTEST_KIND_TEAR_DOWN) {
101 HFTEST_LOG(" \"teardown\": true,");
102 }
103 if (test->kind == HFTEST_KIND_TEST) {
104 if (!tests_in_suite) {
105 HFTEST_LOG(" \"tests\": [");
106 }
Andrew Scullf0551c82018-12-15 20:38:47 +0000107 /*
108 * It's easier to put the comma at the start of the line
Andrew Scull2b5fbad2019-04-05 13:55:56 +0100109 * than the end even though the JSON looks a bit funky.
Andrew Scullf0551c82018-12-15 20:38:47 +0000110 */
Andrew Scullbc7189d2018-08-14 09:35:13 +0100111 HFTEST_LOG(" %c\"%s\"",
112 tests_in_suite ? ',' : ' ', test->name);
113 ++tests_in_suite;
114 }
115 }
116 if (tests_in_suite) {
117 HFTEST_LOG(" ]");
118 HFTEST_LOG(" }");
119 }
120 HFTEST_LOG(" ]");
121 HFTEST_LOG("}");
122}
123
Andrew Walbranbc342d42019-02-05 16:56:02 +0000124/**
125 * Logs a failure message and shut down.
126 */
Andrew Sculla59f9bc2019-04-03 15:24:35 +0100127noreturn void abort(void)
Andrew Scullf0551c82018-12-15 20:38:47 +0000128{
129 HFTEST_LOG("FAIL");
Andrew Walbranc6903d12019-03-05 18:28:20 +0000130 arch_power_off();
Andrew Scullf0551c82018-12-15 20:38:47 +0000131}
132
Andrew Scullbc7189d2018-08-14 09:35:13 +0100133static void run_test(hftest_test_fn set_up, hftest_test_fn test,
134 hftest_test_fn tear_down)
135{
Andrew Scullf0551c82018-12-15 20:38:47 +0000136 /* Prepare the context. */
137 struct hftest_context *ctx = hftest_get_context();
Andrew Scull2b5fbad2019-04-05 13:55:56 +0100138 memset_s(ctx, sizeof(*ctx), 0, sizeof(*ctx));
Andrew Scullf0551c82018-12-15 20:38:47 +0000139 ctx->abort = abort;
Andrew Scullbc7189d2018-08-14 09:35:13 +0100140
Andrew Scullf0551c82018-12-15 20:38:47 +0000141 /* Run any set up functions. */
Andrew Scullbc7189d2018-08-14 09:35:13 +0100142 if (set_up) {
Andrew Scullf0551c82018-12-15 20:38:47 +0000143 set_up();
144 if (ctx->failures) {
145 abort();
Andrew Scullbc7189d2018-08-14 09:35:13 +0100146 }
147 }
148
Andrew Scullf0551c82018-12-15 20:38:47 +0000149 /* Run the test. */
150 test();
151 if (ctx->failures) {
152 abort();
Andrew Scullbc7189d2018-08-14 09:35:13 +0100153 }
154
Andrew Scullf0551c82018-12-15 20:38:47 +0000155 /* Run any tear down functions. */
Andrew Scullbc7189d2018-08-14 09:35:13 +0100156 if (tear_down) {
Andrew Scullf0551c82018-12-15 20:38:47 +0000157 tear_down();
158 if (ctx->failures) {
159 abort();
Andrew Scullbc7189d2018-08-14 09:35:13 +0100160 }
161 }
162
Andrew Scullf0551c82018-12-15 20:38:47 +0000163 HFTEST_LOG("FINISHED");
Andrew Scullbc7189d2018-08-14 09:35:13 +0100164}
165
Andrew Walbranbc342d42019-02-05 16:56:02 +0000166/**
167 * Runs the given test case.
168 */
169void hftest_run(struct memiter suite_name, struct memiter test_name)
Andrew Scullbc7189d2018-08-14 09:35:13 +0100170{
Andrew Walbranbc342d42019-02-05 16:56:02 +0000171 size_t i;
Andrew Scullbc7189d2018-08-14 09:35:13 +0100172 bool found_suite = false;
173 const char *suite = NULL;
174 hftest_test_fn suite_set_up = NULL;
175 hftest_test_fn suite_tear_down = NULL;
176
Andrew Walbranbc342d42019-02-05 16:56:02 +0000177 for (i = 0; i < hftest_count; ++i) {
178 struct hftest_test *test = &hftest_list[i];
Andrew Scullbc7189d2018-08-14 09:35:13 +0100179 /* Find the test suite. */
180 if (found_suite) {
181 if (test->suite != suite) {
182 /* Test wasn't in the suite. */
183 break;
184 }
185 } else {
186 if (test->suite == suite) {
187 /* This isn't the right suite so keep going. */
188 continue;
189 }
190 /* Examine a new suite. */
191 suite = test->suite;
192 if (memiter_iseq(&suite_name, test->suite)) {
193 found_suite = true;
194 }
195 }
196
197 switch (test->kind) {
Andrew Scullf0551c82018-12-15 20:38:47 +0000198 /*
199 * The first entries in the suite are the set up and tear down
200 * functions.
201 */
Andrew Scullbc7189d2018-08-14 09:35:13 +0100202 case HFTEST_KIND_SET_UP:
203 suite_set_up = test->fn;
204 break;
205 case HFTEST_KIND_TEAR_DOWN:
206 suite_tear_down = test->fn;
207 break;
208 /* Find the test. */
209 case HFTEST_KIND_TEST:
210 if (memiter_iseq(&test_name, test->name)) {
211 run_test(suite_set_up, test->fn,
212 suite_tear_down);
213 return;
214 }
215 break;
Andrew Scullf0551c82018-12-15 20:38:47 +0000216 default:
217 /* Ignore other kinds. */
218 break;
Andrew Scullbc7189d2018-08-14 09:35:13 +0100219 }
220 }
221
222 HFTEST_LOG("Unable to find requested tests.");
223}
224
Andrew Walbranbc342d42019-02-05 16:56:02 +0000225/**
226 * Writes out usage information.
227 */
228void hftest_help(void)
Andrew Scullbc7189d2018-08-14 09:35:13 +0100229{
230 HFTEST_LOG("usage:");
231 HFTEST_LOG("");
232 HFTEST_LOG(" help");
233 HFTEST_LOG("");
234 HFTEST_LOG(" Show this help.");
235 HFTEST_LOG("");
236 HFTEST_LOG(" json");
237 HFTEST_LOG("");
238 HFTEST_LOG(
239 " Print a directory of test suites and tests in "
240 "JSON "
241 "format.");
242 HFTEST_LOG("");
243 HFTEST_LOG(" run <suite> <test>");
244 HFTEST_LOG("");
245 HFTEST_LOG(" Run the named test from the named test suite.");
246}