Telemetry options constructor and component name size constraint (#1976)

This commit is contained in:
Anton Kolesnyk 2021-11-03 19:26:25 -07:00 коммит произвёл GitHub
Родитель 23802f047c
Коммит 5ad7985d50
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 73 добавлений и 26 удалений

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

@ -8,6 +8,7 @@
#include <azure/core/az_http.h>
#include <azure/core/az_http_transport.h>
#include <azure/core/az_result.h>
#include <azure/core/internal/az_precondition_internal.h>
#include <azure/core/_az_cfg_prefix.h>
@ -65,12 +66,17 @@ typedef struct
} _az_http_policy_telemetry_options;
/**
* @brief Initialize _az_http_policy_telemetry_options with default values
* @brief Creates _az_http_policy_telemetry_options with default values.
*
* @param[in] component_name The name of the SDK component.
*
* @return Initialized telemetry options.
*/
AZ_NODISCARD AZ_INLINE _az_http_policy_telemetry_options _az_http_policy_telemetry_options_default()
AZ_NODISCARD AZ_INLINE _az_http_policy_telemetry_options
_az_http_policy_telemetry_options_create(az_span component_name)
{
return (_az_http_policy_telemetry_options){ 0 };
_az_PRECONDITION_VALID_SPAN(component_name, 1, false);
return (_az_http_policy_telemetry_options){ .component_name = component_name };
}
AZ_NODISCARD AZ_INLINE _az_http_policy_apiversion_options

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

