Adding posix mutex and timers and x509 cred header (#2537)

* Platform expansion, mutex and timer

* Adding x509 cred

* CODEOWNERS edit

* Removing az_credentials_x509 for now

* removing user from codeowners

* Addressing comments p1

* Renaming

* Formatting revision

* Adding linux check in az_posix

* CODEOWNERS update

* Adding pthreads to VS2022 yml

* Adding pthreads to vcpkg default

* Cmake edit

* Undoing yaml changes

* Fix for builds, and address ret val comment

* lint correction

* Fixing MacOS build, adding more documentation

* CMake edit for Mac

* Disabling mutex and timer IT for macos

* Minor fix

* Quick fix

* Fixing doxygen

* Naming corrections

* formatting corrections
This commit is contained in:
Raul Leclair 2023-05-02 11:41:09 -07:00 коммит произвёл GitHub
Родитель da026eb313
Коммит 037766994f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
16 изменённых файлов: 977 добавлений и 14 удалений

14
.github/CODEOWNERS поставляемый
Просмотреть файл

@ -23,14 +23,16 @@
/sdk/tests/core/ @ahsonkhan @antkmsft @rickwinter @vhvb1989 @gearama @LarryOsterman
# IoT
/sdk/docs/iot/ @CIPop @ericwol-msft @ewertons @jspaith @preethi826 @RLeclair @vaavva
/sdk/inc/azure/iot/ @CIPop @ericwol-msft @ewertons @jspaith @preethi826 @RLeclair @vaavva
/sdk/samples/iot/ @CIPop @ericwol-msft @ewertons @jspaith @preethi826 @RLeclair @vaavva
/sdk/src/azure/iot/ @CIPop @ericwol-msft @ewertons @jspaith @preethi826 @RLeclair @vaavva
/sdk/tests/iot/ @CIPop @ericwol-msft @ewertons @jspaith @preethi826 @RLeclair @vaavva
/sdk/docs/iot/ @CIPop @ericwol-msft @ewertons @jspaith @RLeclair @vaavva
/sdk/inc/azure/iot/ @CIPop @ericwol-msft @ewertons @jspaith @RLeclair @vaavva
/sdk/samples/iot/ @CIPop @ericwol-msft @ewertons @jspaith @RLeclair @vaavva
/sdk/src/azure/iot/ @CIPop @ericwol-msft @ewertons @jspaith @RLeclair @vaavva
/sdk/tests/iot/ @CIPop @ericwol-msft @ewertons @jspaith @RLeclair @vaavva
# Platform
/sdk/src/azure/platform/ @ahsonkhan @antkmsft @rickwinter @vhvb1989 @gearama @LarryOsterman
/sdk/inc/azure/platform/ @CIPop @ericwol-msft @ewertons @jspaith @RLeclair @vaavva
/sdk/src/azure/platform/ @ahsonkhan @antkmsft @rickwinter @vhvb1989 @gearama @LarryOsterman @CIPop @ericwol-msft @ewertons @jspaith @RLeclair @vaavva
/sdk/tests/platform/ @CIPop @ericwol-msft @ewertons @jspaith @RLeclair @vaavva
################
# Automation

Просмотреть файл

@ -13,6 +13,7 @@ option(TRANSPORT_PAHO "Build IoT Samples with Paho MQTT support" OFF)
option(PRECONDITIONS "Build SDK with preconditions enabled" ON)
option(LOGGING "Build SDK with logging support" ON)
option(ADDRESS_SANITIZER "Build with address sanitizer" OFF)
set(AZ_PLATFORM_IMPL "" CACHE STRING "Platform implementation to use. Options are: WIN32, POSIX, CUSTOM")
# vcpkg integration
include(AzureVcpkg)
@ -55,8 +56,10 @@ file(WRITE ${CMAKE_BINARY_DIR}/coverage_targets.txt "")
# Determine platform to build
if(AZ_PLATFORM_IMPL STREQUAL "WIN32")
set(PAL az_win32)
add_compile_definitions(PLATFORM_WIN32)
elseif(AZ_PLATFORM_IMPL STREQUAL "POSIX")
set(PAL az_posix)
add_compile_definitions(PLATFORM_POSIX)
elseif(AZ_PLATFORM_IMPL STREQUAL "CUSTOM")
if(NOT DEFINED AZ_CUSTOM_PLATFORM_IMPL_NAME)
message(FATAL_ERROR "When using AZ_PLATFORM_IMPL=CUSTOM, AZ_CUSTOM_PLATFORM_IMPL_NAME must be defined as well. See Readme.")
@ -110,6 +113,11 @@ if (UNIT_TESTING)
add_subdirectory(sdk/tests/iot/hub)
add_subdirectory(sdk/tests/iot/provisioning)
# Platform
if(AZ_PLATFORM_IMPL STREQUAL "POSIX")
add_subdirectory(sdk/tests/platform)
endif()
endif()
# Fail generation when setting MOCKS ON without GCC

Просмотреть файл

@ -16,9 +16,18 @@
#define _az_PLATFORM_H
#include <azure/core/az_result.h>
#ifndef __APPLE__
#include <azure/platform/internal/az_platform_internal.h>
#endif
#include <stdbool.h>
#include <stdint.h>
#if defined(PLATFORM_POSIX)
#include "azure/platform/az_platform_posix.h"
#elif defined(PLATFORM_WIN32)
#include "azure/platform/az_platform_win32.h"
#else
#include "azure/platform/az_platform_none.h"
#endif
#include <azure/core/_az_cfg_prefix.h>
@ -53,6 +62,134 @@ AZ_NODISCARD az_result az_platform_clock_msec(int64_t* out_clock_msec);
*/
AZ_NODISCARD az_result az_platform_sleep_msec(int32_t milliseconds);
/**
* @brief Gets a positive pseudo-random integer.
*
* @param[out] out_random A pseudo-random number greater than or equal to 0.
*
* @retval #AZ_OK Success.
* @retval #AZ_ERROR_DEPENDENCY_NOT_PROVIDED No platform implementation was supplied to support this
* function.
*
* @note This is NOT cryptographically secure.
*/
AZ_NODISCARD az_result az_platform_get_random(int32_t* out_random);
#ifndef __APPLE__
/**
* @brief Called on critical error. This function should not return.
*
* @note Must be defined by the application.
*
* @details In general, this function should cause the device to reboot or the main process to
* crash or exit.
*/
void az_platform_critical_error();
/**
* @brief Create a timer object.
*
* @param[out] out_timer The timer handle.
* @param[in] callback SDK callback to call when timer elapses.
* @param[in] callback_context SDK data associated with the timer.
*
* @return An #az_result value indicating the result of the operation.
* @retval #AZ_OK Success.
* @retval #AZ_ERROR_DEPENDENCY_NOT_PROVIDED No platform implementation was supplied to support this
* function.
* @retval #AZ_ERROR_OUT_OF_MEMORY Out of memory, unable to allocate timer.
* @retval #AZ_ERROR_ARG Invalid argument.
*/
AZ_NODISCARD az_result az_platform_timer_create(
_az_platform_timer* out_timer,
_az_platform_timer_callback callback,
void* callback_context);
/**
* @brief Starts the timer. This function can be called multiple times. The timer should call the
* callback at most once.
*
* @param[out] out_timer The timer handle.
* @param[in] milliseconds Time in milliseconds after which the platform must call the associated
* _az_platform_timer_callback().
*
* @return An #az_result value indicating the result of the operation.
* @retval #AZ_OK Success.
* @retval #AZ_ERROR_DEPENDENCY_NOT_PROVIDED No platform implementation was supplied to support this
* function.
* @retval #AZ_ERROR_ARG Invalid milliseconds.
*/
AZ_NODISCARD az_result az_platform_timer_start(_az_platform_timer* out_timer, int32_t milliseconds);
/**
* @brief Destroys a timer.
*
* @param[out] out_timer The timer handle.
*
* @return An #az_result value indicating the result of the operation.
* @retval #AZ_OK Success.
* @retval #AZ_ERROR_DEPENDENCY_NOT_PROVIDED No platform implementation was supplied to support this
* function.
* @retval #AZ_ERROR_ARG Invalid timer provided.
*/
AZ_NODISCARD az_result az_platform_timer_destroy(_az_platform_timer* out_timer);
/**
* @brief Initializes a mutex, the mutex must be reentrant.
*
* @param[in] mutex_handle The mutex handle.
*
* @return An #az_result value indicating the result of the operation.
* @retval #AZ_OK Success.
* @retval #AZ_ERROR_DEPENDENCY_NOT_PROVIDED No platform implementation was supplied to support this
* function.
* @retval #AZ_ERROR_OUT_OF_MEMORY Out of memory, unable to initialize mutex.
* @retval #AZ_ERROR_ARG Invalid argument.
*/
AZ_NODISCARD az_result az_platform_mutex_init(az_platform_mutex* mutex_handle);
/**
* @brief Acquires a mutex.
*
* @param[in] mutex_handle The mutex handle.
*
* @return An #az_result value indicating the result of the operation.
* @retval #AZ_OK success.
* @retval #AZ_ERROR_DEPENDENCY_NOT_PROVIDED No platform implementation was supplied to support this
* function.
* @retval #AZ_ERROR_ARG Invalid argument.
*/
AZ_NODISCARD az_result az_platform_mutex_acquire(az_platform_mutex* mutex_handle);
/**
* @brief Releases a mutex.
*
* @param[in] mutex_handle The mutex handle.
*
* @return An #az_result value indicating the result of the operation.
* @retval #AZ_OK success.
* @retval #AZ_ERROR_DEPENDENCY_NOT_PROVIDED No platform implementation was supplied to support this
* function.
* @retval #AZ_ERROR_ARG Invalid argument.
*/
AZ_NODISCARD az_result az_platform_mutex_release(az_platform_mutex* mutex_handle);
/**
* @brief Destroys a mutex.
*
* @param[in] mutex_handle The mutex handle.
*
* @return An #az_result value indicating the result of the operation.
* @retval #AZ_OK success.
* @retval #AZ_ERROR_DEPENDENCY_NOT_PROVIDED No platform implementation was supplied to support this
* function.
* @retval #AZ_ERROR_ARG Invalid argument.
*/
AZ_NODISCARD az_result az_platform_mutex_destroy(az_platform_mutex* mutex_handle);
#endif // __APPLE__
#include <azure/core/_az_cfg_suffix.h>
#endif // _az_PLATFORM_H

Просмотреть файл

@ -27,6 +27,7 @@ enum
_az_TIME_SECONDS_PER_MINUTE = 60,
_az_TIME_MILLISECONDS_PER_SECOND = 1000,
_az_TIME_MICROSECONDS_PER_MILLISECOND = 1000,
_az_TIME_NANOSECONDS_PER_MILLISECOND = 1000000,
};
/*

Просмотреть файл

@ -0,0 +1,38 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @file
*
* @brief Defines platform constructs when no platform is specified.
*
* @note You MUST NOT use any symbols (macros, functions, structures, enums, etc.)
* prefixed with an underscore ('_') directly in your application code. These symbols
* are part of Azure SDK's internal implementation; we do not document these symbols
* and they are subject to change in future versions of the SDK which would break your code.
*/
#ifndef _az_PLATFORM_NONE_H
#define _az_PLATFORM_NONE_H
#include <azure/platform/internal/az_platform_internal.h>
#include <azure/core/_az_cfg_prefix.h>
typedef struct
{
struct
{
_az_platform_timer_common platform_timer;
} _internal;
} _az_platform_timer;
/**
* @brief Platform mutex type.
*/
typedef void* az_platform_mutex;
#include <azure/core/_az_cfg_suffix.h>
#endif // _az_PLATFORM_NONE_H

