From 1d351ceb2c0d0bfda30365a181935ecc2170a155 Mon Sep 17 00:00:00 2001 From: Yasir Khan Date: Tue, 12 May 2020 21:06:12 -0400 Subject: [PATCH 1/2] Fix #381, Add OS_TimerAdd functional test --- .../timer-add-api-test/timer-add-api-test.c | 189 ++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 src/tests/timer-add-api-test/timer-add-api-test.c diff --git a/src/tests/timer-add-api-test/timer-add-api-test.c b/src/tests/timer-add-api-test/timer-add-api-test.c new file mode 100644 index 000000000..f81b421cd --- /dev/null +++ b/src/tests/timer-add-api-test/timer-add-api-test.c @@ -0,0 +1,189 @@ +#include +#include +#include + +#include "common_types.h" +#include "osapi.h" +#include "utassert.h" +#include "uttest.h" +#include "utbsp.h" + +#define NUMBER_OF_TIMERS 4 +#define TASK_1_ID 1 +#define TASK_1_STACK_SIZE 4096 +#define TASK_1_PRIORITY 101 + +OS_time_t StartTime; +OS_time_t EndTime; +uint32 TimerStart[NUMBER_OF_TIMERS] = {1000, 2000000, 3000000, 4000000 }; +uint32 TimerInterval[NUMBER_OF_TIMERS] = {500000, 400000, 800000, 600000 }; + +uint32 TimerTestTaskStack[TASK_1_STACK_SIZE]; +int32 timer_counter[NUMBER_OF_TIMERS]; +uint32 timer_idlookup[OS_MAX_TIMERS]; + +/* +** Test timer function. +** Note: For some Host OSs, this is the equivalent of an ISR, so the calls available are limited. +** For example, Linux and vxWorks can call functions like printf, but RTEMS cannot. +*/ +void test_func(uint32 timer_id , void *arg) +{ + OS_ConvertToArrayIndex(timer_id, &timer_id); + timer_counter[timer_idlookup[timer_id]]++; +} + +/* *************************************** MAIN ************************************** */ + +void TestTimerAddApi(void) +{ + /* + * Test Case For: + * int32 OS_TimerAdd(uint32 *timer_id, const char *timer_name, uint32 timebase_ref_id, OS_ArgCallback_t callback_ptr, void *callback_arg) + */ + + int32 actual; + int32 expected; + uint32 timer_id; + char arg = 'a'; + uint32 time_base_id; + int i = 0; + int32 TimerStatus[NUMBER_OF_TIMERS]; + uint32 TableId; + uint32 TimerID[NUMBER_OF_TIMERS]; + char TimerName[NUMBER_OF_TIMERS][20] = {"TIMER1","TIMER2","TIMER3","TIMER4"}; + uint32 microsecs; + + OS_TimeBaseCreate( &time_base_id, "TimeBase", 0); + OS_TimeBaseSet(time_base_id, 10000, 10000); //ms + + for ( i = 0; i < NUMBER_OF_TIMERS; i++ ) + { + TimerStatus[i] = OS_TimerAdd(&TimerID[i], TimerName[i], time_base_id, &test_func, &arg); + UtAssert_True(TimerStatus[i] == OS_SUCCESS, "Timer %d Created RC=%d ID=%d", i, (int)TimerStatus[i], (int)TimerID[i]); + + OS_ConvertToArrayIndex(TimerID[i], &TableId); + timer_idlookup[TableId] = i; + } + + /* Sample the clock now, before starting any timer */ + OS_GetLocalTime(&StartTime); + for ( i = 0; i < NUMBER_OF_TIMERS; i++ ) + { + /* + * to ensure that all timers are started as closely as possible, + * this just stores the result and does not assert/printf now + */ + TimerStatus[i] = OS_TimerSet(TimerID[i], TimerStart[i], TimerInterval[i]); + } + + /* + * Now the actual OS_TimerSet() return code can be checked. + */ + for ( i = 0; i < NUMBER_OF_TIMERS; i++ ) + { + UtAssert_True(TimerStatus[i] == OS_SUCCESS, "Timer %d programmed RC=%d", i, (int)TimerStatus[i]); + } + + /* + ** Let the main thread sleep + */ + UtPrintf("Starting Delay loop.\n"); + for (i = 0 ; i < 30; i++ ) + { + /* + ** Even though this sleep call is for 1 second, + ** the sigalarm timer for the 1hz will keep waking + ** it up. Keep that in mind when setting the timer down + ** to something very small. + */ + OS_TaskDelay(1000); + } + + OS_GetLocalTime(&EndTime); + + for ( i = 0; i < NUMBER_OF_TIMERS; i++ ) + { + TimerStatus[i] = OS_TimerDelete(TimerID[i]); + } + + for ( i = 0; i < NUMBER_OF_TIMERS; i++ ) + { + UtAssert_True(TimerStatus[i] == OS_SUCCESS, "Timer %d delete RC=%d. Count total = %d", + i, (int)TimerStatus[i], (int)timer_counter[i]); + } + + /* + * Time limited test + */ + microsecs = 1000000 * (EndTime.seconds - StartTime.seconds); + if (EndTime.microsecs < StartTime.microsecs) + { + microsecs -= StartTime.microsecs - EndTime.microsecs; + } + else + { + microsecs += EndTime.microsecs - StartTime.microsecs; + } + + /* Make sure the ratio of the timers are OK */ + for ( i = 0; i < NUMBER_OF_TIMERS; i++ ) + { + /* + * Expect one tick after the start time (i.e. first tick) + * Plus one tick for every interval that occurred during the test + */ + expected = 1 + (microsecs - TimerStart[i]) / TimerInterval[i]; + UtAssert_True(expected > 0, "Expected ticks = %u", (unsigned int)expected); + + /* + * Since all these counts are affected by test system load, + * allow for some fudge factor before declaring failure + */ + UtAssert_True(timer_counter[i] >= (expected - 3), "Timer %d count >= %d", (int)i, (int)(expected - 3)); + UtAssert_True(timer_counter[i] <= (expected + 3), "Timer %d count <= %d", (int)i, (int)(expected + 3)); + } + + /* Test nominal inputs */ + expected = OS_SUCCESS; + actual = OS_TimerAdd(&timer_id, "Timer", time_base_id, test_func, &arg); + UtAssert_True(actual == expected, "OS_TimerAdd() (%ld) == OS_SUCCESS", (long)actual); + + /* Test invalid inputs */ + expected = OS_INVALID_POINTER; + actual = OS_TimerAdd(NULL, "Timer", time_base_id, test_func, &arg); + UtAssert_True(actual == expected, "OS_TimerAdd() (%ld) == OS_INVALID_POINTER", (long)actual); + + expected = OS_ERR_INVALID_ID; + actual = OS_TimerAdd(&timer_id, "Timer", 1, test_func, &arg); + UtAssert_True(actual == expected, "OS_TimerAdd() (%ld) == OS_ERR_INVALID_ID", (long)actual); + + expected = OS_TIMER_ERR_INVALID_ARGS; + actual = OS_TimerAdd(&timer_id, "Timer",time_base_id , NULL, &arg); + UtAssert_True(actual == expected, "OS_TimerAdd() (%ld) == OS_TIMER_ERR_INVALID_ARGS", (long)actual); + + expected = OS_ERR_NAME_TAKEN; + actual = OS_TimerAdd(&timer_id, "Timer", time_base_id, test_func, &arg); + UtAssert_True(actual == expected, "OS_TimerAdd() (%ld) == OS_ERR_NAME_TAKEN", (long)actual); + + expected = OS_INVALID_POINTER; + actual = OS_TimerAdd(&timer_id, 0, time_base_id, test_func, &arg); + UtAssert_True(actual == expected, "OS_TimerAdd() (%ld) == OS_INVALID_POINTER", (long)actual); + + +} /* end TestTimerAddApi */ + + +void UtTest_Setup(void) +{ + if (OS_API_Init() != OS_SUCCESS) + { + UtAssert_Abort("OS_API_Init() failed"); + } + + /* + * Register the test setup and check routines in UT assert + */ + UtTest_Add(TestTimerAddApi, NULL, NULL, "TestTimerAddApi"); +} + From 7a644f8d8d2cd356a6a330f5fc53749b9c1e8297 Mon Sep 17 00:00:00 2001 From: Yasir Khan Date: Thu, 28 May 2020 11:18:03 -0400 Subject: [PATCH 2/2] Fix #381, Updated functional tests to implement all changes requested on Github --- .../timer-add-api-test/timer-add-api-test.c | 71 ++++++++++++------- 1 file changed, 47 insertions(+), 24 deletions(-) diff --git a/src/tests/timer-add-api-test/timer-add-api-test.c b/src/tests/timer-add-api-test/timer-add-api-test.c index f81b421cd..d897848b8 100644 --- a/src/tests/timer-add-api-test/timer-add-api-test.c +++ b/src/tests/timer-add-api-test/timer-add-api-test.c @@ -1,3 +1,20 @@ +/* + * Copyright (c) 2020, United States government as represented by the + * administrator of the National Aeronautics Space Administration. + * All rights reserved. This software was created at NASA Goddard + * Space Flight Center pursuant to government contracts. + * + * This is governed by the NASA Open Source Agreement and may be used, + * distributed and modified only according to the terms of that agreement. + */ + +/* + * Filename: timer-add-api-test.c + * + * Purpose: This file contains functional tests for "osapi-timer" + * + */ + #include #include #include @@ -19,18 +36,18 @@ uint32 TimerStart[NUMBER_OF_TIMERS] = {1000, 2000000, 3000000, 4000000 uint32 TimerInterval[NUMBER_OF_TIMERS] = {500000, 400000, 800000, 600000 }; uint32 TimerTestTaskStack[TASK_1_STACK_SIZE]; -int32 timer_counter[NUMBER_OF_TIMERS]; -uint32 timer_idlookup[OS_MAX_TIMERS]; +uint32 timer_counter[NUMBER_OF_TIMERS]; -/* -** Test timer function. -** Note: For some Host OSs, this is the equivalent of an ISR, so the calls available are limited. -** For example, Linux and vxWorks can call functions like printf, but RTEMS cannot. -*/ -void test_func(uint32 timer_id , void *arg) + +void counter_func(uint32 timer_id , void *arg) { - OS_ConvertToArrayIndex(timer_id, &timer_id); - timer_counter[timer_idlookup[timer_id]]++; + uint32 *counter = arg; + ++(*counter); +} + +void null_func(uint32 timer_id , void *arg) +{ + } /* *************************************** MAIN ************************************** */ @@ -44,26 +61,32 @@ void TestTimerAddApi(void) int32 actual; int32 expected; + int32 tbc_ret_val; + int32 tbs_ret_val; uint32 timer_id; - char arg = 'a'; uint32 time_base_id; int i = 0; int32 TimerStatus[NUMBER_OF_TIMERS]; - uint32 TableId; uint32 TimerID[NUMBER_OF_TIMERS]; char TimerName[NUMBER_OF_TIMERS][20] = {"TIMER1","TIMER2","TIMER3","TIMER4"}; uint32 microsecs; - OS_TimeBaseCreate( &time_base_id, "TimeBase", 0); - OS_TimeBaseSet(time_base_id, 10000, 10000); //ms + /* Create and set the TimeBase obj and verify success */ + + tbc_ret_val = OS_TimeBaseCreate( &time_base_id, "TimeBase", 0); + expected = OS_SUCCESS; + UtAssert_True(tbc_ret_val == expected, "OS_TimeBaseCreate() (%ld) == OS_SUCCESS", (long)tbc_ret_val); + + tbs_ret_val = OS_TimeBaseSet(time_base_id, 10000, 10000); /* ms */ + expected = OS_SUCCESS; + UtAssert_True(tbs_ret_val == expected, "OS_TimeBaseSet() (%ld) == OS_SUCCESS", (long)tbs_ret_val); + for ( i = 0; i < NUMBER_OF_TIMERS; i++ ) { - TimerStatus[i] = OS_TimerAdd(&TimerID[i], TimerName[i], time_base_id, &test_func, &arg); + TimerStatus[i] = OS_TimerAdd(&TimerID[i], TimerName[i], time_base_id, &counter_func, &timer_counter[i]); UtAssert_True(TimerStatus[i] == OS_SUCCESS, "Timer %d Created RC=%d ID=%d", i, (int)TimerStatus[i], (int)TimerID[i]); - OS_ConvertToArrayIndex(TimerID[i], &TableId); - timer_idlookup[TableId] = i; } /* Sample the clock now, before starting any timer */ @@ -145,29 +168,29 @@ void TestTimerAddApi(void) } /* Test nominal inputs */ - expected = OS_SUCCESS; - actual = OS_TimerAdd(&timer_id, "Timer", time_base_id, test_func, &arg); + expected = OS_SUCCESS; + actual = OS_TimerAdd(&timer_id, "Timer", time_base_id, null_func, NULL); UtAssert_True(actual == expected, "OS_TimerAdd() (%ld) == OS_SUCCESS", (long)actual); /* Test invalid inputs */ expected = OS_INVALID_POINTER; - actual = OS_TimerAdd(NULL, "Timer", time_base_id, test_func, &arg); + actual = OS_TimerAdd(NULL, "Timer", time_base_id, null_func, NULL); UtAssert_True(actual == expected, "OS_TimerAdd() (%ld) == OS_INVALID_POINTER", (long)actual); expected = OS_ERR_INVALID_ID; - actual = OS_TimerAdd(&timer_id, "Timer", 1, test_func, &arg); + actual = OS_TimerAdd(&timer_id, "Timer", 1, null_func, NULL); UtAssert_True(actual == expected, "OS_TimerAdd() (%ld) == OS_ERR_INVALID_ID", (long)actual); expected = OS_TIMER_ERR_INVALID_ARGS; - actual = OS_TimerAdd(&timer_id, "Timer",time_base_id , NULL, &arg); + actual = OS_TimerAdd(&timer_id, "Timer",time_base_id , NULL, NULL); UtAssert_True(actual == expected, "OS_TimerAdd() (%ld) == OS_TIMER_ERR_INVALID_ARGS", (long)actual); expected = OS_ERR_NAME_TAKEN; - actual = OS_TimerAdd(&timer_id, "Timer", time_base_id, test_func, &arg); + actual = OS_TimerAdd(&timer_id, "Timer", time_base_id, null_func, NULL); UtAssert_True(actual == expected, "OS_TimerAdd() (%ld) == OS_ERR_NAME_TAKEN", (long)actual); expected = OS_INVALID_POINTER; - actual = OS_TimerAdd(&timer_id, 0, time_base_id, test_func, &arg); + actual = OS_TimerAdd(&timer_id, 0, time_base_id, null_func, NULL); UtAssert_True(actual == expected, "OS_TimerAdd() (%ld) == OS_INVALID_POINTER", (long)actual);