http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/libs/os/src/test/sem_test.c ---------------------------------------------------------------------- diff --git a/libs/os/src/test/sem_test.c b/libs/os/src/test/sem_test.c deleted file mode 100644 index ec79185..0000000 --- a/libs/os/src/test/sem_test.c +++ /dev/null @@ -1,401 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -#include <stdio.h> -#include <string.h> -#include "testutil/testutil.h" -#include "os/os.h" -#include "os/os_cfg.h" -#include "os/os_sem.h" -#include "os_test_priv.h" - -#ifdef ARCH_sim -#define SEM_TEST_STACK_SIZE 1024 -#else -#define SEM_TEST_STACK_SIZE 512 -#endif - -struct os_task task1; -os_stack_t stack1[OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)]; - -struct os_task task2; -os_stack_t stack2[OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)]; - -struct os_task task3; -os_stack_t stack3[OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)]; - -struct os_task task4; -os_stack_t stack4[OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)]; - -#define TASK1_PRIO (1) -#define TASK2_PRIO (2) -#define TASK3_PRIO (3) -#define TASK4_PRIO (4) - -struct os_sem g_sem1; - -/* - * TEST NUMBERS: - * 10: In this test we have the highest priority task getting the semaphore - * then sleeping. Two lower priority tasks then wake up and attempt to get - * the semaphore. They are blocked until the higher priority task releases - * the semaphore, at which point the lower priority tasks should wake up in - * order, get the semaphore, then release it and go back to sleep. - * - */ - -/** - * sem test disp sem - * - * Display semaphore contents - * - * @param sem - */ -static const char * -sem_test_sem_to_s(const struct os_sem *sem) -{ - static char buf[128]; - - snprintf(buf, sizeof buf, "\tSemaphore: tokens=%u head=%p", - sem->sem_tokens, SLIST_FIRST(&sem->sem_head)); - - return buf; -} - -static void -sem_test_sleep_task_handler(void *arg) -{ - struct os_task *t; - - t = os_sched_get_current_task(); - TEST_ASSERT(t->t_func == sem_test_sleep_task_handler); - - os_time_delay(2000); - os_test_restart(); -} - -static void -sem_test_pend_release_loop(int delay, int timeout, int itvl) -{ - os_error_t err; - - os_time_delay(delay); - - while (1) { - err = os_sem_pend(&g_sem1, timeout); - TEST_ASSERT((err == OS_OK) || (err == OS_TIMEOUT)); - - err = os_sem_release(&g_sem1); - TEST_ASSERT(err == OS_OK); - - os_time_delay(itvl); - } -} - -/** - * sem test basic - * - * Basic semaphore tests - * - * @return int - */ -static void -sem_test_basic_handler(void *arg) -{ - struct os_task *t; - struct os_sem *sem; - os_error_t err; - - sem = &g_sem1; - t = os_sched_get_current_task(); - - /* Test some error cases */ - TEST_ASSERT(os_sem_init(NULL, 1) == OS_INVALID_PARM); - TEST_ASSERT(os_sem_release(NULL) == OS_INVALID_PARM); - TEST_ASSERT(os_sem_pend(NULL, 1) == OS_INVALID_PARM); - - /* Get the semaphore */ - err = os_sem_pend(sem, 0); - TEST_ASSERT(err == 0, - "Did not get free semaphore immediately (err=%d)", err); - - /* Check semaphore internals */ - TEST_ASSERT(sem->sem_tokens == 0 && SLIST_EMPTY(&sem->sem_head), - "Semaphore internals wrong after getting semaphore\n" - "%s\n" - "Task: task=%p prio=%u", sem_test_sem_to_s(sem), t, t->t_prio); - - /* Get the semaphore again; should fail */ - err = os_sem_pend(sem, 0); - TEST_ASSERT(err == OS_TIMEOUT, - "Did not time out waiting for semaphore (err=%d)", err); - - /* Check semaphore internals */ - TEST_ASSERT(sem->sem_tokens == 0 && SLIST_EMPTY(&sem->sem_head), - "Semaphore internals wrong after getting semaphore\n" - "%s\n" - "Task: task=%p prio=%u\n", sem_test_sem_to_s(sem), t, - t->t_prio); - - /* Release semaphore */ - err = os_sem_release(sem); - TEST_ASSERT(err == 0, - "Could not release semaphore I own (err=%d)", err); - - /* Check semaphore internals */ - TEST_ASSERT(sem->sem_tokens == 1 && SLIST_EMPTY(&sem->sem_head), - "Semaphore internals wrong after releasing semaphore\n" - "%s\n" - "Task: task=%p prio=%u\n", sem_test_sem_to_s(sem), t, - t->t_prio); - - /* Release it again */ - err = os_sem_release(sem); - TEST_ASSERT(err == 0, - "Could not release semaphore again (err=%d)\n", err); - - /* Check semaphore internals */ - TEST_ASSERT(sem->sem_tokens == 2 && SLIST_EMPTY(&sem->sem_head), - "Semaphore internals wrong after releasing semaphore\n" - "%s\n" - "Task: task=%p prio=%u\n", sem_test_sem_to_s(sem), t, - t->t_prio); - - os_test_restart(); -} - -static void -sem_test_1_task1_handler(void *arg) -{ - os_error_t err; - struct os_task *t; - int i;; - - for (i = 0; i < 3; i++) { - t = os_sched_get_current_task(); - TEST_ASSERT(t->t_func == sem_test_1_task1_handler); - - - err = os_sem_pend(&g_sem1, 0); - TEST_ASSERT(err == OS_OK); - - /* Sleep to let other tasks run */ - os_time_delay(100); - - /* Release the semaphore */ - err = os_sem_release(&g_sem1); - TEST_ASSERT(err == OS_OK); - - /* Sleep to let other tasks run */ - os_time_delay(100); - } - - os_test_restart(); -} - -TEST_CASE(os_sem_test_basic) -{ - os_error_t err; - - os_init(); - - err = os_sem_init(&g_sem1, 1); - TEST_ASSERT(err == OS_OK); - - os_task_init(&task1, "task1", sem_test_basic_handler, NULL, TASK1_PRIO, - OS_WAIT_FOREVER, stack1, OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); - - os_start(); -} - -static void -sem_test_1_task2_handler(void *arg) -{ - sem_test_pend_release_loop(0, 100, 100); -} - -static void -sem_test_1_task3_handler(void *arg) -{ - sem_test_pend_release_loop(0, OS_TIMEOUT_NEVER, 2000); -} - -TEST_CASE(os_sem_test_case_1) -{ - os_error_t err; - - os_init(); - - err = os_sem_init(&g_sem1, 1); - TEST_ASSERT(err == OS_OK); - - os_task_init(&task1, "task1", sem_test_1_task1_handler, NULL, - TASK1_PRIO, OS_WAIT_FOREVER, stack1, - OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); - - os_task_init(&task2, "task2", sem_test_1_task2_handler, NULL, - TASK2_PRIO, OS_WAIT_FOREVER, stack2, - OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); - - os_task_init(&task3, "task3", sem_test_1_task3_handler, NULL, TASK3_PRIO, - OS_WAIT_FOREVER, stack3, OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); - - os_start(); -} - -static void -sem_test_2_task2_handler(void *arg) -{ - sem_test_pend_release_loop(0, 2000, 2000); -} - -static void -sem_test_2_task3_handler(void *arg) -{ - sem_test_pend_release_loop(0, OS_TIMEOUT_NEVER, 2000); -} - -static void -sem_test_2_task4_handler(void *arg) -{ - sem_test_pend_release_loop(0, 2000, 2000); -} - -TEST_CASE(os_sem_test_case_2) -{ - os_error_t err; - - os_init(); - - err = os_sem_init(&g_sem1, 1); - TEST_ASSERT(err == OS_OK); - - os_task_init(&task1, "task1", sem_test_sleep_task_handler, NULL, - TASK1_PRIO, OS_WAIT_FOREVER, stack1, - OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); - - os_task_init(&task2, "task2", sem_test_2_task2_handler, NULL, - TASK2_PRIO, OS_WAIT_FOREVER, stack2, - OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); - - os_task_init(&task3, "task3", sem_test_2_task3_handler, NULL, TASK3_PRIO, - OS_WAIT_FOREVER, stack3, OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); - - os_task_init(&task4, "task4", sem_test_2_task4_handler, NULL, TASK4_PRIO, - OS_WAIT_FOREVER, stack4, OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); - - os_start(); -} - -static void -sem_test_3_task2_handler(void *arg) -{ - sem_test_pend_release_loop(100, 2000, 2000); -} - -static void -sem_test_3_task3_handler(void *arg) -{ - sem_test_pend_release_loop(150, 2000, 2000); -} - -static void -sem_test_3_task4_handler(void *arg) -{ - sem_test_pend_release_loop(0, 2000, 2000); -} - -TEST_CASE(os_sem_test_case_3) -{ - os_error_t err; - - os_init(); - - err = os_sem_init(&g_sem1, 1); - TEST_ASSERT(err == OS_OK); - - os_task_init(&task1, "task1", sem_test_sleep_task_handler, NULL, - TASK1_PRIO, OS_WAIT_FOREVER, stack1, - OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); - - os_task_init(&task2, "task2", sem_test_3_task2_handler, NULL, - TASK2_PRIO, OS_WAIT_FOREVER, stack2, - OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); - - os_task_init(&task3, "task3", sem_test_3_task3_handler, NULL, TASK3_PRIO, - OS_WAIT_FOREVER, stack3, OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); - - os_task_init(&task4, "task4", sem_test_3_task4_handler, NULL, TASK4_PRIO, - OS_WAIT_FOREVER, stack4, OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); - - os_start(); -} - -static void -sem_test_4_task2_handler(void *arg) -{ - sem_test_pend_release_loop(60, 2000, 2000); -} - -static void -sem_test_4_task3_handler(void *arg) -{ - sem_test_pend_release_loop(60, 2000, 2000); -} - -static void -sem_test_4_task4_handler(void *arg) -{ - sem_test_pend_release_loop(0, 2000, 2000); -} - - -TEST_CASE(os_sem_test_case_4) -{ - os_error_t err; - - os_init(); - - err = os_sem_init(&g_sem1, 1); - TEST_ASSERT(err == OS_OK); - - os_task_init(&task1, "task1", sem_test_sleep_task_handler, NULL, - TASK1_PRIO, OS_WAIT_FOREVER, stack1, - OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); - - os_task_init(&task2, "task2", sem_test_4_task2_handler, NULL, - TASK2_PRIO, OS_WAIT_FOREVER, stack2, - OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); - - os_task_init(&task3, "task3", sem_test_4_task3_handler, NULL, TASK3_PRIO, - OS_WAIT_FOREVER, stack3, OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); - - os_task_init(&task4, "task4", sem_test_4_task4_handler, NULL, TASK4_PRIO, - OS_WAIT_FOREVER, stack4, OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); - - os_start(); -} - -TEST_SUITE(os_sem_test_suite) -{ - os_sem_test_basic(); - os_sem_test_case_1(); - os_sem_test_case_2(); - os_sem_test_case_3(); - os_sem_test_case_4(); -}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/libs/os/test/pkg.yml ---------------------------------------------------------------------- diff --git a/libs/os/test/pkg.yml b/libs/os/test/pkg.yml new file mode 100644 index 0000000..e517618 --- /dev/null +++ b/libs/os/test/pkg.yml @@ -0,0 +1,30 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +pkg.name: libs/os/test +pkg.type: unittest +pkg.description: "OS unit tests." +pkg.author: "Apache Mynewt <d...@mynewt.incubator.apache.org>" +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.deps: + - libs/os + - libs/testutil + +pkg.deps.SELFTEST: + - libs/console/stub http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/libs/os/test/src/arch/cortex_m4/os_test_arch_arm.c ---------------------------------------------------------------------- diff --git a/libs/os/test/src/arch/cortex_m4/os_test_arch_arm.c b/libs/os/test/src/arch/cortex_m4/os_test_arch_arm.c new file mode 100644 index 0000000..35134f7 --- /dev/null +++ b/libs/os/test/src/arch/cortex_m4/os_test_arch_arm.c @@ -0,0 +1,27 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "testutil/testutil.h" +#include "os_test_priv.h" + +void +os_test_restart(void) +{ + tu_restart(); +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/libs/os/test/src/arch/sim/os_test_arch_sim.c ---------------------------------------------------------------------- diff --git a/libs/os/test/src/arch/sim/os_test_arch_sim.c b/libs/os/test/src/arch/sim/os_test_arch_sim.c new file mode 100644 index 0000000..3b6cfbf --- /dev/null +++ b/libs/os/test/src/arch/sim/os_test_arch_sim.c @@ -0,0 +1,52 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include <stdio.h> +#include <setjmp.h> +#include <signal.h> +#include <string.h> +#include <sys/time.h> +#include "testutil/testutil.h" +#include "os/os.h" +#include "os_test_priv.h" + +void +os_test_restart(void) +{ + struct sigaction sa; + struct itimerval it; + int rc; + + g_os_started = 0; + + memset(&sa, 0, sizeof sa); + sa.sa_handler = SIG_IGN; + + sigaction(SIGALRM, &sa, NULL); + sigaction(SIGVTALRM, &sa, NULL); + + memset(&it, 0, sizeof(it)); + rc = setitimer(ITIMER_VIRTUAL, &it, NULL); + if (rc != 0) { + perror("Cannot set itimer"); + abort(); + } + + tu_restart(); +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/libs/os/test/src/eventq_test.c ---------------------------------------------------------------------- diff --git a/libs/os/test/src/eventq_test.c b/libs/os/test/src/eventq_test.c new file mode 100644 index 0000000..cb1ed94 --- /dev/null +++ b/libs/os/test/src/eventq_test.c @@ -0,0 +1,416 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include <string.h> +#include "testutil/testutil.h" +#include "os/os.h" +#include "os_test_priv.h" +#include "os/os_eventq.h" + +#define MY_STACK_SIZE (5120) +#define POLL_STACK_SIZE (4096) +/* Task 1 sending task */ +/* Define task stack and task object */ +#define SEND_TASK_PRIO (1) +struct os_task eventq_task_s; +os_stack_t eventq_task_stack_s[MY_STACK_SIZE]; + +/* Task 2 receiving task */ +#define RECEIVE_TASK_PRIO (2) +struct os_task eventq_task_r; +os_stack_t eventq_task_stack_r[MY_STACK_SIZE]; + +struct os_eventq my_eventq; + +#define SIZE_MULTI_EVENT (4) +struct os_eventq multi_eventq[SIZE_MULTI_EVENT]; + +/* This is to set the events we will use below */ +struct os_event g_event; +struct os_event m_event[SIZE_MULTI_EVENT]; + +/* Setting the event to send and receive multiple data */ +uint8_t my_event_type = 1; + +/* Setting up data for the poll */ +/* Define the task stack for the eventq_task_poll_send */ +#define SEND_TASK_POLL_PRIO (3) +struct os_task eventq_task_poll_s; +os_stack_t eventq_task_stack_poll_s[POLL_STACK_SIZE]; + +/* Define the task stack for the eventq_task_poll_receive */ +#define RECEIVE_TASK_POLL_PRIO (4) +struct os_task eventq_task_poll_r; +os_stack_t eventq_task_stack_poll_r[POLL_STACK_SIZE ]; + +/* Setting the data for the poll timeout */ +/* Define the task stack for the eventq_task_poll_timeout_send */ +#define SEND_TASK_POLL_TIMEOUT_PRIO (5) +struct os_task eventq_task_poll_timeout_s; +os_stack_t eventq_task_stack_poll_timeout_s[POLL_STACK_SIZE]; + +/* Define the task stack for the eventq_task_poll_receive */ +#define RECEIVE_TASK_POLL_TIMEOUT_PRIO (6) +struct os_task eventq_task_poll_timeout_r; +os_stack_t eventq_task_stack_poll_timeout_r[POLL_STACK_SIZE]; + +/* Setting the data for the poll single */ +/* Define the task stack for the eventq_task_poll_single_send */ +#define SEND_TASK_POLL_SINGLE_PRIO (7) +struct os_task eventq_task_poll_single_s; +os_stack_t eventq_task_stack_poll_single_s[POLL_STACK_SIZE]; + +/* Define the task stack for the eventq_task_poll_single_receive */ +#define RECEIVE_TASK_POLL_SINGLE_PRIO (8) +struct os_task eventq_task_poll_single_r; +os_stack_t eventq_task_stack_poll_single_r[POLL_STACK_SIZE]; + +/* This is the task function to send data */ +void +eventq_task_send(void *arg) +{ + int i; + + g_event.ev_queued = 0; + g_event.ev_type = my_event_type; + g_event.ev_arg = NULL; + + os_eventq_put(&my_eventq, &g_event); + + os_time_delay(OS_TICKS_PER_SEC / 2); + + for (i = 0; i < SIZE_MULTI_EVENT; i++){ + m_event[i].ev_type = i + 2; + m_event[i].ev_arg = NULL; + + /* Put and send */ + os_eventq_put(&multi_eventq[i], &m_event[i]); + os_time_delay(OS_TICKS_PER_SEC / 2); + } + + /* This task sleeps until the receive task completes the test. */ + os_time_delay(1000000); +} + +/* This is the task function is the receiving function */ +void +eventq_task_receive(void *arg) +{ + struct os_event *event; + int i; + + event = os_eventq_get(&my_eventq); + TEST_ASSERT(event->ev_type == my_event_type); + + /* Receiving multi event from the send task */ + for (i = 0; i < SIZE_MULTI_EVENT; i++) { + event = os_eventq_get(&multi_eventq[i]); + TEST_ASSERT(event->ev_type == i + 2); + } + + /* Finishes the test when OS has been started */ + os_test_restart(); +} + +void +eventq_task_poll_send(void *arg) +{ + struct os_eventq *eventqs[SIZE_MULTI_EVENT]; + int i; + + for (i = 0; i < SIZE_MULTI_EVENT; i++){ + eventqs[i] = &multi_eventq[i]; + } + + for (i = 0; i < SIZE_MULTI_EVENT; i++){ + m_event[i].ev_type = i + 10; + m_event[i].ev_arg = NULL; + + /* Put and send */ + os_eventq_put(eventqs[i], &m_event[i]); + os_time_delay(OS_TICKS_PER_SEC / 2); + } + + /* This task sleeps until the receive task completes the test. */ + os_time_delay(1000000); +} + +void +eventq_task_poll_receive(void *arg) +{ + struct os_eventq *eventqs[SIZE_MULTI_EVENT]; + struct os_event *event; + int i; + + for (i = 0; i < SIZE_MULTI_EVENT; i++){ + eventqs[i] = &multi_eventq[i]; + } + + /* Recieving using the os_eventq_poll*/ + for (i = 0; i < SIZE_MULTI_EVENT; i++) { + event = os_eventq_poll(eventqs, SIZE_MULTI_EVENT, OS_WAIT_FOREVER); + TEST_ASSERT(event->ev_type == i +10); + } + + /* Finishes the test when OS has been started */ + os_test_restart(); + +} + +/* Sending with a time failure */ +void +eventq_task_poll_timeout_send(void *arg) +{ + struct os_eventq *eventqs[SIZE_MULTI_EVENT]; + int i; + + for (i = 0; i < SIZE_MULTI_EVENT; i++){ + eventqs[i] = &multi_eventq[i]; + } + + for (i = 0; i < SIZE_MULTI_EVENT; i++){ + os_time_delay(1000); + + /* Put and send */ + os_eventq_put(eventqs[i], &m_event[i]); + os_time_delay(OS_TICKS_PER_SEC / 2); + } + + /* This task sleeps until the receive task completes the test. */ + os_time_delay(1000000); + +} + +/* Receiving multiple event queues with a time failure */ +void +eventq_task_poll_timeout_receive(void *arg) +{ + struct os_eventq *eventqs[SIZE_MULTI_EVENT]; + struct os_event *event; + int i; + + for (i = 0; i < SIZE_MULTI_EVENT; i++){ + eventqs[i] = &multi_eventq[i]; + } + + /* Recieving using the os_eventq_poll_timeout*/ + for (i = 0; i < SIZE_MULTI_EVENT; i++) { + event = os_eventq_poll(eventqs, SIZE_MULTI_EVENT, 200); + TEST_ASSERT(event == NULL); + } + + /* Finishes the test when OS has been started */ + os_test_restart(); + +} + +/* Sending a single event to poll */ +void +eventq_task_poll_single_send(void *arg) +{ + struct os_eventq *eventqs[SIZE_MULTI_EVENT]; + int i; + int position = 2; + + for (i = 0; i < SIZE_MULTI_EVENT; i++){ + eventqs[i] = &multi_eventq[i]; + } + + /* Put and send */ + os_eventq_put(eventqs[position], &m_event[position]); + os_time_delay(OS_TICKS_PER_SEC / 2); + + /* This task sleeps until the receive task completes the test. */ + os_time_delay(1000000); +} + +/* Recieving the single event */ +void +eventq_task_poll_single_receive(void *arg) +{ + struct os_eventq *eventqs[SIZE_MULTI_EVENT]; + struct os_event *event; + int i; + + for (i = 0; i < SIZE_MULTI_EVENT; i++){ + eventqs[i] = &multi_eventq[i]; + } + + /* Recieving using the os_eventq_poll*/ + event = os_eventq_poll(eventqs, SIZE_MULTI_EVENT, OS_WAIT_FOREVER); + TEST_ASSERT(event->ev_type == 20); + + /* Finishes the test when OS has been started */ + os_test_restart(); +} + +TEST_CASE(event_test_sr) +{ + int i; + + /* Initializing the OS */ + os_init(); + /* Initialize the task */ + os_task_init(&eventq_task_s, "eventq_task_s", eventq_task_send, NULL, + SEND_TASK_PRIO, OS_WAIT_FOREVER, eventq_task_stack_s, MY_STACK_SIZE); + + /* Receive events and check whether the eevnts are correctly received */ + os_task_init(&eventq_task_r, "eventq_task_r", eventq_task_receive, NULL, + RECEIVE_TASK_PRIO, OS_WAIT_FOREVER, eventq_task_stack_r, + MY_STACK_SIZE); + + os_eventq_init(&my_eventq); + + for (i = 0; i < SIZE_MULTI_EVENT; i++){ + os_eventq_init(&multi_eventq[i]); + } + + /* Does not return until OS_restart is called */ + os_start(); + +} + +/* To test for the basic function of os_eventq_poll() */ +TEST_CASE(event_test_poll_sr) +{ + int i; + + /* Initializing the OS */ + os_init(); + /* Initialize the task */ + os_task_init(&eventq_task_poll_s, "eventq_task_poll_s", eventq_task_poll_send, + NULL, SEND_TASK_POLL_PRIO, OS_WAIT_FOREVER, eventq_task_stack_poll_s, + POLL_STACK_SIZE); + + /* Receive events and check whether the eevnts are correctly received */ + os_task_init(&eventq_task_poll_r, "eventq_task_r", eventq_task_poll_receive, + NULL, RECEIVE_TASK_POLL_PRIO, OS_WAIT_FOREVER, eventq_task_stack_poll_r, + POLL_STACK_SIZE); + + /* Initializing the eventqs. */ + for (i = 0; i < SIZE_MULTI_EVENT; i++){ + os_eventq_init(&multi_eventq[i]); + } + + /* Does not return until OS_restart is called */ + os_start(); + +} + +/* Test case for poll timeout */ +TEST_CASE(event_test_poll_timeout_sr) +{ + int i; + + /* Initializing the OS */ + os_init(); + /* Initialize the task */ + os_task_init(&eventq_task_poll_timeout_s, "eventq_task_poll_timeout_s", + eventq_task_poll_timeout_send, NULL, SEND_TASK_POLL_TIMEOUT_PRIO, + OS_WAIT_FOREVER, eventq_task_stack_poll_timeout_s, POLL_STACK_SIZE); + + /* Receive events and check whether the eevnts are correctly received */ + os_task_init(&eventq_task_poll_timeout_r, "eventq_task_timeout_r", + eventq_task_poll_timeout_receive, NULL, RECEIVE_TASK_POLL_TIMEOUT_PRIO, + OS_WAIT_FOREVER, eventq_task_stack_poll_timeout_r, POLL_STACK_SIZE); + + /* Initializing the eventqs. */ + for (i = 0; i < SIZE_MULTI_EVENT; i++){ + os_eventq_init(&multi_eventq[i]); + + m_event[i].ev_type = i + 10; + m_event[i].ev_arg = NULL; + } + + /* Does not return until OS_restart is called */ + os_start(); + +} + +/* The case for poll single */ +/* Test case for poll timeout */ +TEST_CASE(event_test_poll_single_sr) +{ + int i; + + /* Initializing the OS */ + os_init(); + /* Initialize the task */ + os_task_init(&eventq_task_poll_single_s, "eventq_task_poll_single_s", + eventq_task_poll_single_send, NULL, SEND_TASK_POLL_SINGLE_PRIO, + OS_WAIT_FOREVER, eventq_task_stack_poll_single_s, POLL_STACK_SIZE); + + /* Receive events and check whether the eevnts are correctly received */ + os_task_init(&eventq_task_poll_single_r, "eventq_task_single_r", + eventq_task_poll_single_receive, NULL, RECEIVE_TASK_POLL_SINGLE_PRIO, + OS_WAIT_FOREVER, eventq_task_stack_poll_single_r, POLL_STACK_SIZE); + + for (i = 0; i < SIZE_MULTI_EVENT; i++){ + os_eventq_init(&multi_eventq[i]); + + m_event[i].ev_type = 10 * i; + m_event[i].ev_arg = NULL; + } + + /* Does not return until OS_restart is called */ + os_start(); + +} + +/** + * Tests eventq_poll() with a timeout of 0. This should not involve the + * scheduler at all, so it should work without starting the OS. + */ +TEST_CASE(event_test_poll_0timo) +{ + struct os_eventq *eventqs[SIZE_MULTI_EVENT]; + struct os_event *evp; + struct os_event ev; + int i; + + for (i = 0; i < SIZE_MULTI_EVENT; i++){ + os_eventq_init(&multi_eventq[i]); + eventqs[i] = &multi_eventq[i]; + } + + evp = os_eventq_poll(eventqs, SIZE_MULTI_EVENT, 0); + TEST_ASSERT(evp == NULL); + + /* Ensure no eventq thinks a task is waiting on it. */ + for (i = 0; i < SIZE_MULTI_EVENT; i++) { + TEST_ASSERT(eventqs[i]->evq_task == NULL); + } + + /* Put an event on one of the queues. */ + memset(&ev, 0, sizeof ev); + ev.ev_type = 1; + os_eventq_put(eventqs[3], &ev); + + evp = os_eventq_poll(eventqs, SIZE_MULTI_EVENT, 0); + TEST_ASSERT(evp == &ev); +} + +TEST_SUITE(os_eventq_test_suite) +{ + event_test_sr(); + event_test_poll_sr(); + event_test_poll_timeout_sr(); + event_test_poll_single_sr(); + event_test_poll_0timo(); +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/libs/os/test/src/mbuf_test.c ---------------------------------------------------------------------- diff --git a/libs/os/test/src/mbuf_test.c b/libs/os/test/src/mbuf_test.c new file mode 100644 index 0000000..dd4121d --- /dev/null +++ b/libs/os/test/src/mbuf_test.c @@ -0,0 +1,420 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "testutil/testutil.h" +#include "os/os.h" +#include "os_test_priv.h" + +#include <string.h> + +/* + * NOTE: currently, the buffer size cannot be changed as some tests are + * hard-coded for this size. + */ +#define MBUF_TEST_POOL_BUF_SIZE (256) +#define MBUF_TEST_POOL_BUF_COUNT (10) + +#define MBUF_TEST_DATA_LEN (1024) + +static os_membuf_t os_mbuf_membuf[OS_MEMPOOL_SIZE(MBUF_TEST_POOL_BUF_SIZE, + MBUF_TEST_POOL_BUF_COUNT)]; + +static struct os_mbuf_pool os_mbuf_pool; +static struct os_mempool os_mbuf_mempool; +static uint8_t os_mbuf_test_data[MBUF_TEST_DATA_LEN]; + +static void +os_mbuf_test_setup(void) +{ + int rc; + int i; + + rc = os_mempool_init(&os_mbuf_mempool, MBUF_TEST_POOL_BUF_COUNT, + MBUF_TEST_POOL_BUF_SIZE, &os_mbuf_membuf[0], "mbuf_pool"); + TEST_ASSERT_FATAL(rc == 0, "Error creating memory pool %d", rc); + + rc = os_mbuf_pool_init(&os_mbuf_pool, &os_mbuf_mempool, + MBUF_TEST_POOL_BUF_SIZE, MBUF_TEST_POOL_BUF_COUNT); + TEST_ASSERT_FATAL(rc == 0, "Error creating mbuf pool %d", rc); + + for (i = 0; i < sizeof os_mbuf_test_data; i++) { + os_mbuf_test_data[i] = i; + } +} + +static void +os_mbuf_test_misc_assert_sane(struct os_mbuf *om, void *data, + int buflen, int pktlen, int pkthdr_len) +{ + uint8_t *data_min; + uint8_t *data_max; + int totlen; + int i; + + TEST_ASSERT_FATAL(om != NULL); + + if (OS_MBUF_IS_PKTHDR(om)) { + TEST_ASSERT(OS_MBUF_PKTLEN(om) == pktlen); + } + + totlen = 0; + for (i = 0; om != NULL; i++) { + if (i == 0) { + TEST_ASSERT(om->om_len == buflen); + TEST_ASSERT(om->om_pkthdr_len == pkthdr_len); + } + + data_min = om->om_databuf + om->om_pkthdr_len; + data_max = om->om_databuf + om->om_omp->omp_databuf_len - om->om_len; + TEST_ASSERT(om->om_data >= data_min && om->om_data <= data_max); + + if (data != NULL) { + TEST_ASSERT(memcmp(om->om_data, data + totlen, om->om_len) == 0); + } + + totlen += om->om_len; + om = SLIST_NEXT(om, om_next); + } + + TEST_ASSERT(totlen == pktlen); +} + + +TEST_CASE(os_mbuf_test_alloc) +{ + struct os_mbuf *m; + int rc; + + os_mbuf_test_setup(); + + m = os_mbuf_get(&os_mbuf_pool, 0); + TEST_ASSERT_FATAL(m != NULL, "Error allocating mbuf"); + + rc = os_mbuf_free(m); + TEST_ASSERT_FATAL(rc == 0, "Error free'ing mbuf %d", rc); +} + +TEST_CASE(os_mbuf_test_get_pkthdr) +{ + struct os_mbuf *m; + + os_mbuf_test_setup(); + +#if (MBUF_TEST_POOL_BUF_SIZE <= 256) + m = os_mbuf_get_pkthdr(&os_mbuf_pool, MBUF_TEST_POOL_BUF_SIZE - 1); + TEST_ASSERT_FATAL(m == NULL, "Error: should not have returned mbuf"); +#endif + + m = os_mbuf_get(&os_mbuf_pool, MBUF_TEST_POOL_BUF_SIZE); + TEST_ASSERT_FATAL(m == NULL, "Error: should not have returned mbuf"); +} + + +TEST_CASE(os_mbuf_test_dup) +{ + struct os_mbuf *om; + struct os_mbuf *om2; + struct os_mbuf *dup; + int rc; + + os_mbuf_test_setup(); + + /* Test first allocating and duplicating a single mbuf */ + om = os_mbuf_get(&os_mbuf_pool, 0); + TEST_ASSERT_FATAL(om != NULL, "Error allocating mbuf"); + + rc = os_mbuf_append(om, os_mbuf_test_data, 200); + TEST_ASSERT_FATAL(rc == 0); + os_mbuf_test_misc_assert_sane(om, os_mbuf_test_data, 200, 200, 0); + + dup = os_mbuf_dup(om); + TEST_ASSERT_FATAL(dup != NULL, "NULL mbuf returned from dup"); + TEST_ASSERT_FATAL(dup != om, "duplicate matches original."); + os_mbuf_test_misc_assert_sane(dup, os_mbuf_test_data, 200, 200, 0); + + rc = os_mbuf_free(om); + TEST_ASSERT_FATAL(rc == 0, "Error free'ing mbuf om %d", rc); + + rc = os_mbuf_free(dup); + TEST_ASSERT_FATAL(rc == 0, "Error free'ing mbuf dup %d", rc); + + om = os_mbuf_get(&os_mbuf_pool, 0); + TEST_ASSERT_FATAL(om != NULL, "Error allocating mbuf"); + rc = os_mbuf_append(om, os_mbuf_test_data, 200); + TEST_ASSERT_FATAL(rc == 0); + os_mbuf_test_misc_assert_sane(om, os_mbuf_test_data, 200, 200, 0); + + om2 = os_mbuf_get(&os_mbuf_pool, 0); + TEST_ASSERT_FATAL(om2 != NULL, "Error allocating mbuf"); + rc = os_mbuf_append(om2, os_mbuf_test_data + 200, 200); + TEST_ASSERT_FATAL(rc == 0); + os_mbuf_test_misc_assert_sane(om2, os_mbuf_test_data + 200, 200, 200, 0); + + os_mbuf_concat(om, om2); + os_mbuf_test_misc_assert_sane(om, os_mbuf_test_data, 200, 400, 0); + + dup = os_mbuf_dup(om); + TEST_ASSERT_FATAL(dup != NULL, "NULL mbuf returned from dup"); + TEST_ASSERT_FATAL(dup != om, "Duplicate matches original"); + TEST_ASSERT_FATAL(SLIST_NEXT(dup, om_next) != NULL, + "NULL chained element, duplicate should match original"); + + os_mbuf_test_misc_assert_sane(dup, os_mbuf_test_data, 200, 400, 0); + + rc = os_mbuf_free_chain(om); + TEST_ASSERT_FATAL(rc == 0, "Cannot free mbuf chain %d", rc); + + rc = os_mbuf_free_chain(dup); + TEST_ASSERT_FATAL(rc == 0, "Cannot free mbuf chain %d", rc); +} + +TEST_CASE(os_mbuf_test_append) +{ + struct os_mbuf *om; + int rc; + uint8_t databuf[] = {0xa, 0xb, 0xc, 0xd}; + uint8_t cmpbuf[] = {0xff, 0xff, 0xff, 0xff}; + + os_mbuf_test_setup(); + + om = os_mbuf_get(&os_mbuf_pool, 0); + TEST_ASSERT_FATAL(om != NULL, "Error allocating mbuf"); + os_mbuf_test_misc_assert_sane(om, NULL, 0, 0, 0); + + rc = os_mbuf_append(om, databuf, sizeof(databuf)); + TEST_ASSERT_FATAL(rc == 0, "Cannot add %d bytes to mbuf", + sizeof(databuf)); + os_mbuf_test_misc_assert_sane(om, databuf, sizeof databuf, sizeof databuf, + 0); + + memcpy(cmpbuf, OS_MBUF_DATA(om, uint8_t *), om->om_len); + TEST_ASSERT_FATAL(memcmp(cmpbuf, databuf, sizeof(databuf)) == 0, + "Databuf doesn't match cmpbuf"); +} + +TEST_CASE(os_mbuf_test_extend) +{ + struct os_mbuf *om; + void *v; + + os_mbuf_test_setup(); + + /*** Series of successful extensions. */ + om = os_mbuf_get_pkthdr(&os_mbuf_pool, 10); + TEST_ASSERT_FATAL(om != NULL); + + TEST_ASSERT(OS_MBUF_TRAILINGSPACE(om) == 222); + TEST_ASSERT(SLIST_NEXT(om, om_next) == NULL); + os_mbuf_test_misc_assert_sane(om, NULL, 0, 0, 18); + + v = os_mbuf_extend(om, 20); + TEST_ASSERT(v != NULL); + TEST_ASSERT(v == om->om_data); + TEST_ASSERT(om->om_len == 20); + + TEST_ASSERT(OS_MBUF_TRAILINGSPACE(om) == 202); + TEST_ASSERT(SLIST_NEXT(om, om_next) == NULL); + os_mbuf_test_misc_assert_sane(om, NULL, 20, 20, 18); + + v = os_mbuf_extend(om, 100); + TEST_ASSERT(v != NULL); + TEST_ASSERT(v == om->om_data + 20); + TEST_ASSERT(om->om_len == 120); + + TEST_ASSERT(OS_MBUF_TRAILINGSPACE(om) == 102); + TEST_ASSERT(SLIST_NEXT(om, om_next) == NULL); + os_mbuf_test_misc_assert_sane(om, NULL, 120, 120, 18); + + v = os_mbuf_extend(om, 101); + TEST_ASSERT(v != NULL); + TEST_ASSERT(v == om->om_data + 120); + TEST_ASSERT(om->om_len == 221); + + TEST_ASSERT(OS_MBUF_TRAILINGSPACE(om) == 1); + TEST_ASSERT(SLIST_NEXT(om, om_next) == NULL); + os_mbuf_test_misc_assert_sane(om, NULL, 221, 221, 18); + + v = os_mbuf_extend(om, 1); + TEST_ASSERT(v != NULL); + TEST_ASSERT(v == om->om_data + 221); + TEST_ASSERT(om->om_len == 222); + + TEST_ASSERT(OS_MBUF_TRAILINGSPACE(om) == 0); + TEST_ASSERT(SLIST_NEXT(om, om_next) == NULL); + os_mbuf_test_misc_assert_sane(om, NULL, 222, 222, 18); + + /* Overflow into next buffer. */ + v = os_mbuf_extend(om, 1); + TEST_ASSERT(OS_MBUF_TRAILINGSPACE(om) == 0); + TEST_ASSERT(SLIST_NEXT(om, om_next) != NULL); + + TEST_ASSERT(v == SLIST_NEXT(om, om_next)->om_data); + TEST_ASSERT(om->om_len == 222); + TEST_ASSERT(SLIST_NEXT(om, om_next)->om_len == 1); + os_mbuf_test_misc_assert_sane(om, NULL, 222, 223, 18); + + /*** Attempt to extend by an amount larger than max buf size fails. */ + v = os_mbuf_extend(om, 257); + TEST_ASSERT(v == NULL); + TEST_ASSERT(OS_MBUF_TRAILINGSPACE(om) == 0); + TEST_ASSERT(SLIST_NEXT(om, om_next) != NULL); + + TEST_ASSERT(om->om_len == 222); + TEST_ASSERT(SLIST_NEXT(om, om_next)->om_len == 1); + os_mbuf_test_misc_assert_sane(om, NULL, 222, 223, 18); +} + +TEST_CASE(os_mbuf_test_pullup) +{ + struct os_mbuf *om; + struct os_mbuf *om2; + int rc; + + os_mbuf_test_setup(); + + /*** Free when too much os_mbuf_test_data is requested. */ + om = os_mbuf_get_pkthdr(&os_mbuf_pool, 10); + TEST_ASSERT_FATAL(om != NULL); + + om = os_mbuf_pullup(om, 1); + TEST_ASSERT(om == NULL); + + /*** No effect when all os_mbuf_test_data is already at the start. */ + om = os_mbuf_get_pkthdr(&os_mbuf_pool, 10); + TEST_ASSERT_FATAL(om != NULL); + + rc = os_mbuf_append(om, os_mbuf_test_data, 1); + TEST_ASSERT_FATAL(rc == 0); + os_mbuf_test_misc_assert_sane(om, os_mbuf_test_data, 1, 1, 18); + + om = os_mbuf_pullup(om, 1); + os_mbuf_test_misc_assert_sane(om, os_mbuf_test_data, 1, 1, 18); + + /*** Spread os_mbuf_test_data across four mbufs. */ + om2 = os_mbuf_get(&os_mbuf_pool, 10); + TEST_ASSERT_FATAL(om2 != NULL); + rc = os_mbuf_append(om2, os_mbuf_test_data + 1, 1); + TEST_ASSERT_FATAL(rc == 0); + os_mbuf_concat(om, om2); + + om2 = os_mbuf_get(&os_mbuf_pool, 10); + TEST_ASSERT_FATAL(om2 != NULL); + rc = os_mbuf_append(om2, os_mbuf_test_data + 2, 1); + TEST_ASSERT_FATAL(rc == 0); + os_mbuf_concat(om, om2); + + om2 = os_mbuf_get(&os_mbuf_pool, 10); + TEST_ASSERT_FATAL(om2 != NULL); + rc = os_mbuf_append(om2, os_mbuf_test_data + 3, 1); + TEST_ASSERT_FATAL(rc == 0); + os_mbuf_concat(om, om2); + + TEST_ASSERT_FATAL(OS_MBUF_PKTLEN(om) == 4); + + om = os_mbuf_pullup(om, 4); + os_mbuf_test_misc_assert_sane(om, os_mbuf_test_data, 4, 4, 18); + + os_mbuf_free_chain(om); + + /*** Require an allocation. */ + om = os_mbuf_get_pkthdr(&os_mbuf_pool, 10); + TEST_ASSERT_FATAL(om != NULL); + + om->om_data += 100; + rc = os_mbuf_append(om, os_mbuf_test_data, 100); + TEST_ASSERT_FATAL(rc == 0); + + om2 = os_mbuf_get(&os_mbuf_pool, 10); + TEST_ASSERT_FATAL(om2 != NULL); + rc = os_mbuf_append(om2, os_mbuf_test_data + 100, 100); + TEST_ASSERT_FATAL(rc == 0); + os_mbuf_concat(om, om2); + + om = os_mbuf_pullup(om, 200); + os_mbuf_test_misc_assert_sane(om, os_mbuf_test_data, 200, 200, 18); + + /*** Partial pullup. */ + om = os_mbuf_get_pkthdr(&os_mbuf_pool, 10); + TEST_ASSERT_FATAL(om != NULL); + + om->om_data += 100; + rc = os_mbuf_append(om, os_mbuf_test_data, 100); + TEST_ASSERT_FATAL(rc == 0); + + om2 = os_mbuf_get(&os_mbuf_pool, 10); + TEST_ASSERT_FATAL(om2 != NULL); + rc = os_mbuf_append(om2, os_mbuf_test_data + 100, 100); + TEST_ASSERT_FATAL(rc == 0); + os_mbuf_concat(om, om2); + + om = os_mbuf_pullup(om, 150); + os_mbuf_test_misc_assert_sane(om, os_mbuf_test_data, 150, 200, 18); +} + +TEST_CASE(os_mbuf_test_adj) +{ + struct os_mbuf *om; + int rc; + + os_mbuf_test_setup(); + + om = os_mbuf_get_pkthdr(&os_mbuf_pool, 10); + TEST_ASSERT_FATAL(om != NULL); + + rc = os_mbuf_append(om, os_mbuf_test_data, sizeof os_mbuf_test_data); + TEST_ASSERT_FATAL(rc == 0); + + os_mbuf_test_misc_assert_sane(om, os_mbuf_test_data, 222, + sizeof os_mbuf_test_data, 18); + + /* Remove from the front. */ + os_mbuf_adj(om, 10); + os_mbuf_test_misc_assert_sane(om, os_mbuf_test_data + 10, 212, + sizeof os_mbuf_test_data - 10, 18); + + /* Remove from the back. */ + os_mbuf_adj(om, -10); + os_mbuf_test_misc_assert_sane(om, os_mbuf_test_data + 10, 212, + sizeof os_mbuf_test_data - 20, 18); + + /* Remove entire first buffer. */ + os_mbuf_adj(om, 212); + os_mbuf_test_misc_assert_sane(om, os_mbuf_test_data + 222, 0, + sizeof os_mbuf_test_data - 232, 18); + + /* Remove next buffer. */ + os_mbuf_adj(om, 256); + os_mbuf_test_misc_assert_sane(om, os_mbuf_test_data + 478, 0, + sizeof os_mbuf_test_data - 488, 18); + + /* Remove more data than is present. */ + os_mbuf_adj(om, 1000); + os_mbuf_test_misc_assert_sane(om, NULL, 0, 0, 18); +} + +TEST_SUITE(os_mbuf_test_suite) +{ + os_mbuf_test_alloc(); + os_mbuf_test_dup(); + os_mbuf_test_append(); + os_mbuf_test_pullup(); + os_mbuf_test_extend(); + os_mbuf_test_adj(); + os_mbuf_test_get_pkthdr(); +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/libs/os/test/src/mempool_test.c ---------------------------------------------------------------------- diff --git a/libs/os/test/src/mempool_test.c b/libs/os/test/src/mempool_test.c new file mode 100644 index 0000000..cd17c90 --- /dev/null +++ b/libs/os/test/src/mempool_test.c @@ -0,0 +1,227 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +#include <stdio.h> +#include <string.h> +#include "testutil/testutil.h" +#include "os/os.h" +#include "os_test_priv.h" + +/* Create a memory pool for testing */ +#define NUM_MEM_BLOCKS (10) +#define MEM_BLOCK_SIZE (80) + +/* Limit max blocks for testing */ +#define MEMPOOL_TEST_MAX_BLOCKS (128) + +#if OS_CFG_ALIGNMENT == OS_CFG_ALIGN_4 +int alignment = 4; +#else +int alignment = 8; +#endif + +/* Test memory pool structure */ +struct os_mempool g_TstMempool; + +/* Test memory pool buffer */ +os_membuf_t TstMembuf[OS_MEMPOOL_SIZE(NUM_MEM_BLOCKS, MEM_BLOCK_SIZE)]; + +/* Array of block pointers. */ +void *block_array[MEMPOOL_TEST_MAX_BLOCKS]; + +int verbose = 0; + +static int +mempool_test_get_pool_size(int num_blocks, int block_size) +{ + int mem_pool_size; + +#if OS_CFG_ALIGNMENT == OS_CFG_ALIGN_4 + mem_pool_size = (num_blocks * ((block_size + 3)/4) * sizeof(os_membuf_t)); +#else + mem_pool_size = (num_blocks * ((block_size + 7)/8) * sizeof(os_membuf_t)); +#endif + + return mem_pool_size; +} + +static void +mempool_test(int num_blocks, int block_size) +{ + int cnt; + int true_block_size; + int mem_pool_size; + uint32_t test_block; + uint8_t *tstptr; + void **free_ptr; + void *block; + os_error_t rc; + + /* Check for too many blocks */ + TEST_ASSERT(num_blocks <= MEMPOOL_TEST_MAX_BLOCKS); + + rc = os_mempool_init(&g_TstMempool, num_blocks, MEM_BLOCK_SIZE, + &TstMembuf[0], "TestMemPool"); + TEST_ASSERT_FATAL(rc == 0, "Error creating memory pool %d", rc); + + TEST_ASSERT(g_TstMempool.mp_num_free == num_blocks, + "Number of free blocks not equal to total blocks!"); + + TEST_ASSERT(SLIST_FIRST(&g_TstMempool) == (void *)&TstMembuf[0], + "Free list pointer does not point to first block!"); + + mem_pool_size = mempool_test_get_pool_size(num_blocks, block_size); + TEST_ASSERT(mem_pool_size == sizeof(TstMembuf), + "Total memory pool size not correct! (%d vs %lu)", + mem_pool_size, (unsigned long)sizeof(TstMembuf)); + + /* Get the real block size */ +#if (OS_CFG_ALIGNMENT == OS_CFG_ALIGN_4) + true_block_size = (g_TstMempool.mp_block_size + 3) & ~3; +#else + true_block_size = (g_TstMempool.mp_block_size + 7) & ~7; +#endif + + /* Traverse free list. Better add up to number of blocks! */ + cnt = 0; + free_ptr = (void **)&TstMembuf; + tstptr = (uint8_t *)&TstMembuf; + while (1) { + /* Increment # of elements by 1 */ + ++cnt; + + /* If the free list is NULL, leave */ + if (*free_ptr == NULL) { + break; + } + + TEST_ASSERT(((uint8_t *)*free_ptr - (uint8_t *)free_ptr) == + true_block_size, + "Free pointers are more than one block apart!"); + + /* Move to next memory block */ + tstptr += true_block_size; + + TEST_ASSERT(*free_ptr == (void *)tstptr, + "Error: free_ptr=%p testptr=%p\n", *free_ptr, tstptr); + + free_ptr = *free_ptr; + } + + /* Last one in list better be NULL */ + TEST_ASSERT(cnt == g_TstMempool.mp_num_blocks, + "Free list contains too many elements (%u)", cnt); + + /* Get a block */ + block = os_memblock_get(&g_TstMempool); + TEST_ASSERT(block != NULL, + "Error: get block fails when pool should have elements"); + + TEST_ASSERT(g_TstMempool.mp_num_free == (num_blocks-1), + "Number of free blocks incorrect (%u vs %u)", + g_TstMempool.mp_num_free, (num_blocks-1)); + + /* Put back the block */ + rc = os_memblock_put(&g_TstMempool, block); + TEST_ASSERT(rc == 0, "Put block fails with error code=%d\n", rc); + + TEST_ASSERT(g_TstMempool.mp_num_free == num_blocks, + "Number of free blocks incorrect (%u vs %u)", + g_TstMempool.mp_num_free, num_blocks); + + /* remove all the blocks. Make sure we get count. */ + memset(block_array, 0, sizeof(block_array)); + cnt = 0; + while (1) { + block = os_memblock_get(&g_TstMempool); + if (block == NULL) { + break; + } + block_array[cnt] = block; + ++cnt; + if (cnt == MEMPOOL_TEST_MAX_BLOCKS) { + break; + } + } + + TEST_ASSERT((cnt == g_TstMempool.mp_num_blocks) && + (cnt != MEMPOOL_TEST_MAX_BLOCKS), + "Got more blocks than mempool contains (%d vs %d)", + cnt, g_TstMempool.mp_num_blocks); + + /* Better be no free blocks left! */ + TEST_ASSERT(g_TstMempool.mp_num_free == 0, + "Got all blocks but number free not zero! (%d)", + g_TstMempool.mp_num_free); + + /* Now put them all back */ + for (cnt = 0; cnt < g_TstMempool.mp_num_blocks; ++cnt) { + rc = os_memblock_put(&g_TstMempool, block_array[cnt]); + TEST_ASSERT(rc == 0, + "Error putting back block %p (cnt=%d err=%d)", + block_array[cnt], cnt, rc); + } + + /* Better be no free blocks left! */ + TEST_ASSERT(g_TstMempool.mp_num_free == g_TstMempool.mp_num_blocks, + "Put all blocks but number free not equal to total!"); + + /* Better get error when we try these things! */ + rc = os_memblock_put(NULL, block_array[0]); + TEST_ASSERT(rc != 0, + "Should have got an error trying to put to null pool"); + + rc = os_memblock_put(&g_TstMempool, NULL); + TEST_ASSERT(rc != 0, "No error trying to put to NULL block"); + + TEST_ASSERT(os_memblock_get(NULL) == NULL, + "No error trying to get a block from NULL pool"); + + /* Attempt to free a block outside the range of the membuf */ + test_block = g_TstMempool.mp_membuf_addr; + test_block -= 4; + rc = os_memblock_put(&g_TstMempool, (void *)test_block); + TEST_ASSERT(rc == OS_INVALID_PARM, "No error freeing bad block address"); + + test_block += (true_block_size * g_TstMempool.mp_num_blocks) + 100; + rc = os_memblock_put(&g_TstMempool, (void *)test_block); + TEST_ASSERT(rc == OS_INVALID_PARM, "No error freeing bad block address"); + + /* Attempt to free on bad boundary */ + test_block = g_TstMempool.mp_membuf_addr; + test_block += (true_block_size / 2); + rc = os_memblock_put(&g_TstMempool, (void *)test_block); + TEST_ASSERT(rc == OS_INVALID_PARM, "No error freeing bad block address"); +} + +/** + * os mempool test + * + * Main test loop for memory pool testing. + * + * @return int + */ +TEST_CASE(os_mempool_test_case) +{ + mempool_test(NUM_MEM_BLOCKS, MEM_BLOCK_SIZE); +} + +TEST_SUITE(os_mempool_test_suite) +{ + os_mempool_test_case(); +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/libs/os/test/src/mutex_test.c ---------------------------------------------------------------------- diff --git a/libs/os/test/src/mutex_test.c b/libs/os/test/src/mutex_test.c new file mode 100644 index 0000000..ef6a08d --- /dev/null +++ b/libs/os/test/src/mutex_test.c @@ -0,0 +1,407 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include <sys/time.h> +#include "testutil/testutil.h" +#include "os/os.h" +#include "os/os_test.h" +#include "os/os_cfg.h" +#include "os/os_mutex.h" +#include "os_test_priv.h" + +#ifdef ARCH_sim +#define MUTEX_TEST_STACK_SIZE 1024 +#else +#define MUTEX_TEST_STACK_SIZE 256 +#endif + +struct os_task task14; +os_stack_t stack14[OS_STACK_ALIGN(MUTEX_TEST_STACK_SIZE)]; + +struct os_task task15; +os_stack_t stack15[OS_STACK_ALIGN(MUTEX_TEST_STACK_SIZE)]; + +struct os_task task16; +os_stack_t stack16[OS_STACK_ALIGN(MUTEX_TEST_STACK_SIZE)]; + +struct os_task task17; +os_stack_t stack17[OS_STACK_ALIGN(MUTEX_TEST_STACK_SIZE)]; + +#define TASK14_PRIO (4) +#define TASK15_PRIO (5) +#define TASK16_PRIO (6) +#define TASK17_PRIO (7) + +volatile int g_task14_val; +volatile int g_task15_val; +volatile int g_task16_val; +volatile int g_task17_val; +struct os_mutex g_mutex1; +struct os_mutex g_mutex2; + +static volatile int g_mutex_test; + +/** + * mutex test basic + * + * Basic mutex tests + * + * @return int + */ +static void +mutex_test_basic_handler(void *arg) +{ + struct os_mutex *mu; + struct os_task *t; + os_error_t err; + + mu = &g_mutex1; + t = os_sched_get_current_task(); + + /* Test some error cases */ + TEST_ASSERT(os_mutex_init(NULL) == OS_INVALID_PARM); + TEST_ASSERT(os_mutex_release(NULL) == OS_INVALID_PARM); + TEST_ASSERT(os_mutex_pend(NULL, 0) == OS_INVALID_PARM); + + /* Get the mutex */ + err = os_mutex_pend(mu, 0); + TEST_ASSERT(err == 0, + "Did not get free mutex immediately (err=%d)", err); + + /* Check mutex internals */ + TEST_ASSERT(mu->mu_owner == t && mu->mu_level == 1 && + mu->mu_prio == t->t_prio && SLIST_EMPTY(&mu->mu_head), + "Mutex internals not correct after getting mutex\n" + "Mutex: owner=%p prio=%u level=%u head=%p\n" + "Task: task=%p prio=%u", + mu->mu_owner, mu->mu_prio, mu->mu_level, + SLIST_FIRST(&mu->mu_head), + t, t->t_prio); + + /* Get the mutex again; should be level 2 */ + err = os_mutex_pend(mu, 0); + TEST_ASSERT(err == 0, "Did not get my mutex immediately (err=%d)", err); + + /* Check mutex internals */ + TEST_ASSERT(mu->mu_owner == t && mu->mu_level == 2 && + mu->mu_prio == t->t_prio && SLIST_EMPTY(&mu->mu_head), + "Mutex internals not correct after getting mutex\n" + "Mutex: owner=%p prio=%u level=%u head=%p\n" + "Task: task=%p prio=%u", + mu->mu_owner, mu->mu_prio, mu->mu_level, + SLIST_FIRST(&mu->mu_head), t, t->t_prio); + + /* Release mutex */ + err = os_mutex_release(mu); + TEST_ASSERT(err == 0, "Could not release mutex I own (err=%d)", err); + + /* Check mutex internals */ + TEST_ASSERT(mu->mu_owner == t && mu->mu_level == 1 && + mu->mu_prio == t->t_prio && SLIST_EMPTY(&mu->mu_head), + "Error: mutex internals not correct after getting mutex\n" + "Mutex: owner=%p prio=%u level=%u head=%p\n" + "Task: task=%p prio=%u", + mu->mu_owner, mu->mu_prio, mu->mu_level, + SLIST_FIRST(&mu->mu_head), t, t->t_prio); + + /* Release it again */ + err = os_mutex_release(mu); + TEST_ASSERT(err == 0, "Could not release mutex I own (err=%d)", err); + + /* Check mutex internals */ + TEST_ASSERT(mu->mu_owner == NULL && mu->mu_level == 0 && + mu->mu_prio == t->t_prio && SLIST_EMPTY(&mu->mu_head), + "Mutex internals not correct after getting mutex\n" + "Mutex: owner=%p prio=%u level=%u head=%p\n" + "Task: task=%p prio=%u", + mu->mu_owner, mu->mu_prio, mu->mu_level, + SLIST_FIRST(&mu->mu_head), t, t->t_prio); + + os_test_restart(); +} + +static void +mutex_test1_task14_handler(void *arg) +{ + os_error_t err; + struct os_task *t; + int iters; + + t = os_sched_get_current_task(); + TEST_ASSERT(t->t_func == mutex_test1_task14_handler); + + for (iters = 0; iters < 3; iters++) { + os_time_delay(100); + + g_task14_val = 1; + + err = os_mutex_pend(&g_mutex1, 100); + TEST_ASSERT(err == OS_OK); + TEST_ASSERT(g_task16_val == 1); + + os_time_delay(100); + } + + os_test_restart(); +} + +static void +mutex_test2_task14_handler(void *arg) +{ + os_error_t err; + struct os_task *t; + int iters; + + t = os_sched_get_current_task(); + TEST_ASSERT(t->t_func == mutex_test2_task14_handler); + + for (iters = 0; iters < 3; iters++) { + err = os_mutex_pend(&g_mutex1, 0); + TEST_ASSERT(err == OS_OK, "err=%d", err); + + g_task14_val = 1; + os_time_delay(100); + + /* + * Task17 should have its mutex wait flag set; at least the first time + * through! + */ + if (iters == 0) { + TEST_ASSERT(task17.t_flags & OS_TASK_FLAG_MUTEX_WAIT); + } + + if (g_mutex_test == 4) { + os_time_delay(150); + } + + os_mutex_release(&g_mutex1); + os_time_delay(100); + } + + os_test_restart(); +} + +static void +task15_handler(void *arg) +{ + os_error_t err; + struct os_task *t; + + if (g_mutex_test == 1) { + while (1) { + t = os_sched_get_current_task(); + TEST_ASSERT(t->t_func == task15_handler); + + os_time_delay(50); + while (1) { + /* Wait here forever */ + } + } + } else { + if (g_mutex_test == 2) { + /* Sleep for 3 seconds */ + t = os_sched_get_current_task(); + os_time_delay(500); + } else if (g_mutex_test == 3) { + /* Sleep for 3 seconds */ + t = os_sched_get_current_task(); + os_time_delay(30); + } + + while (1) { + t = os_sched_get_current_task(); + TEST_ASSERT(t->t_func == task15_handler); + + err = os_mutex_pend(&g_mutex1, 10000); + if (g_mutex_test == 4) { + TEST_ASSERT(err == OS_TIMEOUT); + } else { + TEST_ASSERT(err == OS_OK); + } + + os_time_delay(100); + } + } +} + +static void +task16_handler(void *arg) +{ + os_error_t err; + struct os_task *t; + + if (g_mutex_test == 1) { + while (1) { + t = os_sched_get_current_task(); + TEST_ASSERT(t->t_func == task16_handler); + + /* Get mutex 1 */ + err = os_mutex_pend(&g_mutex1, 0xFFFFFFFF); + TEST_ASSERT(err == OS_OK); + + while (g_task14_val != 1) { + /* Wait till task 1 wakes up and sets val. */ + } + + g_task16_val = 1; + + err = os_mutex_release(&g_mutex1); + TEST_ASSERT(err == OS_OK); + } + } else { + if (g_mutex_test == 2) { + /* Sleep for 3 seconds */ + t = os_sched_get_current_task(); + os_time_delay(30); + } else if (g_mutex_test == 3) { + /* Sleep for 3 seconds */ + t = os_sched_get_current_task(); + os_time_delay(50); + } + + while (1) { + t = os_sched_get_current_task(); + TEST_ASSERT(t->t_func == task16_handler); + + err = os_mutex_pend(&g_mutex1, 10000); + if (g_mutex_test == 4) { + TEST_ASSERT(err == OS_TIMEOUT); + } else { + TEST_ASSERT(err == OS_OK); + } + + if (err == OS_OK) { + err = os_mutex_release(&g_mutex1); + TEST_ASSERT(err == OS_OK); + } + + os_time_delay(10000); + } + } +} + +static void +task17_handler(void *arg) +{ + os_error_t err; + struct os_task *t; + + while (1) { + t = os_sched_get_current_task(); + TEST_ASSERT(t->t_func == task17_handler); + + if (g_mutex_test == 5) { + err = os_mutex_pend(&g_mutex1, 10); + } else { + err = os_mutex_pend(&g_mutex1, 10000); + TEST_ASSERT((t->t_flags & OS_TASK_FLAG_MUTEX_WAIT) == 0); + } + + if (g_mutex_test == 4 || g_mutex_test == 5) { + TEST_ASSERT(err == OS_TIMEOUT); + } else { + TEST_ASSERT(err == OS_OK); + } + + if (err == OS_OK) { + err = os_mutex_release(&g_mutex1); + TEST_ASSERT(err == OS_OK); + } + + os_time_delay(10000); + } +} + +TEST_CASE(os_mutex_test_basic) +{ + os_init(); + + os_mutex_init(&g_mutex1); + + os_task_init(&task14, "task14", mutex_test_basic_handler, NULL, + TASK14_PRIO, OS_WAIT_FOREVER, stack14, + OS_STACK_ALIGN(MUTEX_TEST_STACK_SIZE)); + + os_start(); +} + +TEST_CASE(os_mutex_test_case_1) +{ + int rc; + + os_init(); + + g_mutex_test = 1; + g_task14_val = 0; + g_task15_val = 0; + g_task16_val = 0; + + rc = os_mutex_init(&g_mutex1); + TEST_ASSERT(rc == 0); + rc = os_mutex_init(&g_mutex2); + TEST_ASSERT(rc == 0); + + os_task_init(&task14, "task14", mutex_test1_task14_handler, NULL, + TASK14_PRIO, OS_WAIT_FOREVER, stack14, + OS_STACK_ALIGN(MUTEX_TEST_STACK_SIZE)); + + os_task_init(&task15, "task15", task15_handler, NULL, TASK15_PRIO, + OS_WAIT_FOREVER, stack15, OS_STACK_ALIGN(MUTEX_TEST_STACK_SIZE)); + + os_task_init(&task16, "task16", task16_handler, NULL, TASK16_PRIO, + OS_WAIT_FOREVER, stack16, OS_STACK_ALIGN(MUTEX_TEST_STACK_SIZE)); + + os_start(); +} + +TEST_CASE(os_mutex_test_case_2) +{ + os_init(); + + g_mutex_test = 2; + g_task14_val = 0; + g_task15_val = 0; + g_task16_val = 0; + os_mutex_init(&g_mutex1); + os_mutex_init(&g_mutex2); + + os_task_init(&task14, "task14", mutex_test2_task14_handler, NULL, + TASK14_PRIO, OS_WAIT_FOREVER, stack14, + OS_STACK_ALIGN(MUTEX_TEST_STACK_SIZE)); + + os_task_init(&task15, "task15", task15_handler, NULL, TASK15_PRIO, + OS_WAIT_FOREVER, stack15, OS_STACK_ALIGN(MUTEX_TEST_STACK_SIZE)); + + os_task_init(&task16, "task16", task16_handler, NULL, TASK16_PRIO, + OS_WAIT_FOREVER, stack16, OS_STACK_ALIGN(MUTEX_TEST_STACK_SIZE)); + + os_task_init(&task17, "task17", task17_handler, NULL, TASK17_PRIO, + OS_WAIT_FOREVER, stack17, OS_STACK_ALIGN(MUTEX_TEST_STACK_SIZE)); + + os_start(); +} + +TEST_SUITE(os_mutex_test_suite) +{ + os_mutex_test_basic(); + os_mutex_test_case_1(); + os_mutex_test_case_2(); +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/libs/os/test/src/os_test.c ---------------------------------------------------------------------- diff --git a/libs/os/test/src/os_test.c b/libs/os/test/src/os_test.c new file mode 100644 index 0000000..809ab9f --- /dev/null +++ b/libs/os/test/src/os_test.c @@ -0,0 +1,53 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include <assert.h> +#include <stddef.h> +#include "syscfg/syscfg.h" +#include "testutil/testutil.h" +#include "os/os_test.h" +#include "os_test_priv.h" + +int +os_test_all(void) +{ + os_mempool_test_suite(); + os_mutex_test_suite(); + os_sem_test_suite(); + os_mbuf_test_suite(); + os_eventq_test_suite(); + + + return tu_case_failed; +} + +#if MYNEWT_VAL(SELFTEST) + +int +main(int argc, char **argv) +{ + tu_config.tc_print_results = 1; + tu_init(); + + os_test_all(); + + return tu_any_failed; +} + +#endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/libs/os/test/src/os_test_priv.h ---------------------------------------------------------------------- diff --git a/libs/os/test/src/os_test_priv.h b/libs/os/test/src/os_test_priv.h new file mode 100644 index 0000000..5193c33 --- /dev/null +++ b/libs/os/test/src/os_test_priv.h @@ -0,0 +1,32 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_OS_TEST_PRIV_ +#define H_OS_TEST_PRIV_ + +void os_test_restart(void); + +int os_mempool_test_suite(void); +int os_mbuf_test_suite(void); +int os_mutex_test_suite(void); +int os_sem_test_suite(void); +int os_eventq_test_suite(void); + + +#endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/libs/os/test/src/sem_test.c ---------------------------------------------------------------------- diff --git a/libs/os/test/src/sem_test.c b/libs/os/test/src/sem_test.c new file mode 100644 index 0000000..ec79185 --- /dev/null +++ b/libs/os/test/src/sem_test.c @@ -0,0 +1,401 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +#include <stdio.h> +#include <string.h> +#include "testutil/testutil.h" +#include "os/os.h" +#include "os/os_cfg.h" +#include "os/os_sem.h" +#include "os_test_priv.h" + +#ifdef ARCH_sim +#define SEM_TEST_STACK_SIZE 1024 +#else +#define SEM_TEST_STACK_SIZE 512 +#endif + +struct os_task task1; +os_stack_t stack1[OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)]; + +struct os_task task2; +os_stack_t stack2[OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)]; + +struct os_task task3; +os_stack_t stack3[OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)]; + +struct os_task task4; +os_stack_t stack4[OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)]; + +#define TASK1_PRIO (1) +#define TASK2_PRIO (2) +#define TASK3_PRIO (3) +#define TASK4_PRIO (4) + +struct os_sem g_sem1; + +/* + * TEST NUMBERS: + * 10: In this test we have the highest priority task getting the semaphore + * then sleeping. Two lower priority tasks then wake up and attempt to get + * the semaphore. They are blocked until the higher priority task releases + * the semaphore, at which point the lower priority tasks should wake up in + * order, get the semaphore, then release it and go back to sleep. + * + */ + +/** + * sem test disp sem + * + * Display semaphore contents + * + * @param sem + */ +static const char * +sem_test_sem_to_s(const struct os_sem *sem) +{ + static char buf[128]; + + snprintf(buf, sizeof buf, "\tSemaphore: tokens=%u head=%p", + sem->sem_tokens, SLIST_FIRST(&sem->sem_head)); + + return buf; +} + +static void +sem_test_sleep_task_handler(void *arg) +{ + struct os_task *t; + + t = os_sched_get_current_task(); + TEST_ASSERT(t->t_func == sem_test_sleep_task_handler); + + os_time_delay(2000); + os_test_restart(); +} + +static void +sem_test_pend_release_loop(int delay, int timeout, int itvl) +{ + os_error_t err; + + os_time_delay(delay); + + while (1) { + err = os_sem_pend(&g_sem1, timeout); + TEST_ASSERT((err == OS_OK) || (err == OS_TIMEOUT)); + + err = os_sem_release(&g_sem1); + TEST_ASSERT(err == OS_OK); + + os_time_delay(itvl); + } +} + +/** + * sem test basic + * + * Basic semaphore tests + * + * @return int + */ +static void +sem_test_basic_handler(void *arg) +{ + struct os_task *t; + struct os_sem *sem; + os_error_t err; + + sem = &g_sem1; + t = os_sched_get_current_task(); + + /* Test some error cases */ + TEST_ASSERT(os_sem_init(NULL, 1) == OS_INVALID_PARM); + TEST_ASSERT(os_sem_release(NULL) == OS_INVALID_PARM); + TEST_ASSERT(os_sem_pend(NULL, 1) == OS_INVALID_PARM); + + /* Get the semaphore */ + err = os_sem_pend(sem, 0); + TEST_ASSERT(err == 0, + "Did not get free semaphore immediately (err=%d)", err); + + /* Check semaphore internals */ + TEST_ASSERT(sem->sem_tokens == 0 && SLIST_EMPTY(&sem->sem_head), + "Semaphore internals wrong after getting semaphore\n" + "%s\n" + "Task: task=%p prio=%u", sem_test_sem_to_s(sem), t, t->t_prio); + + /* Get the semaphore again; should fail */ + err = os_sem_pend(sem, 0); + TEST_ASSERT(err == OS_TIMEOUT, + "Did not time out waiting for semaphore (err=%d)", err); + + /* Check semaphore internals */ + TEST_ASSERT(sem->sem_tokens == 0 && SLIST_EMPTY(&sem->sem_head), + "Semaphore internals wrong after getting semaphore\n" + "%s\n" + "Task: task=%p prio=%u\n", sem_test_sem_to_s(sem), t, + t->t_prio); + + /* Release semaphore */ + err = os_sem_release(sem); + TEST_ASSERT(err == 0, + "Could not release semaphore I own (err=%d)", err); + + /* Check semaphore internals */ + TEST_ASSERT(sem->sem_tokens == 1 && SLIST_EMPTY(&sem->sem_head), + "Semaphore internals wrong after releasing semaphore\n" + "%s\n" + "Task: task=%p prio=%u\n", sem_test_sem_to_s(sem), t, + t->t_prio); + + /* Release it again */ + err = os_sem_release(sem); + TEST_ASSERT(err == 0, + "Could not release semaphore again (err=%d)\n", err); + + /* Check semaphore internals */ + TEST_ASSERT(sem->sem_tokens == 2 && SLIST_EMPTY(&sem->sem_head), + "Semaphore internals wrong after releasing semaphore\n" + "%s\n" + "Task: task=%p prio=%u\n", sem_test_sem_to_s(sem), t, + t->t_prio); + + os_test_restart(); +} + +static void +sem_test_1_task1_handler(void *arg) +{ + os_error_t err; + struct os_task *t; + int i;; + + for (i = 0; i < 3; i++) { + t = os_sched_get_current_task(); + TEST_ASSERT(t->t_func == sem_test_1_task1_handler); + + + err = os_sem_pend(&g_sem1, 0); + TEST_ASSERT(err == OS_OK); + + /* Sleep to let other tasks run */ + os_time_delay(100); + + /* Release the semaphore */ + err = os_sem_release(&g_sem1); + TEST_ASSERT(err == OS_OK); + + /* Sleep to let other tasks run */ + os_time_delay(100); + } + + os_test_restart(); +} + +TEST_CASE(os_sem_test_basic) +{ + os_error_t err; + + os_init(); + + err = os_sem_init(&g_sem1, 1); + TEST_ASSERT(err == OS_OK); + + os_task_init(&task1, "task1", sem_test_basic_handler, NULL, TASK1_PRIO, + OS_WAIT_FOREVER, stack1, OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); + + os_start(); +} + +static void +sem_test_1_task2_handler(void *arg) +{ + sem_test_pend_release_loop(0, 100, 100); +} + +static void +sem_test_1_task3_handler(void *arg) +{ + sem_test_pend_release_loop(0, OS_TIMEOUT_NEVER, 2000); +} + +TEST_CASE(os_sem_test_case_1) +{ + os_error_t err; + + os_init(); + + err = os_sem_init(&g_sem1, 1); + TEST_ASSERT(err == OS_OK); + + os_task_init(&task1, "task1", sem_test_1_task1_handler, NULL, + TASK1_PRIO, OS_WAIT_FOREVER, stack1, + OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); + + os_task_init(&task2, "task2", sem_test_1_task2_handler, NULL, + TASK2_PRIO, OS_WAIT_FOREVER, stack2, + OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); + + os_task_init(&task3, "task3", sem_test_1_task3_handler, NULL, TASK3_PRIO, + OS_WAIT_FOREVER, stack3, OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); + + os_start(); +} + +static void +sem_test_2_task2_handler(void *arg) +{ + sem_test_pend_release_loop(0, 2000, 2000); +} + +static void +sem_test_2_task3_handler(void *arg) +{ + sem_test_pend_release_loop(0, OS_TIMEOUT_NEVER, 2000); +} + +static void +sem_test_2_task4_handler(void *arg) +{ + sem_test_pend_release_loop(0, 2000, 2000); +} + +TEST_CASE(os_sem_test_case_2) +{ + os_error_t err; + + os_init(); + + err = os_sem_init(&g_sem1, 1); + TEST_ASSERT(err == OS_OK); + + os_task_init(&task1, "task1", sem_test_sleep_task_handler, NULL, + TASK1_PRIO, OS_WAIT_FOREVER, stack1, + OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); + + os_task_init(&task2, "task2", sem_test_2_task2_handler, NULL, + TASK2_PRIO, OS_WAIT_FOREVER, stack2, + OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); + + os_task_init(&task3, "task3", sem_test_2_task3_handler, NULL, TASK3_PRIO, + OS_WAIT_FOREVER, stack3, OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); + + os_task_init(&task4, "task4", sem_test_2_task4_handler, NULL, TASK4_PRIO, + OS_WAIT_FOREVER, stack4, OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); + + os_start(); +} + +static void +sem_test_3_task2_handler(void *arg) +{ + sem_test_pend_release_loop(100, 2000, 2000); +} + +static void +sem_test_3_task3_handler(void *arg) +{ + sem_test_pend_release_loop(150, 2000, 2000); +} + +static void +sem_test_3_task4_handler(void *arg) +{ + sem_test_pend_release_loop(0, 2000, 2000); +} + +TEST_CASE(os_sem_test_case_3) +{ + os_error_t err; + + os_init(); + + err = os_sem_init(&g_sem1, 1); + TEST_ASSERT(err == OS_OK); + + os_task_init(&task1, "task1", sem_test_sleep_task_handler, NULL, + TASK1_PRIO, OS_WAIT_FOREVER, stack1, + OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); + + os_task_init(&task2, "task2", sem_test_3_task2_handler, NULL, + TASK2_PRIO, OS_WAIT_FOREVER, stack2, + OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); + + os_task_init(&task3, "task3", sem_test_3_task3_handler, NULL, TASK3_PRIO, + OS_WAIT_FOREVER, stack3, OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); + + os_task_init(&task4, "task4", sem_test_3_task4_handler, NULL, TASK4_PRIO, + OS_WAIT_FOREVER, stack4, OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); + + os_start(); +} + +static void +sem_test_4_task2_handler(void *arg) +{ + sem_test_pend_release_loop(60, 2000, 2000); +} + +static void +sem_test_4_task3_handler(void *arg) +{ + sem_test_pend_release_loop(60, 2000, 2000); +} + +static void +sem_test_4_task4_handler(void *arg) +{ + sem_test_pend_release_loop(0, 2000, 2000); +} + + +TEST_CASE(os_sem_test_case_4) +{ + os_error_t err; + + os_init(); + + err = os_sem_init(&g_sem1, 1); + TEST_ASSERT(err == OS_OK); + + os_task_init(&task1, "task1", sem_test_sleep_task_handler, NULL, + TASK1_PRIO, OS_WAIT_FOREVER, stack1, + OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); + + os_task_init(&task2, "task2", sem_test_4_task2_handler, NULL, + TASK2_PRIO, OS_WAIT_FOREVER, stack2, + OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); + + os_task_init(&task3, "task3", sem_test_4_task3_handler, NULL, TASK3_PRIO, + OS_WAIT_FOREVER, stack3, OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); + + os_task_init(&task4, "task4", sem_test_4_task4_handler, NULL, TASK4_PRIO, + OS_WAIT_FOREVER, stack4, OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)); + + os_start(); +} + +TEST_SUITE(os_sem_test_suite) +{ + os_sem_test_basic(); + os_sem_test_case_1(); + os_sem_test_case_2(); + os_sem_test_case_3(); + os_sem_test_case_4(); +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/libs/shell/include/shell/shell.h ---------------------------------------------------------------------- diff --git a/libs/shell/include/shell/shell.h b/libs/shell/include/shell/shell.h index 53c890d..6b89740 100644 --- a/libs/shell/include/shell/shell.h +++ b/libs/shell/include/shell/shell.h @@ -40,7 +40,6 @@ int shell_nlip_input_register(shell_nlip_input_func_t nf, void *arg); int shell_nlip_output(struct os_mbuf *m); void shell_console_rx_cb(void); -int shell_task_init(uint8_t prio, os_stack_t *stack, uint16_t stack_size, - int max_input_length); +void shell_init(void); #endif /* __SHELL_H__ */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/libs/shell/pkg.yml ---------------------------------------------------------------------- diff --git a/libs/shell/pkg.yml b/libs/shell/pkg.yml index dcfc484..36372ee 100644 --- a/libs/shell/pkg.yml +++ b/libs/shell/pkg.yml @@ -28,5 +28,18 @@ pkg.deps: - libs/util pkg.req_apis: - console -pkg.features: - - SHELL + +pkg.init_function: shell_init +pkg.init_stage: 5 + +pkg.syscfg_defs: + SHELL_TASK_PRIO: + description: 'TBD' + type: 'task_priority' + value: 'any' + SHELL_STACK_SIZE: + description: 'TBD' + value: 512 + SHELL_MAX_INPUT_LEN: + description: 'TBD' + value: 256 http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/libs/shell/src/shell.c ---------------------------------------------------------------------- diff --git a/libs/shell/src/shell.c b/libs/shell/src/shell.c index 115a62c..7fe15e5 100644 --- a/libs/shell/src/shell.c +++ b/libs/shell/src/shell.c @@ -17,22 +17,22 @@ * under the License. */ -#include <os/os.h> - -#include <console/console.h> - -#include "shell/shell.h" -#include "shell_priv.h" - -#include <os/endian.h> -#include <util/base64.h> -#include <util/crc16.h> #include <stdio.h> #include <string.h> #include <assert.h> #include <errno.h> +#include "sysinit/sysinit.h" +#include "syscfg/syscfg.h" +#include "console/console.h" +#include "os/os.h" +#include "os/endian.h" +#include "util/base64.h" +#include "util/crc16.h" +#include "shell/shell.h" +#include "shell_priv.h" + static shell_nlip_input_func_t g_shell_nlip_in_func; static void *g_shell_nlip_in_arg; @@ -42,6 +42,8 @@ static struct os_mqueue g_shell_nlip_mq; #define SHELL_HELP_PER_LINE 6 #define SHELL_MAX_ARGS 20 +static os_stack_t shell_stack[OS_STACK_ALIGN(MYNEWT_VAL(SHELL_STACK_SIZE))]; + static int shell_echo_cmd(int argc, char **argv); static int shell_help_cmd(int argc, char **argv); @@ -73,7 +75,6 @@ static struct os_event console_rdy_ev; static struct os_mutex g_shell_cmd_list_lock; static char *shell_line; -static int shell_line_capacity; static int shell_line_len; static char *argv[SHELL_MAX_ARGS]; @@ -417,7 +418,7 @@ shell_read_console(void) while (1) { rc = console_read(shell_line + shell_line_len, - shell_line_capacity - shell_line_len, &full_line); + MYNEWT_VAL(SHELL_MAX_INPUT_LEN) - shell_line_len, &full_line); if (rc <= 0 && !full_line) { break; } @@ -523,52 +524,36 @@ shell_help_cmd(int argc, char **argv) return (0); } -int -shell_task_init(uint8_t prio, os_stack_t *stack, uint16_t stack_size, - int max_input_length) +void +shell_init(void) { int rc; free(shell_line); + shell_line = NULL; - if (max_input_length > 0) { - shell_line = malloc(max_input_length); - if (shell_line == NULL) { - rc = ENOMEM; - goto err; - } - } - shell_line_capacity = max_input_length; +#if MYNEWT_VAL(SHELL_MAX_INPUT_LEN) > 0 + shell_line = malloc(MYNEWT_VAL(SHELL_MAX_INPUT_LEN)); + SYSINIT_PANIC_ASSERT(shell_line != NULL); +#endif rc = os_mutex_init(&g_shell_cmd_list_lock); - if (rc != 0) { - goto err; - } + SYSINIT_PANIC_ASSERT(rc == 0); rc = shell_cmd_register(&g_shell_echo_cmd); - if (rc != 0) { - goto err; - } + SYSINIT_PANIC_ASSERT(rc == 0); rc = shell_cmd_register(&g_shell_help_cmd); - if (rc != 0) { - goto err; - } + SYSINIT_PANIC_ASSERT(rc == 0); rc = shell_cmd_register(&g_shell_os_tasks_display_cmd); - if (rc != 0) { - goto err; - } + SYSINIT_PANIC_ASSERT(rc == 0); rc = shell_cmd_register(&g_shell_os_mpool_display_cmd); - if (rc != 0) { - goto err; - } + SYSINIT_PANIC_ASSERT(rc == 0); rc = shell_cmd_register(&g_shell_os_date_cmd); - if (rc != 0) { - goto err; - } + SYSINIT_PANIC_ASSERT(rc == 0); os_eventq_init(&shell_evq); os_mqueue_init(&g_shell_nlip_mq, NULL); @@ -576,14 +561,7 @@ shell_task_init(uint8_t prio, os_stack_t *stack, uint16_t stack_size, console_init(shell_console_rx_cb); rc = os_task_init(&shell_task, "shell", shell_task_func, - NULL, prio, OS_WAIT_FOREVER, stack, stack_size); - if (rc != 0) { - goto err; - } - - return (0); -err: - free(shell_line); - shell_line = NULL; - return (rc); + NULL, MYNEWT_VAL(SHELL_TASK_PRIO), OS_WAIT_FOREVER, shell_stack, + MYNEWT_VAL(SHELL_STACK_SIZE)); + SYSINIT_PANIC_ASSERT(rc == 0); } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/libs/testutil/include/testutil/testutil.h ---------------------------------------------------------------------- diff --git a/libs/testutil/include/testutil/testutil.h b/libs/testutil/include/testutil/testutil.h index 9c6192a..de61394 100644 --- a/libs/testutil/include/testutil/testutil.h +++ b/libs/testutil/include/testutil/testutil.h @@ -23,6 +23,8 @@ #include <inttypes.h> #include <setjmp.h> +#include "syscfg/syscfg.h" + /***************************************************************************** * Public declarations * *****************************************************************************/ @@ -163,7 +165,7 @@ extern jmp_buf tu_case_jb; #define TEST_PASS(...) \ tu_case_pass_manual(__FILE__, __LINE__, __VA_ARGS__); -#ifdef MYNEWT_UNIT_TEST +#if MYNEWT_VAL(TEST) #define ASSERT_IF_TEST(expr) assert(expr) #else #define ASSERT_IF_TEST(expr) http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/libs/testutil/pkg.yml ---------------------------------------------------------------------- diff --git a/libs/testutil/pkg.yml b/libs/testutil/pkg.yml index 605065e..8314776 100644 --- a/libs/testutil/pkg.yml +++ b/libs/testutil/pkg.yml @@ -28,5 +28,3 @@ pkg.keywords: pkg.deps: - hw/hal - libs/os - -pkg.cflags.TEST: "-DMYNEWT_UNIT_TEST" http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/libs/util/include/util/mem.h ---------------------------------------------------------------------- diff --git a/libs/util/include/util/mem.h b/libs/util/include/util/mem.h index 52ddce4..46601ba 100644 --- a/libs/util/include/util/mem.h +++ b/libs/util/include/util/mem.h @@ -34,5 +34,8 @@ int mem_malloc_mbufpkt_pool(struct os_mempool *mempool, struct os_mbuf_pool *mbuf_pool, int num_blocks, int block_size, char *name, void **out_buf); +int mem_init_mbuf_pool(void *mem, struct os_mempool *mempool, + struct os_mbuf_pool *mbuf_pool, int num_blocks, + int block_size, char *name); #endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/libs/util/pkg.yml ---------------------------------------------------------------------- diff --git a/libs/util/pkg.yml b/libs/util/pkg.yml index 3b37b11..b922830 100644 --- a/libs/util/pkg.yml +++ b/libs/util/pkg.yml @@ -28,4 +28,3 @@ pkg.keywords: pkg.deps: - hw/hal - libs/os - - libs/testutil http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/libs/util/src/mem.c ---------------------------------------------------------------------- diff --git a/libs/util/src/mem.c b/libs/util/src/mem.c index faf8234..7cbe3d5 100644 --- a/libs/util/src/mem.c +++ b/libs/util/src/mem.c @@ -144,3 +144,23 @@ mem_malloc_mbufpkt_pool(struct os_mempool *mempool, name, out_buf); return rc; } + +int +mem_init_mbuf_pool(void *mem, struct os_mempool *mempool, + struct os_mbuf_pool *mbuf_pool, int num_blocks, + int block_size, char *name) +{ + int rc; + + rc = os_mempool_init(mempool, num_blocks, block_size, mem, name); + if (rc != 0) { + return rc; + } + + rc = os_mbuf_pool_init(mbuf_pool, mempool, block_size, num_blocks); + if (rc != 0) { + return rc; + } + + return 0; +}