Просмотреть файл

@ -0,0 +1,47 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @file
*
* @brief Defines platform constructs for POSIX.
*
* @note You MUST NOT use any symbols (macros, functions, structures, enums, etc.)
* prefixed with an underscore ('_') directly in your application code. These symbols
* are part of Azure SDK's internal implementation; we do not document these symbols
* and they are subject to change in future versions of the SDK which would break your code.
*/
#ifndef _az_PLATFORM_POSIX_H
#define _az_PLATFORM_POSIX_H
#ifndef __APPLE__
#include <azure/platform/internal/az_platform_internal.h>
#include <pthread.h>
#include <signal.h>
#include <time.h>
#include <azure/core/_az_cfg_prefix.h>
typedef struct
{
struct
{
_az_platform_timer_common platform_timer;
timer_t timerid;
struct sigevent sev;
struct itimerspec trigger;
} _internal;
} _az_platform_timer;
/**
* @brief Platform mutex type.
*/
typedef pthread_mutex_t az_platform_mutex;
#include <azure/core/_az_cfg_suffix.h>
#endif // __APPLE__
#endif // _az_PLATFORM_POSIX_H

Просмотреть файл

@ -0,0 +1,38 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @file
*
* @brief Defines platform constructs when no platform is specified.
*
* @note You MUST NOT use any symbols (macros, functions, structures, enums, etc.)
* prefixed with an underscore ('_') directly in your application code. These symbols
* are part of Azure SDK's internal implementation; we do not document these symbols
* and they are subject to change in future versions of the SDK which would break your code.
*/
#ifndef _az_PLATFORM_WIN32_H
#define _az_PLATFORM_WIN32_H
#include <azure/platform/internal/az_platform_internal.h>
#include <azure/core/_az_cfg_prefix.h>
typedef struct
{
struct
{
_az_platform_timer_common platform_timer;
} _internal;
} _az_platform_timer;
/**
* @brief Platform mutex type.
*/
typedef void* az_platform_mutex;
#include <azure/core/_az_cfg_suffix.h>
#endif // _az_PLATFORM_WIN32_H

