From 7c512ec6a2f3b0f8c699d0eeed499fdb5de986f5 Mon Sep 17 00:00:00 2001 From: Chris Knight Date: Tue, 7 Apr 2020 08:08:46 -0700 Subject: [PATCH] fix #377 - select UT --- src/os/inc/osapi-os-core.h | 20 ++- src/os/shared/os-impl.h | 8 - src/os/shared/osapi-select.c | 74 +++++--- src/unit-tests/oscore-test/CMakeLists.txt | 1 + .../oscore-test/ut_oscore_select_test.c | 164 ++++++++++++++++++ .../oscore-test/ut_oscore_select_test.h | 46 +++++ src/unit-tests/oscore-test/ut_oscore_test.c | 4 + src/unit-tests/oscore-test/ut_oscore_test.h | 1 + 8 files changed, 286 insertions(+), 32 deletions(-) create mode 100644 src/unit-tests/oscore-test/ut_oscore_select_test.c create mode 100644 src/unit-tests/oscore-test/ut_oscore_select_test.h diff --git a/src/os/inc/osapi-os-core.h b/src/os/inc/osapi-os-core.h index d7df853d5..fe8e829a8 100644 --- a/src/os/inc/osapi-os-core.h +++ b/src/os/inc/osapi-os-core.h @@ -109,6 +109,20 @@ typedef struct uint32 largest_free_block; }OS_heap_prop_t; +/** + * @brief For the OS_SelectSingle() function's in/out StateFlags parameter, + * the state(s) of the stream and the result of the select is a combination + * of one or more of these states. + * + * @sa OS_SelectSingle() + */ +typedef enum +{ + OS_STREAM_STATE_BOUND = 0x01, /**< @brief whether the stream is bound */ + OS_STREAM_STATE_CONNECTED = 0x02, /**< @brief whether the stream is connected */ + OS_STREAM_STATE_READABLE = 0x04, /**< @brief whether the stream is readable */ + OS_STREAM_STATE_WRITABLE = 0x08, /**< @brief whether the stream is writable */ +} OS_StreamState_t; /* This typedef is for the OS_GetErrorName function, to ensure * everyone is making an array of the same length. @@ -1231,9 +1245,9 @@ int32 OS_SelectMultiple(OS_FdSet *ReadSet, OS_FdSet *WriteSet, int32 msecs); * * This function can be used to wait for a single OSAL stream ID * to become readable or writable. On entry, the "StateFlags" - * parameter should be set to the desired state (readble or writable) - * and upon return the flags will be set to the state actually - * detected. + * parameter should be set to the desired state (OS_STREAM_STATE_READABLE + * and/or OS_STREAM_STATE_WRITABLE) and upon return the flags + * will be set to the state actually detected. * * As this operates on a single ID, the filehandle is protected * during this call, such that another thread accessing the same diff --git a/src/os/shared/os-impl.h b/src/os/shared/os-impl.h index aba3434d6..d20b4b9f3 100644 --- a/src/os/shared/os-impl.h +++ b/src/os/shared/os-impl.h @@ -105,14 +105,6 @@ typedef struct uint16 flags; }OS_common_record_t; -typedef enum -{ - OS_STREAM_STATE_BOUND = 0x01, - OS_STREAM_STATE_CONNECTED = 0x02, - OS_STREAM_STATE_READABLE = 0x04, - OS_STREAM_STATE_WRITABLE = 0x08, -} OS_StreamState_t; - /*tasks */ typedef struct { diff --git a/src/os/shared/osapi-select.c b/src/os/shared/osapi-select.c index 983ff64c5..6c33ac70d 100644 --- a/src/os/shared/osapi-select.c +++ b/src/os/shared/osapi-select.c @@ -59,11 +59,18 @@ int32 OS_SelectSingle(uint32 objid, uint32 *StateFlags, int32 msecs) uint32 local_id; OS_common_record_t *record; - return_code = OS_ObjectIdGetById(OS_LOCK_MODE_REFCOUNT, OS_OBJECT_TYPE_OS_STREAM, objid, &local_id, &record); - if (return_code == OS_SUCCESS) + if(StateFlags == NULL) { - return_code = OS_SelectSingle_Impl(local_id, StateFlags, msecs); - OS_ObjectIdRefcountDecr(record); + return_code = OS_INVALID_POINTER; + } + else + { + return_code = OS_ObjectIdGetById(OS_LOCK_MODE_REFCOUNT, OS_OBJECT_TYPE_OS_STREAM, objid, &local_id, &record); + if (return_code == OS_SUCCESS) + { + return_code = OS_SelectSingle_Impl(local_id, StateFlags, msecs); + OS_ObjectIdRefcountDecr(record); + } } return return_code; @@ -102,8 +109,16 @@ int32 OS_SelectMultiple(OS_FdSet *ReadSet, OS_FdSet *WriteSet, int32 msecs) *-----------------------------------------------------------------*/ int32 OS_SelectFdZero(OS_FdSet *Set) { - memset(Set,0,sizeof(OS_FdSet)); - return OS_SUCCESS; + int32 return_code = OS_SUCCESS; + if (Set == NULL) + { + return_code = OS_INVALID_POINTER; + } + else + { + memset(Set,0,sizeof(OS_FdSet)); + } + return return_code; } /* end OS_SelectFdZero */ /*---------------------------------------------------------------- @@ -116,13 +131,20 @@ int32 OS_SelectFdZero(OS_FdSet *Set) *-----------------------------------------------------------------*/ int32 OS_SelectFdAdd(OS_FdSet *Set, uint32 objid) { - int32 return_code; + int32 return_code = OS_SUCCESS; uint32 local_id; - return_code = OS_ObjectIdToArrayIndex(OS_OBJECT_TYPE_OS_STREAM, objid, &local_id); - if (return_code == OS_SUCCESS) + if (Set == NULL) { - Set->object_ids[local_id >> 3] |= 1 << (local_id & 0x7); + return_code = OS_INVALID_POINTER; + } + else + { + return_code = OS_ObjectIdToArrayIndex(OS_OBJECT_TYPE_OS_STREAM, objid, &local_id); + if (return_code == OS_SUCCESS) + { + Set->object_ids[local_id >> 3] |= 1 << (local_id & 0x7); + } } return return_code; @@ -138,13 +160,20 @@ int32 OS_SelectFdAdd(OS_FdSet *Set, uint32 objid) *-----------------------------------------------------------------*/ int32 OS_SelectFdClear(OS_FdSet *Set, uint32 objid) { - int32 return_code; + int32 return_code = OS_SUCCESS; uint32 local_id; - return_code = OS_ObjectIdToArrayIndex(OS_OBJECT_TYPE_OS_STREAM, objid, &local_id); - if (return_code == OS_SUCCESS) + if (Set == NULL) + { + return_code = OS_INVALID_POINTER; + } + else { - Set->object_ids[local_id >> 3] &= ~(1 << (local_id & 0x7)); + return_code = OS_ObjectIdToArrayIndex(OS_OBJECT_TYPE_OS_STREAM, objid, &local_id); + if (return_code == OS_SUCCESS) + { + Set->object_ids[local_id >> 3] &= ~(1 << (local_id & 0x7)); + } } return return_code; @@ -160,16 +189,19 @@ int32 OS_SelectFdClear(OS_FdSet *Set, uint32 objid) *-----------------------------------------------------------------*/ bool OS_SelectFdIsSet(OS_FdSet *Set, uint32 objid) { - int32 return_code; - uint32 local_id; - - return_code = OS_ObjectIdToArrayIndex(OS_OBJECT_TYPE_OS_STREAM, objid, &local_id); - if (return_code != OS_SUCCESS) + if (Set != NULL) { - return false; + uint32 local_id; + int32 return_code = OS_ObjectIdToArrayIndex(OS_OBJECT_TYPE_OS_STREAM, objid, &local_id); + + if (return_code == OS_SUCCESS) + { + return ((Set->object_ids[local_id >> 3] >> (local_id & 0x7)) & 0x1); + } } - return ((Set->object_ids[local_id >> 3] >> (local_id & 0x7)) & 0x1); + /* error occurred (Set == NULL or ObjjectIdToArrayIndex returned error), return false */ + return false; } /* end OS_SelectFdIsSet */ diff --git a/src/unit-tests/oscore-test/CMakeLists.txt b/src/unit-tests/oscore-test/CMakeLists.txt index 0ed5ba38b..eea988489 100644 --- a/src/unit-tests/oscore-test/CMakeLists.txt +++ b/src/unit-tests/oscore-test/CMakeLists.txt @@ -4,6 +4,7 @@ set(TEST_MODULE_FILES ut_oscore_binsem_test.c ut_oscore_misc_test.c ut_oscore_queue_test.c + ut_oscore_select_test.c ut_oscore_countsem_test.c ut_oscore_mutex_test.c ut_oscore_task_test.c diff --git a/src/unit-tests/oscore-test/ut_oscore_select_test.c b/src/unit-tests/oscore-test/ut_oscore_select_test.c new file mode 100644 index 000000000..c69932147 --- /dev/null +++ b/src/unit-tests/oscore-test/ut_oscore_select_test.c @@ -0,0 +1,164 @@ +/*================================================================================* +** File: ut_oscore_select_test.c +** Owner: Chris Knight +** Date: March 2020 +**================================================================================*/ + +/*--------------------------------------------------------------------------------* +** Includes +**--------------------------------------------------------------------------------*/ + +#include "ut_oscore_select_test.h" + +/*--------------------------------------------------------------------------------* +** Macros +**--------------------------------------------------------------------------------*/ + +#define UT_SELECT_FN "/cf/select_test.tmp" + +/*--------------------------------------------------------------------------------* +** Data types +**--------------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------------* +** External global variables +**--------------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------------* +** Global variables +**--------------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------------* +** External function prototypes +**--------------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------------* +** Local function prototypes +**--------------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------------* +** Local function definitions +**--------------------------------------------------------------------------------*/ + +char *fsAddrPtr = NULL; +static int32 setup_file(void) +{ + OS_mkfs(fsAddrPtr, "/ramdev3", " ", 512, 20); + OS_mount("/ramdev3", "/drive3"); + return OS_creat("/drive3/select_test.txt", OS_READ_WRITE); +} + +static void teardown_file(int32 fd) +{ + OS_close(fd); + OS_remove("/drive3/select_test.txt"); + OS_unmount("/drive3"); + OS_rmfs("/ramdev3"); +} + +/*--------------------------------------------------------------------------------* +** Syntax: OS_SelectFdZero, OS_SelectFdAdd, OS_SelectFdClear, OS_SelectFdIsSet +** Purpose: Configure file descriptor set for select +** Parameters: To-be-filled-in +** Returns: OS_INVALID_POINTER if the pointer passed in is null +** OS_SUCCESS if succeeded +**--------------------------------------------------------------------------------*/ +void UT_os_select_fd_test(void) +{ + OS_FdSet FdSet; + int32 fd = setup_file(); + + if(OS_SelectFdZero(&FdSet) == OS_ERR_NOT_IMPLEMENTED + || OS_SelectFdAdd(&FdSet, fd) == OS_ERR_NOT_IMPLEMENTED + || OS_SelectFdClear(&FdSet, fd) == OS_ERR_NOT_IMPLEMENTED) + { + UtAssertEx(false, UTASSERT_CASETYPE_NA, __FILE__, __LINE__, "OS_SelectFd...() not implemented"); + goto UT_os_select_fd_test_exit_tag; + } + + UtAssert_Simple(OS_SelectFdZero(NULL) == OS_INVALID_POINTER); + UtAssert_Simple(OS_SelectFdAdd(NULL, 0) == OS_INVALID_POINTER); + UtAssert_Simple(OS_SelectFdClear(NULL, 0) == OS_INVALID_POINTER); + UtAssert_Simple(OS_SelectFdIsSet(NULL, 0) == false); + + OS_SelectFdZero(&FdSet); + OS_SelectFdAdd(&FdSet, fd); + UtAssert_Simple(OS_SelectFdIsSet(&FdSet, fd)); + + OS_SelectFdZero(&FdSet); + OS_SelectFdAdd(&FdSet, fd); + OS_SelectFdClear(&FdSet, fd); + UtAssert_Simple(!OS_SelectFdIsSet(&FdSet, fd)); + +UT_os_select_fd_test_exit_tag: + teardown_file(fd); +} + +/*--------------------------------------------------------------------------------* +** Syntax: int32 OS_SelectSingle(uint32 objid, uint32 *StateFlags, int32 msecs); +** Purpose: Select on a single file descriptor +** Parameters: To-be-filled-in +** Returns: OS_INVALID_POINTER if the pointer passed in is null +** OS_SUCCESS if succeeded +**--------------------------------------------------------------------------------*/ +void UT_os_select_single_test(void) +{ + uint32 StateFlags; + int32 fd = setup_file(); + + if(OS_SelectSingle(fd, &StateFlags, 0) == OS_ERR_NOT_IMPLEMENTED) + { + UtAssertEx(false, UTASSERT_CASETYPE_NA, __FILE__, __LINE__, "OS_SelectSingle() not implemented"); + goto UT_os_select_single_test_exit_tag; + } + + UtAssert_Simple(OS_SelectSingle(fd, NULL, 0) != OS_SUCCESS); + + StateFlags = OS_STREAM_STATE_WRITABLE; + UtAssert_Simple(OS_SelectSingle(fd, &StateFlags, 0) == OS_SUCCESS && StateFlags & OS_STREAM_STATE_WRITABLE); + + StateFlags = OS_STREAM_STATE_READABLE; + UtAssert_Simple(OS_SelectSingle(fd, &StateFlags, 1) == OS_SUCCESS); + +UT_os_select_single_test_exit_tag: + teardown_file(fd); +} + +/*--------------------------------------------------------------------------------* +** Syntax: int32 OS_SelectMultiple(OS_FdSet *ReadSet, OS_FdSet *WriteSet, int32 msecs) +** Purpose: Select on a multiple file descriptors +** Parameters: To-be-filled-in +** Returns: OS_INVALID_POINTER if the pointer passed in is null +** OS_SUCCESS if succeeded +**--------------------------------------------------------------------------------*/ +void UT_os_select_multi_test(void) +{ + OS_FdSet ReadSet, WriteSet; + int32 fd = setup_file(); + + if(OS_SelectMultiple(&ReadSet, &WriteSet, 1) == OS_ERR_NOT_IMPLEMENTED) + { + UtAssertEx(false, UTASSERT_CASETYPE_NA, __FILE__, __LINE__, "OS_SelectMultiple() not implemented"); + goto UT_select_multi_test_exit_tag; + } + + OS_SelectFdZero(&WriteSet); + OS_SelectFdAdd(&WriteSet, fd); + UtAssert_Simple(OS_SelectMultiple(NULL, &WriteSet, 1) == OS_SUCCESS); + + OS_SelectFdZero(&ReadSet); + OS_SelectFdAdd(&ReadSet, fd); + UtAssert_Simple(OS_SelectMultiple(&ReadSet, NULL, 1) == OS_SUCCESS); + + OS_SelectFdZero(&ReadSet); + OS_SelectFdAdd(&ReadSet, fd); + OS_SelectFdZero(&WriteSet); + UtAssert_Simple(OS_SelectMultiple(&ReadSet, &WriteSet, 0) == OS_SUCCESS); + +UT_select_multi_test_exit_tag: + teardown_file(fd); +} + +/*================================================================================* +** End of File: ut_oscore_queue_test.c +**================================================================================*/ diff --git a/src/unit-tests/oscore-test/ut_oscore_select_test.h b/src/unit-tests/oscore-test/ut_oscore_select_test.h new file mode 100644 index 000000000..0b41a3162 --- /dev/null +++ b/src/unit-tests/oscore-test/ut_oscore_select_test.h @@ -0,0 +1,46 @@ +/*================================================================================* +** File: ut_oscore_select_test.h +** Owner: Chris Knight +** Date: March 2020 +**================================================================================*/ + +#ifndef _UT_OSCORE_SELECT_TEST_H_ +#define _UT_OSCORE_SELECT_TEST_H_ + +/*--------------------------------------------------------------------------------* +** Includes +**--------------------------------------------------------------------------------*/ + +#include "ut_os_support.h" + +/*--------------------------------------------------------------------------------* +** Macros +**--------------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------------* +** Data types +**--------------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------------* +** External global variables +**--------------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------------* +** Global variables +**--------------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------------* +** Function prototypes +**--------------------------------------------------------------------------------*/ + +void UT_os_select_fd_test(void); +void UT_os_select_single_test(void); +void UT_os_select_multi_test(void); + +/*--------------------------------------------------------------------------------*/ + +#endif /* _UT_OSCORE_SELECT_TEST_H_ */ + +/*================================================================================* +** End of File: ut_oscore_select_test.h +**================================================================================*/ diff --git a/src/unit-tests/oscore-test/ut_oscore_test.c b/src/unit-tests/oscore-test/ut_oscore_test.c index 6b7b75ae7..dd912aad7 100644 --- a/src/unit-tests/oscore-test/ut_oscore_test.c +++ b/src/unit-tests/oscore-test/ut_oscore_test.c @@ -205,6 +205,10 @@ void UtTest_Setup(void) UtTest_Add(UT_os_queue_get_id_by_name_test, NULL, NULL, "OS_QueueGetIdByName"); UtTest_Add(UT_os_queue_get_info_test, NULL, NULL, "OS_QueueGetInfo"); + UtTest_Add(UT_os_select_fd_test, NULL, NULL, "OS_SelectFd"); + UtTest_Add(UT_os_select_single_test, NULL, NULL, "OS_SelectSingle"); + UtTest_Add(UT_os_select_multi_test, NULL, NULL, "OS_SelectMultiple"); + UtTest_Add( NULL, UT_os_init_task_misc, diff --git a/src/unit-tests/oscore-test/ut_oscore_test.h b/src/unit-tests/oscore-test/ut_oscore_test.h index 14d790ca2..f7a2598f3 100644 --- a/src/unit-tests/oscore-test/ut_oscore_test.h +++ b/src/unit-tests/oscore-test/ut_oscore_test.h @@ -17,6 +17,7 @@ #include "ut_oscore_countsem_test.h" #include "ut_oscore_mutex_test.h" #include "ut_oscore_queue_test.h" +#include "ut_oscore_select_test.h" #include "ut_oscore_task_test.h" #include "ut_oscore_interrupt_test.h" #include "ut_oscore_exception_test.h"