1 /*
2  * Copyright (c) 2023 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <string.h>
8 #include <zephyr/kernel.h>
9 #include "iut.h"
10 #include <zephyr/sys/__assert.h>
11 
12 #define ARGC_MIN_NUM 2
13 #define ARGC_MAX_NUM 8
14 static char argv_buf[1024];
15 static uint32_t argv_buf_pos;
16 static int argc_run;
17 static char *argv_run[ARGC_MAX_NUM];
18 
19 static K_SEM_DEFINE(sem_trigger, 1, 1);
20 static K_SEM_DEFINE(sem_run, 0, 1);
21 
22 static uint32_t iut_cnt_run;
23 static uint32_t iut_cnt_fail;
24 
25 const struct iut_case *iut_running;
26 
iut_run(const char * name,const char * group,uint32_t attri,int argc,char ** argv)27 static int iut_run(const char *name, const char *group, uint32_t attri,
28 		int argc, char **argv)
29 {
30 	const struct iut_case *ut = NULL;
31 	int ret;
32 
33 	iut_print("\nIUT: (%s, %s, 0x%x): Start running cases ......\n",
34 			group ? group : "NULL", name ? name : "NULL", attri);
35 
36 	if (argc) {
37 		iut_print("\targc=%d\n", argc);
38 		for (int i = 0; i < argc; i++)
39 			iut_print("\targv[%d]=\"%s\"\n", i, argv[i]);
40 	}
41 
42 	iut_cnt_run = iut_cnt_fail = 0;
43 
44 	while (1) {
45 		if (ut == NULL) {
46 			ut = (void *)__iut_cases_start;
47 		} else {
48 			ut++;
49 		}
50 		if ((char *)ut >= __iut_cases_end) {
51 			break;
52 		}
53 
54 		if (group && strncmp(group, ut->group, strlen(group))) {
55 			continue;
56 		}
57 		if (name && strncmp(ut->name, name, strlen(ut->name) + 1)) {
58 			continue;
59 		}
60 		if (attri && ((ut->attri & attri) != attri)) {
61 			continue;
62 		}
63 
64 		iut_print("IUT: (%s, %s): Case %u, run\n",
65 				ut->group, ut->name, iut_cnt_run);
66 		iut_running = ut;
67 
68 		ret = ut->func(argc, argv);
69 
70 		iut_print("IUT: (%s, %s): Case %u, %s\n",
71 				ut->group, ut->name, iut_cnt_run,
72 				(ret == IUT_ERR_OK) ? "pass" : "fail");
73 		iut_cnt_run++;
74 		if (ret != IUT_ERR_OK) {
75 			iut_cnt_fail++;
76 		}
77 	}
78 
79 	iut_print("\nIUT: (%s, %s, 0x%x): Finished %u cases, %u failed ......\n",
80 			group ? group : "NULL", name ? name : "NULL", attri,
81 			iut_cnt_run, iut_cnt_fail);
82 
83 	return 0;
84 }
85 
iut_trigger(size_t argc,char ** argv)86 int iut_trigger(size_t argc, char **argv)
87 {
88 	if (k_sem_take(&sem_trigger, K_NO_WAIT) != 0) {
89 		iut_print("busy running (%s: %s: %s), please wait and try later!\n",
90 				argv_run[0], argv_run[1],
91 				(argc_run >= 3) ? argv_run[2] : "NULL");
92 		return -EBUSY;
93 	}
94 
95 	if ((argc < ARGC_MIN_NUM) || (argc > ARGC_MAX_NUM)) {
96 		goto err_out;
97 	}
98 
99 	argv_buf_pos = 0;
100 
101 	for (int i = 0; i < argc; i++) {
102 		uint32_t len = strlen(argv[i]);
103 
104 		if ((argv_buf_pos + len + 1) > sizeof(argv_buf)) {
105 			goto err_out;
106 		}
107 
108 		argv_run[i] = &argv_buf[argv_buf_pos];
109 		memcpy(argv_run[i], argv[i], len + 1);
110 		argv_buf_pos += (len + 1);
111 	}
112 
113 	argc_run = argc;
114 	k_sem_give(&sem_run);
115 
116 	return 0;
117 
118 err_out:
119 	iut_print("wrong parameters to run, argc=%d", (int)argc);
120 	return -EPERM;
121 }
122 
main(void)123 int main(void)
124 {
125 	k_msleep(2000);
126 
127 #ifndef CONFIG_DEBUG
128 	/* iut_run(NULL, NULL, IUT_ATTRI_AUTORUN, 0, NULL); */
129 #endif
130 
131 	while (1) {
132 		const char *name = NULL;
133 		const char *group = NULL;
134 
135 		k_sem_take(&sem_run, K_FOREVER);
136 
137 		if (strncmp(argv_run[0], "grun", strlen(argv_run[0])) == 0) {
138 			group = argv_run[1];
139 		} else {
140 			__ASSERT_NO_MSG(strncmp(argv_run[0], "run",
141 						strlen(argv_run[0])) == 0);
142 			name = argv_run[1];
143 		}
144 
145 		iut_run(name, group, 0x0, (argc_run - 2),
146 				(argc_run - 2) ? (&argv_run[2]) : NULL);
147 
148 		k_sem_give(&sem_trigger);
149 	};
150 
151 	return 0;
152 }
153