зеркало из https://github.com/Azure/azure-ulib-c.git
ustream_forward: a lightweight smart-pointer for fast and efficient data transfer (#76)
Interfaces: * flush(): copy data from source to destination directly * read(): copy data from source to destination indirectly utilizing a user-provided local-buffer * get_size(): get total length of data source * dispose(): free all resources associated with ustream_forward smart-pointer Note: does not yet support infinite streams.
This commit is contained in:
Родитель
2518399f69
Коммит
c25479057f
|
@ -98,6 +98,7 @@ ulib_add_standards()
|
|||
add_library(azure_ulib_c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/az_ulib_ustream/az_ulib_ustream_aux.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/az_ulib_ustream/az_ulib_ustream.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/az_ulib_ustream_forward/az_ulib_ustream_forward.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/az_ulib_ipc/az_ulib_ipc.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/az_ulib_ipc/az_ulib_ipc_query_interface.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/az_ulib_ipc/az_ulib_ipc_interface_manager_interface.c
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#define AZ_ULIB_BASE_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#else
|
||||
|
@ -47,6 +48,27 @@ typedef uint32_t az_ulib_version;
|
|||
*/
|
||||
#define AZ_ULIB_STRINGIFIED_VERSION_SIZE 12
|
||||
|
||||
/**
|
||||
* @brief Define offset_t with the same size as size_t.
|
||||
*/
|
||||
typedef size_t offset_t;
|
||||
|
||||
/**
|
||||
* @brief Context that uniquely identifies the callback.
|
||||
*
|
||||
* The callback context is the way that the capability's caller associates the call to its answer.
|
||||
* It can have any value that is meaningful for the caller.
|
||||
*/
|
||||
typedef void* az_ulib_callback_context;
|
||||
|
||||
/**
|
||||
* @brief Signature of the function to release memory passed to the ustream
|
||||
*
|
||||
* @param[in] release_pointer void pointer to memory that needs to be free'd
|
||||
*
|
||||
*/
|
||||
typedef void (*az_ulib_release_callback)(void* release_pointer);
|
||||
|
||||
#include "azure/core/_az_cfg_suffix.h"
|
||||
|
||||
#endif // AZ_ULIB_BASE_H
|
||||
|
|
|
@ -101,14 +101,6 @@ typedef az_result (*az_ulib_capability)(az_ulib_model_in model_in, az_ulib_model
|
|||
typedef az_result (
|
||||
*az_ulib_capability_span_wrapper)(az_span model_in_span, az_span* model_out_span);
|
||||
|
||||
/**
|
||||
* @brief Context that uniquely identifies the callback.
|
||||
*
|
||||
* The callback context is the way that the capability's caller associates the call to its answer.
|
||||
* It can have any value that is meaningful for the caller.
|
||||
*/
|
||||
typedef void* az_ulib_callback_context;
|
||||
|
||||
/**
|
||||
* @brief Telemetry callback signature.
|
||||
*
|
||||
|
|
|
@ -326,6 +326,7 @@
|
|||
* point. In this case, the consumer can call the API az_ulib_ustream_reset().
|
||||
*/
|
||||
|
||||
#include "az_ulib_base.h"
|
||||
#include "az_ulib_config.h"
|
||||
#include "az_ulib_pal_os.h"
|
||||
#include "az_ulib_result.h"
|
||||
|
@ -340,11 +341,6 @@
|
|||
|
||||
#include "azure/core/_az_cfg_prefix.h"
|
||||
|
||||
/**
|
||||
* @brief Define offset_t with the same size as size_t.
|
||||
*/
|
||||
typedef size_t offset_t;
|
||||
|
||||
/**
|
||||
* @brief Forward declaration of az_ulib_ustream. See #az_ulib_ustream_tag for struct members.
|
||||
*/
|
||||
|
@ -393,14 +389,6 @@ typedef struct az_ulib_ustream_interface_tag
|
|||
|
||||
} az_ulib_ustream_interface;
|
||||
|
||||
/**
|
||||
* @brief Signature of the function to release memory passed to the ustream
|
||||
*
|
||||
* @param[in] release_pointer void pointer to memory that needs to be free'd
|
||||
*
|
||||
*/
|
||||
typedef void (*az_ulib_release_callback)(void* release_pointer);
|
||||
|
||||
/**
|
||||
* @brief Pointer to the data from which to read
|
||||
*
|
||||
|
|
|
@ -0,0 +1,359 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
|
||||
/**
|
||||
* @file az_ulib_ustream_forward.h
|
||||
*
|
||||
* @brief The ustream_forward interfaces and accompanying APIs.
|
||||
*/
|
||||
|
||||
#ifndef AZ_ULIB_USTREAM_FORWARD_H
|
||||
#define AZ_ULIB_USTREAM_FORWARD_H
|
||||
|
||||
#include "az_ulib_base.h"
|
||||
#include "az_ulib_result.h"
|
||||
#include "azure/az_core.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#else
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include "azure/core/_az_cfg_prefix.h"
|
||||
|
||||
/**
|
||||
* @brief Forward declaration of az_ulib_ustream_forward. See #az_ulib_ustream_forward_tag for
|
||||
* struct members.
|
||||
*/
|
||||
typedef struct az_ulib_ustream_forward_tag az_ulib_ustream_forward;
|
||||
|
||||
/**
|
||||
* @brief Signature of the function to be invoked by the `az_ulib_ustream_forward_flush`
|
||||
* operation when the `const uint8_t* const` to the buffer has been created.
|
||||
*
|
||||
* @param[in] buffer The `const uint8_t* const` buffer to be handled by the
|
||||
* implementation of this callback.
|
||||
* @param[in] size The number of `uint8_t` bytes in the
|
||||
* `const uint8_t* const` buffer.
|
||||
* @param[in] flush_callback_context The #az_ulib_callback_context contract held between the
|
||||
* owner of this callback and the caller of
|
||||
* `az_ulib_ustream_forward_flush`.
|
||||
*/
|
||||
typedef void (*az_ulib_flush_callback)(
|
||||
const uint8_t* const buffer,
|
||||
size_t size,
|
||||
az_ulib_callback_context flush_callback_context);
|
||||
|
||||
/**
|
||||
* @brief vTable with the ustream_forward APIs.
|
||||
*
|
||||
* Any module that exposes the ustream_forward shall implement the functions on this vTable.
|
||||
*
|
||||
* Any code that will use an exposed ustream_forward shall call the APIs using the
|
||||
* `az_ulib_ustream_forward_...` inline functions.
|
||||
*/
|
||||
typedef struct az_ulib_ustream_forward_interface_tag
|
||||
{
|
||||
/** Concrete `flush` implementation. */
|
||||
az_result (*flush)(
|
||||
az_ulib_ustream_forward* ustream_forward,
|
||||
az_ulib_flush_callback flush_callback,
|
||||
az_ulib_callback_context flush_callback_context);
|
||||
|
||||
/** Concrete `read` implementation. */
|
||||
az_result (*read)(
|
||||
az_ulib_ustream_forward* ustream_forward,
|
||||
uint8_t* const buffer,
|
||||
size_t buffer_length,
|
||||
size_t* const size);
|
||||
|
||||
/** Concrete `get_size` implementation. */
|
||||
size_t (*get_size)(az_ulib_ustream_forward* ustream_forward);
|
||||
|
||||
/** Concrete `dispose` implementation. */
|
||||
az_result (*dispose)(az_ulib_ustream_forward* ustream_forward);
|
||||
} az_ulib_ustream_forward_interface;
|
||||
|
||||
/**
|
||||
* @brief Pointer to the data from which to read
|
||||
*
|
||||
* void pointer to memory where the data is located or any needed controls to access the data.
|
||||
* The content of the memory to which this points is up to the ustream_forward implementation.
|
||||
*
|
||||
*/
|
||||
typedef void* az_ulib_ustream_forward_data;
|
||||
|
||||
/**
|
||||
* @brief Structure for the ustream_forward control block
|
||||
*
|
||||
* For any given ustream_forward that is created, one control block is created and initialized.
|
||||
*
|
||||
* @note This structure should be viewed and used as internal to the implementation of the
|
||||
* ustream_forward. Users should therefore not act on it directly and only allocate the
|
||||
* memory necessary for it to be passed to the ustream_forward.
|
||||
*
|
||||
*/
|
||||
struct az_ulib_ustream_forward_tag
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** The #az_ulib_ustream_forward_interface* for this ustream_forward instance type. */
|
||||
const az_ulib_ustream_forward_interface* api;
|
||||
|
||||
/** The #az_ulib_ustream_forward_data* pointing to the data to read. It can be anything that a
|
||||
* give ustream_forward implementation needs to access the data, whether it be a memory address
|
||||
* to a buffer, another struct with more controls, etc */
|
||||
const az_ulib_ustream_forward_data* ptr;
|
||||
|
||||
/** The #az_ulib_release_callback to call to release `ptr` */
|
||||
az_ulib_release_callback data_release;
|
||||
|
||||
/** The #az_ulib_release_callback to call to release the #az_ulib_ustream_forward. */
|
||||
az_ulib_release_callback ustream_forward_release;
|
||||
|
||||
/** The #offset_t used to keep track of the current position (next returned position). */
|
||||
offset_t inner_current_position;
|
||||
|
||||
/** The number of `uint8_t` bytes of data in the control_block. */
|
||||
size_t length;
|
||||
} _internal;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Check if a handle is the same type of the API.
|
||||
*
|
||||
* It will return true if the handle is valid and it is the same type of the API. It will
|
||||
* return false if the handle is `NULL` or not the correct type.
|
||||
*/
|
||||
#define AZ_ULIB_USTREAM_FORWARD_IS_TYPE_OF(handle, type_api) \
|
||||
(!((handle == NULL) || (handle->_internal.api == NULL) || (handle->_internal.api != &type_api)))
|
||||
|
||||
/**
|
||||
* @brief Provide data from the source to the #az_ulib_flush_callback.
|
||||
*
|
||||
* The `az_ulib_ustream_forward_flush` API will forward the data directly from the
|
||||
* source (provider) to be handled by the `#az_ulib_flush_callback* flush_callback`.
|
||||
*
|
||||
* In the event that the source (provider) memory is not immediately available without a call
|
||||
* to an external API (e.g. an HTTP connection to a blob storage provider), the flush operation
|
||||
* will call this external API (e.g. http_response_body_get) in a loop, invoking the
|
||||
* `flush_callback` each pass of the loop.
|
||||
*
|
||||
* The `az_ulib_ustream_forward_flush` API will provide the consumer a pointer to the memory
|
||||
* associated with the ustream_forward in the form of a `const uint8_t* const` buffer,
|
||||
* to be handled in the `#az_ulib_flush_callback* flush_callback` function implemented by the
|
||||
* consumer.
|
||||
*
|
||||
* The `az_ulib_ustream_forward_flush` API shall meet the following minimum requirements:
|
||||
* - The flush operation creates a `const uint8_t* const` from the `Data Source` and hands it
|
||||
* off to the `flush_callback`
|
||||
* - If the totality of `Data Source` is not available in the provided memory location,
|
||||
* the API shall request the next portion of the data using the appropriate external API.
|
||||
* This process shall be repeated in a loop until the totality of the `Data Source` has been
|
||||
* copied.
|
||||
* - The API shall satisfy all of the precondition requirements laid forth below.
|
||||
*
|
||||
* @param[in] ustream_forward The #az_ulib_ustream_forward* with the interface of
|
||||
* the ustream_forward.
|
||||
* @param[out] flush_callback The #az_ulib_flush_callback* for the consumer to
|
||||
* handle the incoming data.
|
||||
* @param[out] flush_callback_context The #az_ulib_callback_context contract between the
|
||||
* caller and flush_callback.
|
||||
*
|
||||
* @pre \p ustream_forward shall not be `NULL`.
|
||||
* @pre \p ustream_forward shall be a valid ustream_forward that is the
|
||||
* implemented ustream_forward type.
|
||||
* @pre \p flush_callback shall not be `NULL`.
|
||||
*
|
||||
* @return The #az_result with the result of the flush operation
|
||||
* @retval #AZ_OK If the flush operation succeeded in pushing the
|
||||
* entire stream content to `flush_callback`.
|
||||
* @retval #AZ_ERROR_ULIB_BUSY If the resource necessary to get the next portion of
|
||||
* data is busy.
|
||||
* @retval #AZ_ERROR_CANCELED If any one of the flush operation's dependent
|
||||
* external calls is canceled.
|
||||
* @retval #AZ_ERROR_NOT_ENOUGH_SPACE If there is not enough memory to finish copying the
|
||||
* data from source to destination.
|
||||
* @retval #AZ_ERROR_ULIB_SECURITY If any one of the flush operation's dependent
|
||||
* external calls returns an error for security reasons.
|
||||
* @retval #AZ_ERROR_ULIB_SYSTEM If any one of the flush operation's dependent
|
||||
* fails at the system level.
|
||||
*/
|
||||
AZ_NODISCARD AZ_INLINE az_result az_ulib_ustream_forward_flush(
|
||||
az_ulib_ustream_forward* ustream_forward,
|
||||
az_ulib_flush_callback flush_callback,
|
||||
az_ulib_callback_context flush_callback_context)
|
||||
{
|
||||
return ustream_forward->_internal.api->flush(
|
||||
ustream_forward, flush_callback, flush_callback_context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the next portion of the ustream_forward.
|
||||
*
|
||||
* The `az_ulib_ustream_forward_read` API will copy the contents of the `Data Source` to the local
|
||||
* buffer starting at the offset set by the previous call to `az_ulib_ustream_forward_read`.
|
||||
* This position will be the beginning of the stream (offset of 0) the first time this API is
|
||||
* called. The local buffer is the one referenced by the parameter `buffer`, and with the
|
||||
* maximum size `buffer_length`.
|
||||
*
|
||||
* The buffer is defined as a `uint8_t*` and can represent any sequence of data. Pay
|
||||
* special attention, if the data is a string, the buffer will still copy it as a sequence of
|
||||
* `uint8_t`, and will <b>NOT</b> put any terminator at the end of the string. The size of
|
||||
* the content copied in the local buffer will be returned in the parameter `size`.
|
||||
*
|
||||
* The `az_ulib_ustream_forward_read` API shall follow the following minimum requirements:
|
||||
* - The read shall copy the contents of the `Data Source` to the provided local buffer.
|
||||
* - If the contents of the `Data Source` is bigger than the `buffer_length`, the read shall
|
||||
* limit the copy size up to the buffer_length.
|
||||
* - The read shall return the number of valid `uint8_t` values in the local buffer in
|
||||
* the provided `size`.
|
||||
* - If there is no more content to return, the read shall return
|
||||
* #AZ_ULIB_EOF, size shall be set to 0, and will not change the contents
|
||||
* of the local buffer.
|
||||
* - The API shall satisfy all of the precondition requirements laid forth below.
|
||||
*
|
||||
* @param[in] ustream_forward The #az_ulib_ustream_forward* with the interface of the
|
||||
* ustream_forward.
|
||||
* @param[out] buffer The `uint8_t* const` that points to the local buffer.
|
||||
* @param[in] buffer_length The `size_t` with the size of the local buffer.
|
||||
* @param[out] size The `size_t* const` that points to the place where the
|
||||
* read shall store the number of valid `uint8_t` values
|
||||
* returned in the local buffer.
|
||||
*
|
||||
* @pre \p ustream_forward shall not be `NULL`.
|
||||
* @pre \p ustream_forward shall be a valid ustream_forward that is the implemented
|
||||
* ustream_forward type.
|
||||
* @pre \p buffer shall not be `NULL`.
|
||||
* @pre \p buffer_length shall not be bigger than 0.
|
||||
* @pre \p size shall not be `NULL`.
|
||||
*
|
||||
* @return The #az_result with the result of the read operation.
|
||||
* @retval #AZ_OK If the ustream_forward copied the content of the
|
||||
* `Data Source` to the local buffer with success.
|
||||
* @retval #AZ_ERROR_ULIB_BUSY If the resource necessary to read the ustream_forward
|
||||
* content is busy.
|
||||
* @retval #AZ_ERROR_CANCELED If the read of the content was cancelled.
|
||||
* @retval #AZ_ULIB_EOF If there are no more `uint8_t` values in the `Data
|
||||
* Source` to read.
|
||||
* @retval #AZ_ERROR_NOT_ENOUGH_SPACE If there is not enough memory to execute the read.
|
||||
* @retval #AZ_ERROR_ULIB_SECURITY If the read was denied for security reasons.
|
||||
* @retval #AZ_ERROR_ULIB_SYSTEM If the read operation failed on the system level.
|
||||
*/
|
||||
AZ_NODISCARD AZ_INLINE az_result az_ulib_ustream_forward_read(
|
||||
az_ulib_ustream_forward* ustream_forward,
|
||||
uint8_t* const buffer,
|
||||
size_t buffer_length,
|
||||
size_t* const size)
|
||||
{
|
||||
return ustream_forward->_internal.api->read(ustream_forward, buffer, buffer_length, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the size of the ustream_forward.
|
||||
*
|
||||
* This API returns the number of bytes in the ustream_forward.
|
||||
*
|
||||
* The `az_ulib_ustream_forward_get_size` API shall follow the following minimum requirements:
|
||||
* - The API shall return the number of bytes in the ustream_forward.
|
||||
* - The API shall satisfy all of the precondition requirements laid forth below.
|
||||
*
|
||||
* @param[in] ustream_forward The #az_ulib_ustream_forward* with the interface of the
|
||||
* ustream_forward.
|
||||
*
|
||||
* @pre \p ustream_forward shall not be `NULL`.
|
||||
* @pre \p ustream_forward shall be a valid ustream_forward that is the implemented
|
||||
* ustream_forward type.
|
||||
*
|
||||
* @return The `size_t` of the ustream_forward
|
||||
*/
|
||||
AZ_NODISCARD AZ_INLINE size_t
|
||||
az_ulib_ustream_forward_get_size(az_ulib_ustream_forward* ustream_forward)
|
||||
{
|
||||
return ustream_forward->_internal.api->get_size(ustream_forward);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release all the resources allocated to the ustream_forward.
|
||||
*
|
||||
* The `az_ulib_ustream_forward_dispose` API shall follow the following minimum requirements:
|
||||
* - The `dispose` shall release all resources allocated to the ustream_forward.
|
||||
* - The API shall satisfy all of the precondition requirements laid forth below.
|
||||
*
|
||||
* @param[in] ustream_forward The #az_ulib_ustream_forward* with the interface of the
|
||||
* ustream_forward.
|
||||
*
|
||||
* @pre \p ustream_forward shall not be `NULL`.
|
||||
* @pre \p ustream_forward shall be a valid ustream_forward that is the implemented
|
||||
* ustream_forward type.
|
||||
*
|
||||
* @return The #az_result with the result of the `dispose` operation.
|
||||
* @retval #AZ_OK If the instance of the ustream_forward was disposed
|
||||
* with success.
|
||||
*
|
||||
* @note: While the simplest implementation of this API returns only #AZ_OK, other implementations
|
||||
* may return errors.
|
||||
*/
|
||||
AZ_NODISCARD AZ_INLINE az_result
|
||||
az_ulib_ustream_forward_dispose(az_ulib_ustream_forward* ustream_forward)
|
||||
{
|
||||
return ustream_forward->_internal.api->dispose(ustream_forward);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Factory to initialize a new ustream_forward.
|
||||
*
|
||||
* This factory initializes a ustream_forward that handles the content of the provided buffer. As a
|
||||
* result, it will return an #az_ulib_ustream_forward* with this content. The initialized
|
||||
* ustream_forward takes ownership of the passed memory and will release the memory with the
|
||||
* passed #az_ulib_release_callback function when the caller goes out of scope.
|
||||
*
|
||||
* @param[out] ustream_forward The pointer to the allocated
|
||||
* #az_ulib_ustream_forward struct.
|
||||
* @param[in] ustream_forward_release The #az_ulib_release_callback function that will be
|
||||
* called to release the ustream_forward block (the
|
||||
* passed `ustream_forward` parameter). If `NULL` is
|
||||
* passed, the `az_ulib_ustream_forward_dispose` will
|
||||
* not release the memory associated with
|
||||
* `ustream_forward`, so it will be the caller's
|
||||
* responsibility to do so. For example, developers
|
||||
* may use the stdlib `free` to release malloc'd
|
||||
* memory.
|
||||
* @param[in] data_buffer The `const uint8_t* const` that points to a memory
|
||||
* position where the buffer starts.
|
||||
* @param[in] data_buffer_length The `size_t` with the number of `uint8_t` in the
|
||||
* provided buffer.
|
||||
* @param[in] data_buffer_release The #az_ulib_release_callback function that will be
|
||||
* called to release the data. If `NULL` is passed,
|
||||
* the `az_ulib_ustream_forward_dispose` will not
|
||||
* release the memory associated with
|
||||
* `ustream_forward`, so it will be the caller's
|
||||
* responsibility to do so. For example, developers
|
||||
* may use the stdlib `free` to release malloc'd
|
||||
* memory.
|
||||
*
|
||||
* @pre \p ustream_forward shall not be `NULL`.
|
||||
* @pre \p data_buffer shall not be `NULL`.
|
||||
* @pre \p data_buffer_length shall be greater than `0`.
|
||||
*
|
||||
* @return The #az_result with result of the initialization.
|
||||
* @retval #AZ_OK If the #az_ulib_ustream_forward* is successfully
|
||||
* initialized.
|
||||
*
|
||||
* @note: While the simplest implementation of this API returns only #AZ_OK, other implementations
|
||||
* may return errors.
|
||||
*/
|
||||
AZ_NODISCARD az_result az_ulib_ustream_forward_init(
|
||||
az_ulib_ustream_forward* ustream_forward,
|
||||
az_ulib_release_callback ustream_forward_release,
|
||||
const uint8_t* const data_buffer,
|
||||
size_t data_buffer_length,
|
||||
az_ulib_release_callback data_buffer_release);
|
||||
|
||||
#include "azure/core/_az_cfg_suffix.h"
|
||||
|
||||
#endif /* AZ_ULIB_USTREAM_FORWARD_H */
|
|
@ -7,4 +7,5 @@ add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/ipc_call_interface)
|
|||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/ipc_hardware_update)
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/ipc_telemetry)
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/ustream_basic)
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/ustream_forward_basic)
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/ustream_split)
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
#Copyright (c) Microsoft. All rights reserved.
|
||||
#Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
add_executable(ustream_forward_basic
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/main.c
|
||||
)
|
||||
|
||||
ulib_populate_sample_target(ustream_forward_basic)
|
|
@ -0,0 +1,78 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
|
||||
#include "az_ulib_result.h"
|
||||
#include "az_ulib_ustream_forward.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define START_MEMORY_OFFSET 0
|
||||
static const char ustream_forward_producer_buf[] = "Hello World!\r\n";
|
||||
|
||||
typedef struct ustream_forward_basic_context
|
||||
{
|
||||
offset_t offset;
|
||||
char buffer[100];
|
||||
} consumer_context;
|
||||
|
||||
static void flush_callback(
|
||||
const uint8_t* const buffer,
|
||||
size_t size,
|
||||
az_ulib_callback_context flush_callback_context)
|
||||
{
|
||||
// handle buffer
|
||||
consumer_context* flush_context = (consumer_context*)flush_callback_context;
|
||||
(void)snprintf(
|
||||
flush_context->buffer + flush_context->offset,
|
||||
sizeof(flush_context->buffer) / sizeof(char),
|
||||
"%s", buffer);
|
||||
|
||||
// adjust offset
|
||||
flush_context->offset += size;
|
||||
}
|
||||
|
||||
static az_result my_consumer(void)
|
||||
{
|
||||
AZ_ULIB_TRY
|
||||
{
|
||||
// initialize ustream_forward with producer data
|
||||
az_ulib_ustream_forward ustream_forward_instance;
|
||||
AZ_ULIB_THROW_IF_AZ_ERROR(az_ulib_ustream_forward_init(
|
||||
&ustream_forward_instance,
|
||||
NULL,
|
||||
(const uint8_t*)ustream_forward_producer_buf,
|
||||
sizeof(ustream_forward_producer_buf),
|
||||
NULL));
|
||||
|
||||
// initialize context
|
||||
consumer_context my_consumer_context = { 0 };
|
||||
|
||||
(void)printf("my_consumer_context.buffer = %s\r\n", my_consumer_context.buffer);
|
||||
|
||||
// flush from producer to consumer buffer
|
||||
(void)printf("----- FLUSH ----\r\n");
|
||||
AZ_ULIB_THROW_IF_AZ_ERROR(
|
||||
az_ulib_ustream_forward_flush(&ustream_forward_instance, flush_callback, &my_consumer_context));
|
||||
|
||||
(void)printf("my_consumer_context.buffer = %s\r\n", my_consumer_context.buffer);
|
||||
}
|
||||
AZ_ULIB_CATCH(...) {}
|
||||
|
||||
return AZ_ULIB_TRY_RESULT;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
az_result result;
|
||||
|
||||
if ((result = my_consumer()) != AZ_OK)
|
||||
{
|
||||
printf("my_consumer() failed\r\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,165 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "az_ulib_port.h"
|
||||
#include "az_ulib_result.h"
|
||||
#include "az_ulib_ustream_forward.h"
|
||||
#include "azure/core/az_span.h"
|
||||
|
||||
|
||||
#include <azure/core/internal/az_precondition_internal.h>
|
||||
|
||||
#ifdef __clang__
|
||||
#define IGNORE_POINTER_TYPE_QUALIFICATION \
|
||||
_Pragma("clang diagnostic push") \
|
||||
_Pragma("clang diagnostic ignored \"-Wincompatible-pointer-types-discards-qualifiers\"")
|
||||
#define IGNORE_MEMCPY_TO_NULL _Pragma("GCC diagnostic push")
|
||||
#define RESUME_WARNINGS _Pragma("clang diagnostic pop")
|
||||
#elif defined(__GNUC__)
|
||||
#define IGNORE_POINTER_TYPE_QUALIFICATION \
|
||||
_Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wdiscarded-qualifiers\"")
|
||||
#define IGNORE_MEMCPY_TO_NULL _Pragma("GCC diagnostic push")
|
||||
#define RESUME_WARNINGS _Pragma("GCC diagnostic pop")
|
||||
#else
|
||||
#define IGNORE_POINTER_TYPE_QUALIFICATION __pragma(warning(push));
|
||||
#define IGNORE_MEMCPY_TO_NULL \
|
||||
__pragma(warning(push)); \
|
||||
__pragma(warning(suppress : 6387));
|
||||
#define RESUME_WARNINGS __pragma(warning(pop));
|
||||
#endif // __clang__
|
||||
|
||||
static az_result concrete_flush(
|
||||
az_ulib_ustream_forward* ustream_forward,
|
||||
az_ulib_flush_callback flush_callback,
|
||||
az_ulib_callback_context flush_callback_context);
|
||||
static az_result concrete_read(
|
||||
az_ulib_ustream_forward* ustream_forward,
|
||||
uint8_t* const buffer,
|
||||
size_t buffer_length,
|
||||
size_t* const size);
|
||||
static size_t concrete_get_size(az_ulib_ustream_forward* ustream_forward);
|
||||
static az_result concrete_dispose(az_ulib_ustream_forward* ustream_forward);
|
||||
static const az_ulib_ustream_forward_interface api
|
||||
= { concrete_flush, concrete_read, concrete_get_size, concrete_dispose };
|
||||
|
||||
static az_result concrete_flush(
|
||||
az_ulib_ustream_forward* ustream_forward,
|
||||
az_ulib_flush_callback flush_callback,
|
||||
az_ulib_callback_context flush_callback_context)
|
||||
{
|
||||
// precondition checks
|
||||
_az_PRECONDITION_NOT_NULL(ustream_forward);
|
||||
_az_PRECONDITION(AZ_ULIB_USTREAM_FORWARD_IS_TYPE_OF(ustream_forward, api));
|
||||
_az_PRECONDITION_NOT_NULL(flush_callback);
|
||||
|
||||
// get size of data
|
||||
size_t buffer_size = concrete_get_size(ustream_forward);
|
||||
|
||||
// point to data
|
||||
const uint8_t* buffer = (const uint8_t*)ustream_forward->_internal.ptr
|
||||
+ ustream_forward->_internal.inner_current_position;
|
||||
|
||||
// invoke callback
|
||||
(*flush_callback)(buffer, buffer_size, flush_callback_context);
|
||||
|
||||
return AZ_OK;
|
||||
}
|
||||
|
||||
static az_result concrete_read(
|
||||
az_ulib_ustream_forward* ustream_forward,
|
||||
uint8_t* const buffer,
|
||||
size_t buffer_length,
|
||||
size_t* const size)
|
||||
{
|
||||
_az_PRECONDITION(AZ_ULIB_USTREAM_FORWARD_IS_TYPE_OF(ustream_forward, api));
|
||||
_az_PRECONDITION_NOT_NULL(buffer);
|
||||
_az_PRECONDITION(buffer_length > 0);
|
||||
_az_PRECONDITION_NOT_NULL(size);
|
||||
|
||||
az_result result;
|
||||
|
||||
if (ustream_forward->_internal.inner_current_position >= ustream_forward->_internal.length)
|
||||
{
|
||||
*size = 0;
|
||||
result = AZ_ULIB_EOF;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t remain_size = ustream_forward->_internal.length
|
||||
- (size_t)ustream_forward->_internal.inner_current_position;
|
||||
*size = (buffer_length < remain_size) ? buffer_length : remain_size;
|
||||
|
||||
/**
|
||||
* Since pre-conditions can be disabled by the user, compilers throw a warning for a potential
|
||||
* memcpy to `NULL`. We disable this warning knowing that it is the user's responsibility to
|
||||
* assure `buffer` is a valid pointer when pre-conditions are disabled for release mode.
|
||||
* See \ref Pre-conditions "https://azure.github.io/azure-sdk/clang_design.html#pre-conditions"
|
||||
* for more details.
|
||||
*/
|
||||
IGNORE_MEMCPY_TO_NULL
|
||||
memcpy(
|
||||
buffer,
|
||||
(const uint8_t*)ustream_forward->_internal.ptr
|
||||
+ ustream_forward->_internal.inner_current_position,
|
||||
*size);
|
||||
RESUME_WARNINGS
|
||||
ustream_forward->_internal.inner_current_position += *size;
|
||||
result = AZ_OK;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static size_t concrete_get_size(az_ulib_ustream_forward* ustream_forward)
|
||||
{
|
||||
_az_PRECONDITION(AZ_ULIB_USTREAM_FORWARD_IS_TYPE_OF(ustream_forward, api));
|
||||
|
||||
return ustream_forward->_internal.length - ustream_forward->_internal.inner_current_position;
|
||||
}
|
||||
|
||||
static az_result concrete_dispose(az_ulib_ustream_forward* ustream_forward)
|
||||
{
|
||||
_az_PRECONDITION(AZ_ULIB_USTREAM_FORWARD_IS_TYPE_OF(ustream_forward, api));
|
||||
|
||||
if (ustream_forward->_internal.data_release)
|
||||
{
|
||||
/* If `data_relese` was provided is because `ptr` is not `const`. So, we have an Warning
|
||||
* exception here to remove the `const` qualification of the `ptr`. */
|
||||
IGNORE_POINTER_TYPE_QUALIFICATION
|
||||
ustream_forward->_internal.data_release(ustream_forward->_internal.ptr);
|
||||
RESUME_WARNINGS
|
||||
}
|
||||
if (ustream_forward->_internal.ustream_forward_release)
|
||||
{
|
||||
ustream_forward->_internal.ustream_forward_release(ustream_forward);
|
||||
}
|
||||
|
||||
return AZ_OK;
|
||||
}
|
||||
|
||||
AZ_NODISCARD az_result az_ulib_ustream_forward_init(
|
||||
az_ulib_ustream_forward* ustream_forward,
|
||||
az_ulib_release_callback ustream_forward_release,
|
||||
const uint8_t* const data_buffer,
|
||||
size_t data_buffer_length,
|
||||
az_ulib_release_callback data_buffer_release)
|
||||
{
|
||||
_az_PRECONDITION_NOT_NULL(ustream_forward);
|
||||
_az_PRECONDITION_NOT_NULL(data_buffer);
|
||||
_az_PRECONDITION(data_buffer_length > 0);
|
||||
|
||||
ustream_forward->_internal.api = &api;
|
||||
ustream_forward->_internal.ptr = (const az_ulib_ustream_forward_data*)data_buffer;
|
||||
ustream_forward->_internal.data_release = data_buffer_release;
|
||||
ustream_forward->_internal.ustream_forward_release = ustream_forward_release;
|
||||
ustream_forward->_internal.inner_current_position = 0;
|
||||
ustream_forward->_internal.length = data_buffer_length;
|
||||
|
||||
return AZ_OK;
|
||||
}
|
|
@ -9,7 +9,9 @@ ulib_use_permissive_rules_for_samples_and_tests()
|
|||
if(${UNIT_TESTING})
|
||||
add_subdirectory(tests_ut/az_ulib_ipc_ut)
|
||||
add_subdirectory(tests_ut/az_ulib_ustream_ut)
|
||||
add_subdirectory(tests_ut/az_ulib_ustream_forward_ut)
|
||||
add_subdirectory(tests_e2e/az_ulib_ipc_e2e)
|
||||
add_subdirectory(tests_e2e/az_ulib_ustream_e2e)
|
||||
add_subdirectory(tests_e2e/az_ulib_ustream_forward_e2e)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
|
||||
#ifndef AZ_ULIB_CTEST_AUX_H
|
||||
#define AZ_ULIB_CTEST_AUX_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "az_ulib_ustream_base.h"
|
||||
|
||||
#include "cmocka.h"
|
||||
|
||||
/**
|
||||
* Check buffer
|
||||
*/
|
||||
static void check_buffer(
|
||||
az_ulib_ustream* ustream_instance,
|
||||
uint8_t offset,
|
||||
const uint8_t* const expected_content,
|
||||
uint8_t expected_content_length)
|
||||
{
|
||||
uint8_t buf_result[256];
|
||||
size_t size_result;
|
||||
|
||||
if (offset < expected_content_length)
|
||||
{
|
||||
assert_int_equal(az_ulib_ustream_read(ustream_instance, buf_result, 256, &size_result), AZ_OK);
|
||||
|
||||
assert_int_equal(size_result, expected_content_length - offset);
|
||||
assert_memory_equal((const uint8_t* const)(expected_content + offset), buf_result, size_result);
|
||||
}
|
||||
|
||||
size_result = 10;
|
||||
assert_int_equal(
|
||||
az_ulib_ustream_read(ustream_instance, buf_result, 256, &size_result), AZ_ULIB_EOF);
|
||||
assert_int_equal(size_result, 0);
|
||||
}
|
||||
|
||||
#endif /* AZ_ULIB_CTEST_AUX_H */
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
|
||||
#ifndef AZ_ULIB_TEST_HELPERS_H
|
||||
#define AZ_ULIB_TEST_HELPERS_H
|
||||
|
||||
#include "az_ulib_ustream_base.h"
|
||||
#include "az_ulib_ustream_forward.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstdint>
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* Check buffer
|
||||
*/
|
||||
void check_buffer(
|
||||
az_ulib_ustream* ustream_instance,
|
||||
uint8_t offset,
|
||||
const uint8_t* const expected_content,
|
||||
uint8_t expected_content_length);
|
||||
/**
|
||||
* Check buffer
|
||||
*/
|
||||
void check_ustream_forward_buffer(
|
||||
az_ulib_ustream_forward* ustream_forward,
|
||||
uint8_t offset,
|
||||
const uint8_t* const expected_content,
|
||||
uint8_t expected_content_length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* AZ_ULIB_TEST_HELPERS_H */
|
|
@ -5,7 +5,7 @@
|
|||
#ifndef AZ_ULIB_USTREAM_COMPLIANCE_UT_H
|
||||
#define AZ_ULIB_USTREAM_COMPLIANCE_UT_H
|
||||
|
||||
#include "az_ulib_ctest_aux.h"
|
||||
#include "az_ulib_test_helpers.h"
|
||||
#include "az_ulib_test_precondition.h"
|
||||
#include "az_ulib_ustream_mock_buffer.h"
|
||||
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
|
||||
#ifndef AZ_ULIB_USTREAM_FORWARD_COMPLIANCE_E2E_H
|
||||
#define AZ_ULIB_USTREAM_FORWARD_COMPLIANCE_E2E_H
|
||||
|
||||
#include "az_ulib_ustream_mock_buffer.h"
|
||||
|
||||
#include "cmocka.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstdio>
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* check for test artifacts. */
|
||||
#ifndef USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH
|
||||
#error "USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH not defined"
|
||||
#endif
|
||||
|
||||
#ifndef USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY
|
||||
#error "USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY not defined"
|
||||
#endif
|
||||
|
||||
#if (USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH / 20 == 0)
|
||||
#error "USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH must be at least 20 uint8_t long"
|
||||
#endif
|
||||
|
||||
/* split the content in 2 parts. */
|
||||
#define USTREAM_FORWARD_COMPLIANCE_LENGTH_1 (USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH / 2)
|
||||
#define USTREAM_FORWARD_COMPLIANCE_LENGTH_2 \
|
||||
(USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH - USTREAM_FORWARD_COMPLIANCE_LENGTH_1)
|
||||
|
||||
/* create local buffer with enough size to handle the full content. */
|
||||
#define USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH \
|
||||
(USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH / 2)
|
||||
|
||||
static const uint8_t* const compliance_expected_content
|
||||
= (const uint8_t*)USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT;
|
||||
|
||||
/**
|
||||
* @brief E2e test flush callback.
|
||||
*/
|
||||
typedef struct ustream_forward_basic_context
|
||||
{
|
||||
offset_t offset;
|
||||
char buffer[100];
|
||||
} consumer_context;
|
||||
|
||||
static void flush_callback(
|
||||
const uint8_t* const buffer,
|
||||
size_t size,
|
||||
az_ulib_callback_context flush_callback_context)
|
||||
{
|
||||
// handle buffer
|
||||
consumer_context* flush_context = (consumer_context*)flush_callback_context;
|
||||
(void)snprintf(
|
||||
flush_context->buffer + flush_context->offset,
|
||||
sizeof(flush_context->buffer) / sizeof(char),
|
||||
"%s",
|
||||
buffer);
|
||||
|
||||
// adjust offset
|
||||
flush_context->offset += size;
|
||||
}
|
||||
/**
|
||||
* Start compliance tests.
|
||||
*/
|
||||
|
||||
/**
|
||||
* In the event that read does not completely traverse the buffer, flush shall pick up where read
|
||||
* left off and successfully hand off the remaining buffer to the flush callback.
|
||||
*/
|
||||
static void az_ulib_ustream_forward_e2e_compliance_read_flush_succeed(void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward* ustream_forward;
|
||||
USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY(&ustream_forward);
|
||||
uint8_t buf_result[USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH];
|
||||
size_t size_result;
|
||||
consumer_context test_consumer_context = { 0 };
|
||||
|
||||
/// act
|
||||
az_result result_read = az_ulib_ustream_forward_read(
|
||||
ustream_forward, buf_result, USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH, &size_result);
|
||||
az_result result_flush
|
||||
= az_ulib_ustream_forward_flush(ustream_forward, flush_callback, &test_consumer_context);
|
||||
|
||||
/// assert
|
||||
assert_int_equal(result_read, AZ_OK);
|
||||
assert_int_equal(size_result, USTREAM_FORWARD_COMPLIANCE_LENGTH_1);
|
||||
assert_memory_equal(USTREAM_FORWARD_COMPLIANCE_LOCAL_EXPECTED_CONTENT, buf_result, size_result);
|
||||
|
||||
assert_int_equal(result_flush, AZ_OK);
|
||||
assert_int_equal(test_consumer_context.offset, USTREAM_FORWARD_COMPLIANCE_LENGTH_2);
|
||||
assert_memory_equal(
|
||||
(const uint8_t* const)(
|
||||
USTREAM_FORWARD_COMPLIANCE_LOCAL_EXPECTED_CONTENT + USTREAM_FORWARD_COMPLIANCE_LENGTH_1),
|
||||
test_consumer_context.buffer,
|
||||
size_result);
|
||||
|
||||
/// cleanup
|
||||
az_result result = az_ulib_ustream_forward_dispose(ustream_forward);
|
||||
(void)result;
|
||||
}
|
||||
|
||||
#define AZ_ULIB_USTREAM_FORWARD_COMPLIANCE_E2E_LIST \
|
||||
cmocka_unit_test(az_ulib_ustream_forward_e2e_compliance_read_flush_succeed)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* AZ_ULIB_USTREAM_FORWARD_COMPLIANCE_E2E_H */
|
|
@ -0,0 +1,614 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
|
||||
#ifndef AZ_ULIB_USTREAM_FORWARD_COMPLIANCE_UT_H
|
||||
#define AZ_ULIB_USTREAM_FORWARD_COMPLIANCE_UT_H
|
||||
|
||||
#include "az_ulib_test_helpers.h"
|
||||
#include "az_ulib_test_precondition.h"
|
||||
#include "az_ulib_ustream_forward_mock_buffer.h"
|
||||
|
||||
#include "cmocka.h"
|
||||
|
||||
/* check for test artifacts. */
|
||||
#ifndef USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH
|
||||
#error "USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH not defined"
|
||||
#endif
|
||||
|
||||
#ifndef USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY
|
||||
#error "USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY not defined"
|
||||
#endif
|
||||
|
||||
#if (USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH / 20 == 0)
|
||||
#error "USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH must be at least 20 uint8_t long"
|
||||
#endif
|
||||
|
||||
/* split the content in 4 parts. */
|
||||
#define USTREAM_FORWARD_COMPLIANCE_LENGTH_1 \
|
||||
(USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH >> 2)
|
||||
#define USTREAM_FORWARD_COMPLIANCE_LENGTH_2 \
|
||||
(USTREAM_FORWARD_COMPLIANCE_LENGTH_1 + USTREAM_FORWARD_COMPLIANCE_LENGTH_1)
|
||||
#define USTREAM_FORWARD_COMPLIANCE_LENGTH_3 \
|
||||
(USTREAM_FORWARD_COMPLIANCE_LENGTH_2 + USTREAM_FORWARD_COMPLIANCE_LENGTH_1)
|
||||
|
||||
/* create local buffer with enough size to handle the full content. */
|
||||
#define USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH \
|
||||
(USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH + 2)
|
||||
|
||||
// flush callback global variables
|
||||
static uint8_t* flush_callback_buffer_check[USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH]
|
||||
= { 0 };
|
||||
static size_t flush_callback_size_check = 0;
|
||||
static az_ulib_callback_context flush_callback_context_check;
|
||||
|
||||
// mock callback function
|
||||
static void mock_flush_callback(
|
||||
const uint8_t* const buffer,
|
||||
size_t size,
|
||||
az_ulib_callback_context flush_callback_context)
|
||||
{
|
||||
(void)memcpy(flush_callback_buffer_check, buffer, size);
|
||||
flush_callback_size_check = size;
|
||||
flush_callback_context_check = flush_callback_context;
|
||||
}
|
||||
|
||||
/*
|
||||
* Start compliance tests:
|
||||
*/
|
||||
|
||||
#ifndef AZ_NO_PRECONDITION_CHECKING
|
||||
/* If the provided handle is NULL, the dispose shall fail with precondition. */
|
||||
static void az_ulib_ustream_forward_dispose_compliance_null_buffer_failed(void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward* ustream_forward;
|
||||
USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY(&ustream_forward);
|
||||
|
||||
/// act
|
||||
/// assert
|
||||
AZ_ULIB_ASSERT_PRECONDITION_CHECKED((ustream_forward)->_internal.api->dispose(NULL));
|
||||
|
||||
/// cleanup
|
||||
az_result result = az_ulib_ustream_forward_dispose(ustream_forward);
|
||||
(void)result;
|
||||
}
|
||||
|
||||
/* If the provided handle is not the implemented buffer type, the dispose shall fail with
|
||||
* precondition. */
|
||||
static void az_ulib_ustream_forward_dispose_compliance_buffer_is_not_type_of_buffer_failed(
|
||||
void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward* ustream_forward;
|
||||
USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY(&ustream_forward);
|
||||
|
||||
/// act
|
||||
/// assert
|
||||
AZ_ULIB_ASSERT_PRECONDITION_CHECKED(
|
||||
ustream_forward->_internal.api->dispose(ustream_forward_mock_create()));
|
||||
|
||||
/// cleanup
|
||||
az_result result = az_ulib_ustream_forward_dispose(ustream_forward);
|
||||
(void)result;
|
||||
}
|
||||
|
||||
/* If the provided handle is NULL, the get_size shall fail with precondition. */
|
||||
static void az_ulib_ustream_forward_get_size_compliance_null_buffer_failed(void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward* ustream_forward;
|
||||
USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY(&ustream_forward);
|
||||
|
||||
/// act
|
||||
/// assert
|
||||
AZ_ULIB_ASSERT_PRECONDITION_CHECKED(ustream_forward->_internal.api->get_size(NULL));
|
||||
|
||||
/// cleanup
|
||||
az_result result = az_ulib_ustream_forward_dispose(ustream_forward);
|
||||
(void)result;
|
||||
}
|
||||
|
||||
/* If the provided handle is not properly initialized, the get_size shall fail with precondition. */
|
||||
static void az_ulib_ustream_forward_get_size_compliance_buffer_is_not_type_of_buffer_failed(
|
||||
void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward* ustream_forward;
|
||||
USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY(&ustream_forward);
|
||||
|
||||
/// act
|
||||
/// assert
|
||||
AZ_ULIB_ASSERT_PRECONDITION_CHECKED(
|
||||
ustream_forward->_internal.api->get_size(ustream_forward_mock_create()));
|
||||
|
||||
/// cleanup
|
||||
az_result result = az_ulib_ustream_forward_dispose(ustream_forward);
|
||||
(void)result;
|
||||
}
|
||||
|
||||
/* If the provided handle is NULL, the flush shall fail with precondition. */
|
||||
static void az_ulib_ustream_forward_flush_compliance_null_handle_failed(void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward* ustream_forward;
|
||||
USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY(&ustream_forward);
|
||||
az_ulib_callback_context callback_context = { 0 };
|
||||
|
||||
/// act
|
||||
/// assert
|
||||
AZ_ULIB_ASSERT_PRECONDITION_CHECKED(
|
||||
ustream_forward->_internal.api->flush(NULL, mock_flush_callback, callback_context));
|
||||
|
||||
/// cleanup
|
||||
az_result result = az_ulib_ustream_forward_dispose(ustream_forward);
|
||||
(void)result;
|
||||
}
|
||||
|
||||
/* If the provided handle is not the implemented ustream_forward type, the flush shall fail with
|
||||
* precondition.
|
||||
*/
|
||||
static void az_ulib_ustream_forward_flush_compliance_non_type_of_ustream_forward_api_failed(
|
||||
void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward* ustream_forward;
|
||||
USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY(&ustream_forward);
|
||||
az_ulib_callback_context callback_context = { 0 };
|
||||
|
||||
/// act
|
||||
/// assert
|
||||
AZ_ULIB_ASSERT_PRECONDITION_CHECKED(ustream_forward->_internal.api->flush(
|
||||
ustream_forward_mock_create(), mock_flush_callback, callback_context));
|
||||
|
||||
/// cleanup
|
||||
az_result result = az_ulib_ustream_forward_dispose(ustream_forward);
|
||||
(void)result;
|
||||
}
|
||||
|
||||
/* If the provided flush_callback is NULL, the flush shall fail with precondition. */
|
||||
static void az_ulib_ustream_forward_flush_compliance_null_flush_callback_failed(void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward* ustream_forward;
|
||||
USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY(&ustream_forward);
|
||||
az_ulib_callback_context callback_context = { 0 };
|
||||
|
||||
/// act
|
||||
/// assert
|
||||
AZ_ULIB_ASSERT_PRECONDITION_CHECKED(
|
||||
ustream_forward->_internal.api->flush(ustream_forward, NULL, callback_context));
|
||||
|
||||
/// cleanup
|
||||
az_result result = az_ulib_ustream_forward_dispose(ustream_forward);
|
||||
(void)result;
|
||||
}
|
||||
|
||||
static void az_ulib_ustream_forward_flush_compliance_single_buffer_succeed(void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward* ustream_forward;
|
||||
USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY(&ustream_forward);
|
||||
struct _test_context
|
||||
{
|
||||
uint8_t test_value;
|
||||
} test_context = { 0 };
|
||||
|
||||
az_ulib_callback_context callback_context = (az_ulib_callback_context)&test_context;
|
||||
|
||||
/// act
|
||||
az_result result
|
||||
= az_ulib_ustream_forward_flush(ustream_forward, mock_flush_callback, callback_context);
|
||||
|
||||
/// assert
|
||||
assert_int_equal(result, AZ_OK);
|
||||
assert_int_equal(flush_callback_size_check, USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH);
|
||||
assert_int_equal(flush_callback_context_check, callback_context);
|
||||
assert_memory_equal(
|
||||
USTREAM_FORWARD_COMPLIANCE_LOCAL_EXPECTED_CONTENT,
|
||||
flush_callback_buffer_check,
|
||||
flush_callback_size_check);
|
||||
|
||||
/// cleanup
|
||||
result = az_ulib_ustream_forward_dispose(ustream_forward);
|
||||
(void)result;
|
||||
}
|
||||
|
||||
/* If the provided handle is NULL, the read shall fail with precondition. */
|
||||
static void az_ulib_ustream_forward_read_compliance_null_handle_failed(void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward* ustream_forward;
|
||||
USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY(&ustream_forward);
|
||||
uint8_t buf_result[USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH];
|
||||
size_t size_result;
|
||||
|
||||
/// act
|
||||
/// assert
|
||||
AZ_ULIB_ASSERT_PRECONDITION_CHECKED(ustream_forward->_internal.api->read(
|
||||
NULL, buf_result, USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH, &size_result));
|
||||
|
||||
/// cleanup
|
||||
az_result result = az_ulib_ustream_forward_dispose(ustream_forward);
|
||||
(void)result;
|
||||
}
|
||||
|
||||
/* If the provided handle is not the implemented buffer type, the read shall fail with precondition.
|
||||
*/
|
||||
static void az_ulib_ustream_forward_read_compliance_non_type_of_buffer_api_failed(void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward* ustream_forward;
|
||||
USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY(&ustream_forward);
|
||||
uint8_t buf_result[USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH];
|
||||
size_t size_result;
|
||||
|
||||
/// act
|
||||
/// assert
|
||||
AZ_ULIB_ASSERT_PRECONDITION_CHECKED(ustream_forward->_internal.api->read(
|
||||
ustream_forward_mock_create(),
|
||||
buf_result,
|
||||
USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH,
|
||||
&size_result));
|
||||
|
||||
/// cleanup
|
||||
az_result result = az_ulib_ustream_forward_dispose(ustream_forward);
|
||||
(void)result;
|
||||
}
|
||||
|
||||
/* If the provided buffer_length is zero, the read shall fail with precondition. */
|
||||
static void az_ulib_ustream_forward_read_compliance_buffer_with_zero_size_failed(void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward* ustream_forward;
|
||||
USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY(&ustream_forward);
|
||||
uint8_t buf_result[USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH];
|
||||
size_t size_result;
|
||||
|
||||
/// act
|
||||
/// assert
|
||||
AZ_ULIB_ASSERT_PRECONDITION_CHECKED(
|
||||
az_ulib_ustream_forward_read(ustream_forward, buf_result, 0, &size_result));
|
||||
|
||||
/// cleanup
|
||||
az_result result = az_ulib_ustream_forward_dispose(ustream_forward);
|
||||
(void)result;
|
||||
}
|
||||
|
||||
/* If the provided handle is NULL, the read shall fail with precondition. */
|
||||
static void az_ulib_ustream_forward_read_compliance_null_return_buffer_failed(void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward* ustream_forward;
|
||||
USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY(&ustream_forward);
|
||||
size_t size_result;
|
||||
|
||||
/// act
|
||||
/// assert
|
||||
AZ_ULIB_ASSERT_PRECONDITION_CHECKED(az_ulib_ustream_forward_read(
|
||||
ustream_forward, NULL, USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH, &size_result));
|
||||
|
||||
/// cleanup
|
||||
az_result result = az_ulib_ustream_forward_dispose(ustream_forward);
|
||||
(void)result;
|
||||
}
|
||||
|
||||
/* If the provided return size pointer is NULL, the read shall fail with precondition. */
|
||||
static void az_ulib_ustream_forward_read_compliance_null_return_size_failed(void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward* ustream_forward;
|
||||
USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY(&ustream_forward);
|
||||
uint8_t buf_result[USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH];
|
||||
|
||||
/// act
|
||||
/// assert
|
||||
AZ_ULIB_ASSERT_PRECONDITION_CHECKED(az_ulib_ustream_forward_read(
|
||||
ustream_forward, buf_result, USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH, NULL));
|
||||
|
||||
/// cleanup
|
||||
az_result result = az_ulib_ustream_forward_dispose(ustream_forward);
|
||||
(void)result;
|
||||
}
|
||||
#endif // AZ_NO_PRECONDITION_CHECKING
|
||||
|
||||
/* The dispose shall release all allocated resources to control the buffer. */
|
||||
static void az_ulib_ustream_forward_dispose_compliance_single_instance_succeed(void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward* ustream_forward;
|
||||
USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY(&ustream_forward);
|
||||
|
||||
/// act
|
||||
az_result result = az_ulib_ustream_forward_dispose(ustream_forward);
|
||||
|
||||
/// assert
|
||||
assert_int_equal(result, AZ_OK);
|
||||
|
||||
/// cleanup
|
||||
(void)result;
|
||||
}
|
||||
|
||||
/* The get_size shall return the number of bytes between the current position and the end
|
||||
* of the buffer. */
|
||||
static void az_ulib_ustream_forward_get_size_compliance_new_buffer_succeed(void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward* ustream_forward;
|
||||
USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY(&ustream_forward);
|
||||
|
||||
/// act
|
||||
size_t size = az_ulib_ustream_forward_get_size(ustream_forward);
|
||||
|
||||
/// assert
|
||||
assert_int_equal(size, USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH);
|
||||
|
||||
/// cleanup
|
||||
az_result result = az_ulib_ustream_forward_dispose(ustream_forward);
|
||||
(void)result;
|
||||
}
|
||||
|
||||
/* [1]The read shall copy the content in the provided buffer and return the number of valid
|
||||
* <tt>uint8_t</tt> values in the local buffer in the provided `size`. */
|
||||
/* [2]If the length of the content is bigger than the `buffer_length`, the read shall limit the copy
|
||||
* size to the buffer_length.*/
|
||||
/* [3]If there is no more content to return, the read shall return AZ_ERROR_ITEM_NOT_FOUND,
|
||||
* size shall receive 0, and do not change the content of the local buffer. */
|
||||
static void az_ulib_ustream_forward_read_compliance_get_from_original_buffer_succeed(void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward* ustream_forward;
|
||||
USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY(&ustream_forward);
|
||||
uint8_t buf_result1[USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH];
|
||||
uint8_t buf_result2[USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH];
|
||||
uint8_t buf_result3[USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH];
|
||||
size_t size_result1;
|
||||
size_t size_result2;
|
||||
size_t size_result3;
|
||||
|
||||
/// act
|
||||
az_result result1 = az_ulib_ustream_forward_read(
|
||||
ustream_forward, buf_result1, USTREAM_FORWARD_COMPLIANCE_LENGTH_1, &size_result1);
|
||||
az_result result2 = az_ulib_ustream_forward_read(
|
||||
ustream_forward, buf_result2, USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH, &size_result2);
|
||||
az_result result3 = az_ulib_ustream_forward_read(
|
||||
ustream_forward, buf_result3, USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH, &size_result3);
|
||||
|
||||
/// assert
|
||||
assert_int_equal(result1, AZ_OK);
|
||||
assert_int_equal(size_result1, USTREAM_FORWARD_COMPLIANCE_LENGTH_1);
|
||||
assert_memory_equal(USTREAM_FORWARD_COMPLIANCE_LOCAL_EXPECTED_CONTENT, buf_result1, size_result1);
|
||||
|
||||
assert_int_equal(result2, AZ_OK);
|
||||
assert_int_equal(
|
||||
size_result2,
|
||||
USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH - USTREAM_FORWARD_COMPLIANCE_LENGTH_1);
|
||||
assert_memory_equal(
|
||||
(const uint8_t* const)(
|
||||
USTREAM_FORWARD_COMPLIANCE_LOCAL_EXPECTED_CONTENT + USTREAM_FORWARD_COMPLIANCE_LENGTH_1),
|
||||
buf_result2,
|
||||
size_result2);
|
||||
|
||||
assert_int_equal(result3, AZ_ULIB_EOF);
|
||||
|
||||
/// cleanup
|
||||
az_result result = az_ulib_ustream_forward_dispose(ustream_forward);
|
||||
(void)result;
|
||||
}
|
||||
|
||||
static void az_ulib_ustream_forward_read_compliance_single_buffer_succeed(void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward* ustream_forward;
|
||||
USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY(&ustream_forward);
|
||||
uint8_t buf_result[USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH];
|
||||
size_t size_result;
|
||||
|
||||
/// act
|
||||
az_result result = az_ulib_ustream_forward_read(
|
||||
ustream_forward, buf_result, USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH, &size_result);
|
||||
|
||||
/// assert
|
||||
assert_int_equal(result, AZ_OK);
|
||||
assert_int_equal(size_result, USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH);
|
||||
assert_memory_equal(USTREAM_FORWARD_COMPLIANCE_LOCAL_EXPECTED_CONTENT, buf_result, size_result);
|
||||
|
||||
/// cleanup
|
||||
result = az_ulib_ustream_forward_dispose(ustream_forward);
|
||||
(void)result;
|
||||
}
|
||||
|
||||
static void az_ulib_ustream_forward_read_compliance_right_boundary_condition_succeed(void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward* ustream_forward;
|
||||
USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY(&ustream_forward);
|
||||
uint8_t buf_result[USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH];
|
||||
size_t size_result;
|
||||
|
||||
/// act
|
||||
az_result result = az_ulib_ustream_forward_read(
|
||||
ustream_forward,
|
||||
buf_result,
|
||||
USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH - 1,
|
||||
&size_result);
|
||||
|
||||
/// assert
|
||||
assert_int_equal(result, AZ_OK);
|
||||
assert_int_equal(size_result, USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH - 1);
|
||||
assert_memory_equal(USTREAM_FORWARD_COMPLIANCE_LOCAL_EXPECTED_CONTENT, buf_result, size_result);
|
||||
|
||||
assert_int_equal(
|
||||
az_ulib_ustream_forward_read(
|
||||
ustream_forward, buf_result, USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH, &size_result),
|
||||
AZ_OK);
|
||||
assert_int_equal(size_result, 1);
|
||||
assert_memory_equal(
|
||||
(const uint8_t* const)(
|
||||
USTREAM_FORWARD_COMPLIANCE_LOCAL_EXPECTED_CONTENT
|
||||
+ USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH - 1),
|
||||
buf_result,
|
||||
size_result);
|
||||
|
||||
assert_int_equal(
|
||||
az_ulib_ustream_forward_read(
|
||||
ustream_forward, buf_result, USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH, &size_result),
|
||||
AZ_ULIB_EOF);
|
||||
|
||||
/// cleanup
|
||||
result = az_ulib_ustream_forward_dispose(ustream_forward);
|
||||
(void)result;
|
||||
}
|
||||
|
||||
static void az_ulib_ustream_forward_read_compliance_boundary_condition_succeed(void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward* ustream_forward;
|
||||
USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY(&ustream_forward);
|
||||
uint8_t buf_result[USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH];
|
||||
size_t size_result;
|
||||
|
||||
/// act
|
||||
az_result result = az_ulib_ustream_forward_read(
|
||||
ustream_forward,
|
||||
buf_result,
|
||||
USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH,
|
||||
&size_result);
|
||||
|
||||
/// assert
|
||||
assert_int_equal(result, AZ_OK);
|
||||
assert_int_equal(size_result, USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH);
|
||||
assert_memory_equal(USTREAM_FORWARD_COMPLIANCE_LOCAL_EXPECTED_CONTENT, buf_result, size_result);
|
||||
|
||||
assert_int_equal(
|
||||
az_ulib_ustream_forward_read(
|
||||
ustream_forward, buf_result, USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH, &size_result),
|
||||
AZ_ULIB_EOF);
|
||||
|
||||
/// cleanup
|
||||
result = az_ulib_ustream_forward_dispose(ustream_forward);
|
||||
(void)result;
|
||||
}
|
||||
|
||||
static void az_ulib_ustream_forward_read_compliance_left_boundary_condition_succeed(void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward* ustream_forward;
|
||||
USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY(&ustream_forward);
|
||||
uint8_t buf_result[USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH];
|
||||
size_t size_result;
|
||||
|
||||
/// act
|
||||
az_result result = az_ulib_ustream_forward_read(
|
||||
ustream_forward,
|
||||
buf_result,
|
||||
USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH + 1,
|
||||
&size_result);
|
||||
|
||||
/// assert
|
||||
assert_int_equal(result, AZ_OK);
|
||||
assert_int_equal(size_result, USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH);
|
||||
assert_memory_equal(USTREAM_FORWARD_COMPLIANCE_LOCAL_EXPECTED_CONTENT, buf_result, size_result);
|
||||
|
||||
assert_int_equal(
|
||||
az_ulib_ustream_forward_read(
|
||||
ustream_forward, buf_result, USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH, &size_result),
|
||||
AZ_ULIB_EOF);
|
||||
|
||||
/// cleanup
|
||||
result = az_ulib_ustream_forward_dispose(ustream_forward);
|
||||
(void)result;
|
||||
}
|
||||
|
||||
static void az_ulib_ustream_forward_read_compliance_single_byte_succeed(void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward* ustream_forward;
|
||||
USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY(&ustream_forward);
|
||||
uint8_t buf_result[USTREAM_FORWARD_COMPLIANCE_TEMP_BUFFER_LENGTH];
|
||||
size_t size_result;
|
||||
|
||||
/// act
|
||||
az_result result = az_ulib_ustream_forward_read(ustream_forward, buf_result, 1, &size_result);
|
||||
|
||||
/// assert
|
||||
assert_int_equal(result, AZ_OK);
|
||||
assert_int_equal(size_result, 1);
|
||||
assert_memory_equal(USTREAM_FORWARD_COMPLIANCE_LOCAL_EXPECTED_CONTENT, buf_result, size_result);
|
||||
|
||||
check_ustream_forward_buffer(
|
||||
ustream_forward,
|
||||
1,
|
||||
USTREAM_FORWARD_COMPLIANCE_LOCAL_EXPECTED_CONTENT,
|
||||
USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH);
|
||||
|
||||
/// cleanup
|
||||
result = az_ulib_ustream_forward_dispose(ustream_forward);
|
||||
(void)result;
|
||||
}
|
||||
|
||||
#define AZ_ULIB_USTREAM_FORWARD_PRECONDITION_COMPLIANCE_UT_LIST \
|
||||
cmocka_unit_test(az_ulib_ustream_forward_dispose_compliance_null_buffer_failed), \
|
||||
cmocka_unit_test( \
|
||||
az_ulib_ustream_forward_dispose_compliance_buffer_is_not_type_of_buffer_failed), \
|
||||
cmocka_unit_test(az_ulib_ustream_forward_get_size_compliance_null_buffer_failed), \
|
||||
cmocka_unit_test( \
|
||||
az_ulib_ustream_forward_get_size_compliance_buffer_is_not_type_of_buffer_failed), \
|
||||
cmocka_unit_test(az_ulib_ustream_forward_flush_compliance_null_handle_failed), \
|
||||
cmocka_unit_test( \
|
||||
az_ulib_ustream_forward_flush_compliance_non_type_of_ustream_forward_api_failed), \
|
||||
cmocka_unit_test(az_ulib_ustream_forward_flush_compliance_null_flush_callback_failed), \
|
||||
cmocka_unit_test(az_ulib_ustream_forward_read_compliance_null_handle_failed), \
|
||||
cmocka_unit_test(az_ulib_ustream_forward_read_compliance_non_type_of_buffer_api_failed), \
|
||||
cmocka_unit_test(az_ulib_ustream_forward_read_compliance_buffer_with_zero_size_failed), \
|
||||
cmocka_unit_test(az_ulib_ustream_forward_read_compliance_null_return_buffer_failed), \
|
||||
cmocka_unit_test(az_ulib_ustream_forward_read_compliance_null_return_size_failed),
|
||||
|
||||
#define AZ_ULIB_USTREAM_FORWARD_COMPLIANCE_UT_LIST \
|
||||
cmocka_unit_test_setup_teardown( \
|
||||
az_ulib_ustream_forward_dispose_compliance_single_instance_succeed, setup, teardown), \
|
||||
cmocka_unit_test_setup_teardown( \
|
||||
az_ulib_ustream_forward_get_size_compliance_new_buffer_succeed, setup, teardown), \
|
||||
cmocka_unit_test_setup_teardown( \
|
||||
az_ulib_ustream_forward_flush_compliance_single_buffer_succeed, setup, teardown), \
|
||||
cmocka_unit_test_setup_teardown( \
|
||||
az_ulib_ustream_forward_read_compliance_get_from_original_buffer_succeed, \
|
||||
setup, \
|
||||
teardown), \
|
||||
cmocka_unit_test_setup_teardown( \
|
||||
az_ulib_ustream_forward_read_compliance_single_buffer_succeed, setup, teardown), \
|
||||
cmocka_unit_test_setup_teardown( \
|
||||
az_ulib_ustream_forward_read_compliance_right_boundary_condition_succeed, \
|
||||
setup, \
|
||||
teardown), \
|
||||
cmocka_unit_test_setup_teardown( \
|
||||
az_ulib_ustream_forward_read_compliance_boundary_condition_succeed, setup, teardown), \
|
||||
cmocka_unit_test_setup_teardown( \
|
||||
az_ulib_ustream_forward_read_compliance_left_boundary_condition_succeed, \
|
||||
setup, \
|
||||
teardown), \
|
||||
cmocka_unit_test_setup_teardown( \
|
||||
az_ulib_ustream_forward_read_compliance_single_byte_succeed, setup, teardown),
|
||||
|
||||
#endif /* AZ_ULIB_USTREAM_FORWARD_COMPLIANCE_UT_H */
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
|
||||
#ifndef AZ_ULIB_USTREAM_FORWARD_MOCK_BUFFER_H
|
||||
#define AZ_ULIB_USTREAM_FORWARD_MOCK_BUFFER_H
|
||||
|
||||
#include "az_ulib_ustream_forward.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
az_ulib_ustream_forward* ustream_forward_mock_create(void);
|
||||
|
||||
void reset_mock_buffer(void);
|
||||
void set_concurrency_ustream_forward(void);
|
||||
void set_delay_return_value(uint32_t delay);
|
||||
|
||||
void set_flush_result(az_result result);
|
||||
void set_read_result(az_result result);
|
||||
void set_dispose_result(az_result result);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* AZ_ULIB_USTREAM_FORWARD_MOCK_BUFFER_H */
|
|
@ -6,11 +6,13 @@
|
|||
#define AZ_ULIB_USTREAM_MOCK_BUFFER_H
|
||||
|
||||
#include "az_ulib_ustream_base.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstdint>
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif /* __cplusplus */
|
||||
|
||||
az_ulib_ustream* ustream_mock_create(void);
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "az_ulib_test_helpers.h"
|
||||
|
||||
#include "cmocka.h"
|
||||
|
||||
void check_buffer(
|
||||
az_ulib_ustream* ustream_instance,
|
||||
uint8_t offset,
|
||||
const uint8_t* const expected_content,
|
||||
uint8_t expected_content_length)
|
||||
{
|
||||
uint8_t buf_result[256];
|
||||
size_t size_result;
|
||||
|
||||
if (offset < expected_content_length)
|
||||
{
|
||||
assert_int_equal(az_ulib_ustream_read(ustream_instance, buf_result, 256, &size_result), AZ_OK);
|
||||
|
||||
assert_int_equal(size_result, expected_content_length - offset);
|
||||
assert_memory_equal((const uint8_t* const)(expected_content + offset), buf_result, size_result);
|
||||
}
|
||||
|
||||
size_result = 10;
|
||||
assert_int_equal(
|
||||
az_ulib_ustream_read(ustream_instance, buf_result, 256, &size_result), AZ_ULIB_EOF);
|
||||
assert_int_equal(size_result, 0);
|
||||
}
|
||||
|
||||
void check_ustream_forward_buffer(
|
||||
az_ulib_ustream_forward* ustream_forward,
|
||||
uint8_t offset,
|
||||
const uint8_t* const expected_content,
|
||||
uint8_t expected_content_length)
|
||||
{
|
||||
uint8_t buf_result[256];
|
||||
size_t size_result;
|
||||
|
||||
if (offset < expected_content_length)
|
||||
{
|
||||
assert_int_equal(az_ulib_ustream_forward_read(ustream_forward, buf_result, 256, &size_result), AZ_OK);
|
||||
|
||||
assert_int_equal(size_result, expected_content_length - offset);
|
||||
assert_memory_equal((const uint8_t* const)(expected_content + offset), buf_result, size_result);
|
||||
}
|
||||
|
||||
size_result = 10;
|
||||
assert_int_equal(
|
||||
az_ulib_ustream_forward_read(ustream_forward, buf_result, 256, &size_result), AZ_ULIB_EOF);
|
||||
assert_int_equal(size_result, 0);
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
|
||||
#include "az_ulib_result.h"
|
||||
#include "az_ulib_test_thread.h"
|
||||
#include "az_ulib_ustream_base.h"
|
||||
#include "az_ulib_ustream_forward_mock_buffer.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
static az_result _concrete_flush_result = AZ_OK;
|
||||
static az_result _concrete_read_result = AZ_OK;
|
||||
static az_result _concrete_dispose_result = AZ_OK;
|
||||
|
||||
static offset_t current_position = 0;
|
||||
|
||||
static bool concurrency_ustream_forward = false;
|
||||
static uint32_t delay_return_value = 0;
|
||||
|
||||
void reset_mock_buffer(void)
|
||||
{
|
||||
current_position = 0;
|
||||
concurrency_ustream_forward = false;
|
||||
delay_return_value = 0;
|
||||
}
|
||||
|
||||
void set_concurrency_ustream_forward(void) { concurrency_ustream_forward = true; }
|
||||
|
||||
void set_delay_return_value(uint32_t delay) { delay_return_value = delay; }
|
||||
|
||||
static az_result concrete_flush(
|
||||
az_ulib_ustream_forward* ustream_forward,
|
||||
az_ulib_flush_callback flush_callback,
|
||||
az_ulib_callback_context flush_callback_context)
|
||||
{
|
||||
(void)ustream_forward;
|
||||
(void)flush_callback;
|
||||
(void)flush_callback_context;
|
||||
|
||||
az_result result = _concrete_flush_result;
|
||||
_concrete_flush_result = AZ_OK;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static az_result concrete_read(
|
||||
az_ulib_ustream_forward* ustream_forward,
|
||||
uint8_t* const buffer,
|
||||
size_t buffer_length,
|
||||
size_t* const size)
|
||||
{
|
||||
(void)ustream_forward;
|
||||
(void)buffer;
|
||||
(void)size;
|
||||
|
||||
current_position += buffer_length;
|
||||
|
||||
*size = buffer_length;
|
||||
|
||||
az_result result = _concrete_read_result;
|
||||
_concrete_read_result = AZ_OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
static size_t concrete_get_size(az_ulib_ustream_forward* ustream_forward)
|
||||
{
|
||||
(void)ustream_forward;
|
||||
|
||||
return 10;
|
||||
}
|
||||
|
||||
static az_result concrete_dispose(az_ulib_ustream_forward* ustream_forward)
|
||||
{
|
||||
(void)ustream_forward;
|
||||
|
||||
az_result result = _concrete_dispose_result;
|
||||
_concrete_dispose_result = AZ_OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
static const az_ulib_ustream_forward_interface api
|
||||
= { concrete_flush, concrete_read, concrete_get_size, concrete_dispose };
|
||||
|
||||
static az_ulib_ustream_forward USTREAM_FORWARD_COMPLIANCE_MOCK_BUFFER
|
||||
= { ._internal.api = (const az_ulib_ustream_forward_interface*)&api,
|
||||
._internal.ptr = NULL,
|
||||
._internal.data_release = NULL,
|
||||
._internal.ustream_forward_release = NULL,
|
||||
._internal.inner_current_position = 0,
|
||||
._internal.length = 10 };
|
||||
|
||||
az_ulib_ustream_forward* ustream_forward_mock_create(void)
|
||||
{
|
||||
_concrete_flush_result = AZ_OK;
|
||||
_concrete_read_result = AZ_OK;
|
||||
_concrete_dispose_result = AZ_OK;
|
||||
|
||||
return &USTREAM_FORWARD_COMPLIANCE_MOCK_BUFFER;
|
||||
}
|
||||
|
||||
void set_flush_result(az_result result) { _concrete_flush_result = result; }
|
||||
|
||||
void set_read_result(az_result result) { _concrete_read_result = result; }
|
||||
|
||||
void set_dispose_result(az_result result) { _concrete_dispose_result = result; }
|
|
@ -2,9 +2,10 @@
|
|||
// Licensed under the MIT license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
|
||||
#include "az_ulib_ustream_mock_buffer.h"
|
||||
#include "az_ulib_result.h"
|
||||
#include "az_ulib_test_thread.h"
|
||||
#include "az_ulib_ustream_base.h"
|
||||
#include "az_ulib_ustream_mock_buffer.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
static az_result _concrete_set_position_result = AZ_OK;
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#Copyright (c) Microsoft. All rights reserved.
|
||||
#Licensed under the MIT license.
|
||||
#See LICENSE file in the project root for full license information.
|
||||
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
project(az_ulib_ustream_forward_e2e)
|
||||
|
||||
include(AddCMockaTest)
|
||||
|
||||
add_cmocka_test(az_ulib_ustream_forward_e2e SOURCES
|
||||
main.c
|
||||
az_ulib_ustream_forward_e2e.c
|
||||
${TEST_DIRECTORY}/src/az_ulib_ustream_forward_mock_buffer.c
|
||||
COMPILE_OPTIONS ${DEFAULT_C_COMPILE_FLAGS} ${NO_CLOBBERED_WARNING}
|
||||
LINK_LIBRARIES ${CMOCKA_LIBRARIES} azure_ulib_c ${PAL} az::cmocka
|
||||
LINK_OPTIONS ${WRAP_FUNCTIONS}
|
||||
# include cmoka headers and private folder headers
|
||||
INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/deps/cmocka/include ${CMAKE_SOURCE_DIR}/inc/ ${CMAKE_SOURCE_DIR}/tests/inc/
|
||||
)
|
||||
|
||||
add_cmocka_test_environment(az_ulib_ustream_forward_e2e)
|
|
@ -0,0 +1,59 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "az_ulib_ustream_forward.h"
|
||||
#include "az_ulib_ustream_forward_e2e.h"
|
||||
|
||||
#include "az_ulib_ustream_forward_mock_buffer.h"
|
||||
|
||||
#include "cmocka.h"
|
||||
|
||||
/* define constants for the compliance test */
|
||||
#define USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT \
|
||||
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
#define USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH 62
|
||||
|
||||
static const uint8_t* const USTREAM_FORWARD_COMPLIANCE_LOCAL_EXPECTED_CONTENT
|
||||
= (const uint8_t* const)USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT;
|
||||
|
||||
static void ustream_forward_factory(az_ulib_ustream_forward** ustream_forward)
|
||||
{
|
||||
*ustream_forward = (az_ulib_ustream_forward*)malloc(sizeof(az_ulib_ustream_forward));
|
||||
uint8_t* buf
|
||||
= (uint8_t*)malloc(sizeof(uint8_t) * USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH);
|
||||
assert_non_null(buf);
|
||||
(void)memcpy(
|
||||
buf,
|
||||
USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT,
|
||||
USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH);
|
||||
assert_int_equal(
|
||||
az_ulib_ustream_forward_init(
|
||||
*ustream_forward, free, buf, USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH, free),
|
||||
AZ_OK);
|
||||
}
|
||||
#define USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY(ustream_forward) \
|
||||
ustream_forward_factory(ustream_forward)
|
||||
|
||||
#define TEST_CONST_BUFFER_LENGTH (USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH + 2)
|
||||
#define TEST_CONST_MAX_BUFFER_SIZE (TEST_CONST_BUFFER_LENGTH - 1)
|
||||
|
||||
/**
|
||||
* Beginning of the e2e for ustream_forward.c on ownership model.
|
||||
*/
|
||||
|
||||
// Run e2e compliance tests for ustream_forward
|
||||
#include "az_ulib_ustream_forward_compliance_e2e.h"
|
||||
|
||||
int az_ulib_ustream_forward_e2e()
|
||||
{
|
||||
const struct CMUnitTest tests[] = { AZ_ULIB_USTREAM_FORWARD_COMPLIANCE_E2E_LIST };
|
||||
|
||||
return cmocka_run_group_tests_name("az_ulib_ustream_forward_e2e", tests, NULL, NULL);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
|
||||
#ifndef AZ_ULIB_USTREAM_FORWARD_E2E_H
|
||||
#define AZ_ULIB_USTREAM_FORWARD_E2E_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
int az_ulib_ustream_forward_e2e();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* AZ_ULIB_USTREAM_FORWARD_E2E_H */
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "az_ulib_ustream_forward_e2e.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
(void)printf("[==========]\r\n[ STARTING ] Running az_ulib_ustream_forward_e2e.\r\n");
|
||||
result += az_ulib_ustream_forward_e2e();
|
||||
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#Copyright (c) Microsoft. All rights reserved.
|
||||
#Licensed under the MIT license.
|
||||
#See LICENSE file in the project root for full license information.
|
||||
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
project(az_ulib_ustream_forward_ut)
|
||||
|
||||
include(AddCMockaTest)
|
||||
|
||||
add_cmocka_test(az_ulib_ustream_forward_ut SOURCES
|
||||
main.c
|
||||
az_ulib_ustream_forward_ut.c
|
||||
${TEST_DIRECTORY}/src/az_ulib_test_helpers.c
|
||||
${TEST_DIRECTORY}/src/az_ulib_ustream_forward_mock_buffer.c
|
||||
COMPILE_OPTIONS ${DEFAULT_C_COMPILE_FLAGS} ${NO_CLOBBERED_WARNING}
|
||||
LINK_LIBRARIES ${CMOCKA_LIBRARIES} azure_ulib_c ${PAL} az::cmocka
|
||||
LINK_OPTIONS ${WRAP_FUNCTIONS}
|
||||
# include cmoka headers and private folder headers
|
||||
INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/deps/cmocka/include ${CMAKE_SOURCE_DIR}/inc/ ${CMAKE_SOURCE_DIR}/tests/inc/
|
||||
)
|
||||
|
||||
add_cmocka_test_environment(az_ulib_ustream_forward_ut)
|
|
@ -0,0 +1,203 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "az_ulib_ustream_forward.h"
|
||||
#include "az_ulib_ustream_forward_ut.h"
|
||||
|
||||
#include "az_ulib_ustream_forward_mock_buffer.h"
|
||||
|
||||
#include "az_ulib_test_precondition.h"
|
||||
#include "azure/core/az_precondition.h"
|
||||
|
||||
#include "cmocka.h"
|
||||
|
||||
/* define constants for the compliance test */
|
||||
#define USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT \
|
||||
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
#define USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH 62
|
||||
|
||||
static const uint8_t* const USTREAM_FORWARD_COMPLIANCE_LOCAL_EXPECTED_CONTENT
|
||||
= (const uint8_t* const)USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT;
|
||||
|
||||
static az_ulib_ustream_forward test_ustream_forward;
|
||||
static void ustream_forward_factory(az_ulib_ustream_forward** ustream_forward)
|
||||
{
|
||||
*ustream_forward = (az_ulib_ustream_forward*)malloc(sizeof(az_ulib_ustream_forward));
|
||||
uint8_t* buf
|
||||
= (uint8_t*)malloc(sizeof(uint8_t) * USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH);
|
||||
assert_non_null(buf);
|
||||
(void)memcpy(
|
||||
buf,
|
||||
USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT,
|
||||
USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH);
|
||||
assert_int_equal(
|
||||
az_ulib_ustream_forward_init(
|
||||
*ustream_forward, free, buf, USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH, free),
|
||||
AZ_OK);
|
||||
}
|
||||
#define USTREAM_FORWARD_COMPLIANCE_TARGET_FACTORY(ustream_forward) \
|
||||
ustream_forward_factory(ustream_forward)
|
||||
|
||||
#define TEST_CONST_BUFFER_LENGTH (USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH + 2)
|
||||
#define TEST_CONST_MAX_BUFFER_SIZE (TEST_CONST_BUFFER_LENGTH - 1)
|
||||
|
||||
#ifndef AZ_NO_PRECONDITION_CHECKING
|
||||
AZ_ULIB_ENABLE_PRECONDITION_CHECK_TESTS()
|
||||
#endif // AZ_NO_PRECONDITION_CHECKING
|
||||
|
||||
/**
|
||||
* Beginning of the UT for ustream_forward.c on ownership model.
|
||||
*/
|
||||
static int setup(void** state)
|
||||
{
|
||||
(void)state;
|
||||
|
||||
memset(&test_ustream_forward, 0, sizeof(az_ulib_ustream_forward));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int teardown(void** state)
|
||||
{
|
||||
(void)state;
|
||||
|
||||
reset_mock_buffer();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef AZ_NO_PRECONDITION_CHECKING
|
||||
/* az_ulib_ustream_forward_init shall fail with precondition if the provided buffer is NULL. */
|
||||
static void az_ulib_ustream_forward_init_null_buffer_failed(void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward ustream_forward;
|
||||
|
||||
/// act
|
||||
/// assert
|
||||
AZ_ULIB_ASSERT_PRECONDITION_CHECKED(az_ulib_ustream_forward_init(
|
||||
&ustream_forward, NULL, NULL, USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH, NULL));
|
||||
|
||||
/// cleanup
|
||||
}
|
||||
|
||||
/* az_ulib_ustream_forward_init shall fail with precondition if the provided buffer length is zero.
|
||||
*/
|
||||
static void az_ulib_ustream_forward_init_zero_length_failed(void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward ustream_forward;
|
||||
|
||||
/// act
|
||||
/// assert
|
||||
AZ_ULIB_ASSERT_PRECONDITION_CHECKED(az_ulib_ustream_forward_init(
|
||||
&ustream_forward, NULL, USTREAM_FORWARD_COMPLIANCE_LOCAL_EXPECTED_CONTENT, 0, NULL));
|
||||
|
||||
/// cleanup
|
||||
}
|
||||
|
||||
/* az_ulib_ustream_forward_init shall fail with precondition if the provided ustream_forward
|
||||
is NULL. */
|
||||
static void az_ulib_ustream_forward_init_NULL_ustream_forward_instance_failed(void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
|
||||
/// act
|
||||
/// assert
|
||||
AZ_ULIB_ASSERT_PRECONDITION_CHECKED(az_ulib_ustream_forward_init(
|
||||
NULL,
|
||||
NULL,
|
||||
USTREAM_FORWARD_COMPLIANCE_LOCAL_EXPECTED_CONTENT,
|
||||
USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH,
|
||||
NULL));
|
||||
|
||||
/// cleanup
|
||||
}
|
||||
#endif // AZ_NO_PRECONDITION_CHECKING
|
||||
|
||||
/* az_ulib_ustream_forward_init shall create an instance of the ustream_forward and initialize the
|
||||
* instance. */
|
||||
static void az_ulib_ustream_forward_init_const_succeed(void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
az_ulib_ustream_forward ustream_forward;
|
||||
|
||||
/// act
|
||||
az_result result = az_ulib_ustream_forward_init(
|
||||
&ustream_forward,
|
||||
NULL,
|
||||
USTREAM_FORWARD_COMPLIANCE_LOCAL_EXPECTED_CONTENT,
|
||||
USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH,
|
||||
NULL);
|
||||
|
||||
/// assert
|
||||
assert_int_equal(result, AZ_OK);
|
||||
|
||||
/// cleanup
|
||||
result = az_ulib_ustream_forward_dispose(&ustream_forward);
|
||||
(void)result;
|
||||
}
|
||||
|
||||
/* az_ulib_ustream_forward_init shall create an instance of the ustream_forward and initialize the
|
||||
* instance. */
|
||||
static void az_ulib_ustream_forward_init_succeed(void** state)
|
||||
{
|
||||
/// arrange
|
||||
(void)state;
|
||||
uint8_t* buf
|
||||
= (uint8_t*)malloc(sizeof(uint8_t) * USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH);
|
||||
assert_non_null(buf);
|
||||
(void)memcpy(
|
||||
buf,
|
||||
USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT,
|
||||
USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH);
|
||||
az_ulib_ustream_forward ustream_forward;
|
||||
|
||||
/// act
|
||||
az_result result = az_ulib_ustream_forward_init(
|
||||
&ustream_forward, NULL, buf, USTREAM_FORWARD_COMPLIANCE_EXPECTED_CONTENT_LENGTH, free);
|
||||
|
||||
/// assert
|
||||
assert_int_equal(result, AZ_OK);
|
||||
|
||||
/// cleanup
|
||||
result = az_ulib_ustream_forward_dispose(&ustream_forward);
|
||||
(void)result;
|
||||
}
|
||||
|
||||
#include "az_ulib_ustream_forward_compliance_ut.h"
|
||||
|
||||
int az_ulib_ustream_forward_ut()
|
||||
{
|
||||
#ifndef AZ_NO_PRECONDITION_CHECKING
|
||||
AZ_ULIB_SETUP_PRECONDITION_CHECK_TESTS();
|
||||
#endif // AZ_NO_PRECONDITION_CHECKING
|
||||
|
||||
const struct CMUnitTest tests[] = {
|
||||
#ifndef AZ_NO_PRECONDITION_CHECKING
|
||||
cmocka_unit_test(az_ulib_ustream_forward_init_null_buffer_failed),
|
||||
cmocka_unit_test(az_ulib_ustream_forward_init_zero_length_failed),
|
||||
cmocka_unit_test(az_ulib_ustream_forward_init_NULL_ustream_forward_instance_failed),
|
||||
#endif // AZ_NO_PRECONDITION_CHECKING
|
||||
cmocka_unit_test_setup_teardown(az_ulib_ustream_forward_init_const_succeed, setup, teardown),
|
||||
cmocka_unit_test_setup_teardown(az_ulib_ustream_forward_init_succeed, setup, teardown),
|
||||
#ifndef AZ_NO_PRECONDITION_CHECKING
|
||||
AZ_ULIB_USTREAM_FORWARD_PRECONDITION_COMPLIANCE_UT_LIST
|
||||
#endif // AZ_NO_PRECONDITION_CHECKING
|
||||
AZ_ULIB_USTREAM_FORWARD_COMPLIANCE_UT_LIST
|
||||
};
|
||||
|
||||
return cmocka_run_group_tests_name("az_ulib_ustream_forward_ut", tests, NULL, NULL);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
|
||||
#ifndef AZ_ULIB_USTREAM_FORWARD_UT_H
|
||||
#define AZ_ULIB_USTREAM_FORWARD_UT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
int az_ulib_ustream_forward_ut();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* AZ_ULIB_USTREAM_FORWARD_UT_H */
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
// See LICENSE file in the project root for full license information.
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "az_ulib_ustream_forward_ut.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
(void)printf("[==========]\r\n[ STARTING ] Running az_ulib_ustream_ut.\r\n");
|
||||
result += az_ulib_ustream_forward_ut();
|
||||
|
||||
return result;
|
||||
}
|
|
@ -12,6 +12,7 @@ add_cmocka_test(az_ulib_ustream_ut SOURCES
|
|||
main.c
|
||||
az_ulib_ustream_ut.c
|
||||
az_ulib_ustream_aux_ut.c
|
||||
${TEST_DIRECTORY}/src/az_ulib_test_helpers.c
|
||||
${TEST_DIRECTORY}/src/az_ulib_ustream_mock_buffer.c
|
||||
${TEST_DIRECTORY}/src/${ULIB_PAL_OS_DIRECTORY}/az_ulib_test_thread.c
|
||||
COMPILE_OPTIONS ${DEFAULT_C_COMPILE_FLAGS} ${NO_CLOBBERED_WARNING}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "az_ulib_ustream.h"
|
||||
#include "az_ulib_ustream_ut.h"
|
||||
|
||||
#include "az_ulib_ctest_aux.h"
|
||||
#include "az_ulib_test_helpers.h"
|
||||
#include "az_ulib_ustream_mock_buffer.h"
|
||||
|
||||
#include "az_ulib_test_precondition.h"
|
||||
|
|
Загрузка…
Ссылка в новой задаче