Просмотреть файл

@ -0,0 +1,44 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @file
*
* @brief Defines platform internals that are used across other platforms.
*
* @note You MUST NOT use any symbols (macros, functions, structures, enums, etc.)
* prefixed with an underscore ('_') directly in your application code. These symbols
* are part of Azure SDK's internal implementation; we do not document these symbols
* and they are subject to change in future versions of the SDK which would break your code.
*/
#ifndef _az_PLATFORM_INTERNAL_H
#define _az_PLATFORM_INTERNAL_H
#include <azure/core/_az_cfg_prefix.h>
/**
* @brief Timer callback.
*
* @details Function may be re-entered by timer callback, locks must be used if re-entrancy is
* not desired.
*
* @param[in] callback_context Data passed by the SDK during the #az_platform_timer_create call.
*/
typedef void (*_az_platform_timer_callback)(void* callback_context);
/**
* @brief Common timer struct. Contains pointer to callback and data pointer.
*/
typedef struct
{
struct
{
_az_platform_timer_callback callback;
void* callback_context;
} _internal;
} _az_platform_timer_common;
#include <azure/core/_az_cfg_suffix.h>
#endif // _az_PLATFORM_INTERNAL_H

Просмотреть файл

@ -22,10 +22,19 @@ elseif(AZ_PLATFORM_IMPL STREQUAL "POSIX")
${CMAKE_CURRENT_LIST_DIR}/az_posix.c
)
target_link_libraries(az_posix
PRIVATE
az_core
)
if (NOT APPLE)
target_link_libraries(az_posix
PRIVATE
az_core
-lrt
-pthread
)
else()
target_link_libraries(az_posix
PRIVATE
az_core
)
endif()
else()
#noplatform
add_library(az_noplatform STATIC

Просмотреть файл

@ -18,3 +18,65 @@ AZ_NODISCARD az_result az_platform_sleep_msec(int32_t milliseconds)
(void)milliseconds;
return AZ_ERROR_DEPENDENCY_NOT_PROVIDED;
}
AZ_NODISCARD az_result az_platform_get_random(int32_t* out_random)
{
_az_PRECONDITION_NOT_NULL(out_random);
*out_random = 0;
return AZ_ERROR_DEPENDENCY_NOT_PROVIDED;
}
AZ_NODISCARD az_result az_platform_timer_create(
_az_platform_timer* out_timer,
_az_platform_timer_callback callback,
void* callback_context)
{
(void)out_timer;
(void)callback;
(void)callback_context;
return AZ_ERROR_DEPENDENCY_NOT_PROVIDED;
}
AZ_NODISCARD az_result az_platform_timer_start(_az_platform_timer* out_timer, int32_t milliseconds)
{
(void)out_timer;
(void)milliseconds;
return AZ_ERROR_DEPENDENCY_NOT_PROVIDED;
}
AZ_NODISCARD az_result az_platform_timer_destroy(_az_platform_timer* out_timer)
{
(void)out_timer;
return AZ_ERROR_DEPENDENCY_NOT_PROVIDED;
}
AZ_NODISCARD az_result az_platform_mutex_init(az_platform_mutex* mutex_handle)
{
(void)mutex_handle;
return AZ_ERROR_DEPENDENCY_NOT_PROVIDED;
}
AZ_NODISCARD az_result az_platform_mutex_acquire(az_platform_mutex* mutex_handle)
{
(void)mutex_handle;
return AZ_ERROR_DEPENDENCY_NOT_PROVIDED;
}
AZ_NODISCARD az_result az_platform_mutex_release(az_platform_mutex* mutex_handle)
{
(void)mutex_handle;
return AZ_ERROR_DEPENDENCY_NOT_PROVIDED;
}
AZ_NODISCARD az_result az_platform_mutex_destroy(az_platform_mutex* mutex_handle)
{
(void)mutex_handle;
return AZ_ERROR_DEPENDENCY_NOT_PROVIDED;
}

