blob: 86d4f127c2674b3365bfb3f3ea3814810fcda519 [file] [log] [blame]
/*
* Copyright (c) 2019 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdlib.h>
#include <string.h>
#include "settings_priv.h"
#include "settings_test.h"
uint8_t val8;
uint8_t val8_un;
uint32_t val32;
uint64_t val64;
int test_get_called;
int test_set_called;
int test_commit_called;
int test_export_block;
int c2_var_count = 1;
int c1_handle_get(const char *name, char *val, int val_len_max);
int c1_handle_set(const char *name, size_t len, settings_read_cb read_cb,
void *cb_arg);
int c1_handle_commit(void);
int c1_handle_export(int (*cb)(const char *name,
const void *value, size_t val_len));
int c2_handle_get(const char *name, char *val, int val_len_max);
int c2_handle_set(const char *name, size_t len, settings_read_cb read_cb,
void *cb_arg);
int c2_handle_export(int (*cb)(const char *name,
const void *value, size_t val_len));
int c3_handle_get(const char *name, char *val, int val_len_max);
int c3_handle_set(const char *name, size_t len, settings_read_cb read_cb,
void *cb_arg);
int c3_handle_export(int (*cb)(const char *name,
const void *value, size_t val_len));
struct settings_handler c_test_handlers[] = {
{
.name = "myfoo",
.h_get = c1_handle_get,
.h_set = c1_handle_set,
.h_commit = c1_handle_commit,
.h_export = c1_handle_export
},
{
.name = "2nd",
.h_get = c2_handle_get,
.h_set = c2_handle_set,
.h_commit = NULL,
.h_export = c2_handle_export
},
{
.name = "3",
.h_get = c3_handle_get,
.h_set = c3_handle_set,
.h_commit = NULL,
.h_export = c3_handle_export
}
};
char val_string[SETTINGS_TEST_NVS_VAL_STR_CNT][SETTINGS_MAX_VAL_LEN];
char test_ref_value[SETTINGS_TEST_NVS_VAL_STR_CNT][SETTINGS_MAX_VAL_LEN];
int c1_handle_get(const char *name, char *val, int val_len_max)
{
const char *next;
test_get_called = 1;
if (settings_name_steq(name, "mybar", &next) && !next) {
val_len_max = MIN(val_len_max, sizeof(val8));
memcpy(val, &val8, MIN(val_len_max, sizeof(val8)));
return val_len_max;
}
if (settings_name_steq(name, "mybar64", &next) && !next) {
val_len_max = MIN(val_len_max, sizeof(val64));
memcpy(val, &val64, MIN(val_len_max, sizeof(val64)));
return val_len_max;
}
return -ENOENT;
}
int c1_handle_set(const char *name, size_t len, settings_read_cb read_cb,
void *cb_arg)
{
size_t val_len;
int rc;
const char *next;
test_set_called = 1;
if (settings_name_steq(name, "mybar", &next) && !next) {
rc = read_cb(cb_arg, &val8, sizeof(val8));
zassert_true(rc >= 0, "SETTINGS_VALUE_SET callback");
return 0;
}
if (settings_name_steq(name, "mybar64", &next) && !next) {
rc = read_cb(cb_arg, &val64, sizeof(val64));
zassert_true(rc >= 0, "SETTINGS_VALUE_SET callback");
return 0;
}
if (settings_name_steq(name, "unaligned", &next) && !next) {
val_len = len;
zassert_equal(val_len, sizeof(val8_un),
"value length: %d, ought equal 1", val_len);
rc = read_cb(cb_arg, &val8_un, sizeof(val8_un));
zassert_true(rc >= 0, "SETTINGS_VALUE_SET callback");
return 0;
}
return -ENOENT;
}
int c1_handle_commit(void)
{
test_commit_called = 1;
return 0;
}
int c1_handle_export(int (*cb)(const char *name,
const void *value, size_t val_len))
{
if (test_export_block) {
return 0;
}
(void)cb("myfoo/mybar", &val8, sizeof(val8));
(void)cb("myfoo/mybar64", &val64, sizeof(val64));
(void)cb("myfoo/unaligned", &val8_un, sizeof(val8_un));
return 0;
}
void ctest_clear_call_state(void)
{
test_get_called = 0;
test_set_called = 0;
test_commit_called = 0;
}
int ctest_get_call_state(void)
{
return test_get_called + test_set_called + test_commit_called;
}
void config_wipe_srcs(void)
{
sys_slist_init(&settings_load_srcs);
settings_save_dst = NULL;
}
char *c2_var_find(char *name)
{
int idx = 0;
int len;
char *eptr;
len = strlen(name);
zassert_true(len > 6, "string type expected");
zassert_true(!strncmp(name, "string", 6), "string type expected");
idx = strtoul(&name[6], &eptr, 10);
zassert_true(*eptr == '\0', "EOF");
zassert_true(idx < c2_var_count,
"var index greather than any exporter");
return val_string[idx];
}
int c2_handle_get(const char *name, char *val, int val_len_max)
{
int len;
char *valptr;
const char *next;
char argv[32];
len = settings_name_next(name, &next);
if (len && !next) {
strncpy(argv, name, len);
argv[len] = '\0';
valptr = c2_var_find(argv);
if (!valptr) {
return -ENOENT;
}
len = strlen(val_string[0]);
if (len > val_len_max) {
len = val_len_max;
}
len = MIN(strlen(valptr), len);
memcpy(val, valptr, len);
return len;
}
return -ENOENT;
}
int c2_handle_set(const char *name, size_t len, settings_read_cb read_cb,
void *cb_arg)
{
char *valptr;
const char *next;
char argv[32];
int rc;
len = settings_name_next(name, &next);
if (len && !next) {
strncpy(argv, name, len);
argv[len] = '\0';
valptr = c2_var_find(argv);
if (!valptr) {
return -ENOENT;
}
rc = read_cb(cb_arg, valptr, sizeof(val_string[0]));
zassert_true(rc >= 0, "SETTINGS_VALUE_SET callback");
if (rc == 0) {
(void)memset(valptr, 0, sizeof(val_string[0]));
}
return 0;
}
return -ENOENT;
}
int c2_handle_export(int (*cb)(const char *name,
const void *value, size_t val_len))
{
int i;
char name[32];
for (i = 0; i < c2_var_count; i++) {
snprintf(name, sizeof(name), "2nd/string%d", i);
(void)cb(name, val_string[i], strlen(val_string[i]));
}
return 0;
}
int c3_handle_get(const char *name, char *val, int val_len_max)
{
const char *next;
if (settings_name_steq(name, "v", &next) && !next) {
val_len_max = MIN(val_len_max, sizeof(val32));
memcpy(val, &val32, MIN(val_len_max, sizeof(val32)));
return val_len_max;
}
return -EINVAL;
}
int c3_handle_set(const char *name, size_t len, settings_read_cb read_cb,
void *cb_arg)
{
int rc;
size_t val_len;
const char *next;
if (settings_name_steq(name, "v", &next) && !next) {
val_len = len;
zassert_true(val_len == 4, "bad set-value size");
rc = read_cb(cb_arg, &val32, sizeof(val32));
zassert_true(rc >= 0, "SETTINGS_VALUE_SET callback");
return 0;
}
return -ENOENT;
}
int c3_handle_export(int (*cb)(const char *name,
const void *value, size_t val_len))
{
(void)cb("3/v", &val32, sizeof(val32));
return 0;
}
ZTEST_SUITE(settings_config, NULL, settings_config_setup, NULL, NULL,
settings_config_teardown);