1 /*
2  * Copyright (c) 2022 Google LLC
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdlib.h>
8 #include <zephyr/ztest.h>
9 
10 
11 static const char *test_args;
12 
13 /**
14  * @brief Try to shorten a filename by removing the current directory
15  *
16  * This helps to reduce the very long filenames in assertion failures. It
17  * removes the current directory from the filename and returns the rest.
18  * This makes assertions a lot more readable, and sometimes they fit on one
19  * line.
20  *
21  * @param file Filename to check
22  * @returns Shortened filename, or @file if it could not be shortened
23  */
ztest_relative_filename(const char * file)24 const char *ztest_relative_filename(const char *file)
25 {
26 	return file;
27 }
28 
29 /**
30  * Default entry point for running registered unit tests.
31  *
32  * @param state The current state of the machine as it relates to the test executable.
33  */
z_ztest_run_all(const void * state,bool shuffle,int suite_iter,int case_iter)34 void z_ztest_run_all(const void *state, bool shuffle, int suite_iter, int case_iter)
35 {
36 	ztest_run_test_suites(state, shuffle, suite_iter, case_iter);
37 }
38 
ztest_reset_test_args(void)39 void ztest_reset_test_args(void)
40 {
41 	if (test_args != NULL) {
42 		free((void *)test_args);
43 	}
44 	test_args = NULL;
45 }
46 
ztest_set_test_args(char * args)47 void ztest_set_test_args(char *args)
48 {
49 	ztest_reset_test_args();
50 	test_args = strdup(args);
51 }
52 
53 /**
54  * @brief Helper function to get command line test arguments
55  *
56  * @return const char*
57  */
ztest_get_test_args(void)58 char *ztest_get_test_args(void)
59 {
60 	if (test_args != NULL) {
61 		return strdup(test_args);
62 	} else {
63 		return NULL;
64 	}
65 }
66 
67 
68 /**
69  * @brief Checks if the test_args contains the suite/test name.
70  *
71  * @param suite_name
72  * @param test_name
73  * @return true
74  * @return false
75  */
z_ztest_testargs_contains(const char * suite_name,const char * test_name)76 static bool z_ztest_testargs_contains(const char *suite_name, const char *test_name)
77 {
78 	bool found = false;
79 	char *test_args_local = ztest_get_test_args();
80 	char *suite_test_pair;
81 	char *last_suite_test_pair;
82 	char *suite_arg;
83 	char *test_arg;
84 	char *last_arg;
85 
86 	if (test_args_local == NULL) {
87 		return true;
88 	}
89 	suite_test_pair = strtok_r(test_args_local, ",", &last_suite_test_pair);
90 
91 	while (suite_test_pair && !found) {
92 		suite_arg = strtok_r(suite_test_pair, ":", &last_arg);
93 		test_arg = strtok_r(NULL, ":", &last_arg);
94 
95 		found = !strcmp(suite_arg, suite_name);
96 		if (test_name && test_arg) {
97 			found &= !strcmp(test_arg, "*") ||
98 				 !strcmp(test_arg, test_name);
99 		}
100 
101 		suite_test_pair = strtok_r(NULL, ",", &last_suite_test_pair);
102 	}
103 	free((void *)test_args_local);
104 	return found;
105 }
106 
107 /**
108  * @brief Determines if the test suite should run based on test cases listed
109  *	  in the command line argument.
110  *
111  * Overrides implementation in ztest.c
112  *
113  * @param state The current state of the machine as it relates to the test
114  *		executable.
115  * @param suite Pointer to ztest_suite_node
116  * @return true
117  * @return false
118  */
z_ztest_should_suite_run(const void * state,struct ztest_suite_node * suite)119 bool z_ztest_should_suite_run(const void *state, struct ztest_suite_node *suite)
120 {
121 	char *test_args_local = ztest_get_test_args();
122 	bool run_suite = true;
123 
124 	if (test_args_local != NULL && !z_ztest_testargs_contains(suite->name, NULL)) {
125 		run_suite = false;
126 		suite->stats->run_count++;
127 	} else if (suite->predicate != NULL) {
128 		run_suite = suite->predicate(state);
129 	}
130 
131 	if (test_args_local != NULL) {
132 		free((void *)test_args_local);
133 	}
134 	return run_suite;
135 }
136 
137 
138 
139 /**
140  * @brief Determines if the test case should run based on test cases listed
141  *	  in the command line argument. Run all tests for non-posix builds
142  *
143  * @param suite - name of test suite
144  * @param test  - name of unit test
145  * @return true
146  * @return false
147  */
z_ztest_should_test_run(const char * suite,const char * test)148 bool z_ztest_should_test_run(const char *suite, const char *test)
149 {
150 	bool run_test = false;
151 
152 	run_test = z_ztest_testargs_contains(suite, test);
153 
154 	return run_test;
155 }
156 
157 ZTEST_DMEM const struct ztest_arch_api ztest_api = {
158 	.run_all = z_ztest_run_all,
159 	.should_suite_run = z_ztest_should_suite_run,
160 	.should_test_run = z_ztest_should_test_run
161 };
162