Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2016 Intel Corporation
3 : : *
4 : : * SPDX-License-Identifier: Apache-2.0
5 : : */
6 : :
7 : : #include <ztest.h>
8 : : #include <stdio.h>
9 : : #include <app_memory/app_memdomain.h>
10 : : #ifdef CONFIG_USERSPACE
11 : : #include <sys/libc-hooks.h>
12 : : #endif
13 : : #include <sys/reboot.h>
14 : : #include <logging/log_ctrl.h>
15 : :
16 : : #ifdef KERNEL
17 : : static struct k_thread ztest_thread;
18 : : #endif
19 : :
20 : : #ifdef CONFIG_ARCH_POSIX
21 : : #include <unistd.h>
22 : : #endif
23 : :
24 : : /* ZTEST_DMEM and ZTEST_BMEM are used for the application shared memory test */
25 : :
26 : : /**
27 : : * @brief Each enum member represents a distinct phase of execution for the
28 : : * test binary. TEST_PHASE_FRAMEWORK is active when internal ztest code
29 : : * is executing; the rest refer to corresponding phases of user test
30 : : * code.
31 : : */
32 : : enum ztest_phase {
33 : : TEST_PHASE_SETUP,
34 : : TEST_PHASE_BEFORE,
35 : : TEST_PHASE_TEST,
36 : : TEST_PHASE_AFTER,
37 : : TEST_PHASE_TEARDOWN,
38 : : TEST_PHASE_FRAMEWORK
39 : : };
40 : :
41 : : /**
42 : : * @brief Tracks the current phase that ztest is operating in.
43 : : */
44 : : ZTEST_DMEM enum ztest_phase phase = TEST_PHASE_FRAMEWORK;
45 : :
46 : : static ZTEST_BMEM int test_status;
47 : :
48 : : /**
49 : : * @brief Try to shorten a filename by removing the current directory
50 : : *
51 : : * This helps to reduce the very long filenames in assertion failures. It
52 : : * removes the current directory from the filename and returns the rest.
53 : : * This makes assertions a lot more readable, and sometimes they fit on one
54 : : * line.
55 : : *
56 : : * @param file Filename to check
57 : : * @returns Shortened filename, or @file if it could not be shortened
58 : : */
59 : 0 : const char *ztest_relative_filename(const char *file)
60 : : {
61 : : #ifdef CONFIG_ARCH_POSIX
62 : : const char *cwd;
63 : : char buf[200];
64 : :
65 : : cwd = getcwd(buf, sizeof(buf));
66 : : if (cwd && strlen(file) > strlen(cwd) &&
67 : : !strncmp(file, cwd, strlen(cwd)))
68 : : return file + strlen(cwd) + 1; /* move past the trailing '/' */
69 : : #endif
70 : 0 : return file;
71 : : }
72 : :
73 : 1 : static int cleanup_test(struct ztest_unit_test *test)
74 : : {
75 : 1 : int ret = TC_PASS;
76 : : int mock_status;
77 : :
78 : 1 : mock_status = z_cleanup_mock();
79 : :
80 : : #ifdef KERNEL
81 : : /* we need to remove the ztest_thread information from the timeout_q.
82 : : * Because we reuse the same k_thread structure this would
83 : : * causes some problems.
84 : : */
85 : : if (IS_ENABLED(CONFIG_MULTITHREADING)) {
86 : 1 : k_thread_abort(&ztest_thread);
87 : : }
88 : : #endif
89 : :
90 [ + - - + ]: 1 : if (!ret && mock_status == 1) {
91 : 0 : PRINT("Test %s failed: Unused mock parameter values\n",
92 : : test->name);
93 : 0 : ret = TC_FAIL;
94 [ + - - + ]: 1 : } else if (!ret && mock_status == 2) {
95 : 0 : PRINT("Test %s failed: Unused mock return values\n",
96 : : test->name);
97 : 0 : ret = TC_FAIL;
98 : : } else {
99 : : ;
100 : : }
101 : :
102 : 1 : return ret;
103 : : }
104 : :
105 : : #ifdef KERNEL
106 : : #ifdef CONFIG_SMP
107 : : #define NUM_CPUHOLD (CONFIG_MP_NUM_CPUS - 1)
108 : : #else
109 : : #define NUM_CPUHOLD 0
110 : : #endif
111 : : #define CPUHOLD_STACK_SZ (512 + CONFIG_TEST_EXTRA_STACK_SIZE)
112 : :
113 : : static struct k_thread cpuhold_threads[NUM_CPUHOLD];
114 : : K_KERNEL_STACK_ARRAY_DEFINE(cpuhold_stacks, NUM_CPUHOLD, CPUHOLD_STACK_SZ);
115 : : static struct k_sem cpuhold_sem;
116 : : volatile int cpuhold_active;
117 : :
118 : : /* "Holds" a CPU for use with the "1cpu" test cases. Note that we
119 : : * can't use tools like the cpumask feature because we have tests that
120 : : * may need to control that configuration themselves. We do this at
121 : : * the lowest level, but locking interrupts directly and spinning.
122 : : */
123 : 0 : static void cpu_hold(void *arg1, void *arg2, void *arg3)
124 : : {
125 : : ARG_UNUSED(arg1);
126 : : ARG_UNUSED(arg2);
127 : : ARG_UNUSED(arg3);
128 : 0 : unsigned int key = arch_irq_lock();
129 : 0 : uint32_t dt, start_ms = k_uptime_get_32();
130 : :
131 : 0 : k_sem_give(&cpuhold_sem);
132 : :
133 : : #if defined(CONFIG_ARM64) && defined(CONFIG_FPU_SHARING)
134 : : /*
135 : : * We'll be spinning with IRQs disabled. The flush-your-FPU request
136 : : * IPI will never be serviced during that time. Therefore we flush
137 : : * the FPU preemptively here to prevent any other CPU waiting after
138 : : * this CPU forever and deadlock the system.
139 : : */
140 : : extern void z_arm64_flush_local_fpu(void);
141 : : z_arm64_flush_local_fpu();
142 : : #endif
143 : :
144 [ # # ]: 0 : while (cpuhold_active) {
145 : 0 : k_busy_wait(1000);
146 : : }
147 : :
148 : : /* Holding the CPU via spinning is expensive, and abusing this
149 : : * for long-running test cases tends to overload the CI system
150 : : * (qemu runs separate CPUs in different threads, but the CI
151 : : * logic views it as one "job") and cause other test failures.
152 : : */
153 : 0 : dt = k_uptime_get_32() - start_ms;
154 : 0 : zassert_true(dt < 3000,
155 : : "1cpu test took too long (%d ms)", dt);
156 : 0 : arch_irq_unlock(key);
157 : 0 : }
158 : :
159 : 0 : void z_impl_z_test_1cpu_start(void)
160 : : {
161 : 0 : cpuhold_active = 1;
162 : : char tname[CONFIG_THREAD_MAX_NAME_LEN];
163 : :
164 : 0 : k_sem_init(&cpuhold_sem, 0, 999);
165 : :
166 : : /* Spawn N-1 threads to "hold" the other CPUs, waiting for
167 : : * each to signal us that it's locked and spinning.
168 : : *
169 : : * Note that NUM_CPUHOLD can be a value that causes coverity
170 : : * to flag the following loop as DEADCODE so suppress the warning.
171 : : */
172 : : /* coverity[DEADCODE] */
173 [ # # ]: 0 : for (int i = 0; i < NUM_CPUHOLD; i++) {
174 : 0 : k_thread_create(&cpuhold_threads[i],
175 : 0 : cpuhold_stacks[i], CPUHOLD_STACK_SZ,
176 : : (k_thread_entry_t) cpu_hold, NULL, NULL, NULL,
177 : 0 : K_HIGHEST_THREAD_PRIO, 0, K_NO_WAIT);
178 : : if (IS_ENABLED(CONFIG_THREAD_NAME)) {
179 : 0 : snprintk(tname, CONFIG_THREAD_MAX_NAME_LEN, "cpuhold%02d", i);
180 : 0 : k_thread_name_set(&cpuhold_threads[i], tname);
181 : : }
182 : 0 : k_sem_take(&cpuhold_sem, K_FOREVER);
183 : : }
184 : 0 : }
185 : :
186 : 0 : void z_impl_z_test_1cpu_stop(void)
187 : : {
188 : 0 : cpuhold_active = 0;
189 : :
190 : : /* Note that NUM_CPUHOLD can be a value that causes coverity
191 : : * to flag the following loop as DEADCODE so suppress the warning.
192 : : */
193 : : /* coverity[DEADCODE] */
194 [ # # ]: 0 : for (int i = 0; i < NUM_CPUHOLD; i++) {
195 : 0 : k_thread_abort(&cpuhold_threads[i]);
196 : : }
197 : 0 : }
198 : :
199 : : #ifdef CONFIG_USERSPACE
200 : : void z_vrfy_z_test_1cpu_start(void)
201 : : {
202 : : z_impl_z_test_1cpu_start();
203 : : }
204 : : #include <syscalls/z_test_1cpu_start_mrsh.c>
205 : :
206 : : void z_vrfy_z_test_1cpu_stop(void)
207 : : {
208 : : z_impl_z_test_1cpu_stop();
209 : : }
210 : : #include <syscalls/z_test_1cpu_stop_mrsh.c>
211 : : #endif /* CONFIG_USERSPACE */
212 : : #endif
213 : :
214 : 2 : static void run_test_rules(bool is_before, struct ztest_unit_test *test, void *data)
215 : : {
216 [ - + ]: 2 : for (struct ztest_test_rule *rule = _ztest_test_rule_list_start;
217 : 0 : rule < _ztest_test_rule_list_end; ++rule) {
218 [ # # # # ]: 0 : if (is_before && rule->before_each) {
219 : 0 : rule->before_each(test, data);
220 [ # # # # ]: 0 : } else if (!is_before && rule->after_each) {
221 : 0 : rule->after_each(test, data);
222 : : }
223 : : }
224 : 2 : }
225 : :
226 : 1 : static void run_test_functions(struct ztest_suite_node *suite, struct ztest_unit_test *test,
227 : : void *data)
228 : : {
229 : 1 : phase = TEST_PHASE_TEST;
230 : 1 : test->test(data);
231 : 1 : }
232 : :
233 : : #ifndef KERNEL
234 : :
235 : : /* Static code analysis tool can raise a violation that the standard header
236 : : * <setjmp.h> shall not be used.
237 : : *
238 : : * setjmp is using in a test code, not in a runtime code, it is acceptable.
239 : : * It is a deliberate deviation.
240 : : */
241 : : #include <setjmp.h> /* parasoft-suppress MISRAC2012-RULE_21_4-a MISRAC2012-RULE_21_4-b*/
242 : : #include <signal.h>
243 : : #include <string.h>
244 : : #include <stdlib.h>
245 : :
246 : : #define FAIL_FAST 0
247 : :
248 : : static jmp_buf test_fail;
249 : : static jmp_buf test_pass;
250 : : static jmp_buf stack_fail;
251 : :
252 : : void ztest_test_fail(void)
253 : : {
254 : : raise(SIGABRT);
255 : : }
256 : :
257 : : void ztest_test_pass(void)
258 : : {
259 : : longjmp(test_pass, 1);
260 : : }
261 : :
262 : : /**
263 : : * @brief Get a friendly name string for a given test phrase.
264 : : *
265 : : * @param phase an enum ztest_phase value describing the desired test phase
266 : : * @returns a string name for `phase`
267 : : */
268 : : static inline const char *get_friendly_phase_name(enum ztest_phase phase)
269 : : {
270 : : switch (phase) {
271 : : case TEST_PHASE_SETUP:
272 : : return "setup";
273 : : case TEST_PHASE_BEFORE:
274 : : return "before";
275 : : case TEST_PHASE_TEST:
276 : : return "test";
277 : : case TEST_PHASE_AFTER:
278 : : return "after";
279 : : case TEST_PHASE_TEARDOWN:
280 : : return "teardown";
281 : : case TEST_PHASE_FRAMEWORK:
282 : : return "framework";
283 : : default:
284 : : return "(unknown)";
285 : : }
286 : : }
287 : :
288 : : static void handle_signal(int sig)
289 : : {
290 : : PRINT(" %s", strsignal(sig));
291 : : switch (phase) {
292 : : case TEST_PHASE_SETUP:
293 : : case TEST_PHASE_BEFORE:
294 : : case TEST_PHASE_TEST:
295 : : case TEST_PHASE_AFTER:
296 : : case TEST_PHASE_TEARDOWN:
297 : : PRINT(" at %s function\n", get_friendly_phase_name(phase));
298 : : longjmp(test_fail, 1);
299 : : case TEST_PHASE_FRAMEWORK:
300 : : PRINT("\n");
301 : : longjmp(stack_fail, 1);
302 : : }
303 : : }
304 : :
305 : : static void init_testing(void)
306 : : {
307 : : signal(SIGABRT, handle_signal);
308 : : signal(SIGSEGV, handle_signal);
309 : :
310 : : if (setjmp(stack_fail)) {
311 : : PRINT("Test suite crashed.");
312 : : exit(1);
313 : : }
314 : : }
315 : :
316 : : static int run_test(struct ztest_suite_node *suite, struct ztest_unit_test *test, void *data)
317 : : {
318 : : int ret = TC_PASS;
319 : :
320 : : TC_START(test->name);
321 : :
322 : : if (setjmp(test_fail)) {
323 : : ret = TC_FAIL;
324 : : goto out;
325 : : }
326 : :
327 : : if (setjmp(test_pass)) {
328 : : ret = TC_PASS;
329 : : goto out;
330 : : }
331 : :
332 : : run_test_functions(suite, test, data);
333 : : out:
334 : : ret |= cleanup_test(test);
335 : : Z_TC_END_RESULT(ret, test->name);
336 : :
337 : : return ret;
338 : : }
339 : :
340 : : #else /* KERNEL */
341 : :
342 : : /* Zephyr's probably going to cause all tests to fail if one test fails, so
343 : : * skip the rest of tests if one of them fails
344 : : */
345 : : #ifdef CONFIG_ZTEST_FAIL_FAST
346 : : #define FAIL_FAST 1
347 : : #else
348 : : #define FAIL_FAST 0
349 : : #endif
350 : :
351 : : K_THREAD_STACK_DEFINE(ztest_thread_stack, CONFIG_ZTEST_STACK_SIZE + CONFIG_TEST_EXTRA_STACK_SIZE);
352 : : static ZTEST_BMEM int test_result;
353 : :
354 : 0 : static void test_finalize(void)
355 : : {
356 : : if (IS_ENABLED(CONFIG_MULTITHREADING)) {
357 : 0 : k_thread_abort(&ztest_thread);
358 : 0 : k_thread_abort(k_current_get());
359 : : }
360 : 0 : }
361 : :
362 : 0 : void ztest_test_fail(void)
363 : : {
364 : 0 : test_result = -1;
365 : 0 : test_finalize();
366 : 0 : }
367 : :
368 : 0 : void ztest_test_pass(void)
369 : : {
370 : 0 : test_result = 0;
371 : 0 : test_finalize();
372 : 0 : }
373 : :
374 : 0 : void ztest_test_skip(void)
375 : : {
376 : 0 : test_result = -2;
377 : 0 : test_finalize();
378 : 0 : }
379 : :
380 : 0 : void ztest_simple_1cpu_before(void *data)
381 : : {
382 : : ARG_UNUSED(data);
383 : 0 : z_test_1cpu_start();
384 : 0 : }
385 : :
386 : 0 : void ztest_simple_1cpu_after(void *data)
387 : : {
388 : : ARG_UNUSED(data);
389 : 0 : z_test_1cpu_stop();
390 : 0 : }
391 : :
392 : 1 : static void init_testing(void)
393 : : {
394 : 1 : k_object_access_all_grant(&ztest_thread);
395 : 1 : }
396 : :
397 : 1 : static void test_cb(void *a, void *b, void *c)
398 : : {
399 : 1 : struct ztest_suite_node *suite = a;
400 : 1 : struct ztest_unit_test *test = b;
401 : :
402 : 1 : test_result = 1;
403 : 1 : run_test_rules(/*is_before=*/true, test, /*data=*/c);
404 [ - + ]: 1 : if (suite->before) {
405 : 0 : suite->before(/*data=*/c);
406 : : }
407 : 1 : run_test_functions(suite, test, c);
408 : 1 : test_result = 0;
409 : 1 : }
410 : :
411 : 1 : static int run_test(struct ztest_suite_node *suite, struct ztest_unit_test *test, void *data)
412 : : {
413 : 1 : int ret = TC_PASS;
414 : :
415 : 1 : TC_START(test->name);
416 : :
417 : 1 : phase = TEST_PHASE_BEFORE;
418 : :
419 : : if (IS_ENABLED(CONFIG_MULTITHREADING)) {
420 : 1 : k_thread_create(&ztest_thread, ztest_thread_stack,
421 : : K_THREAD_STACK_SIZEOF(ztest_thread_stack),
422 : : (k_thread_entry_t)test_cb, suite, test, data,
423 : : CONFIG_ZTEST_THREAD_PRIORITY,
424 : 1 : test->thread_options | K_INHERIT_PERMS, K_FOREVER);
425 : :
426 [ + - ]: 1 : if (test->name != NULL) {
427 : 1 : k_thread_name_set(&ztest_thread, test->name);
428 : : }
429 : 1 : k_thread_start(&ztest_thread);
430 : 1 : k_thread_join(&ztest_thread, K_FOREVER);
431 : : } else {
432 : : test_result = 1;
433 : : run_test_rules(/*is_before=*/true, test, data);
434 : : if (suite->before) {
435 : : suite->before(data);
436 : : }
437 : : run_test_functions(suite, test, data);
438 : : }
439 : :
440 : 1 : phase = TEST_PHASE_AFTER;
441 [ - + ]: 1 : if (suite->after != NULL) {
442 : 0 : suite->after(data);
443 : : }
444 : 1 : run_test_rules(/*is_before=*/false, test, data);
445 : 1 : phase = TEST_PHASE_FRAMEWORK;
446 : :
447 : : /* Flush all logs in case deferred mode and default logging thread are used. */
448 : 1 : while (IS_ENABLED(CONFIG_TEST_LOGGING_FLUSH_AFTER_TEST) &&
449 : : IS_ENABLED(CONFIG_LOG_PROCESS_THREAD) &&
450 : : log_data_pending()) {
451 : : k_msleep(100);
452 : : }
453 : :
454 [ - + ]: 1 : if (test_result == -1) {
455 : 0 : ret = TC_FAIL;
456 : : }
457 : :
458 : : if (!test_result || !FAIL_FAST) {
459 : 1 : ret |= cleanup_test(test);
460 : : }
461 : :
462 [ - + ]: 1 : if (test_result == -2) {
463 : 0 : Z_TC_END_RESULT(TC_SKIP, test->name);
464 : : } else {
465 : 1 : Z_TC_END_RESULT(ret, test->name);
466 : : }
467 : :
468 : 1 : return ret;
469 : : }
470 : :
471 : : #endif /* !KERNEL */
472 : :
473 : 1 : static struct ztest_suite_node *ztest_find_test_suite(const char *name)
474 : : {
475 : : struct ztest_suite_node *node;
476 : :
477 [ + - ]: 1 : for (node = _ztest_suite_node_list_start; node < _ztest_suite_node_list_end; ++node) {
478 [ + - ]: 1 : if (strcmp(name, node->name) == 0) {
479 : 1 : return node;
480 : : }
481 : : }
482 : :
483 : 0 : return NULL;
484 : : }
485 : :
486 : 2 : struct ztest_unit_test *ztest_get_next_test(const char *suite, struct ztest_unit_test *prev)
487 : : {
488 [ + + ]: 2 : struct ztest_unit_test *test = (prev == NULL) ? _ztest_unit_test_list_start : prev + 1;
489 : :
490 [ + + ]: 2 : for (; test < _ztest_unit_test_list_end; ++test) {
491 [ + - ]: 1 : if (strcmp(suite, test->test_suite_name) == 0) {
492 : 1 : return test;
493 : : }
494 : : }
495 : 1 : return NULL;
496 : : }
497 : :
498 : 1 : static int z_ztest_run_test_suite_ptr(struct ztest_suite_node *suite)
499 : : {
500 : 1 : struct ztest_unit_test *test = NULL;
501 : 1 : void *data = NULL;
502 : 1 : int fail = 0;
503 : :
504 [ - + ]: 1 : if (test_status < 0) {
505 : 0 : return test_status;
506 : : }
507 : :
508 [ - + ]: 1 : if (suite == NULL) {
509 : 0 : test_status = 1;
510 : 0 : return -1;
511 : : }
512 : :
513 : 1 : init_testing();
514 : :
515 : 1 : TC_SUITE_START(suite->name);
516 : 1 : phase = TEST_PHASE_SETUP;
517 [ - + ]: 1 : if (suite->setup != NULL) {
518 : 0 : data = suite->setup();
519 : : }
520 [ + + ]: 2 : while ((test = ztest_get_next_test(suite->name, test)) != NULL) {
521 : 1 : fail += run_test(suite, test, data);
522 : :
523 : : if (fail && FAIL_FAST) {
524 : : break;
525 : : }
526 : : }
527 [ + - ]: 1 : TC_SUITE_END(suite->name, (fail > 0 ? TC_FAIL : TC_PASS));
528 : 1 : phase = TEST_PHASE_TEARDOWN;
529 [ - + ]: 1 : if (suite->teardown != NULL) {
530 : 0 : suite->teardown(data);
531 : : }
532 : :
533 [ + - - + ]: 1 : test_status = (test_status || fail) ? 1 : 0;
534 : :
535 : 1 : return fail;
536 : : }
537 : :
538 : 0 : int z_ztest_run_test_suite(const char *name)
539 : : {
540 : 0 : return z_ztest_run_test_suite_ptr(ztest_find_test_suite(name));
541 : : }
542 : :
543 : 1 : void end_report(void)
544 : : {
545 [ - + ]: 1 : if (test_status) {
546 : 0 : TC_END_REPORT(TC_FAIL);
547 : : } else {
548 : 1 : TC_END_REPORT(TC_PASS);
549 : : }
550 : 1 : }
551 : :
552 : : #ifdef CONFIG_USERSPACE
553 : : K_APPMEM_PARTITION_DEFINE(ztest_mem_partition);
554 : : #endif
555 : :
556 : 1 : int ztest_run_test_suites(const void *state)
557 : : {
558 : : struct ztest_suite_node *ptr;
559 : 1 : int count = 0;
560 : :
561 [ + + ]: 2 : for (ptr = _ztest_suite_node_list_start; ptr < _ztest_suite_node_list_end; ++ptr) {
562 : 1 : struct ztest_suite_stats *stats = &ptr->stats;
563 : 1 : bool should_run = true;
564 : :
565 [ - + ]: 1 : if (ptr->predicate != NULL) {
566 : 0 : should_run = ptr->predicate(state);
567 : : } else {
568 : : /* If predicate is NULL, only run this test once. */
569 : 1 : should_run = stats->run_count == 0;
570 : : }
571 : :
572 [ + - ]: 1 : if (should_run) {
573 : 1 : int fail = z_ztest_run_test_suite_ptr(ptr);
574 : :
575 : 1 : count++;
576 : 1 : stats->run_count++;
577 [ - + ]: 1 : stats->fail_count += (fail != 0) ? 1 : 0;
578 : : } else {
579 : 0 : stats->skip_count++;
580 : : }
581 : : }
582 : :
583 : 1 : return count;
584 : : }
585 : :
586 : 1 : void ztest_verify_all_test_suites_ran(void)
587 : : {
588 : 1 : bool all_tests_run = true;
589 : : struct ztest_suite_node *suite;
590 : : struct ztest_unit_test *test;
591 : :
592 [ + + ]: 2 : for (suite = _ztest_suite_node_list_start; suite < _ztest_suite_node_list_end; ++suite) {
593 [ - + ]: 1 : if (suite->stats.run_count < 1) {
594 : 0 : PRINT("ERROR: Test suite '%s' did not run.\n", suite->name);
595 : 0 : all_tests_run = false;
596 : : }
597 : : }
598 : :
599 [ + + ]: 2 : for (test = _ztest_unit_test_list_start; test < _ztest_unit_test_list_end; ++test) {
600 : 1 : suite = ztest_find_test_suite(test->test_suite_name);
601 [ - + ]: 1 : if (suite == NULL) {
602 : 0 : PRINT("ERROR: Test '%s' assigned to test suite '%s' which doesn't exist\n",
603 : : test->name, test->test_suite_name);
604 : 0 : all_tests_run = false;
605 : : }
606 : : }
607 : :
608 [ - + ]: 1 : if (!all_tests_run) {
609 : 0 : test_status = 1;
610 : : }
611 : 1 : }
612 : :
613 : 1 : void __weak test_main(void)
614 : : {
615 : 1 : ztest_run_test_suites(NULL);
616 : 1 : ztest_verify_all_test_suites_ran();
617 : 1 : }
618 : :
619 : : #ifndef KERNEL
620 : : int main(void)
621 : : {
622 : : z_init_mock();
623 : : test_main();
624 : : end_report();
625 : :
626 : : return test_status;
627 : : }
628 : : #else
629 : 1 : void main(void)
630 : : {
631 : : #ifdef CONFIG_USERSPACE
632 : : /* Partition containing globals tagged with ZTEST_DMEM and ZTEST_BMEM
633 : : * macros. Any variables that user code may reference need to be
634 : : * placed in this partition if no other memory domain configuration
635 : : * is made.
636 : : */
637 : : k_mem_domain_add_partition(&k_mem_domain_default,
638 : : &ztest_mem_partition);
639 : : #ifdef Z_MALLOC_PARTITION_EXISTS
640 : : /* Allow access to malloc() memory */
641 : : k_mem_domain_add_partition(&k_mem_domain_default,
642 : : &z_malloc_partition);
643 : : #endif
644 : : #endif /* CONFIG_USERSPACE */
645 : :
646 : : z_init_mock();
647 : 1 : test_main();
648 : 1 : end_report();
649 : : LOG_PANIC();
650 : : if (IS_ENABLED(CONFIG_ZTEST_RETEST_IF_PASSED)) {
651 : : static __noinit struct {
652 : : uint32_t magic;
653 : : uint32_t boots;
654 : : } state;
655 : : const uint32_t magic = 0x152ac523;
656 : :
657 : : if (state.magic != magic) {
658 : : state.magic = magic;
659 : : state.boots = 0;
660 : : }
661 : : state.boots += 1;
662 : : if (test_status == 0) {
663 : : PRINT("Reset board #%u to test again\n",
664 : : state.boots);
665 : : k_msleep(10);
666 : : sys_reboot(SYS_REBOOT_COLD);
667 : : } else {
668 : : PRINT("Failed after %u attempts\n", state.boots);
669 : : state.boots = 0;
670 : : }
671 : : }
672 : 1 : }
673 : : #endif
|