@ -46,6 +46,11 @@ AZ_NODISCARD az_result az_http_pipeline_policy_apiversion(
// "-1" below is to account for the null terminator at the end of the string.
#define _az_TELEMETRY_ID_PREFIX "azsdk-c-"
#define _az_TELEMETRY_ID_PREFIX_LENGTH (sizeof(_az_TELEMETRY_ID_PREFIX) - 1)
#define _az_TELEMETRY_COMPONENT_NAME_MAX_LENGTH 40
#define _az_TELEMETRY_VERSION_MAX_LENGTH (sizeof("12.345.6789-preview.123") - 1)
#define _az_TELEMETRY_ID_MAX_LENGTH \
(_az_TELEMETRY_ID_PREFIX_LENGTH + _az_TELEMETRY_COMPONENT_NAME_MAX_LENGTH + sizeof('/') \
+ _az_TELEMETRY_VERSION_MAX_LENGTH)
AZ_NODISCARD az_result az_http_pipeline_policy_telemetry(
_az_http_policy* ref_policies,
@ -56,14 +61,19 @@ AZ_NODISCARD az_result az_http_pipeline_policy_telemetry(
_az_PRECONDITION_NOT_NULL(ref_options);
// Format spec: https://azure.github.io/azure-sdk/general_azurecore.html#telemetry-policy
uint8_t telemetry_id_buffer[200] = _az_TELEMETRY_ID_PREFIX;
uint8_t telemetry_id_buffer[_az_TELEMETRY_ID_MAX_LENGTH] = _az_TELEMETRY_ID_PREFIX;
az_span telemetry_id = AZ_SPAN_FROM_BUFFER(telemetry_id_buffer);
{
az_span remainder = az_span_slice_to_end(telemetry_id, _az_TELEMETRY_ID_PREFIX_LENGTH);
_az_http_policy_telemetry_options* options = (_az_http_policy_telemetry_options*)(ref_options);
az_span const component_name = options->component_name;
_az_PRECONDITION_VALID_SPAN(component_name, 1, false);
#ifndef AZ_NO_PRECONDITION_CHECKING
{
int32_t const component_name_size = az_span_size(component_name);
_az_PRECONDITION_RANGE(1, component_name_size, _az_TELEMETRY_COMPONENT_NAME_MAX_LENGTH);
}
#endif // AZ_NO_PRECONDITION_CHECKING
remainder = az_span_copy(remainder, component_name);
remainder = az_span_copy_u8(remainder, '/');
@ -80,6 +90,9 @@ AZ_NODISCARD az_result az_http_pipeline_policy_telemetry(
#undef _az_TELEMETRY_ID_PREFIX
#undef _az_TELEMETRY_ID_PREFIX_LENGTH
#undef _az_TELEMETRY_COMPONENT_NAME_MAX_LENGTH
#undef _az_TELEMETRY_VERSION_MAX_LENGTH
#undef _az_TELEMETRY_ID_MAX_LENGTH
AZ_NODISCARD az_result az_http_pipeline_policy_credential(
_az_http_policy* ref_policies,

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

@ -68,16 +68,38 @@ az_result test_policy_transport(
return AZ_OK;
}
static az_span telemetry_policy_expected_value;
static az_result validate_telemetry_policy_value(
_az_http_policy* ref_policies,
void* ref_options,
az_http_request* ref_request,
az_http_response* ref_response)
{
(void)ref_policies;
(void)ref_options;
(void)ref_response;
az_span header_name = { 0 };
az_span header_value = { 0 };
assert_return_code(
az_http_request_get_header(ref_request, 0, &header_name, &header_value), AZ_OK);
assert_true(az_span_is_content_equal(header_name, AZ_SPAN_FROM_STR("User-Agent")));
assert_true(az_span_is_content_equal(header_value, telemetry_policy_expected_value));
return AZ_OK;
}
void test_az_http_pipeline_policy_telemetry(void** state)
{
(void)state;
uint8_t buf[100];
uint8_t header_buf[(2 * sizeof(_az_http_request_header))];
memset(buf, 0, sizeof(buf));
memset(header_buf, 0, sizeof(header_buf));
uint8_t url_buf[100] = { 0 };
uint8_t header_buf[(2 * sizeof(_az_http_request_header))] = { 0 };
az_span url_span = AZ_SPAN_FROM_BUFFER(buf);
az_span url_span = AZ_SPAN_FROM_BUFFER(url_buf);
az_span remainder = az_span_copy(url_span, AZ_SPAN_FROM_STR("url"));
assert_int_equal(az_span_size(remainder), 97);
az_span header_span = AZ_SPAN_FROM_BUFFER(header_buf);
@ -95,36 +117,42 @@ void test_az_http_pipeline_policy_telemetry(void** state)
AZ_OK);
// Create policy options
_az_http_policy_telemetry_options telemetry = _az_http_policy_telemetry_options_default();
_az_http_policy_telemetry_options telemetry = _az_http_policy_telemetry_options_create(
AZ_SPAN_FROM_STR("a-fourty-character-component-id-for-test"));
telemetry_policy_expected_value
= AZ_SPAN_FROM_STR("azsdk-c-a-fourty-character-component-id-for-test/" AZ_SDK_VERSION_STRING);
_az_http_policy policies[1] = {
{
._internal = {
.process = test_policy_transport,
.process = validate_telemetry_policy_value,
.options = NULL,
},
},
};
// Non-empty Component ID
telemetry.component_name = AZ_SPAN_FROM_STR("test");
{
assert_return_code(
az_http_pipeline_policy_telemetry(policies, &telemetry, &request, NULL), AZ_OK);
az_span header_name = { 0 };
az_span header_value = { 0 };
assert_return_code(az_http_request_get_header(&request, 0, &header_name, &header_value), AZ_OK);
assert_true(az_span_is_content_equal(header_name, AZ_SPAN_FROM_STR("User-Agent")));
assert_true(az_span_is_content_equal(
header_value, AZ_SPAN_FROM_STR("azsdk-c-test/" AZ_SDK_VERSION_STRING)));
}
// Valid Component ID
assert_return_code(
az_http_pipeline_policy_telemetry(policies, &telemetry, &request, NULL), AZ_OK);
#ifndef AZ_NO_PRECONDITION_CHECKING
// Non-empty Component ID
policies[0] = (_az_http_policy){
._internal = {
.process = test_policy_transport,
.options = NULL,
},
};
// Empty Component ID
telemetry.component_name = AZ_SPAN_EMPTY;
ASSERT_PRECONDITION_CHECKED(
az_http_pipeline_policy_telemetry(policies, &telemetry, &request, NULL));
// Component ID too long
telemetry.component_name = AZ_SPAN_FROM_STR("a-fourty1-character-component-id-for-test");
ASSERT_PRECONDITION_CHECKED(
az_http_pipeline_policy_telemetry(policies, &telemetry, &request, NULL));
#endif // AZ_NO_PRECONDITION_CHECKING
}