Skip to content

Commit 162426c

Browse files
committed
test/runtest: Move testbench code into runtest
Prior to this commit, the testbench app predefined a set of four tasks for use by unit tests. Unit tests that needed to use generic tasks would assume the presence of tasks called "task1", "task2", etc. In addition, the testbench was responsible for logging test results. This approach had some problems: * Introduction of unit tests requires major changes to the app: o Define new tasks and stacks and add code to initialize and suspend o Create a cbmem and register a test log. o Write dedicated "driver" code for each test suite. * Different test code for SELFTEST vs. real-hardware (the testbench app is not present during a self-test). * Number of generic tasks limited to four. This commit adds a generic task-allocation mechanism to the `test/runtest` library. When a unit test needs a new task, it requests one from runtest. When a test completes, runtest suspends all the allocated tasks. In addition, runtest registers a cbmem-backed test log if configured to do so (`RUNTEST_LOG`).
1 parent 4d5f9e6 commit 162426c

File tree

14 files changed

+446
-968
lines changed

14 files changed

+446
-968
lines changed

apps/testbench/src/testbench.c

+15-267
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
#include <id/id.h>
4545
#include <oic/oc_api.h>
4646
#include <oic/oc_gatt.h>
47+
#include "json_test/json_test.h"
48+
#include "os_test/os_test.h"
4749

4850
#include "testutil/testutil.h"
4951

@@ -67,17 +69,11 @@
6769
#if MYNEWT_VAL(RUNTEST_CLI)
6870
#include "runtest/runtest.h"
6971
#endif
70-
71-
#include "testbench.h"
7272
#include "tbb.h"
7373

7474
struct os_timeval tv;
7575
struct os_timezone tz;
7676

77-
/* Init all tasks */
78-
volatile int tasks_initialized;
79-
int init_tasks(void);
80-
8177
/* Test Task */
8278
#define TESTTASK_PRIO (1)
8379
#define TESTTASK_STACK_SIZE OS_STACK_ALIGN(256)
@@ -86,193 +82,19 @@ static struct os_task testtask;
8682
/* For LED toggling */
8783
int g_led_pin;
8884

89-
os_stack_t *stack1;
90-
os_stack_t *stack2;
91-
os_stack_t *stack3;
92-
os_stack_t *stack4;
93-
94-
/*
95-
* Test log cbmem buf
96-
*/
97-
#define MAX_CBMEM_BUF 2048
98-
uint32_t *cbmem_buf;
99-
struct cbmem cbmem;
100-
101-
struct log testlog;
102-
int total_tests;
103-
int total_fails;
10485
int blinky_blink;
10586

106-
int forcefail; /* to optionally force a fail on a tests */
107-
10887
#define BLINKY_DUTYCYCLE_SUCCESS 1
10988
#define BLINKY_DUTYCYCLE_FAIL 16
11089

111-
char buildID[TESTBENCH_BUILDID_SZ];
112-
113-
struct runtest_evq_arg test_event_arg;
114-
char runtest_token[RUNTEST_REQ_SIZE];
115-
static int testbench_runtests(struct os_event *ev);
116-
static void testbench_test_complete(void);
117-
118-
extern uint32_t stack1_size;
119-
extern uint32_t stack2_size;
120-
extern uint32_t stack3_size;
121-
extern uint32_t stack4_size;
122-
123-
struct ts_suite *current_ts;
124-
125-
void
126-
testbench_ts_result(char *msg, void *arg, bool passed)
127-
{
128-
/* Must log valid json with a strlen less than LOG_PRINTF_MAX_ENTRY_LEN */
129-
char buf[LOG_PRINTF_MAX_ENTRY_LEN];
130-
char *n;
131-
int n_len;
132-
char *s;
133-
int s_len;
134-
char *m;
135-
int m_len;
136-
137-
int len = 35; /* str length of {"k":"","n":"","s":"","m":"","r":1} */
138-
len += strlen(runtest_token);
139-
140-
/* How much of the test name can we log? */
141-
n_len = strlen(tu_case_name);
142-
if (len + n_len >= LOG_PRINTF_MAX_ENTRY_LEN) {
143-
n_len = LOG_PRINTF_MAX_ENTRY_LEN - len - 1;
144-
}
145-
len += n_len;
146-
n = buf;
147-
strncpy(n, tu_case_name, n_len + 1);
148-
149-
/* How much of the suite name can we log? */
150-
s_len = strlen(current_ts->ts_name);
151-
if (len + s_len >= LOG_PRINTF_MAX_ENTRY_LEN) {
152-
s_len = LOG_PRINTF_MAX_ENTRY_LEN - len - 1;
153-
}
154-
len += s_len;
155-
s = n + n_len + 2;
156-
strncpy(s, current_ts->ts_name, s_len + 1);
157-
158-
/* How much of the message can we log? */
159-
m_len = strlen(msg);
160-
if (len + m_len >= LOG_PRINTF_MAX_ENTRY_LEN) {
161-
m_len = LOG_PRINTF_MAX_ENTRY_LEN - len - 1;
162-
}
163-
m = s + s_len + 2;
164-
strncpy(m, msg, m_len + 1);
165-
166-
167-
TESTBENCH_UPDATE_TOD;
168-
169-
total_tests++;
170-
if (!passed) {
171-
total_fails++;
172-
}
173-
174-
MODLOG_INFO(
175-
LOG_MODULE_TEST,
176-
"{\"k\":\"%s\",\"n\":\"%s\",\"s\":\"%s\",\"m\":\"%s\",\"r\":%d}",
177-
runtest_token, n, s, m, passed);
178-
}
179-
180-
void
181-
testbench_ts_pass(char *msg, void *arg)
182-
{
183-
testbench_ts_result(msg, arg, true);
184-
}
185-
186-
void
187-
testbench_ts_fail(char *msg, void *arg)
188-
{
189-
testbench_ts_result(msg, arg, false);
190-
}
90+
OS_TASK_STACK_DEFINE(teststack, TESTTASK_STACK_SIZE);
19191

