LCOV - code coverage report
Current view: top level - subsys/testsuite/ztest/src - ztest_new.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 107 186 57.5 %
Date: 2022-08-18 11:36:24 Functions: 14 25 56.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 39 80 48.8 %

           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

Generated by: LCOV version 1.14