Просмотреть файл

@ -5,18 +5,53 @@
#include <azure/core/internal/az_config_internal.h>
#include <azure/core/internal/az_precondition_internal.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <azure/core/_az_cfg.h>
#ifdef __linux__
#define _az_PLATFORM_POSIX_CLOCK_ID CLOCK_BOOTTIME
#else
#define _az_PLATFORM_POSIX_CLOCK_ID CLOCK_MONOTONIC
#endif
#ifndef __APPLE__
static void _timer_callback_handler(union sigval sv)
{
_az_platform_timer* out_timer = sv.sival_ptr;
_az_PRECONDITION_NOT_NULL(out_timer);
_az_PRECONDITION_NOT_NULL(out_timer->_internal.platform_timer._internal.callback);
out_timer->_internal.platform_timer._internal.callback(
out_timer->_internal.platform_timer._internal.callback_context);
}
#endif // __APPLE__
AZ_NODISCARD az_result az_platform_clock_msec(int64_t* out_clock_msec)
{
_az_PRECONDITION_NOT_NULL(out_clock_msec);
struct timespec curr_time;
// NOLINTNEXTLINE(bugprone-misplaced-widening-cast)
*out_clock_msec = (int64_t)((clock() / CLOCKS_PER_SEC) * _az_TIME_MILLISECONDS_PER_SECOND);
if (clock_getres(_az_PLATFORM_POSIX_CLOCK_ID, &curr_time)
== 0) // Check if high-res timer is available
{
clock_gettime(_az_PLATFORM_POSIX_CLOCK_ID, &curr_time);
*out_clock_msec = ((int64_t)curr_time.tv_sec * _az_TIME_MILLISECONDS_PER_SECOND)
+ ((int64_t)curr_time.tv_nsec / _az_TIME_NANOSECONDS_PER_MILLISECOND);
}
else
{
// NOLINTNEXTLINE(bugprone-misplaced-widening-cast)
*out_clock_msec = (int64_t)((time(NULL)) * _az_TIME_MILLISECONDS_PER_SECOND);
}
return AZ_OK;
}
@ -26,3 +61,136 @@ AZ_NODISCARD az_result az_platform_sleep_msec(int32_t milliseconds)
(void)usleep((useconds_t)milliseconds * _az_TIME_MICROSECONDS_PER_MILLISECOND);
return AZ_OK;
}
AZ_NODISCARD az_result az_platform_get_random(int32_t* out_random)
{
_az_PRECONDITION_NOT_NULL(out_random);
*out_random = (int32_t)random();
return AZ_OK;
}
#ifndef __APPLE__
AZ_NODISCARD az_result az_platform_timer_create(
_az_platform_timer* out_timer,
_az_platform_timer_callback callback,
void* callback_context)
{
_az_PRECONDITION_NOT_NULL(out_timer);
_az_PRECONDITION_NOT_NULL(callback);
// NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)
memset(out_timer, 0, sizeof(_az_platform_timer));
out_timer->_internal.platform_timer._internal.callback = callback;
out_timer->_internal.platform_timer._internal.callback_context = callback_context;
out_timer->_internal.sev.sigev_notify = SIGEV_THREAD;
out_timer->_internal.sev.sigev_notify_function = &_timer_callback_handler;
out_timer->_internal.sev.sigev_value.sival_ptr = out_timer;
if (0
!= timer_create(
_az_PLATFORM_POSIX_CLOCK_ID, &out_timer->_internal.sev, &out_timer->_internal.timerid))
{
if (ENOMEM == errno)
{
return AZ_ERROR_OUT_OF_MEMORY;
}
else
{
return AZ_ERROR_ARG;
}
}
return AZ_OK;
}
AZ_NODISCARD az_result az_platform_timer_start(_az_platform_timer* out_timer, int32_t milliseconds)
{
_az_PRECONDITION_NOT_NULL(out_timer);
out_timer->_internal.trigger.it_value.tv_sec = milliseconds / _az_TIME_MILLISECONDS_PER_SECOND;
out_timer->_internal.trigger.it_value.tv_nsec
= (milliseconds % _az_TIME_MILLISECONDS_PER_SECOND) * _az_TIME_NANOSECONDS_PER_MILLISECOND;
if (0 != timer_settime(out_timer->_internal.timerid, 0, &out_timer->_internal.trigger, NULL))
{
return AZ_ERROR_ARG;
}
return AZ_OK;
}
AZ_NODISCARD az_result az_platform_timer_destroy(_az_platform_timer* out_timer)
{
_az_PRECONDITION_NOT_NULL(out_timer);
if (0 != timer_delete(out_timer->_internal.timerid))
{
return AZ_ERROR_ARG;
}
return AZ_OK;
}
AZ_NODISCARD az_result az_platform_mutex_init(az_platform_mutex* mutex_handle)
{
_az_PRECONDITION_NOT_NULL(mutex_handle);
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
int mutex_init_result = pthread_mutex_init(mutex_handle, &attr);
if (ENOMEM == mutex_init_result)
{
return AZ_ERROR_OUT_OF_MEMORY;
}
else if (0 != mutex_init_result)
{
return AZ_ERROR_ARG;
}
return AZ_OK;
}
AZ_NODISCARD az_result az_platform_mutex_acquire(az_platform_mutex* mutex_handle)
{
_az_PRECONDITION_NOT_NULL(mutex_handle);
if (0 != pthread_mutex_lock(mutex_handle))
{
return AZ_ERROR_ARG;
}
return AZ_OK;
}
AZ_NODISCARD az_result az_platform_mutex_release(az_platform_mutex* mutex_handle)
{
_az_PRECONDITION_NOT_NULL(mutex_handle);
if (0 != pthread_mutex_unlock(mutex_handle))
{
return AZ_ERROR_ARG;
}
return AZ_OK;
}
AZ_NODISCARD az_result az_platform_mutex_destroy(az_platform_mutex* mutex_handle)
{
_az_PRECONDITION_NOT_NULL(mutex_handle);
if (0 != pthread_mutex_destroy(mutex_handle))
{
return AZ_ERROR_ARG;
}
return AZ_OK;
}
#endif // __APPLE__