19292
void
19393
testbench_test_init(void)
19494
{
195-
total_tests = 0;
196-
total_fails = 0;
197-
forcefail = 0;
19895
blinky_blink = BLINKY_DUTYCYCLE_SUCCESS;
19996
}
20097

201-
static int
202-
testbench_runtests(struct os_event *ev)
203-
{
204-
struct runtest_evq_arg *runtest_arg;
205-
int run_all = 0;
206-
207-
/*
208-
* testbench_runtests is normally initiated from newtmanager using the cli
209-
*/
210-
testbench_test_init();
211-
if (ev != NULL) {
212-
runtest_arg = ev->ev_arg;
213-
214-
ts_config.ts_print_results = 0;
215-
ts_config.ts_system_assert = 0;
216-
217-
/*
218-
* The specified "token" is appended to the end of every log message
219-
* that is level INFO and above (i.e. not log_debug log messages)
220-
*/
221-
strcpy(runtest_token, runtest_arg->run_token);
222-
223-
/*
224-
* In run_all set, each test suite is executed
225-
*/
226-
run_all = (strcmp(runtest_arg->run_testname, "all") == 0);
227-
228-
/*
229-
* If no testname was provided (e.g., in the case where mgmt protocol
230-
* did not use the newtmgr application), make the default to run all
231-
* the tests.
232-
*/
233-
if (runtest_arg->run_testname[0] == '\0') {
234-
run_all = 1;
235-
}
236-
237-
/*
238-
* go through entire list of registered test suites
239-
*/
240-
SLIST_FOREACH(current_ts, &g_ts_suites, ts_next) {
241-
if (run_all || !strcmp(runtest_arg->run_testname, current_ts->ts_name)) {
242-
current_ts->ts_test();
243-
}
244-
}
245-
} else {
246-
/*
247-
* run all tests if NULL event is passed as an argument (untested)
248-
*/
249-
SLIST_FOREACH(current_ts, &g_ts_suites, ts_next) {
250-
current_ts->ts_test();
251-
}
252-
}
253-
testbench_test_complete();
254-
255-
return tu_any_failed;
256-
}
257-
258-
/*
259-
* Print results - ci gateway is checking this message syntax to
260-
* determine success or failure
261-
*/
262-
static void
263-
testbench_test_complete(void)
264-
{
265-
MODLOG_INFO(LOG_MODULE_TEST, "%s Done", runtest_token);
266-
MODLOG_INFO(LOG_MODULE_TEST,
267-
"%s TESTBENCH TEST %s - Tests run:%d pass:%d fail:%d %s",
268-
buildID,
269-
(total_fails ? "FAILED" : "PASSED"),
270-
total_tests,
271-
(total_tests-total_fails),
272-
total_fails,
273-
runtest_token);
274-
}
275-
27698
/*
27799
* Run the tests
278100
* If any tests fail, blink the LED BLINKY_DUTYCYCLE_FAIL (16) times a second
@@ -290,79 +112,18 @@ testtask_handler(void *arg)
290112
* if any test fails, blinky the LED more rapidly to
291113
* provide visual feedback from physical device.
292114
*/
293-
if (total_fails) {
115+
if (runtest_total_fails_get() > 0) {
294116
blinky_blink = BLINKY_DUTYCYCLE_FAIL;
295117
}
296118

297-
while (1) {
298-
/* Wait one second */
299-
os_time_delay(OS_TICKS_PER_SEC / blinky_blink);
119+
/* Wait one second */
120+
os_time_delay(OS_TICKS_PER_SEC / blinky_blink);
300121

301-
/* Toggle the LED */
302-
hal_gpio_toggle(g_led_pin);
303-
}
122+
/* Toggle the LED */
123+
hal_gpio_toggle(g_led_pin);
304124
}
305125
}
306126

