7372 lines
189 KiB
C
7372 lines
189 KiB
C
/*
|
|
* SPDX-License-Identifier: ISC
|
|
*
|
|
* Copyright (C) 2018-2021 Michael Drake <tlsa@netsurf-browser.org>
|
|
*/
|
|
|
|
#include <stdbool.h>
|
|
#include <assert.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
#include <cyaml/cyaml.h>
|
|
|
|
#include "ttest.h"
|
|
#include "test.h"
|
|
|
|
/** Macro to squash unused variable compiler warnings. */
|
|
#define UNUSED(_x) ((void)(_x))
|
|
|
|
/** Helper macro to count bytes of YAML input data. */
|
|
#define YAML_LEN(_y) (sizeof(_y) - 1)
|
|
|
|
/**
|
|
* Unit test context data.
|
|
*/
|
|
typedef struct test_data {
|
|
char **buffer;
|
|
cyaml_data_t **data;
|
|
unsigned *seq_count;
|
|
const struct cyaml_config *config;
|
|
const struct cyaml_schema_value *schema;
|
|
} test_data_t;
|
|
|
|
/**
|
|
* Common clean up function to free data loaded by tests.
|
|
*
|
|
* \param[in] data The unit test context data.
|
|
*/
|
|
static void cyaml_cleanup(void *data)
|
|
{
|
|
struct test_data *td = data;
|
|
unsigned seq_count = 0;
|
|
|
|
if (td->seq_count != NULL) {
|
|
seq_count = *(td->seq_count);
|
|
}
|
|
|
|
if (td->config->mem_fn != NULL && td->buffer != NULL) {
|
|
td->config->mem_fn(td->config->mem_ctx, *(td->buffer), 0);
|
|
}
|
|
|
|
if (td->data != NULL) {
|
|
cyaml_free(td->config, td->schema, *(td->data), seq_count);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test loading with NULL data parameter.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_null_data(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] = "";
|
|
struct target_struct {
|
|
int value;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) NULL, NULL);
|
|
if (err != CYAML_ERR_BAD_PARAM_NULL_DATA) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test saving with NULL data parameter.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_save_null_data(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
struct target_struct {
|
|
int value;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
char *buffer = NULL;
|
|
size_t len = 0;
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_save_data(&buffer, &len, config, &top_schema, NULL, 0);
|
|
if (err != CYAML_ERR_BAD_PARAM_NULL_DATA) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (buffer != NULL || len != 0) {
|
|
return ttest_fail(&tc, "Buffer/len not untouched.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading with NULL config parameter.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_null_config(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] = "";
|
|
void *data_tgt = NULL;
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = NULL,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), NULL, NULL,
|
|
(cyaml_data_t **) NULL, NULL);
|
|
if (err != CYAML_ERR_BAD_PARAM_NULL_CONFIG) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test saving with NULL config parameter.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_save_null_config(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const struct target_struct {
|
|
unsigned test_uint;
|
|
} data = {
|
|
.test_uint = 555,
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_UINT("test_uint", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, test_uint),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
char *buffer = NULL;
|
|
size_t len = 0;
|
|
test_data_t td = {
|
|
.buffer = &buffer,
|
|
.config = config,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_save_data(&buffer, &len, NULL, &top_schema, &data, 0);
|
|
if (err != CYAML_ERR_BAD_PARAM_NULL_CONFIG) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (buffer != NULL || len != 0) {
|
|
return ttest_fail(&tc, "Buffer/len not untouched.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading with NULL memory allocation function.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_null_mem_fn(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] = "";
|
|
cyaml_config_t cfg = *config;
|
|
void *data_tgt = NULL;
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = &cfg,
|
|
.schema = NULL,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
cfg.mem_fn = NULL;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, NULL,
|
|
(cyaml_data_t **) NULL, NULL);
|
|
if (err != CYAML_ERR_BAD_CONFIG_NULL_MEMFN) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test saving with NULL memory allocation function.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_save_null_mem_fn(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
cyaml_config_t cfg = *config;
|
|
static const struct target_struct {
|
|
unsigned test_uint;
|
|
} data = {
|
|
.test_uint = 555,
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_UINT("test_uint", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, test_uint),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
char *buffer = NULL;
|
|
size_t len = 0;
|
|
test_data_t td = {
|
|
.buffer = &buffer,
|
|
.config = &cfg,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
cfg.mem_fn = NULL;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_save_data(&buffer, &len, &cfg, &top_schema, &data, 0);
|
|
if (err != CYAML_ERR_BAD_CONFIG_NULL_MEMFN) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (buffer != NULL || len != 0) {
|
|
return ttest_fail(&tc, "Buffer/len not untouched.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading with NULL schema.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_null_schema(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] = "";
|
|
void *data_tgt = NULL;
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = NULL,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, NULL,
|
|
(cyaml_data_t **) NULL, NULL);
|
|
if (err != CYAML_ERR_BAD_PARAM_NULL_SCHEMA) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test saving with NULL schema.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_save_null_schema(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const struct target_struct {
|
|
unsigned test_uint;
|
|
} data = {
|
|
.test_uint = 555,
|
|
};
|
|
char *buffer = NULL;
|
|
size_t len = 0;
|
|
test_data_t td = {
|
|
.buffer = &buffer,
|
|
.config = config,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_save_data(&buffer, &len, config, NULL, &data, 0);
|
|
if (err != CYAML_ERR_BAD_PARAM_NULL_SCHEMA) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (buffer != NULL || len != 0) {
|
|
return ttest_fail(&tc, "Buffer/len not untouched.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading with schema with bad top level type (non-pointer).
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_top_level_non_pointer(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"7\n";
|
|
int *value = NULL;
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, int)
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &value,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &value, NULL);
|
|
if (err != CYAML_ERR_TOP_LEVEL_NON_PTR) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (value != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test saving with schema with bad top level type (non-pointer).
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_save_schema_top_level_non_pointer(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const struct target_struct {
|
|
unsigned test_uint;
|
|
} data = {
|
|
.test_uint = 555,
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, int)
|
|
};
|
|
char *buffer = NULL;
|
|
size_t len = 0;
|
|
test_data_t td = {
|
|
.buffer = &buffer,
|
|
.config = config,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_save_data(&buffer, &len, config, &top_schema, &data, 0);
|
|
if (err != CYAML_ERR_TOP_LEVEL_NON_PTR) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (buffer != NULL || len != 0) {
|
|
return ttest_fail(&tc, "Buffer/len not untouched.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading with schema with bad top level sequence and no seq_count.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_top_level_sequence_no_count(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"key:\n";
|
|
struct target_struct {
|
|
int *value;
|
|
unsigned value_count;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_value entry_schema = {
|
|
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, int)
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_SEQUENCE(CYAML_FLAG_POINTER, int,
|
|
&entry_schema, 0, CYAML_UNLIMITED),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_BAD_PARAM_SEQ_COUNT) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading with schema with bad top level sequence and no seq_count.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_top_level_not_sequence_count(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"7\n";
|
|
int *value = NULL;
|
|
unsigned count = 0;
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, int)
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &value,
|
|
.seq_count = &count,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &value, &count);
|
|
if (err != CYAML_ERR_BAD_PARAM_SEQ_COUNT) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (value != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test saving with schema with a non-sequence and non-zero sequence count.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_save_schema_top_level_not_sequence_count(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const struct target_struct {
|
|
unsigned *test_uint;
|
|
} data = {
|
|
.test_uint = NULL,
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_INT(CYAML_FLAG_POINTER, int)
|
|
};
|
|
char *buffer = NULL;
|
|
size_t len = 0;
|
|
test_data_t td = {
|
|
.buffer = &buffer,
|
|
.config = config,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_save_data(&buffer, &len, config, &top_schema, &data, 42);
|
|
if (err != CYAML_ERR_BAD_PARAM_SEQ_COUNT) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (buffer != NULL || len != 0) {
|
|
return ttest_fail(&tc, "Buffer/len not untouched.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading with schema with bad type.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_bad_type(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"key:\n";
|
|
struct target_struct {
|
|
int value;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
{
|
|
.key = "key",
|
|
.value = {
|
|
.type = 99999,
|
|
.flags = CYAML_FLAG_DEFAULT,
|
|
.data_size = sizeof(data_tgt->value),
|
|
},
|
|
.data_offset = offsetof(struct target_struct, value),
|
|
},
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_BAD_TYPE_IN_SCHEMA) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test saving with schema with bad type.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_save_schema_bad_type(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
struct target_struct {
|
|
int value;
|
|
} data = {
|
|
.value = 99,
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
{
|
|
.key = "key",
|
|
.value = {
|
|
.type = 99999,
|
|
.flags = CYAML_FLAG_DEFAULT,
|
|
.data_size = sizeof(data.value),
|
|
},
|
|
.data_offset = offsetof(struct target_struct, value),
|
|
},
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
char *buffer = NULL;
|
|
size_t len = 0;
|
|
test_data_t td = {
|
|
.buffer = &buffer,
|
|
.config = config,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_save_data(&buffer, &len, config, &top_schema, &data, 0);
|
|
if (err != CYAML_ERR_BAD_TYPE_IN_SCHEMA) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (buffer != NULL || len != 0) {
|
|
return ttest_fail(&tc, "Buffer/len not untouched.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading with schema with string min greater than max.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_string_min_max(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"value: foo\n";
|
|
struct target_struct {
|
|
const char *value;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_STRING_PTR("value", CYAML_FLAG_POINTER,
|
|
struct target_struct, value,
|
|
10, 9),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_BAD_MIN_MAX_SCHEMA) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Only scalar mapping keys are allowed by libcyaml.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_non_scalar_mapping_key(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"{1}: value";
|
|
struct target_struct {
|
|
unsigned value;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_UINT("key", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, value),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INTERNAL_ERROR) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading with schema with data size (0).
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_bad_data_size_1(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"key: 1\n";
|
|
struct target_struct {
|
|
int value;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
{
|
|
.key = "key",
|
|
.value = {
|
|
.type = CYAML_INT,
|
|
.flags = CYAML_FLAG_DEFAULT,
|
|
.data_size = 0,
|
|
},
|
|
.data_offset = offsetof(struct target_struct, value),
|
|
},
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_DATA_SIZE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading with schema with data size (9).
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_bad_data_size_2(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"key: 1\n";
|
|
struct target_struct {
|
|
int value;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
{
|
|
.key = "key",
|
|
.value = {
|
|
.type = CYAML_INT,
|
|
.flags = CYAML_FLAG_DEFAULT,
|
|
.data_size = 9,
|
|
},
|
|
.data_offset = offsetof(struct target_struct, value),
|
|
},
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_DATA_SIZE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading with schema with data size (0) for flags.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_bad_data_size_3(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const cyaml_strval_t strings[] = {
|
|
{ "foo", 0 },
|
|
{ "bar", 1 },
|
|
{ "baz", 2 },
|
|
{ "bat", 3 },
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"key:\n"
|
|
" - bat\n"
|
|
" - bar\n";
|
|
struct target_struct {
|
|
int value;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
{
|
|
.key = "key",
|
|
.value = {
|
|
.type = CYAML_FLAGS,
|
|
.flags = CYAML_FLAG_DEFAULT,
|
|
.data_size = 0,
|
|
.enumeration = {
|
|
.strings = strings,
|
|
.count = CYAML_ARRAY_LEN(strings),
|
|
},
|
|
},
|
|
.data_offset = offsetof(struct target_struct, value),
|
|
},
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_DATA_SIZE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading with schema with data size (0) for sequence count.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_bad_data_size_4(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"key:\n"
|
|
" - 2\n"
|
|
" - 4\n";
|
|
struct target_struct {
|
|
int *value;
|
|
unsigned value_count;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_value entry_schema = {
|
|
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, int),
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
{
|
|
.key = "key",
|
|
.value = {
|
|
.type = CYAML_SEQUENCE,
|
|
.flags = CYAML_FLAG_POINTER,
|
|
.data_size = sizeof(*(data_tgt->value)),
|
|
.sequence = {
|
|
.min = 0,
|
|
.max = CYAML_UNLIMITED,
|
|
.entry = &entry_schema,
|
|
},
|
|
},
|
|
.data_offset = offsetof(struct target_struct, value),
|
|
.count_size = 0,
|
|
.count_offset = offsetof(
|
|
struct target_struct,
|
|
value_count),
|
|
},
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_DATA_SIZE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading with schema with data size (9) for sequence count.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_bad_data_size_5(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"key:\n"
|
|
" - 2\n"
|
|
" - 4\n";
|
|
struct target_struct {
|
|
int *value;
|
|
unsigned value_count;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_value entry_schema = {
|
|
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, int),
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
{
|
|
.key = "key",
|
|
.value = {
|
|
.type = CYAML_SEQUENCE,
|
|
.flags = CYAML_FLAG_POINTER,
|
|
.data_size = sizeof(*(data_tgt->value)),
|
|
.sequence = {
|
|
.min = 0,
|
|
.max = CYAML_UNLIMITED,
|
|
.entry = &entry_schema,
|
|
},
|
|
},
|
|
.data_offset = offsetof(struct target_struct, value),
|
|
.count_size = 9,
|
|
.count_offset = offsetof(
|
|
struct target_struct,
|
|
value_count),
|
|
},
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_DATA_SIZE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading with schema with data size (9) for sequence count.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_bad_data_size_6(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"key:\n"
|
|
" - 2\n"
|
|
" - 4\n";
|
|
struct target_struct {
|
|
int value[4];
|
|
unsigned value_count;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_value entry_schema = {
|
|
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, int),
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
{
|
|
.key = "key",
|
|
.value = {
|
|
.type = CYAML_SEQUENCE,
|
|
.flags = CYAML_FLAG_DEFAULT,
|
|
.data_size = sizeof(*(data_tgt->value)),
|
|
.sequence = {
|
|
.min = 0,
|
|
.max = 4,
|
|
.entry = &entry_schema,
|
|
},
|
|
},
|
|
.data_offset = offsetof(struct target_struct, value),
|
|
.count_size = 9,
|
|
.count_offset = offsetof(
|
|
struct target_struct,
|
|
value_count),
|
|
},
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_DATA_SIZE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading with schema with data size (0).
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_bad_data_size_7(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"key: 1\n";
|
|
struct target_struct {
|
|
unsigned value;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
{
|
|
.key = "key",
|
|
.value = {
|
|
.type = CYAML_UINT,
|
|
.flags = CYAML_FLAG_DEFAULT,
|
|
.data_size = 0,
|
|
},
|
|
.data_offset = offsetof(struct target_struct, value),
|
|
},
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_DATA_SIZE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading with schema with data size (9) for bitfield.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_bad_data_size_8(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const cyaml_bitdef_t bitvals[] = {
|
|
{ .name = "a", .offset = 0, .bits = 3 },
|
|
{ .name = "b", .offset = 3, .bits = 7 },
|
|
{ .name = "c", .offset = 10, .bits = 32 },
|
|
{ .name = "d", .offset = 42, .bits = 8 },
|
|
{ .name = "e", .offset = 50, .bits = 14 },
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"test_bitfield:\n"
|
|
" a: 0x7\n"
|
|
" b: 0x7f\n"
|
|
" c: 0xffffffff\n"
|
|
" d: 0xff\n"
|
|
" e: 0x3fff\n";
|
|
struct target_struct {
|
|
uint64_t value;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
{
|
|
.key = "test_bitfield",
|
|
.value = {
|
|
.type = CYAML_BITFIELD,
|
|
.flags = CYAML_FLAG_DEFAULT,
|
|
.data_size = 9,
|
|
.bitfield = {
|
|
.bitdefs = bitvals,
|
|
.count = CYAML_ARRAY_LEN(bitvals),
|
|
},
|
|
},
|
|
.data_offset = offsetof(struct target_struct, value),
|
|
},
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_DATA_SIZE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading with schema with data size (9) for flags.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_bad_data_size_9(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const cyaml_strval_t strings[] = {
|
|
{ "foo", 0 },
|
|
{ "bar", 1 },
|
|
{ "baz", 2 },
|
|
{ "bat", 3 },
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"key:\n"
|
|
" - bat\n"
|
|
" - bar\n";
|
|
struct target_struct {
|
|
int value;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
{
|
|
.key = "key",
|
|
.value = {
|
|
.type = CYAML_FLAGS,
|
|
.flags = CYAML_FLAG_DEFAULT,
|
|
.data_size = 9,
|
|
.enumeration = {
|
|
.strings = strings,
|
|
.count = CYAML_ARRAY_LEN(strings),
|
|
},
|
|
},
|
|
.data_offset = offsetof(struct target_struct, value),
|
|
},
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_DATA_SIZE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test saving with schema with data size (0).
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_save_schema_bad_data_size_1(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const struct target_struct {
|
|
int value;
|
|
} data = {
|
|
.value = 9,
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
{
|
|
.key = "key",
|
|
.value = {
|
|
.type = CYAML_INT,
|
|
.flags = CYAML_FLAG_DEFAULT,
|
|
.data_size = 0,
|
|
},
|
|
.data_offset = offsetof(struct target_struct, value),
|
|
},
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
char *buffer = NULL;
|
|
size_t len = 0;
|
|
test_data_t td = {
|
|
.buffer = &buffer,
|
|
.config = config,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_save_data(&buffer, &len, config, &top_schema, &data, 0);
|
|
if (err != CYAML_ERR_INVALID_DATA_SIZE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (buffer != NULL || len != 0) {
|
|
return ttest_fail(&tc, "Buffer/len not untouched.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test saving with schema with data size (0).
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_save_schema_bad_data_size_2(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const struct target_struct {
|
|
unsigned value;
|
|
} data = {
|
|
.value = 9,
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
{
|
|
.key = "key",
|
|
.value = {
|
|
.type = CYAML_UINT,
|
|
.flags = CYAML_FLAG_DEFAULT,
|
|
.data_size = 0,
|
|
},
|
|
.data_offset = offsetof(struct target_struct, value),
|
|
},
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
char *buffer = NULL;
|
|
size_t len = 0;
|
|
test_data_t td = {
|
|
.buffer = &buffer,
|
|
.config = config,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_save_data(&buffer, &len, config, &top_schema, &data, 0);
|
|
if (err != CYAML_ERR_INVALID_DATA_SIZE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (buffer != NULL || len != 0) {
|
|
return ttest_fail(&tc, "Buffer/len not untouched.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test saving with schema with data size (0).
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_save_schema_bad_data_size_3(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const struct target_struct {
|
|
bool value;
|
|
} data = {
|
|
.value = 1,
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
{
|
|
.key = "key",
|
|
.value = {
|
|
.type = CYAML_BOOL,
|
|
.flags = CYAML_FLAG_DEFAULT,
|
|
.data_size = 0,
|
|
},
|
|
.data_offset = offsetof(struct target_struct, value),
|
|
},
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
char *buffer = NULL;
|
|
size_t len = 0;
|
|
test_data_t td = {
|
|
.buffer = &buffer,
|
|
.config = config,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_save_data(&buffer, &len, config, &top_schema, &data, 0);
|
|
if (err != CYAML_ERR_INVALID_DATA_SIZE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (buffer != NULL || len != 0) {
|
|
return ttest_fail(&tc, "Buffer/len not untouched.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test saving with schema with data size (0).
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_save_schema_bad_data_size_4(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
enum test_e {
|
|
FIRST, SECOND, THIRD, FOURTH, COUNT
|
|
};
|
|
static const cyaml_strval_t strings[COUNT] = {
|
|
[FIRST] = { "first", 0 },
|
|
[SECOND] = { "second", 1 },
|
|
[THIRD] = { "third", 2 },
|
|
[FOURTH] = { "fourth", 3 },
|
|
};
|
|
static const struct target_struct {
|
|
enum test_e value;
|
|
} data = {
|
|
.value = 1,
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
{
|
|
.key = "key",
|
|
.value = {
|
|
.type = CYAML_ENUM,
|
|
.flags = CYAML_FLAG_DEFAULT,
|
|
.data_size = 0,
|
|
.enumeration = {
|
|
.strings = strings,
|
|
.count = COUNT,
|
|
},
|
|
},
|
|
.data_offset = offsetof(struct target_struct, value),
|
|
},
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
char *buffer = NULL;
|
|
size_t len = 0;
|
|
test_data_t td = {
|
|
.buffer = &buffer,
|
|
.config = config,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_save_data(&buffer, &len, config, &top_schema, &data, 0);
|
|
if (err != CYAML_ERR_INVALID_DATA_SIZE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (buffer != NULL || len != 0) {
|
|
return ttest_fail(&tc, "Buffer/len not untouched.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test saving with schema with data size (5 for floating point value).
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_save_schema_bad_data_size_5(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const struct target_struct {
|
|
float value;
|
|
} data = {
|
|
.value = 3.14f,
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
{
|
|
.key = "key",
|
|
.value = {
|
|
.type = CYAML_FLOAT,
|
|
.flags = CYAML_FLAG_DEFAULT,
|
|
.data_size = 5,
|
|
},
|
|
.data_offset = offsetof(struct target_struct, value),
|
|
},
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
char *buffer = NULL;
|
|
size_t len = 0;
|
|
test_data_t td = {
|
|
.buffer = &buffer,
|
|
.config = config,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_save_data(&buffer, &len, config, &top_schema, &data, 0);
|
|
if (err != CYAML_ERR_INVALID_DATA_SIZE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (buffer != NULL || len != 0) {
|
|
return ttest_fail(&tc, "Buffer/len not untouched.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test saving with schema with data size (0).
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_save_schema_bad_data_size_6(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
enum test_f {
|
|
NONE = 0,
|
|
FIRST = (1 << 0),
|
|
SECOND = (1 << 1),
|
|
THIRD = (1 << 2),
|
|
FOURTH = (1 << 3),
|
|
};
|
|
static const cyaml_strval_t strings[] = {
|
|
{ "first", (1 << 0) },
|
|
{ "second", (1 << 1) },
|
|
{ "third", (1 << 2) },
|
|
{ "fourth", (1 << 3) },
|
|
};
|
|
static const struct target_struct {
|
|
enum test_f value;
|
|
} data = {
|
|
.value = THIRD,
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
{
|
|
.key = "key",
|
|
.value = {
|
|
.type = CYAML_FLAGS,
|
|
.flags = CYAML_FLAG_DEFAULT,
|
|
.data_size = 0,
|
|
.enumeration = {
|
|
.strings = strings,
|
|
.count = 4,
|
|
},
|
|
},
|
|
.data_offset = offsetof(struct target_struct, value),
|
|
},
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
char *buffer = NULL;
|
|
size_t len = 0;
|
|
test_data_t td = {
|
|
.buffer = &buffer,
|
|
.config = config,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_save_data(&buffer, &len, config, &top_schema, &data, 0);
|
|
if (err != CYAML_ERR_INVALID_DATA_SIZE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (buffer != NULL || len != 0) {
|
|
return ttest_fail(&tc, "Buffer/len not untouched.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test saving with schema with a bad sequence count size.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_save_schema_bad_data_size_7(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
struct target_struct {
|
|
unsigned *seq;
|
|
uint32_t seq_count;
|
|
} data = {
|
|
.seq = NULL,
|
|
};
|
|
static const struct cyaml_schema_value entry_schema = {
|
|
CYAML_VALUE_UINT(CYAML_FLAG_DEFAULT, *(data.seq)),
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
{
|
|
.key = "sequence",
|
|
.value = {
|
|
.type = CYAML_SEQUENCE,
|
|
.flags = CYAML_FLAG_POINTER,
|
|
.data_size = sizeof(*(data.seq)),
|
|
.sequence = {
|
|
.entry = &entry_schema,
|
|
.min = 0,
|
|
.max = 10,
|
|
|
|
},
|
|
},
|
|
.data_offset = offsetof(struct target_struct, seq),
|
|
.count_offset = offsetof(struct target_struct, seq_count),
|
|
.count_size = 9,
|
|
},
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
char *buffer = NULL;
|
|
size_t len = 0;
|
|
test_data_t td = {
|
|
.buffer = &buffer,
|
|
.config = config,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_save_data(&buffer, &len, config, &top_schema, &data, 0);
|
|
if (err != CYAML_ERR_INVALID_DATA_SIZE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (buffer != NULL || len != 0) {
|
|
return ttest_fail(&tc, "Buffer/len not untouched.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test saving with schema with data size (0).
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_save_schema_bad_data_size_8(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const cyaml_bitdef_t bitvals[] = {
|
|
{ .name = "a", .offset = 0, .bits = 3 },
|
|
{ .name = "b", .offset = 3, .bits = 7 },
|
|
{ .name = "c", .offset = 10, .bits = 32 },
|
|
{ .name = "d", .offset = 42, .bits = 8 },
|
|
{ .name = "e", .offset = 50, .bits = 14 },
|
|
};
|
|
static const struct target_struct {
|
|
uint64_t test_bitfield;
|
|
} data = {
|
|
.test_bitfield = 0xFFFFFFFFFFFFFFFFu,
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
{
|
|
.key = "test_bitfield",
|
|
.value = {
|
|
.type = CYAML_BITFIELD,
|
|
.flags = CYAML_FLAG_DEFAULT,
|
|
.data_size = 0,
|
|
.bitfield = {
|
|
.bitdefs = bitvals,
|
|
.count = CYAML_ARRAY_LEN(bitvals),
|
|
},
|
|
},
|
|
.data_offset = offsetof(struct target_struct,
|
|
test_bitfield),
|
|
},
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
char *buffer = NULL;
|
|
size_t len = 0;
|
|
test_data_t td = {
|
|
.buffer = &buffer,
|
|
.config = config,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_save_data(&buffer, &len, config, &top_schema,
|
|
&data, 0);
|
|
if (err != CYAML_ERR_INVALID_DATA_SIZE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (buffer != NULL || len != 0) {
|
|
return ttest_fail(&tc, "Buffer/len not untouched.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading with schema with sequence fixed with unequal min and max.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_sequence_min_max(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"sequence:\n"
|
|
" - \n";
|
|
struct target_struct {
|
|
unsigned *seq;
|
|
uint32_t seq_count;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_value entry_schema = {
|
|
CYAML_VALUE_UINT(CYAML_FLAG_DEFAULT, *(data_tgt->seq)),
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
{
|
|
.key = "sequence",
|
|
.value = {
|
|
.type = CYAML_SEQUENCE_FIXED,
|
|
.flags = CYAML_FLAG_POINTER,
|
|
.data_size = sizeof(*(data_tgt->seq)),
|
|
.sequence = {
|
|
.entry = &entry_schema,
|
|
.min = 0,
|
|
.max = CYAML_UNLIMITED,
|
|
|
|
},
|
|
},
|
|
.data_offset = offsetof(struct target_struct, seq),
|
|
.count_offset = offsetof(struct target_struct, seq_count),
|
|
.count_size = sizeof(data_tgt->seq_count),
|
|
},
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_SEQUENCE_FIXED_COUNT) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test saving with schema with sequence fixed with unequal min and max.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_save_schema_sequence_min_max(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
unsigned value = 5;
|
|
struct target_struct {
|
|
unsigned *seq;
|
|
} data = {
|
|
.seq = &value,
|
|
};
|
|
static const struct cyaml_schema_value entry_schema = {
|
|
CYAML_VALUE_UINT(CYAML_FLAG_DEFAULT, *(data.seq)),
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
{
|
|
.key = "sequence",
|
|
.value = {
|
|
.type = CYAML_SEQUENCE_FIXED,
|
|
.flags = CYAML_FLAG_POINTER,
|
|
.data_size = sizeof(*(data.seq)),
|
|
.sequence = {
|
|
.entry = &entry_schema,
|
|
.min = 0,
|
|
.max = CYAML_UNLIMITED,
|
|
|
|
},
|
|
},
|
|
.data_offset = offsetof(struct target_struct, seq),
|
|
},
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
char *buffer = NULL;
|
|
size_t len = 0;
|
|
test_data_t td = {
|
|
.buffer = &buffer,
|
|
.config = config,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_save_data(&buffer, &len, config, &top_schema, &data, 0);
|
|
if (err != CYAML_ERR_SEQUENCE_FIXED_COUNT) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (buffer != NULL || len != 0) {
|
|
return ttest_fail(&tc, "Buffer/len not untouched.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading with schema with data size for float.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_bad_data_size_float(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"key: 1\n";
|
|
struct target_struct {
|
|
int value;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
{
|
|
.key = "key",
|
|
.value = {
|
|
.type = CYAML_FLOAT,
|
|
.flags = CYAML_FLAG_DEFAULT,
|
|
.data_size = 7,
|
|
},
|
|
.data_offset = offsetof(struct target_struct, value),
|
|
},
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_DATA_SIZE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading with schema with sequence in sequence.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_sequence_in_sequence(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"- -\n";
|
|
unsigned **seq = NULL;
|
|
unsigned count = 0;
|
|
static const struct cyaml_schema_value inner_entry_schema = {
|
|
CYAML_VALUE_UINT(CYAML_FLAG_DEFAULT, **seq),
|
|
};
|
|
static const struct cyaml_schema_value outer_entry_schema = {
|
|
CYAML_VALUE_SEQUENCE(CYAML_FLAG_POINTER, unsigned,
|
|
&inner_entry_schema, 0, CYAML_UNLIMITED)
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_SEQUENCE(CYAML_FLAG_POINTER, unsigned *,
|
|
&outer_entry_schema, 0, CYAML_UNLIMITED)
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &seq,
|
|
.seq_count = &count,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &seq, &count);
|
|
if (err != CYAML_ERR_SEQUENCE_IN_SEQUENCE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (seq != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test saving with schema with sequence in sequence.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_save_schema_sequence_in_sequence(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned seq[4] = { 1, 2, 3 };
|
|
static const unsigned *data[] = { seq, seq };
|
|
static const struct cyaml_schema_value inner_entry_schema = {
|
|
CYAML_VALUE_UINT(CYAML_FLAG_DEFAULT, **data),
|
|
};
|
|
static const struct cyaml_schema_value outer_entry_schema = {
|
|
CYAML_VALUE_SEQUENCE(CYAML_FLAG_POINTER, unsigned,
|
|
&inner_entry_schema, 0, CYAML_UNLIMITED)
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_SEQUENCE(CYAML_FLAG_POINTER, unsigned *,
|
|
&outer_entry_schema, 0, CYAML_UNLIMITED)
|
|
};
|
|
char *buffer = NULL;
|
|
size_t len = 0;
|
|
test_data_t td = {
|
|
.buffer = &buffer,
|
|
.config = config,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_save_data(&buffer, &len, config, &top_schema, &data, 2);
|
|
if (err != CYAML_ERR_SEQUENCE_IN_SEQUENCE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (buffer != NULL || len != 0) {
|
|
return ttest_fail(&tc, "Buffer/len not untouched.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects uint, but value is invalid.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_uint(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: scalar\n";
|
|
struct target_struct {
|
|
unsigned a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_UINT("a", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading with schema with string top level type, with bad value.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_string(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"{ Hello }\n";
|
|
char *value = NULL;
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_STRING(CYAML_FLAG_POINTER, int, 0, CYAML_UNLIMITED)
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &value,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &value, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when flags expected, but numerical value has trailing junk.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_flags_junk(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
enum test_flags {
|
|
TEST_FLAGS_NONE = 0,
|
|
TEST_FLAGS_FIRST = (1 << 0),
|
|
TEST_FLAGS_SECOND = (1 << 1),
|
|
TEST_FLAGS_THIRD = (1 << 2),
|
|
TEST_FLAGS_FOURTH = (1 << 3),
|
|
TEST_FLAGS_FIFTH = (1 << 4),
|
|
TEST_FLAGS_SIXTH = (1 << 5),
|
|
};
|
|
static const cyaml_strval_t strings[] = {
|
|
{ "first", (1 << 0) },
|
|
{ "second", (1 << 1) },
|
|
{ "third", (1 << 2) },
|
|
{ "fourth", (1 << 3) },
|
|
{ "fifth", (1 << 4) },
|
|
{ "sixth", (1 << 5) },
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"key:\n"
|
|
" - first\n"
|
|
" - 1thousand\n";
|
|
struct target_struct {
|
|
enum test_flags a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_FLAGS("key", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a,
|
|
strings, CYAML_ARRAY_LEN(strings)),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects flags, but numerical value is invalid.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_flags_1(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
enum test_flags {
|
|
TEST_FLAGS_NONE = 0,
|
|
TEST_FLAGS_FIRST = (1 << 0),
|
|
TEST_FLAGS_SECOND = (1 << 1),
|
|
TEST_FLAGS_THIRD = (1 << 2),
|
|
TEST_FLAGS_FOURTH = (1 << 3),
|
|
TEST_FLAGS_FIFTH = (1 << 4),
|
|
TEST_FLAGS_SIXTH = (1 << 5),
|
|
};
|
|
static const cyaml_strval_t strings[] = {
|
|
{ "first", (1 << 0) },
|
|
{ "second", (1 << 1) },
|
|
{ "third", (1 << 2) },
|
|
{ "fourth", (1 << 3) },
|
|
{ "fifth", (1 << 4) },
|
|
{ "sixth", (1 << 5) },
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"key:\n"
|
|
" - first\n"
|
|
" - -7\n";
|
|
struct target_struct {
|
|
enum test_flags a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_FLAGS("key", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a,
|
|
strings, CYAML_ARRAY_LEN(strings)),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects flags, but numerical value is invalid.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_flags_2(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
enum test_flags {
|
|
TEST_FLAGS_NONE = 0,
|
|
TEST_FLAGS_FIRST = (1 << 0),
|
|
TEST_FLAGS_SECOND = (1 << 1),
|
|
TEST_FLAGS_THIRD = (1 << 2),
|
|
TEST_FLAGS_FOURTH = (1 << 3),
|
|
TEST_FLAGS_FIFTH = (1 << 4),
|
|
TEST_FLAGS_SIXTH = (1 << 5),
|
|
};
|
|
static const cyaml_strval_t strings[] = {
|
|
{ "first", (1 << 0) },
|
|
{ "second", (1 << 1) },
|
|
{ "third", (1 << 2) },
|
|
{ "fourth", (1 << 3) },
|
|
{ "fifth", (1 << 4) },
|
|
{ "sixth", (1 << 5) },
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"key:\n"
|
|
" - first\n"
|
|
" - 0x100000000\n";
|
|
struct target_struct {
|
|
enum test_flags a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_FLAGS("key", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a,
|
|
strings, CYAML_ARRAY_LEN(strings)),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects flags, but numerical value is invalid.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_flags_3(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
enum test_flags {
|
|
TEST_FLAGS_NONE = 0,
|
|
TEST_FLAGS_FIRST = (1 << 0),
|
|
TEST_FLAGS_SECOND = (1 << 1),
|
|
TEST_FLAGS_THIRD = (1 << 2),
|
|
TEST_FLAGS_FOURTH = (1 << 3),
|
|
TEST_FLAGS_FIFTH = (1 << 4),
|
|
TEST_FLAGS_SIXTH = (1 << 5),
|
|
};
|
|
static const cyaml_strval_t strings[] = {
|
|
{ "first", (1 << 0) },
|
|
{ "second", (1 << 1) },
|
|
{ "third", (1 << 2) },
|
|
{ "fourth", (1 << 3) },
|
|
{ "fifth", (1 << 4) },
|
|
{ "sixth", (1 << 5) },
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"key:\n"
|
|
" - first\n"
|
|
" - 0x10000000000000000\n";
|
|
struct target_struct {
|
|
enum test_flags a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_FLAGS("key", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a,
|
|
strings, CYAML_ARRAY_LEN(strings)),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test saving a NULL when NULLs aren't allowed by the schema.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_save_schema_invalid_value_null_ptr(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const int d[] = { 7, 6, 5, 4, 3, 2, 1, 0 };
|
|
static const int *data[] = { d + 0, d + 1, d + 2, NULL,
|
|
d + 4, d + 5, d + 6, d + 7, };
|
|
static const struct cyaml_schema_value entry_schema = {
|
|
CYAML_VALUE_INT(CYAML_FLAG_POINTER, int)
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_SEQUENCE(CYAML_FLAG_POINTER, int,
|
|
&entry_schema, 0, 3),
|
|
};
|
|
char *buffer = NULL;
|
|
size_t len = 0;
|
|
cyaml_config_t cfg = *config;
|
|
test_data_t td = {
|
|
.buffer = &buffer,
|
|
.config = &cfg,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
cfg.flags |= CYAML_CFG_STYLE_BLOCK;
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_save_data(&buffer, &len, &cfg, &top_schema, data,
|
|
CYAML_ARRAY_LEN(data));
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects bitfield, but numerical value is invalid.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_bitfield_1(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const cyaml_bitdef_t bitvals[] = {
|
|
{ .name = "a", .offset = 0, .bits = 3 },
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"test_bitfield:\n"
|
|
" a: invalid\n";
|
|
struct target_struct {
|
|
uint64_t test_value_bitfield;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_BITFIELD("test_bitfield", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, test_value_bitfield,
|
|
bitvals, CYAML_ARRAY_LEN(bitvals)),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects bitfield, but value is non-scalar.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_bitfield_2(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const cyaml_bitdef_t bitvals[] = {
|
|
{ .name = "a", .offset = 0, .bits = 3 },
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"test_bitfield:\n"
|
|
" a: {}\n";
|
|
struct target_struct {
|
|
uint64_t test_value_bitfield;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_BITFIELD("test_bitfield", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, test_value_bitfield,
|
|
bitvals, CYAML_ARRAY_LEN(bitvals)),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_UNEXPECTED_EVENT) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects bitfield, but value is not in schema.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_bitfield_3(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const cyaml_bitdef_t bitvals[] = {
|
|
{ .name = "a", .offset = 0, .bits = 3 },
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"test_bitfield:\n"
|
|
" b: {}\n";
|
|
struct target_struct {
|
|
uint64_t test_value_bitfield;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_BITFIELD("test_bitfield", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, test_value_bitfield,
|
|
bitvals, CYAML_ARRAY_LEN(bitvals)),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects bitfield, but value too big.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_bitfield_4(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const cyaml_bitdef_t bitvals[] = {
|
|
{ .name = "a", .offset = 0, .bits = 3 },
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"test_bitfield:\n"
|
|
" a: 0xf\n";
|
|
struct target_struct {
|
|
uint64_t test_value_bitfield;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_BITFIELD("test_bitfield", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, test_value_bitfield,
|
|
bitvals, CYAML_ARRAY_LEN(bitvals)),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects bitfield, but value is of wrong type.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_bitfield_5(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const cyaml_bitdef_t bitvals[] = {
|
|
{ .name = "a", .offset = 0, .bits = 3 },
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"test_bitfield:\n"
|
|
" {}: {}\n";
|
|
struct target_struct {
|
|
uint64_t test_value_bitfield;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_BITFIELD("test_bitfield", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, test_value_bitfield,
|
|
bitvals, CYAML_ARRAY_LEN(bitvals)),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_UNEXPECTED_EVENT) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects bitfield, but value is of wrong type.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_bitfield_6(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const cyaml_bitdef_t bitvals[] = {
|
|
{ .name = "a", .offset = 0, .bits = 3 },
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"test_bitfield:\n"
|
|
" []\n";
|
|
struct target_struct {
|
|
uint64_t test_value_bitfield;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_BITFIELD("test_bitfield", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, test_value_bitfield,
|
|
bitvals, CYAML_ARRAY_LEN(bitvals)),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects bitfield, but value outside data.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_bad_bitfield(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const cyaml_bitdef_t bitvals[] = {
|
|
{ .name = "a", .offset = 62, .bits = 4 },
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"test_bitfield:\n"
|
|
" a: 1\n";
|
|
struct target_struct {
|
|
uint64_t test_value_bitfield;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_BITFIELD("test_bitfield", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, test_value_bitfield,
|
|
bitvals, CYAML_ARRAY_LEN(bitvals)),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_BAD_BITVAL_IN_SCHEMA) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test saving when schema has bitfield defined outside value data.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_save_schema_bad_bitfield(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const cyaml_bitdef_t bitvals[] = {
|
|
{ .name = "a", .offset = 30, .bits = 4 },
|
|
};
|
|
static const struct target_struct {
|
|
uint32_t test_bitfield;
|
|
} data = {
|
|
.test_bitfield = 0xFFFFFFFFu,
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_BITFIELD("test_bitfield", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, test_bitfield,
|
|
bitvals, CYAML_ARRAY_LEN(bitvals)),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
char *buffer = NULL;
|
|
size_t len = 0;
|
|
test_data_t td = {
|
|
.buffer = &buffer,
|
|
.config = config,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_save_data(&buffer, &len, config, &top_schema,
|
|
&data, 0);
|
|
if (err != CYAML_ERR_BAD_BITVAL_IN_SCHEMA) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (buffer != NULL || len != 0) {
|
|
return ttest_fail(&tc, "Buffer/len not untouched.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects float but value is out of range.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_float_range1(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: 3.5e+38\n";
|
|
struct target_struct {
|
|
float a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_FLOAT("a",
|
|
CYAML_FLAG_DEFAULT | CYAML_FLAG_STRICT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects float but value is out of range.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_float_range2(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: -3.5e+38\n";
|
|
struct target_struct {
|
|
float a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_FLOAT("a",
|
|
CYAML_FLAG_DEFAULT | CYAML_FLAG_STRICT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects float but value is out of range.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_float_range3(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: 1.55331e-40f\n";
|
|
struct target_struct {
|
|
float a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_FLOAT("a",
|
|
CYAML_FLAG_DEFAULT | CYAML_FLAG_STRICT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects float but value is out of range.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_float_range4(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: -1.55331e-40f\n";
|
|
struct target_struct {
|
|
float a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_FLOAT("a",
|
|
CYAML_FLAG_DEFAULT | CYAML_FLAG_STRICT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects float but value is invalid.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_float_junk(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: 0.452*00E003\n";
|
|
struct target_struct {
|
|
float a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_FLOAT("a", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects float but value is invalid.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_float_invalid(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: Gasp\n";
|
|
struct target_struct {
|
|
float a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_FLOAT("a", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects double but value is out of range.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_double_range1(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: 1.8e+4999\n";
|
|
struct target_struct {
|
|
double a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_FLOAT("a",
|
|
CYAML_FLAG_DEFAULT | CYAML_FLAG_STRICT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects double but value is out of range.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_double_range2(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: -1.8e+4999\n";
|
|
struct target_struct {
|
|
double a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_FLOAT("a",
|
|
CYAML_FLAG_DEFAULT | CYAML_FLAG_STRICT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects double but value is invalid.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_double_junk(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: 0.452*00E003\n";
|
|
struct target_struct {
|
|
double a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_FLOAT("a", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects double but value is invalid.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_double_invalid(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: Gasp\n";
|
|
struct target_struct {
|
|
double a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_FLOAT("a", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects int but value has trailing junk.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_int_junk(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: 3*9+4\n";
|
|
struct target_struct {
|
|
int a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_INT("a", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects int but value is out of range.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_int_range_1(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: -129\n";
|
|
struct target_struct {
|
|
signed char a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_INT("a", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects int but value is out of range.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_int_range_2(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: 128\n";
|
|
struct target_struct {
|
|
signed char a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_INT("a", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects int but value is out of range.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_int_range_3(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: 0x10000\n";
|
|
struct target_struct {
|
|
int16_t a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_INT("a", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects int but value is out of range.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_int_range_4(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: 0x100000000\n";
|
|
struct target_struct {
|
|
int32_t a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_INT("a", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects int but value is out of range.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_int_range_5(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: 0x10000000000000000\n";
|
|
struct target_struct {
|
|
int32_t a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_INT("a", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects uint but value has trailing junk.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_uint_junk(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: 3*8+4\n";
|
|
struct target_struct {
|
|
unsigned int a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_UINT("a", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects uint but value is out of range.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_uint_range_1(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: -1\n";
|
|
struct target_struct {
|
|
unsigned char a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_UINT("a", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects uint but value is out of range.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_uint_range_2(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: 256\n";
|
|
struct target_struct {
|
|
unsigned char a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_UINT("a", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects uint but value is out of range.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_uint_range_3(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: 0x10000\n";
|
|
struct target_struct {
|
|
uint16_t a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_UINT("a", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects uint but value is out of range.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_uint_range_4(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: 0x100000000\n";
|
|
struct target_struct {
|
|
uint32_t a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_UINT("a", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects uint but value is out of range.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_uint_range_5(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: 0x10000000000000000\n";
|
|
struct target_struct {
|
|
uint32_t a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_UINT("a", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test integer limit.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_int8_limit_neg(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"val: -129\n";
|
|
struct target_struct {
|
|
int8_t val;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_INT("val", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, val),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test integer limit.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_int8_limit_pos(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"val: 128\n";
|
|
struct target_struct {
|
|
int8_t val;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_INT("val", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, val),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test integer limit.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_int16_limit_neg(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"val: -32769\n";
|
|
struct target_struct {
|
|
int16_t val;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_INT("val", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, val),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test integer limit.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_int16_limit_pos(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"val: 32768\n";
|
|
struct target_struct {
|
|
int16_t val;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_INT("val", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, val),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test integer limit.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_int32_limit_neg(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"val: -2147483649\n";
|
|
struct target_struct {
|
|
int32_t val;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_INT("val", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, val),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test integer limit.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_int32_limit_pos(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"val: 2147483648\n";
|
|
struct target_struct {
|
|
int32_t val;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_INT("val", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, val),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test integer limit.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_int64_limit_neg(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"val: -9223372036854775809\n";
|
|
struct target_struct {
|
|
int64_t val;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_INT("val", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, val),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test integer limit.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_invalid_value_int64_limit_pos(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"val: 9223372036854775808\n";
|
|
struct target_struct {
|
|
int64_t val;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_INT("val", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, val),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects string, but it's too short.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_string_min_length(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: foo\n";
|
|
struct target_struct {
|
|
char *a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_STRING_PTR("a", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a, 4, 4),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_STRING_LENGTH_MIN) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects string, but it's too long.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_string_max_length(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: fifth\n";
|
|
struct target_struct {
|
|
char *a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_STRING_PTR("a", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a, 4, 4),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_STRING_LENGTH_MAX) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading a mapping with a duplicate field.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_duplicate_mapping_field(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"test_uint: 9998\n"
|
|
"test_uint: 9999\n";
|
|
struct target_struct {
|
|
unsigned test_value_uint;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_UINT("test_uint", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, test_value_uint),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_UNEXPECTED_EVENT) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects mapping field which is not present.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_missing_mapping_field(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"a: 2\n";
|
|
struct target_struct {
|
|
int a;
|
|
int b;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_INT("a", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_INT("b", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, b),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_MAPPING_FIELD_MISSING) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema disallows mapping field.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_unknown_mapping_field(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"wrong_key: 2\n";
|
|
struct target_struct {
|
|
int a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_INT("key", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_KEY) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects sequence, it has too few entries.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_sequence_min_entries(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"key:\n"
|
|
" - 1\n"
|
|
" - 2\n";
|
|
struct target_struct {
|
|
int *a;
|
|
unsigned a_count;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_value entry_schema = {
|
|
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, *(data_tgt->a)),
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_SEQUENCE("key", CYAML_FLAG_POINTER,
|
|
struct target_struct, a, &entry_schema,
|
|
3, CYAML_UNLIMITED),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_SEQUENCE_ENTRIES_MIN) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects sequence, it has too many entries.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_sequence_max_entries(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"key:\n"
|
|
" - 1\n"
|
|
" - 2\n"
|
|
" - 3\n";
|
|
struct target_struct {
|
|
int *a;
|
|
unsigned a_count;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_value entry_schema = {
|
|
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, *(data_tgt->a)),
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_SEQUENCE("key", CYAML_FLAG_POINTER,
|
|
struct target_struct, a, &entry_schema,
|
|
2, 2),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_SEQUENCE_ENTRIES_MAX) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects flags and finds a mapping inside.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_flags_mapping(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
enum test_flags {
|
|
TEST_FLAGS_NONE = 0,
|
|
TEST_FLAGS_FIRST = (1 << 0),
|
|
TEST_FLAGS_SECOND = (1 << 1),
|
|
TEST_FLAGS_THIRD = (1 << 2),
|
|
TEST_FLAGS_FOURTH = (1 << 3),
|
|
TEST_FLAGS_FIFTH = (1 << 4),
|
|
TEST_FLAGS_SIXTH = (1 << 5),
|
|
};
|
|
static const cyaml_strval_t strings[] = {
|
|
{ "first", (1 << 0) },
|
|
{ "second", (1 << 1) },
|
|
{ "third", (1 << 2) },
|
|
{ "fourth", (1 << 3) },
|
|
{ "fifth", (1 << 4) },
|
|
{ "sixth", (1 << 5) },
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"key:\n"
|
|
" - first\n"
|
|
" - map:\n"
|
|
" a:\n"
|
|
" b:\n";
|
|
struct target_struct {
|
|
enum test_flags a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_FLAGS("key", CYAML_FLAG_STRICT,
|
|
struct target_struct, a,
|
|
strings, CYAML_ARRAY_LEN(strings)),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_UNEXPECTED_EVENT) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects enum, but string is not allowed.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_enum_bad_string(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
enum test_enum {
|
|
TEST_ENUM_FIRST,
|
|
TEST_ENUM_SECOND,
|
|
TEST_ENUM_THIRD,
|
|
TEST_ENUM__COUNT,
|
|
};
|
|
static const cyaml_strval_t strings[TEST_ENUM__COUNT] = {
|
|
[TEST_ENUM_FIRST] = { "first", 0 },
|
|
[TEST_ENUM_SECOND] = { "second", 1 },
|
|
[TEST_ENUM_THIRD] = { "third", 2 },
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"key: fourth\n";
|
|
struct target_struct {
|
|
enum test_enum a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_ENUM("key", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a,
|
|
strings, TEST_ENUM__COUNT),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects flags but YAML has bad flag string.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_flags_bad_string(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
enum test_flags {
|
|
TEST_FLAGS_NONE = 0,
|
|
TEST_FLAGS_FIRST = (1 << 0),
|
|
TEST_FLAGS_SECOND = (1 << 1),
|
|
TEST_FLAGS_THIRD = (1 << 2),
|
|
TEST_FLAGS_FOURTH = (1 << 3),
|
|
TEST_FLAGS_FIFTH = (1 << 4),
|
|
TEST_FLAGS_SIXTH = (1 << 5),
|
|
};
|
|
static const cyaml_strval_t strings[] = {
|
|
{ "first", (1 << 0) },
|
|
{ "second", (1 << 1) },
|
|
{ "third", (1 << 2) },
|
|
{ "fourth", (1 << 3) },
|
|
{ "fifth", (1 << 4) },
|
|
{ "sixth", (1 << 5) },
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"key:\n"
|
|
" - first\n"
|
|
" - seventh\n";
|
|
struct target_struct {
|
|
enum test_flags a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_FLAGS("key", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a,
|
|
strings, CYAML_ARRAY_LEN(strings)),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test saving when schema expects strict enum, but value not allowed.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_save_schema_strict_enum_bad_value(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
enum test_enum {
|
|
TEST_ENUM_FIRST,
|
|
TEST_ENUM_SECOND,
|
|
TEST_ENUM_THIRD,
|
|
TEST_ENUM__COUNT,
|
|
};
|
|
static const cyaml_strval_t strings[TEST_ENUM__COUNT] = {
|
|
[TEST_ENUM_FIRST] = { "first", 0 },
|
|
[TEST_ENUM_SECOND] = { "second", 1 },
|
|
[TEST_ENUM_THIRD] = { "third", 2 },
|
|
};
|
|
struct target_struct {
|
|
enum test_enum a;
|
|
} data = {
|
|
.a = 876,
|
|
};
|
|
char *buffer = NULL;
|
|
size_t len = 0;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_ENUM("key", CYAML_FLAG_STRICT,
|
|
struct target_struct, a,
|
|
strings, TEST_ENUM__COUNT),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.buffer = &buffer,
|
|
.config = config,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_save_data(&buffer, &len, config, &top_schema,
|
|
&data, 0);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (buffer != NULL || len != 0) {
|
|
return ttest_fail(&tc, "Buffer/len not untouched.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects strict enum but YAML has bad string.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_strict_enum_bad_string(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
enum test_enum {
|
|
TEST_ENUM_FIRST,
|
|
TEST_ENUM_SECOND,
|
|
TEST_ENUM_THIRD,
|
|
TEST_ENUM__COUNT,
|
|
};
|
|
static const cyaml_strval_t strings[TEST_ENUM__COUNT] = {
|
|
[TEST_ENUM_FIRST] = { "first", 0 },
|
|
[TEST_ENUM_SECOND] = { "second", 1 },
|
|
[TEST_ENUM_THIRD] = { "third", 2 },
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"key: fourth\n";
|
|
struct target_struct {
|
|
enum test_enum a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_ENUM("key", CYAML_FLAG_STRICT,
|
|
struct target_struct, a,
|
|
strings, TEST_ENUM__COUNT),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test saving when schema expects strict flags, but value not allowed.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_save_schema_strict_flags_bad_value(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
enum test_flags {
|
|
TEST_FLAGS_NONE = 0,
|
|
TEST_FLAGS_FIRST = (1 << 0),
|
|
TEST_FLAGS_SECOND = (1 << 1),
|
|
TEST_FLAGS_THIRD = (1 << 2),
|
|
TEST_FLAGS_FOURTH = (1 << 3),
|
|
TEST_FLAGS_FIFTH = (1 << 4),
|
|
TEST_FLAGS_SIXTH = (1 << 5),
|
|
};
|
|
static const cyaml_strval_t strings[] = {
|
|
{ "first", (1 << 0) },
|
|
{ "second", (1 << 1) },
|
|
{ "third", (1 << 2) },
|
|
{ "fourth", (1 << 3) },
|
|
{ "fifth", (1 << 4) },
|
|
{ "sixth", (1 << 5) },
|
|
};
|
|
struct target_struct {
|
|
enum test_flags a;
|
|
} data = {
|
|
.a = TEST_FLAGS_SECOND | TEST_FLAGS_FIFTH | (1 << 9),
|
|
};
|
|
char *buffer = NULL;
|
|
size_t len = 0;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_FLAGS("key", CYAML_FLAG_STRICT,
|
|
struct target_struct, a,
|
|
strings, CYAML_ARRAY_LEN(strings)),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.buffer = &buffer,
|
|
.config = config,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_save_data(&buffer, &len, config, &top_schema,
|
|
&data, 0);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (buffer != NULL || len != 0) {
|
|
return ttest_fail(&tc, "Buffer/len not untouched.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects strict flags but YAML has bad string.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_strict_flags_bad_string(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
enum test_flags {
|
|
TEST_FLAGS_NONE = 0,
|
|
TEST_FLAGS_FIRST = (1 << 0),
|
|
TEST_FLAGS_SECOND = (1 << 1),
|
|
TEST_FLAGS_THIRD = (1 << 2),
|
|
TEST_FLAGS_FOURTH = (1 << 3),
|
|
TEST_FLAGS_FIFTH = (1 << 4),
|
|
TEST_FLAGS_SIXTH = (1 << 5),
|
|
};
|
|
static const cyaml_strval_t strings[] = {
|
|
{ "first", (1 << 0) },
|
|
{ "second", (1 << 1) },
|
|
{ "third", (1 << 2) },
|
|
{ "fourth", (1 << 3) },
|
|
{ "fifth", (1 << 4) },
|
|
{ "sixth", (1 << 5) },
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"key:\n"
|
|
" - first\n"
|
|
" - seventh\n";
|
|
struct target_struct {
|
|
enum test_flags a;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_FLAGS("key", CYAML_FLAG_STRICT,
|
|
struct target_struct, a,
|
|
strings, CYAML_ARRAY_LEN(strings)),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects int, but YAML has sequence.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_expect_int_read_seq(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"key:\n"
|
|
" - 90";
|
|
struct target_struct {
|
|
int value;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_INT("key", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, value),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects int, but YAML ends.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_expect_int_read_end_1(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"key:\n";
|
|
struct target_struct {
|
|
int value;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_INT("key", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, value),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects int, but YAML ends.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_expect_int_read_end_2(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"key: |"
|
|
"...";
|
|
struct target_struct {
|
|
int value;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_INT("key", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, value),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_LIBYAML_PARSER) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects flags, but YAML has scalar.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_expect_flags_read_scalar(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const cyaml_strval_t strings[] = {
|
|
{ "first", (1 << 0) },
|
|
{ "second", (1 << 1) },
|
|
{ "third", (1 << 2) },
|
|
{ "fourth", (1 << 3) },
|
|
{ "fifth", (1 << 4) },
|
|
{ "sixth", (1 << 5) },
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"key: first\n";
|
|
struct target_struct {
|
|
int value;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_FLAGS("key", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, value,
|
|
strings, CYAML_ARRAY_LEN(strings)),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects mapping, but YAML has scalar.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_expect_mapping_read_scalar(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"key: scalar\n";
|
|
struct value_s {
|
|
int a;
|
|
};
|
|
struct target_struct {
|
|
struct value_s test_value_mapping;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field test_mapping_schema[] = {
|
|
CYAML_FIELD_INT("a", CYAML_FLAG_DEFAULT, struct value_s, a),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_MAPPING("key", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, test_value_mapping,
|
|
test_mapping_schema),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading when schema expects sequence, but YAML has scalar.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_schema_expect_sequence_read_scalar(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"key: foo\n";
|
|
struct target_struct {
|
|
int *a;
|
|
unsigned a_count;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_value entry_schema = {
|
|
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, *(data_tgt->a)),
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_SEQUENCE("key", CYAML_FLAG_POINTER,
|
|
struct target_struct, a, &entry_schema,
|
|
0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_VALUE) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (data_tgt != NULL) {
|
|
return ttest_fail(&tc, "Data non-NULL on error.");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading, with all memory allocation failure at every possible point.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_free_null(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, NULL, NULL, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
UNUSED(config);
|
|
|
|
cyaml_mem(NULL, NULL, 0);
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/** Context for allocation failure tests. */
|
|
struct test_cyaml_mem_ctx {
|
|
unsigned required;
|
|
unsigned fail;
|
|
unsigned current;
|
|
};
|
|
|
|
/*
|
|
* Allocation counter.
|
|
*
|
|
* Used to count all allocations made when loading an input.
|
|
*
|
|
* \param[in] ctx Allocation context.
|
|
* \param[in] ptr Pointer to allocation to resize or NULL.
|
|
* \param[in] size Size to set allocation to.
|
|
* \return Pointer to new allocation, or NULL on failure.
|
|
*/
|
|
static void * test_cyaml_mem_count_allocs(
|
|
void *ctx,
|
|
void *ptr,
|
|
size_t size)
|
|
{
|
|
struct test_cyaml_mem_ctx *mem_ctx = ctx;
|
|
|
|
if (size == 0) {
|
|
free(ptr);
|
|
return NULL;
|
|
}
|
|
|
|
mem_ctx->required++;
|
|
|
|
return realloc(ptr, size);
|
|
}
|
|
|
|
/**
|
|
* Allocation failure tester.
|
|
*
|
|
* Used to make specific allocation fail.
|
|
*
|
|
* \param[in] ctx Allocation context.
|
|
* \param[in] ptr Pointer to allocation to resize or NULL.
|
|
* \param[in] size Size to set allocation to.
|
|
* \return Pointer to new allocation, or NULL on failure.
|
|
*/
|
|
static void * test_cyaml_mem_fail(
|
|
void *ctx,
|
|
void *ptr,
|
|
size_t size)
|
|
{
|
|
struct test_cyaml_mem_ctx *mem_ctx = ctx;
|
|
|
|
if (size == 0) {
|
|
free(ptr);
|
|
return NULL;
|
|
}
|
|
|
|
if (mem_ctx->current == mem_ctx->fail) {
|
|
return NULL;
|
|
}
|
|
|
|
mem_ctx->current++;
|
|
|
|
return realloc(ptr, size);
|
|
}
|
|
|
|
/**
|
|
* Test loading, with all memory allocation failure at every possible point.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_alloc_oom_1(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
cyaml_config_t cfg = *config;
|
|
static const unsigned char yaml[] =
|
|
"animals:\n"
|
|
" - kind: cat\n"
|
|
" sound: meow\n"
|
|
" position: [ 1, 2, 1]\n"
|
|
" - kind: snake\n"
|
|
" sound: hiss\n"
|
|
" position: [ 3, 1, 0]\n";
|
|
struct animal_s {
|
|
char *kind;
|
|
char *sound;
|
|
int *position;
|
|
};
|
|
struct target_struct {
|
|
struct animal_s **animal;
|
|
uint32_t animal_count;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_value position_entry_schema = {
|
|
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, int),
|
|
};
|
|
static const struct cyaml_schema_field animal_schema[] = {
|
|
CYAML_FIELD_STRING_PTR("kind", CYAML_FLAG_POINTER,
|
|
struct animal_s, kind, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_STRING_PTR("sound", CYAML_FLAG_POINTER,
|
|
struct animal_s, sound, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_SEQUENCE_FIXED("position", CYAML_FLAG_POINTER,
|
|
struct animal_s, position,
|
|
&position_entry_schema, 3),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value animal_entry_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, **(data_tgt->animal),
|
|
animal_schema),
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_SEQUENCE("animals", CYAML_FLAG_POINTER,
|
|
struct target_struct, animal,
|
|
&animal_entry_schema, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = &cfg,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
struct test_cyaml_mem_ctx mem_ctx = {
|
|
.required = 0,
|
|
};
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* First we load the YAML with the counting allocation function,
|
|
* to find the number of allocations required to load the document.
|
|
* This is deterministic.
|
|
*/
|
|
cfg.mem_fn = test_cyaml_mem_count_allocs;
|
|
cfg.mem_ctx = &mem_ctx;
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_OK) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (mem_ctx.required == 0) {
|
|
return ttest_fail(&tc, "There were no allocations.");
|
|
}
|
|
|
|
/* Now free what was loaded. */
|
|
cyaml_free(config, &top_schema, data_tgt, 0);
|
|
data_tgt = NULL;
|
|
|
|
/*
|
|
* Now we load the document multiple times, forcing every possible
|
|
* allocation to fail.
|
|
*/
|
|
cfg.mem_fn = test_cyaml_mem_fail;
|
|
|
|
for (mem_ctx.fail = 0; mem_ctx.fail < mem_ctx.required;
|
|
mem_ctx.fail++) {
|
|
mem_ctx.current = 0;
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_OOM) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
/* Now free what was loaded. */
|
|
cyaml_free(config, &top_schema, data_tgt, 0);
|
|
data_tgt = NULL;
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading, with all memory allocation failure at every possible point.
|
|
*
|
|
* Uses aliases and anchors, to exercies the event/anchor recording error
|
|
* paths too.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_alloc_oom_2(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
enum test_f {
|
|
NONE = 0,
|
|
FIRST = (1 << 0),
|
|
SECOND = (1 << 1),
|
|
THIRD = (1 << 2),
|
|
FOURTH = (1 << 3),
|
|
};
|
|
static const cyaml_strval_t strings[] = {
|
|
{ "first", (1 << 0) },
|
|
{ "second", (1 << 1) },
|
|
{ "third", (1 << 2) },
|
|
{ "fourth", (1 << 3) },
|
|
};
|
|
cyaml_config_t cfg = *config;
|
|
static const unsigned char yaml[] =
|
|
"anchors:\n"
|
|
" - &a1 {"
|
|
" kind: cat,\n"
|
|
" sound: meow,\n"
|
|
" position: &a2 [ 1, &my_value 2, 1],\n"
|
|
" flags: &a3 [\n"
|
|
" first,\n"
|
|
" &a4 second,\n"
|
|
" third,\n"
|
|
" fourth,\n"
|
|
" ]\n"
|
|
" }\n"
|
|
" - kind: snake\n"
|
|
" sound: &a5 hiss\n"
|
|
" position: &a6 [ 3, 1, 0]\n"
|
|
" flags: &a7 [\n"
|
|
" first,\n"
|
|
" second,\n"
|
|
" third,\n"
|
|
" fourth,\n"
|
|
" ]\n"
|
|
"animals:\n"
|
|
" - *a1\n"
|
|
" - kind: snake\n"
|
|
" sound: *a5\n"
|
|
" position: *a6\n"
|
|
" flags: *a7\n"
|
|
" value: *my_value\n";
|
|
struct animal_s {
|
|
char *kind;
|
|
char *sound;
|
|
int **position;
|
|
unsigned position_count;
|
|
enum test_f *flags;
|
|
int value;
|
|
};
|
|
struct target_struct {
|
|
struct animal_s **animal;
|
|
uint32_t animal_count;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_value position_entry_schema = {
|
|
CYAML_VALUE_INT(CYAML_FLAG_POINTER, int),
|
|
};
|
|
static const struct cyaml_schema_field animal_schema[] = {
|
|
CYAML_FIELD_STRING_PTR("kind", CYAML_FLAG_POINTER,
|
|
struct animal_s, kind, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_STRING_PTR("sound", CYAML_FLAG_POINTER,
|
|
struct animal_s, sound, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_SEQUENCE("position", CYAML_FLAG_POINTER,
|
|
struct animal_s, position,
|
|
&position_entry_schema, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_FLAGS("flags",
|
|
CYAML_FLAG_STRICT | CYAML_FLAG_POINTER,
|
|
struct animal_s, flags, strings, 4),
|
|
CYAML_FIELD_INT("value", CYAML_FLAG_OPTIONAL,
|
|
struct animal_s, value),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value animal_entry_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, **(data_tgt->animal),
|
|
animal_schema),
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_IGNORE("anchors", CYAML_FLAG_OPTIONAL),
|
|
CYAML_FIELD_SEQUENCE("animals", CYAML_FLAG_POINTER,
|
|
struct target_struct, animal,
|
|
&animal_entry_schema, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
struct test_cyaml_mem_ctx mem_ctx = {
|
|
.required = 0,
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = &cfg,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* First we load the YAML with the counting allocation function,
|
|
* to find the number of allocations required to load the document.
|
|
* This is deterministic.
|
|
*/
|
|
cfg.mem_fn = test_cyaml_mem_count_allocs;
|
|
cfg.mem_ctx = &mem_ctx;
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_OK) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (mem_ctx.required == 0) {
|
|
return ttest_fail(&tc, "There were no allocations.");
|
|
}
|
|
|
|
/* Now free what was loaded. */
|
|
cyaml_free(config, &top_schema, data_tgt, 0);
|
|
data_tgt = NULL;
|
|
|
|
/*
|
|
* Now we load the document multiple times, forcing every possible
|
|
* allocation to fail.
|
|
*/
|
|
cfg.mem_fn = test_cyaml_mem_fail;
|
|
|
|
for (mem_ctx.fail = 0; mem_ctx.fail < mem_ctx.required;
|
|
mem_ctx.fail++) {
|
|
mem_ctx.current = 0;
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_OOM) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
/* Now free what was loaded. */
|
|
cyaml_free(config, &top_schema, data_tgt, 0);
|
|
data_tgt = NULL;
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test saving, with memory allocation failure at every possible point.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_save_alloc_oom_1(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
cyaml_config_t cfg = *config;
|
|
static const unsigned char yaml[] =
|
|
"animals:\n"
|
|
" - kind: cat\n"
|
|
" sound: meow\n"
|
|
" position: [ 1, 2, 1]\n"
|
|
" - kind: snake\n"
|
|
" sound: hiss\n"
|
|
" position: [ 3, 1, 0]\n";
|
|
struct animal_s {
|
|
char *kind;
|
|
char *sound;
|
|
int *position;
|
|
};
|
|
struct target_struct {
|
|
struct animal_s **animal;
|
|
uint32_t animal_count;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_value position_entry_schema = {
|
|
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, int),
|
|
};
|
|
static const struct cyaml_schema_field animal_schema[] = {
|
|
CYAML_FIELD_STRING_PTR("kind", CYAML_FLAG_POINTER,
|
|
struct animal_s, kind, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_STRING_PTR("sound", CYAML_FLAG_POINTER,
|
|
struct animal_s, sound, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_SEQUENCE_FIXED("position", CYAML_FLAG_POINTER,
|
|
struct animal_s, position,
|
|
&position_entry_schema, 3),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value animal_entry_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, **(data_tgt->animal),
|
|
animal_schema),
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_SEQUENCE("animals", CYAML_FLAG_POINTER,
|
|
struct target_struct, animal,
|
|
&animal_entry_schema, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
struct test_cyaml_mem_ctx mem_ctx = {
|
|
.required = 0,
|
|
};
|
|
char *buffer = NULL;
|
|
size_t len = 0;
|
|
test_data_t td = {
|
|
.buffer = &buffer,
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = &cfg,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
/* First we load the YAML, so we have something to test saving. */
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_OK) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
/*
|
|
* First we load the YAML with the counting allocation function,
|
|
* to find the number of allocations required to load the document.
|
|
* This is deterministic.
|
|
*/
|
|
cfg.mem_fn = test_cyaml_mem_count_allocs;
|
|
cfg.mem_ctx = &mem_ctx;
|
|
|
|
err = cyaml_save_data(&buffer, &len, &cfg, &top_schema, data_tgt, 0);
|
|
if (err != CYAML_OK) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (mem_ctx.required == 0) {
|
|
return ttest_fail(&tc, "There were no allocations.");
|
|
}
|
|
|
|
/* Now free what was loaded. */
|
|
cyaml_mem(&mem_ctx, buffer, 0);
|
|
buffer = NULL;
|
|
len = 0;
|
|
|
|
/*
|
|
* Now we load the document multiple times, forcing every possible
|
|
* allocation to fail.
|
|
*/
|
|
cfg.mem_fn = test_cyaml_mem_fail;
|
|
|
|
for (mem_ctx.fail = 0; mem_ctx.fail < mem_ctx.required;
|
|
mem_ctx.fail++) {
|
|
mem_ctx.current = 0;
|
|
err = cyaml_save_data(&buffer, &len, &cfg, &top_schema,
|
|
data_tgt, 0);
|
|
if (err != CYAML_ERR_OOM) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
/* Now free what was loaded. */
|
|
cyaml_mem(&mem_ctx, buffer, 0);
|
|
buffer = NULL;
|
|
len = 0;
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading, with all memory allocation failure at every possible point.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_save_alloc_oom_2(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
enum test_f {
|
|
NONE = 0,
|
|
FIRST = (1 << 0),
|
|
SECOND = (1 << 1),
|
|
THIRD = (1 << 2),
|
|
FOURTH = (1 << 3),
|
|
};
|
|
static const cyaml_strval_t strings[] = {
|
|
{ "first", (1 << 0) },
|
|
{ "second", (1 << 1) },
|
|
{ "third", (1 << 2) },
|
|
{ "fourth", (1 << 3) },
|
|
};
|
|
cyaml_config_t cfg = *config;
|
|
static const unsigned char yaml[] =
|
|
"animals:\n"
|
|
" - kind: cat\n"
|
|
" sound: meow\n"
|
|
" position: [ 1, 2, 1]\n"
|
|
" flags:\n"
|
|
" - first\n"
|
|
" - second\n"
|
|
" - third\n"
|
|
" - fourth\n"
|
|
" - kind: snake\n"
|
|
" sound: hiss\n"
|
|
" position: [ 3, 1, 0]\n"
|
|
" flags:\n"
|
|
" - first\n"
|
|
" - second\n"
|
|
" - third\n"
|
|
" - fourth\n";
|
|
struct animal_s {
|
|
char *kind;
|
|
char *sound;
|
|
int **position;
|
|
unsigned position_count;
|
|
enum test_f *flags;
|
|
};
|
|
struct target_struct {
|
|
struct animal_s **animal;
|
|
uint32_t animal_count;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_value position_entry_schema = {
|
|
CYAML_VALUE_INT(CYAML_FLAG_POINTER, int),
|
|
};
|
|
static const struct cyaml_schema_field animal_schema[] = {
|
|
CYAML_FIELD_STRING_PTR("kind", CYAML_FLAG_POINTER,
|
|
struct animal_s, kind, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_STRING_PTR("sound", CYAML_FLAG_POINTER,
|
|
struct animal_s, sound, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_SEQUENCE("position", CYAML_FLAG_POINTER,
|
|
struct animal_s, position,
|
|
&position_entry_schema, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_FLAGS("flags",
|
|
CYAML_FLAG_STRICT | CYAML_FLAG_POINTER,
|
|
struct animal_s, flags, strings, 4),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value animal_entry_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, **(data_tgt->animal),
|
|
animal_schema),
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_SEQUENCE("animals", CYAML_FLAG_POINTER,
|
|
struct target_struct, animal,
|
|
&animal_entry_schema, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
struct test_cyaml_mem_ctx mem_ctx = {
|
|
.required = 0,
|
|
};
|
|
char *buffer = NULL;
|
|
size_t len = 0;
|
|
test_data_t td = {
|
|
.buffer = &buffer,
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = &cfg,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
/* First we load the YAML, so we have something to test saving. */
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_OK) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
/*
|
|
* First we load the YAML with the counting allocation function,
|
|
* to find the number of allocations required to load the document.
|
|
* This is deterministic.
|
|
*/
|
|
cfg.mem_fn = test_cyaml_mem_count_allocs;
|
|
cfg.mem_ctx = &mem_ctx;
|
|
|
|
err = cyaml_save_data(&buffer, &len, &cfg, &top_schema, data_tgt, 0);
|
|
if (err != CYAML_OK) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (mem_ctx.required == 0) {
|
|
return ttest_fail(&tc, "There were no allocations.");
|
|
}
|
|
|
|
/* Now free what was loaded. */
|
|
cyaml_mem(&mem_ctx, buffer, 0);
|
|
buffer = NULL;
|
|
len = 0;
|
|
|
|
/*
|
|
* Now we load the document multiple times, forcing every possible
|
|
* allocation to fail.
|
|
*/
|
|
cfg.mem_fn = test_cyaml_mem_fail;
|
|
|
|
for (mem_ctx.fail = 0; mem_ctx.fail < mem_ctx.required;
|
|
mem_ctx.fail++) {
|
|
mem_ctx.current = 0;
|
|
err = cyaml_save_data(&buffer, &len, &cfg, &top_schema,
|
|
data_tgt, 0);
|
|
if (err != CYAML_ERR_OOM) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
/* Now free what was loaded. */
|
|
cyaml_mem(&mem_ctx, buffer, 0);
|
|
buffer = NULL;
|
|
len = 0;
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading a flag with an aliased value.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_flag_value_alias(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
cyaml_config_t cfg = *config;
|
|
struct target_struct {
|
|
unsigned a;
|
|
unsigned b;
|
|
};
|
|
static const cyaml_strval_t str[] = {
|
|
{ "one", (1 << 0) },
|
|
{ "two", (1 << 1) },
|
|
{ "three", (1 << 2) },
|
|
{ "four", (1 << 3) },
|
|
{ "five", (1 << 4) },
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"a: \n"
|
|
" - &foo one\n"
|
|
" - two\n"
|
|
" - five\n"
|
|
"b:\n"
|
|
" - *foo\n";
|
|
struct target_struct *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_FLAGS("a", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, a, str, 5),
|
|
CYAML_FIELD_FLAGS("b", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, b, str, 5),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = &cfg,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
cfg.flags |= CYAML_CFG_NO_ALIAS;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_ALIAS) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading a bitfield with an aliased value.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_bitfield_value_alias_1(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
cyaml_config_t cfg = *config;
|
|
static const cyaml_bitdef_t bitvals[] = {
|
|
{ .name = "7", .offset = 0, .bits = 1 },
|
|
{ .name = "a", .offset = 1, .bits = 2 },
|
|
{ .name = "b", .offset = 3, .bits = 7 },
|
|
{ .name = "c", .offset = 10, .bits = 32 },
|
|
{ .name = "d", .offset = 42, .bits = 8 },
|
|
{ .name = "e", .offset = 50, .bits = 14 },
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"test_bitfield:\n"
|
|
" a: &foo 2\n"
|
|
" b: 0x7f\n"
|
|
" c: 0xffffffff\n"
|
|
" d: 0xff\n"
|
|
" e: 0x3fff\n"
|
|
"test_bitfield2:\n"
|
|
" *foo: 1\n"
|
|
" b: 0x7f\n"
|
|
" c: 0xffffffff\n"
|
|
" d: 0xff\n"
|
|
" e: 0x3fff\n";
|
|
struct target_struct {
|
|
uint64_t test_value_bitfield;
|
|
uint64_t test_value_bitfield2;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_BITFIELD("test_bitfield", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, test_value_bitfield,
|
|
bitvals, CYAML_ARRAY_LEN(bitvals)),
|
|
CYAML_FIELD_BITFIELD("test_bitfield2", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, test_value_bitfield2,
|
|
bitvals, CYAML_ARRAY_LEN(bitvals)),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = &cfg,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
cfg.flags |= CYAML_CFG_NO_ALIAS;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_ALIAS) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading a bitfield with an aliased value.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_bitfield_value_alias_2(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
cyaml_config_t cfg = *config;
|
|
static const cyaml_bitdef_t bitvals[] = {
|
|
{ .name = "7", .offset = 0, .bits = 1 },
|
|
{ .name = "a", .offset = 1, .bits = 2 },
|
|
{ .name = "b", .offset = 3, .bits = 7 },
|
|
{ .name = "c", .offset = 10, .bits = 32 },
|
|
{ .name = "d", .offset = 42, .bits = 8 },
|
|
{ .name = "e", .offset = 50, .bits = 14 },
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"test_bitfield:\n"
|
|
" a: &foo 2\n"
|
|
" b: 0x7f\n"
|
|
" c: 0xffffffff\n"
|
|
" d: 0xff\n"
|
|
" e: 0x3fff\n"
|
|
"test_bitfield2:\n"
|
|
" a: *foo\n"
|
|
" b: 0x7f\n"
|
|
" c: 0xffffffff\n"
|
|
" d: 0xff\n"
|
|
" e: 0x3fff\n";
|
|
struct target_struct {
|
|
uint64_t test_value_bitfield;
|
|
uint64_t test_value_bitfield2;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_BITFIELD("test_bitfield", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, test_value_bitfield,
|
|
bitvals, CYAML_ARRAY_LEN(bitvals)),
|
|
CYAML_FIELD_BITFIELD("test_bitfield2", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, test_value_bitfield2,
|
|
bitvals, CYAML_ARRAY_LEN(bitvals)),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = &cfg,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
cfg.flags |= CYAML_CFG_NO_ALIAS;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_ALIAS) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading a mapping with an aliased value.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_mapping_key_alias(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
cyaml_config_t cfg = *config;
|
|
struct target_struct {
|
|
char *a;
|
|
char *b;
|
|
char *c;
|
|
char *d;
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"a: &example b\n"
|
|
"*example: test\n"
|
|
"c: meh\n"
|
|
"d: foo\n";
|
|
struct target_struct *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_STRING_PTR("a", CYAML_FLAG_POINTER,
|
|
struct target_struct, a, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_STRING_PTR("b", CYAML_FLAG_POINTER,
|
|
struct target_struct, b, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_STRING_PTR("c", CYAML_FLAG_POINTER,
|
|
struct target_struct, c, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_STRING_PTR("d", CYAML_FLAG_POINTER,
|
|
struct target_struct, d, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = &cfg,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
cfg.flags |= CYAML_CFG_NO_ALIAS;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_ALIAS) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading a mapping with an aliased value.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_mapping_value_alias_1(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
cyaml_config_t cfg = *config;
|
|
struct target_struct {
|
|
char *a;
|
|
char *b;
|
|
char *c;
|
|
char *d;
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"a: 9\n"
|
|
"b: 90\n"
|
|
"c: &foo 900\n"
|
|
"d: *foo\n";
|
|
struct target_struct *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_STRING_PTR("a", CYAML_FLAG_POINTER,
|
|
struct target_struct, a, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_STRING_PTR("b", CYAML_FLAG_POINTER,
|
|
struct target_struct, b, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_STRING_PTR("c", CYAML_FLAG_POINTER,
|
|
struct target_struct, c, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_STRING_PTR("d", CYAML_FLAG_POINTER,
|
|
struct target_struct, d, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = &cfg,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
cfg.flags |= CYAML_CFG_NO_ALIAS;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_ALIAS) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading a mapping with an aliased value.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_mapping_value_alias_2(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
cyaml_config_t cfg = *config;
|
|
struct target_struct {
|
|
char *a;
|
|
char *b;
|
|
char *c;
|
|
char *d;
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"a: 9\n"
|
|
"b: &foo d\n"
|
|
"c: *d\n";
|
|
struct target_struct *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_STRING_PTR("a", CYAML_FLAG_POINTER,
|
|
struct target_struct, a, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_STRING_PTR("b", CYAML_FLAG_POINTER,
|
|
struct target_struct, b, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_STRING_PTR("d", CYAML_FLAG_POINTER,
|
|
struct target_struct, d, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = &cfg,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
cfg.flags |= CYAML_CFG_NO_ALIAS | CYAML_CFG_IGNORE_UNKNOWN_KEYS;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_ALIAS) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading a mapping with an aliased value.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_mapping_value_alias_3(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
cyaml_config_t cfg = *config;
|
|
struct target_struct {
|
|
char *a;
|
|
char *b;
|
|
};
|
|
static const unsigned char yaml[] =
|
|
"a: 9\n"
|
|
"b: &foo d\n"
|
|
"c: [a, b, c, *foo]\n";
|
|
struct target_struct *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_STRING_PTR("a", CYAML_FLAG_POINTER,
|
|
struct target_struct, a, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_STRING_PTR("b", CYAML_FLAG_POINTER,
|
|
struct target_struct, b, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_IGNORE("c", CYAML_FLAG_DEFAULT),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = &cfg,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
cfg.flags |= CYAML_CFG_NO_ALIAS;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_ALIAS) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading with an aliased string value.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_invalid_alias(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"test_string_anchor: &foo Hello World!\n"
|
|
"test_string: *bar\n"
|
|
"test_int: 9\n";
|
|
struct target_struct {
|
|
char * test_value_string;
|
|
int test_value_int;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_IGNORE("test_string_anchor", CYAML_FLAG_OPTIONAL),
|
|
CYAML_FIELD_STRING_PTR("test_string", CYAML_FLAG_POINTER,
|
|
struct target_struct, test_value_string,
|
|
0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_INT("test_int", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, test_value_int),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_ALIAS) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Test loading an incomplete alias.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_incomplete_alias(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
static const unsigned char yaml[] =
|
|
"anchors:\n"
|
|
" - &a1 {\n"
|
|
" a: 777,\n"
|
|
" b: *a1,\n"
|
|
" }\n"
|
|
"test: *a1\n";
|
|
struct my_test {
|
|
int a;
|
|
char *b;
|
|
};
|
|
struct target_struct {
|
|
struct my_test test;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_field inner_mapping_schema[] = {
|
|
CYAML_FIELD_INT("a", CYAML_FLAG_DEFAULT,
|
|
struct my_test, a),
|
|
CYAML_FIELD_STRING_PTR("b", CYAML_FLAG_POINTER,
|
|
struct my_test, b,
|
|
0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_IGNORE("anchors", CYAML_FLAG_OPTIONAL),
|
|
CYAML_FIELD_MAPPING("test", CYAML_FLAG_DEFAULT,
|
|
struct target_struct, test,
|
|
inner_mapping_schema),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = config,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err != CYAML_ERR_INVALID_ALIAS) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/** Structure for log messages checking. */
|
|
struct log_check {
|
|
unsigned string_count_expected; /**< Number of expected log messages. */
|
|
const char *const *strings; /**< Array of expected log messages. */
|
|
unsigned string_count; /**< Number of log messages captured. */
|
|
bool error; /**< Whether a logging error has been found. */
|
|
};
|
|
|
|
/**
|
|
* Initialise a log check structure for a given log string vector.
|
|
*
|
|
* \param[in] lc The log check structure to initialise.
|
|
* \param[in] strv A string vector containing expected log messages.
|
|
* \return true on success, false otherwise.
|
|
*/
|
|
static inline bool log_check_init(
|
|
struct log_check *lc,
|
|
const char *const *strv)
|
|
{
|
|
if (lc == NULL) {
|
|
return false;
|
|
}
|
|
|
|
lc->string_count_expected = 0;
|
|
lc->string_count = 0;
|
|
lc->strings = strv;
|
|
lc->error = false;
|
|
|
|
while (strv[lc->string_count_expected] != NULL) {
|
|
lc->string_count_expected++;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static struct log_check lc;
|
|
|
|
/**
|
|
* CYAML log function, for checking logs.
|
|
*
|
|
* Uses the lc static state.
|
|
*
|
|
* \param[in] level Log level of message to log.
|
|
* \param[in] ctx Client's private logging context.
|
|
* \param[in] fmt Format string for message to log.
|
|
* \param[in] args Additional arguments used by fmt.
|
|
*/
|
|
static void cyaml_log_check(
|
|
cyaml_log_t level,
|
|
void *ctx,
|
|
const char *fmt,
|
|
va_list args)
|
|
{
|
|
int ret;
|
|
size_t len;
|
|
char buffer[128];
|
|
|
|
(void)(ctx);
|
|
|
|
if (level < CYAML_LOG_ERROR) {
|
|
/* We only care that critical log messages emerge. */
|
|
return;
|
|
}
|
|
|
|
ret = vsnprintf(buffer, sizeof(buffer), fmt, args);
|
|
if (ret <= 0) {
|
|
fprintf(stderr, "TEST ERROR: Logging error\n");
|
|
return;
|
|
}
|
|
len = (unsigned)ret;
|
|
if (len >= sizeof(buffer)) {
|
|
fprintf(stderr, "TEST ERROR: Buffer too small\n");
|
|
assert(len < sizeof(buffer));
|
|
return;
|
|
}
|
|
|
|
if (lc.string_count >= lc.string_count_expected) {
|
|
fprintf(stderr, "ERROR: More log messages than expected\n");
|
|
fprintf(stderr, " got: %s", buffer);
|
|
lc.error |= true;
|
|
goto out;
|
|
}
|
|
|
|
if (strcmp(lc.strings[lc.string_count], buffer) != 0) {
|
|
fprintf(stderr, "ERROR: Unexpected log message\n");
|
|
fprintf(stderr, " got: %s", buffer);
|
|
fprintf(stderr, "expected: %s", lc.strings[lc.string_count]);
|
|
lc.error |= true;
|
|
goto out;
|
|
}
|
|
|
|
out:
|
|
lc.string_count++;
|
|
}
|
|
|
|
/**
|
|
* Check that the logging contains the expected information.
|
|
*
|
|
* \param[in] report The test report context.
|
|
* \param[in] config The CYAML config to use for the test.
|
|
* \return true if test passes, false otherwise.
|
|
*/
|
|
static bool test_err_load_log(
|
|
ttest_report_ctx_t *report,
|
|
const cyaml_config_t *config)
|
|
{
|
|
enum test_f {
|
|
NONE = 0,
|
|
FIRST = (1 << 0),
|
|
SECOND = (1 << 1),
|
|
THIRD = (1 << 2),
|
|
FOURTH = (1 << 3),
|
|
};
|
|
static const char * const expected_log[] = {
|
|
"Load: Invalid INT value: 'foo'\n",
|
|
"Load: Backtrace:\n",
|
|
" in sequence entry '2' (line: 5, column: 26)\n",
|
|
" in mapping field 'position' (line: 5, column: 17)\n",
|
|
" in sequence entry '1' (line: 2, column: 5)\n",
|
|
" in mapping field 'animals' (line: 23, column: 3)\n",
|
|
NULL
|
|
};
|
|
static const cyaml_strval_t strings[] = {
|
|
{ "first", (1 << 0) },
|
|
{ "second", (1 << 1) },
|
|
{ "third", (1 << 2) },
|
|
{ "fourth", (1 << 3) },
|
|
};
|
|
cyaml_config_t cfg = *config;
|
|
static const unsigned char yaml[] =
|
|
"anchors:\n"
|
|
" - &a1 {\n"
|
|
" kind: cat,\n"
|
|
" sound: meow,\n"
|
|
" position: &a2 [ 1, &my_value foo, 1],\n"
|
|
" flags: &a3 [\n"
|
|
" first,\n"
|
|
" &a4 second,\n"
|
|
" third,\n"
|
|
" fourth,\n"
|
|
" ]\n"
|
|
" }\n"
|
|
" - kind: snake\n"
|
|
" sound: &a5 hiss\n"
|
|
" position: &a6 [ 3, 1, 0]\n"
|
|
" flags: &a7 [\n"
|
|
" first,\n"
|
|
" second,\n"
|
|
" third,\n"
|
|
" fourth,\n"
|
|
" ]\n"
|
|
"animals:\n"
|
|
" - *a1\n"
|
|
" - kind: snake\n"
|
|
" sound: *a5\n"
|
|
" position: *a6\n"
|
|
" flags: *a7\n"
|
|
" value: *my_value\n";
|
|
struct animal_s {
|
|
char *kind;
|
|
char *sound;
|
|
int **position;
|
|
unsigned position_count;
|
|
enum test_f *flags;
|
|
int value;
|
|
};
|
|
struct target_struct {
|
|
struct animal_s **animal;
|
|
uint32_t animal_count;
|
|
} *data_tgt = NULL;
|
|
static const struct cyaml_schema_value position_entry_schema = {
|
|
CYAML_VALUE_INT(CYAML_FLAG_POINTER, int),
|
|
};
|
|
static const struct cyaml_schema_field animal_schema[] = {
|
|
CYAML_FIELD_STRING_PTR("kind", CYAML_FLAG_POINTER,
|
|
struct animal_s, kind, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_STRING_PTR("sound", CYAML_FLAG_POINTER,
|
|
struct animal_s, sound, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_SEQUENCE("position", CYAML_FLAG_POINTER,
|
|
struct animal_s, position,
|
|
&position_entry_schema, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_FLAGS("flags",
|
|
CYAML_FLAG_STRICT | CYAML_FLAG_POINTER,
|
|
struct animal_s, flags, strings, 4),
|
|
CYAML_FIELD_INT("value", CYAML_FLAG_OPTIONAL,
|
|
struct animal_s, value),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value animal_entry_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, **(data_tgt->animal),
|
|
animal_schema),
|
|
};
|
|
static const struct cyaml_schema_field mapping_schema[] = {
|
|
CYAML_FIELD_IGNORE("anchors", CYAML_FLAG_OPTIONAL),
|
|
CYAML_FIELD_SEQUENCE("animals", CYAML_FLAG_POINTER,
|
|
struct target_struct, animal,
|
|
&animal_entry_schema, 0, CYAML_UNLIMITED),
|
|
CYAML_FIELD_END
|
|
};
|
|
static const struct cyaml_schema_value top_schema = {
|
|
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
|
|
struct target_struct, mapping_schema),
|
|
};
|
|
test_data_t td = {
|
|
.data = (cyaml_data_t **) &data_tgt,
|
|
.config = &cfg,
|
|
.schema = &top_schema,
|
|
};
|
|
cyaml_err_t err;
|
|
ttest_ctx_t tc;
|
|
|
|
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
|
|
return true;
|
|
}
|
|
|
|
log_check_init(&lc, expected_log);
|
|
cfg.log_fn = cyaml_log_check;
|
|
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, &top_schema,
|
|
(cyaml_data_t **) &data_tgt, NULL);
|
|
if (err == CYAML_OK) {
|
|
return ttest_fail(&tc, cyaml_strerror(err));
|
|
}
|
|
|
|
if (lc.error == true) {
|
|
return ttest_fail(&tc, "Unexpected log message");
|
|
}
|
|
if (lc.string_count_expected > lc.string_count) {
|
|
return ttest_fail(&tc, "Missing log message(s)");
|
|
}
|
|
|
|
return ttest_pass(&tc);
|
|
}
|
|
|
|
/**
|
|
* Run the CYAML error unit tests.
|
|
*
|
|
* \param[in] rc The ttest report context.
|
|
* \param[in] log_level CYAML log level.
|
|
* \param[in] log_fn CYAML logging function, or NULL.
|
|
* \return true iff all unit tests pass, otherwise false.
|
|
*/
|
|
bool errs_tests(
|
|
ttest_report_ctx_t *rc,
|
|
cyaml_log_t log_level,
|
|
cyaml_log_fn_t log_fn)
|
|
{
|
|
bool pass = true;
|
|
cyaml_config_t config = {
|
|
.log_fn = log_fn,
|
|
.mem_fn = cyaml_mem,
|
|
.log_level = log_level,
|
|
.flags = CYAML_CFG_DEFAULT,
|
|
};
|
|
|
|
/* Since we expect loads of error logging for these tests,
|
|
* suppress log output if required log level is greater
|
|
* than \ref CYAML_LOG_INFO.
|
|
*/
|
|
if (log_level > CYAML_LOG_INFO) {
|
|
config.log_fn = NULL;
|
|
}
|
|
|
|
ttest_heading(rc, "Bad parameter tests");
|
|
|
|
pass &= test_err_load_null_data(rc, &config);
|
|
pass &= test_err_save_null_data(rc, &config);
|
|
pass &= test_err_load_null_config(rc, &config);
|
|
pass &= test_err_save_null_config(rc, &config);
|
|
pass &= test_err_load_null_mem_fn(rc, &config);
|
|
pass &= test_err_save_null_mem_fn(rc, &config);
|
|
pass &= test_err_load_null_schema(rc, &config);
|
|
pass &= test_err_save_null_schema(rc, &config);
|
|
pass &= test_err_load_schema_top_level_non_pointer(rc, &config);
|
|
pass &= test_err_save_schema_top_level_non_pointer(rc, &config);
|
|
pass &= test_err_load_schema_top_level_sequence_no_count(rc, &config);
|
|
pass &= test_err_load_schema_top_level_not_sequence_count(rc, &config);
|
|
pass &= test_err_save_schema_top_level_not_sequence_count(rc, &config);
|
|
|
|
ttest_heading(rc, "Bad schema tests");
|
|
|
|
pass &= test_err_load_schema_bad_type(rc, &config);
|
|
pass &= test_err_save_schema_bad_type(rc, &config);
|
|
pass &= test_err_load_schema_bad_bitfield(rc, &config);
|
|
pass &= test_err_save_schema_bad_bitfield(rc, &config);
|
|
pass &= test_err_load_schema_string_min_max(rc, &config);
|
|
pass &= test_err_load_schema_bad_data_size_1(rc, &config);
|
|
pass &= test_err_load_schema_bad_data_size_2(rc, &config);
|
|
pass &= test_err_load_schema_bad_data_size_3(rc, &config);
|
|
pass &= test_err_load_schema_bad_data_size_4(rc, &config);
|
|
pass &= test_err_load_schema_bad_data_size_5(rc, &config);
|
|
pass &= test_err_load_schema_bad_data_size_6(rc, &config);
|
|
pass &= test_err_load_schema_bad_data_size_7(rc, &config);
|
|
pass &= test_err_load_schema_bad_data_size_8(rc, &config);
|
|
pass &= test_err_load_schema_bad_data_size_9(rc, &config);
|
|
pass &= test_err_save_schema_bad_data_size_1(rc, &config);
|
|
pass &= test_err_save_schema_bad_data_size_2(rc, &config);
|
|
pass &= test_err_save_schema_bad_data_size_3(rc, &config);
|
|
pass &= test_err_save_schema_bad_data_size_4(rc, &config);
|
|
pass &= test_err_save_schema_bad_data_size_5(rc, &config);
|
|
pass &= test_err_save_schema_bad_data_size_6(rc, &config);
|
|
pass &= test_err_save_schema_bad_data_size_7(rc, &config);
|
|
pass &= test_err_save_schema_bad_data_size_8(rc, &config);
|
|
pass &= test_err_load_schema_sequence_min_max(rc, &config);
|
|
pass &= test_err_save_schema_sequence_min_max(rc, &config);
|
|
pass &= test_err_load_schema_bad_data_size_float(rc, &config);
|
|
pass &= test_err_load_schema_sequence_in_sequence(rc, &config);
|
|
pass &= test_err_save_schema_sequence_in_sequence(rc, &config);
|
|
|
|
ttest_heading(rc, "YAML / schema mismatch: bad values");
|
|
|
|
pass &= test_err_load_non_scalar_mapping_key(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_uint(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_string(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_flags_1(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_flags_2(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_flags_3(rc, &config);
|
|
pass &= test_err_save_schema_invalid_value_null_ptr(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_int_junk(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_uint_junk(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_flags_junk(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_bitfield_1(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_bitfield_2(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_bitfield_3(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_bitfield_4(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_bitfield_5(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_bitfield_6(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_float_junk(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_double_junk(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_int_range_1(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_int_range_2(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_int_range_3(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_int_range_4(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_int_range_5(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_uint_range_1(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_uint_range_2(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_uint_range_3(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_uint_range_4(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_uint_range_5(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_float_range1(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_float_range2(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_float_range3(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_float_range4(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_double_range1(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_double_range2(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_float_invalid(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_double_invalid(rc, &config);
|
|
|
|
ttest_heading(rc, "YAML / schema mismatch: Test integer limits");
|
|
|
|
pass &= test_err_load_schema_invalid_value_int8_limit_neg(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_int8_limit_pos(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_int16_limit_neg(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_int16_limit_pos(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_int32_limit_neg(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_int32_limit_pos(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_int64_limit_neg(rc, &config);
|
|
pass &= test_err_load_schema_invalid_value_int64_limit_pos(rc, &config);
|
|
|
|
ttest_heading(rc, "YAML / schema mismatch: string lengths");
|
|
|
|
pass &= test_err_load_schema_string_min_length(rc, &config);
|
|
pass &= test_err_load_schema_string_max_length(rc, &config);
|
|
|
|
ttest_heading(rc, "YAML / schema mismatch: mapping fields");
|
|
|
|
pass &= test_err_load_schema_missing_mapping_field(rc, &config);
|
|
pass &= test_err_load_schema_unknown_mapping_field(rc, &config);
|
|
pass &= test_err_load_schema_duplicate_mapping_field(rc, &config);
|
|
|
|
ttest_heading(rc, "YAML / schema mismatch: sequence counts");
|
|
|
|
pass &= test_err_load_schema_sequence_min_entries(rc, &config);
|
|
pass &= test_err_load_schema_sequence_max_entries(rc, &config);
|
|
|
|
ttest_heading(rc, "YAML / schema mismatch: bad flags/enum strings");
|
|
|
|
pass &= test_err_load_schema_flags_mapping(rc, &config);
|
|
pass &= test_err_load_schema_enum_bad_string(rc, &config);
|
|
pass &= test_err_load_schema_flags_bad_string(rc, &config);
|
|
pass &= test_err_save_schema_strict_enum_bad_value(rc, &config);
|
|
pass &= test_err_load_schema_strict_enum_bad_string(rc, &config);
|
|
pass &= test_err_save_schema_strict_flags_bad_value(rc, &config);
|
|
pass &= test_err_load_schema_strict_flags_bad_string(rc, &config);
|
|
|
|
ttest_heading(rc, "YAML / schema mismatch: expected value type tests");
|
|
|
|
pass &= test_err_load_schema_expect_int_read_seq(rc, &config);
|
|
pass &= test_err_load_schema_expect_int_read_end_1(rc, &config);
|
|
pass &= test_err_load_schema_expect_int_read_end_2(rc, &config);
|
|
pass &= test_err_load_schema_expect_flags_read_scalar(rc, &config);
|
|
pass &= test_err_load_schema_expect_mapping_read_scalar(rc, &config);
|
|
pass &= test_err_load_schema_expect_sequence_read_scalar(rc, &config);
|
|
|
|
ttest_heading(rc, "Memory allocation handling tests");
|
|
|
|
pass &= test_err_load_log(rc, &config);
|
|
pass &= test_err_free_null(rc, &config);
|
|
pass &= test_err_load_alloc_oom_1(rc, &config);
|
|
pass &= test_err_load_alloc_oom_2(rc, &config);
|
|
pass &= test_err_save_alloc_oom_1(rc, &config);
|
|
pass &= test_err_save_alloc_oom_2(rc, &config);
|
|
|
|
ttest_heading(rc, "Alias tests");
|
|
|
|
pass &= test_err_load_invalid_alias(rc, &config);
|
|
pass &= test_err_load_incomplete_alias(rc, &config);
|
|
pass &= test_err_load_flag_value_alias(rc, &config);
|
|
pass &= test_err_load_mapping_key_alias(rc, &config);
|
|
pass &= test_err_load_mapping_value_alias_1(rc, &config);
|
|
pass &= test_err_load_mapping_value_alias_2(rc, &config);
|
|
pass &= test_err_load_mapping_value_alias_3(rc, &config);
|
|
pass &= test_err_load_bitfield_value_alias_1(rc, &config);
|
|
pass &= test_err_load_bitfield_value_alias_2(rc, &config);
|
|
|
|
return pass;
|
|
}
|