Просмотреть файл

@ -23,3 +23,65 @@ AZ_NODISCARD az_result az_platform_sleep_msec(int32_t milliseconds)
Sleep(milliseconds);
return AZ_OK;
}
AZ_NODISCARD az_result az_platform_get_random(int32_t* out_random)
{
_az_PRECONDITION_NOT_NULL(out_random);
*out_random = 0;
return AZ_ERROR_DEPENDENCY_NOT_PROVIDED;
}
AZ_NODISCARD az_result az_platform_timer_create(
_az_platform_timer* out_timer,
_az_platform_timer_callback callback,
void* callback_context)
{
(void)out_timer;
(void)callback;
(void)callback_context;
return AZ_ERROR_DEPENDENCY_NOT_PROVIDED;
}
AZ_NODISCARD az_result az_platform_timer_start(_az_platform_timer* out_timer, int32_t milliseconds)
{
(void)out_timer;
(void)milliseconds;
return AZ_ERROR_DEPENDENCY_NOT_PROVIDED;
}
AZ_NODISCARD az_result az_platform_timer_destroy(_az_platform_timer* out_timer)
{
(void)out_timer;
return AZ_ERROR_DEPENDENCY_NOT_PROVIDED;
}
AZ_NODISCARD az_result az_platform_mutex_init(az_platform_mutex* mutex_handle)
{
(void)mutex_handle;
return AZ_ERROR_DEPENDENCY_NOT_PROVIDED;
}
AZ_NODISCARD az_result az_platform_mutex_acquire(az_platform_mutex* mutex_handle)
{
(void)mutex_handle;
return AZ_ERROR_DEPENDENCY_NOT_PROVIDED;
}
AZ_NODISCARD az_result az_platform_mutex_release(az_platform_mutex* mutex_handle)
{
(void)mutex_handle;
return AZ_ERROR_DEPENDENCY_NOT_PROVIDED;
}
AZ_NODISCARD az_result az_platform_mutex_destroy(az_platform_mutex* mutex_handle)
{
(void)mutex_handle;
return AZ_ERROR_DEPENDENCY_NOT_PROVIDED;
}