307-
/*
308-
* init_tasks include test workers
309-
*/
310-
int
311-
init_tasks(void)
312-
{
313-
os_stack_t *teststack;
314-
315-
/*
316-
* malloc the stacks for the testworker tasks
317-
*/
318-
stack1 = malloc(sizeof(os_stack_t) * TASK1_STACK_SIZE);
319-
assert(stack1);
320-
stack1_size = TASK1_STACK_SIZE;
321-
322-
stack2 = malloc(sizeof(os_stack_t) * TASK2_STACK_SIZE);
323-
assert(stack2);
324-
stack2_size = TASK2_STACK_SIZE;
325-
326-
stack3 = malloc(sizeof(os_stack_t) * TASK3_STACK_SIZE);
327-
assert(stack3);
328-
stack3_size = TASK3_STACK_SIZE;
329-
330-
stack4 = malloc(sizeof(os_stack_t) * TASK4_STACK_SIZE);
331-
assert(stack4);
332-
stack4_size = TASK4_STACK_SIZE;
333-
334-
teststack = malloc(sizeof(os_stack_t) * TESTTASK_STACK_SIZE);
335-
assert(teststack);
336-
os_task_init(&testtask, "testtask", testtask_handler, NULL,
337-
TESTTASK_PRIO, OS_WAIT_FOREVER, teststack,
338-
TESTTASK_STACK_SIZE);
339-
340-
tasks_initialized = 1;
341-
return 0;
342-
}
343-
344-
/*
345-
* buildID string is prepended to each log message.
346-
* BUILD_TARGET and BUILD_ID are assume to be initialized by
347-
* build infrastructure. testbench.h sets default values if not.
348-
*/
349-
void
350-
getBuildID(void)
351-
{
352-
sprintf(buildID, "%s Build %s:", BUILD_TARGET, BUILD_ID);
353-
}
354-
355-
/*
356-
* Test suites must be declared before being referenced.
357-
* Note that we're not actually declaring the test suites themselves,
358-
* but rather their helper functions which initialize the appropriate
359-
* callbacks before executing on target HW.
360-
*/
361-
TEST_SUITE_DECL(testbench_mempool);
362-
TEST_SUITE_DECL(testbench_mutex);
363-
TEST_SUITE_DECL(testbench_sem);
364-
TEST_SUITE_DECL(testbench_json);
365-
366127
static void
367128
omgr_app_init(void)
368129
{ }
@@ -383,15 +144,6 @@ main(int argc, char **argv)
383144

384145
sysinit();
385146

386-
getBuildID();
387-
388-
cbmem_buf = malloc(sizeof(uint32_t) * MAX_CBMEM_BUF);
389-
cbmem_init(&cbmem, cbmem_buf, MAX_CBMEM_BUF);
390-
log_register("testlog", &testlog, &log_cbmem_handler, &cbmem, LOG_SYSLEVEL);
391-
392-
rc = modlog_register(LOG_MODULE_TEST, &testlog, LOG_LEVEL_DEBUG, NULL);
393-
assert(rc == 0);
394-
395147
/* Initialize the OIC */
396148
oc_main_init((oc_handler_t *)&omgr_oc_handler);
397149

@@ -406,20 +158,16 @@ main(int argc, char **argv)
406158
* Register the tests that can be run by lookup
407159
* - each test is added to the ts_suites slist
408160
*/
409-
TEST_SUITE_REGISTER(testbench_mempool);
410-
TEST_SUITE_REGISTER(testbench_mutex);
411-
TEST_SUITE_REGISTER(testbench_sem);
412-
TEST_SUITE_REGISTER(testbench_json);
161+
TEST_SUITE_REGISTER(os_mempool_test_suite);
162+
TEST_SUITE_REGISTER(os_mutex_test_suite);
163+
TEST_SUITE_REGISTER(os_sem_test_suite);
164+
TEST_SUITE_REGISTER(test_json_suite);
413165

414166
testbench_test_init(); /* initialize globals include blink duty cycle */
415167

416-
rc = init_tasks();
417-
418-
/*
419-
* This sets the callback function for the events that are
420-
* generated from newtmanager.
421-
*/
422-
run_evcb_set((os_event_fn*) testbench_runtests);
168+
os_task_init(&testtask, "testtask", testtask_handler, NULL,
169+
TESTTASK_PRIO, OS_WAIT_FOREVER, teststack,
170+
TESTTASK_STACK_SIZE);
423171

424172
MODLOG_INFO(LOG_MODULE_TEST, "testbench app initialized");
425173

0 commit comments

Comments
 (0)