Просмотреть файл

@ -0,0 +1,23 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# SPDX-License-Identifier: MIT
cmake_minimum_required (VERSION 3.10)
project (az_platform_test LANGUAGES C)
set(CMAKE_C_STANDARD 99)
include(AddCMockaTest)
add_cmocka_test(az_platform_test SOURCES
main.c
test_az_platform.c
COMPILE_OPTIONS ${DEFAULT_C_COMPILE_FLAGS} ${NO_CLOBBERED_WARNING}
LINK_LIBRARIES ${CMOCKA_LIB} az_core
# include cmocka headers and private folder headers
INCLUDE_DIRECTORIES ${CMOCKA_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/sdk/src/azure/core/
)
create_map_file(az_platform_test az_platform_test.map)
add_cmocka_test_environment(az_platform_test)

Просмотреть файл

@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
int test_az_platform();

23
sdk/tests/platform/main.c Normal file
Просмотреть файл

@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
#include <stdlib.h>
#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <cmocka.h>
#include "az_test_definitions.h"
int main()
{
int result = 0;
// every test function returns the number of tests failed, 0 means success (there shouldn't be
// negative numbers
result += test_az_platform();
return result;
}

Просмотреть файл

@ -0,0 +1,297 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
#include "az_test_definitions.h"
#include <az_test_precondition.h>
#include <azure/core/az_platform.h>
#include <azure/core/az_result.h>
#include <azure/core/internal/az_config_internal.h>
#include <azure/core/internal/az_precondition_internal.h>
#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
#include <cmocka.h>
#define RANDOM_TRIES 100
#define TEST_MILLISECOND_TIME 10
#ifndef __APPLE__
static int test_timer_callback_counter = 0;
// Will record the time at which the callback was called
static void _test_az_platform_timer_callback_set_time(void* callback_context)
{
test_timer_callback_counter++;
assert_int_equal(az_platform_clock_msec((int64_t*)callback_context), AZ_OK);
}
#endif // __APPLE__
#ifndef AZ_NO_PRECONDITION_CHECKING
ENABLE_PRECONDITION_CHECK_TESTS()
#endif // AZ_NO_PRECONDITION_CHECKING
// Checking for preconditions
#ifndef AZ_NO_PRECONDITION_CHECKING
static void test_az_platform_clock_msec_null(void** state)
{
SETUP_PRECONDITION_CHECK_TESTS();
(void)state;
ASSERT_PRECONDITION_CHECKED(az_platform_clock_msec(NULL));
}
static void test_az_platform_get_random_null(void** state)
{
SETUP_PRECONDITION_CHECK_TESTS();
(void)state;
ASSERT_PRECONDITION_CHECKED(az_platform_get_random(NULL));
}
#ifndef __APPLE__
static void test_az_platform_timer_create_null(void** state)
{
SETUP_PRECONDITION_CHECK_TESTS();
(void)state;
ASSERT_PRECONDITION_CHECKED(az_platform_timer_create(NULL, NULL, NULL));
}
static void test_az_platform_timer_start_null(void** state)
{
SETUP_PRECONDITION_CHECK_TESTS();
(void)state;
ASSERT_PRECONDITION_CHECKED(az_platform_timer_start(NULL, 0));
}
static void test_az_platform_timer_destroy_null(void** state)
{
SETUP_PRECONDITION_CHECK_TESTS();
(void)state;
ASSERT_PRECONDITION_CHECKED(az_platform_timer_destroy(NULL));
}
static void test_az_platform_mutex_init_null(void** state)
{
SETUP_PRECONDITION_CHECK_TESTS();
(void)state;
ASSERT_PRECONDITION_CHECKED(az_platform_mutex_init(NULL));
}
static void test_az_platform_mutex_acquire_null(void** state)
{
SETUP_PRECONDITION_CHECK_TESTS();
(void)state;
ASSERT_PRECONDITION_CHECKED(az_platform_mutex_acquire(NULL));
}
static void test_az_platform_mutex_release_null(void** state)
{
SETUP_PRECONDITION_CHECK_TESTS();
(void)state;
ASSERT_PRECONDITION_CHECKED(az_platform_mutex_release(NULL));
}
static void test_az_platform_mutex_destroy_null(void** state)
{
SETUP_PRECONDITION_CHECK_TESTS();
(void)state;
ASSERT_PRECONDITION_CHECKED(az_platform_mutex_destroy(NULL));
}
#endif // __APPLE__
#endif // AZ_NO_PRECONDITION_CHECKING
static void test_az_platform_clock_msec_once(void** state)
{
(void)state;
int64_t test_clock = 0;
assert_int_equal(az_platform_clock_msec(&test_clock), AZ_OK);
assert_true(test_clock >= 0);
}
static void test_az_platform_sleep_msec(void** state)
{
(void)state;
int64_t test_clock_one = 0; // Time before sleep.
int64_t test_clock_two = 0; // Time after sleep.
assert_int_equal(az_platform_clock_msec(&test_clock_one), AZ_OK);
assert_int_equal(az_platform_sleep_msec(TEST_MILLISECOND_TIME), AZ_OK);
assert_int_equal(az_platform_clock_msec(&test_clock_two), AZ_OK);
assert_int_not_equal(test_clock_one, 0);
assert_int_not_equal(test_clock_two, 0);
assert_true((test_clock_two - test_clock_one) >= TEST_MILLISECOND_TIME);
}
static void test_az_platform_get_random(void** state)
{
(void)state;
int32_t test_random_1 = 0;
int32_t test_random_2 = 0;
assert_int_equal(az_platform_get_random(&test_random_1), AZ_OK);
assert_int_equal(az_platform_get_random(&test_random_2), AZ_OK);
assert_true(test_random_1 > -1);
assert_true(test_random_2 > -1);
int i = 0;
while ((test_random_1 == test_random_2) && i < RANDOM_TRIES)
{
assert_int_equal(az_platform_get_random(&test_random_2), AZ_OK);
assert_true(test_random_2 > -1);
i++;
}
assert_true(test_random_2 != test_random_1);
}
#ifndef __APPLE__
static void test_az_platform_timer_single(void** state)
{
(void)state;
_az_platform_timer test_out_timer;
int64_t test_clock_one = 0; // Time before timer start.
int64_t test_clock_two = 0; // Time after timer callback.
test_timer_callback_counter = 0;
assert_int_equal(
az_platform_timer_create(
&test_out_timer, _test_az_platform_timer_callback_set_time, &test_clock_two),
AZ_OK);
assert_int_equal(az_platform_clock_msec(&test_clock_one), AZ_OK);
assert_int_equal(az_platform_timer_start(&test_out_timer, TEST_MILLISECOND_TIME), AZ_OK);
// Sleep until callback is triggered
assert_int_equal(az_platform_sleep_msec(2 * TEST_MILLISECOND_TIME), AZ_OK);
assert_int_equal(test_timer_callback_counter, 1);
assert_int_not_equal(test_clock_one, 0);
assert_int_not_equal(test_clock_two, 0);
assert_true((test_clock_two - test_clock_one) >= TEST_MILLISECOND_TIME);
assert_int_equal(az_platform_timer_destroy(&test_out_timer), AZ_OK);
}
static void test_az_platform_timer_double(void** state)
{
(void)state;
_az_platform_timer test_out_timer_1;
_az_platform_timer test_out_timer_2;
int64_t test_clock_one = 0;
int64_t test_clock_two = 0;
test_timer_callback_counter = 0;
assert_int_equal(
az_platform_timer_create(
&test_out_timer_1, _test_az_platform_timer_callback_set_time, &test_clock_one),
AZ_OK);
assert_int_equal(
az_platform_timer_create(
&test_out_timer_2, _test_az_platform_timer_callback_set_time, &test_clock_two),
AZ_OK);
assert_int_equal(az_platform_timer_start(&test_out_timer_1, TEST_MILLISECOND_TIME), AZ_OK);
assert_int_equal(az_platform_timer_start(&test_out_timer_2, 2 * TEST_MILLISECOND_TIME), AZ_OK);
assert_int_equal(az_platform_sleep_msec(3 * TEST_MILLISECOND_TIME), AZ_OK);
assert_int_equal(test_timer_callback_counter, 2);
assert_int_not_equal(test_clock_one, 0);
assert_int_not_equal(test_clock_two, 0);
assert_true(test_clock_two > test_clock_one);
assert_int_equal(az_platform_timer_destroy(&test_out_timer_1), AZ_OK);
assert_int_equal(az_platform_timer_destroy(&test_out_timer_2), AZ_OK);
}
static void test_az_platform_mutex(void** state)
{
(void)state;
az_platform_mutex test_mutex_handle;
assert_int_equal(az_platform_mutex_init(&test_mutex_handle), AZ_OK);
assert_int_equal(az_platform_mutex_acquire(&test_mutex_handle), AZ_OK);
assert_int_equal(az_platform_mutex_release(&test_mutex_handle), AZ_OK);
assert_int_equal(az_platform_mutex_destroy(&test_mutex_handle), AZ_OK);
}
static void test_az_platform_mutex_double(void** state)
{
(void)state;
az_platform_mutex test_mutex_handle_1;
az_platform_mutex test_mutex_handle_2;
assert_int_equal(az_platform_mutex_init(&test_mutex_handle_1), AZ_OK);
assert_int_equal(az_platform_mutex_init(&test_mutex_handle_2), AZ_OK);
assert_int_equal(az_platform_mutex_acquire(&test_mutex_handle_1), AZ_OK);
assert_int_equal(az_platform_mutex_acquire(&test_mutex_handle_2), AZ_OK);
assert_int_equal(az_platform_mutex_release(&test_mutex_handle_1), AZ_OK);
assert_int_equal(az_platform_mutex_release(&test_mutex_handle_2), AZ_OK);
assert_int_equal(az_platform_mutex_destroy(&test_mutex_handle_1), AZ_OK);
assert_int_equal(az_platform_mutex_destroy(&test_mutex_handle_2), AZ_OK);
}
static void test_az_platform_mutex_reentrant(void** state)
{
(void)state;
az_platform_mutex test_mutex_handle_1;
assert_int_equal(az_platform_mutex_init(&test_mutex_handle_1), AZ_OK);
assert_int_equal(az_platform_mutex_acquire(&test_mutex_handle_1), AZ_OK);
assert_int_equal(az_platform_mutex_acquire(&test_mutex_handle_1), AZ_OK);
assert_int_equal(az_platform_mutex_release(&test_mutex_handle_1), AZ_OK);
assert_int_equal(az_platform_mutex_release(&test_mutex_handle_1), AZ_OK);
assert_int_equal(az_platform_mutex_destroy(&test_mutex_handle_1), AZ_OK);
}
#endif // __APPLE__
int test_az_platform()
{
const struct CMUnitTest tests[] = {
#ifndef AZ_NO_PRECONDITION_CHECKING
cmocka_unit_test(test_az_platform_clock_msec_null),
cmocka_unit_test(test_az_platform_get_random_null),
#ifndef __APPLE__
cmocka_unit_test(test_az_platform_timer_create_null),
cmocka_unit_test(test_az_platform_timer_start_null),
cmocka_unit_test(test_az_platform_timer_destroy_null),
cmocka_unit_test(test_az_platform_mutex_init_null),
cmocka_unit_test(test_az_platform_mutex_acquire_null),
cmocka_unit_test(test_az_platform_mutex_release_null),
cmocka_unit_test(test_az_platform_mutex_destroy_null),
#endif // __APPLE__
#endif // AZ_NO_PRECONDITION_CHECKING
cmocka_unit_test(test_az_platform_clock_msec_once),
cmocka_unit_test(test_az_platform_sleep_msec),
cmocka_unit_test(test_az_platform_get_random),
#ifndef __APPLE__
cmocka_unit_test(test_az_platform_timer_single),
cmocka_unit_test(test_az_platform_timer_double),
cmocka_unit_test(test_az_platform_mutex),
cmocka_unit_test(test_az_platform_mutex_double),
cmocka_unit_test(test_az_platform_mutex_reentrant),
#endif // __APPLE__
};
return cmocka_run_group_tests_name("az_platform", tests, NULL, NULL);
}