| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| #include <stdio.h> |
| #include <string.h> |
| |
| #include "os/mynewt.h" |
| #include <flash_map/flash_map.h> |
| #include <testutil/testutil.h> |
| #include <fcb/fcb.h> |
| #include "config/config.h" |
| #include "config/config_file.h" |
| #include "config/config_fcb.h" |
| #include "config_priv.h" |
| #include "conf_test_fcb.h" |
| |
| uint8_t val8; |
| int c2_var_count = 1; |
| |
| char val_string[CONF_TEST_FCB_VAL_STR_CNT][CONF_MAX_VAL_LEN]; |
| |
| uint32_t val32; |
| uint64_t val64; |
| |
| int test_get_called; |
| int test_set_called; |
| int test_commit_called; |
| int test_export_block; |
| |
| char *ctest_handle_get(int argc, char **argv, char *val, |
| int val_len_max); |
| int ctest_handle_set(int argc, char **argv, char *val); |
| int ctest_handle_commit(void); |
| int ctest_handle_export(void (*cb)(char *name, char *value), |
| enum conf_export_tgt tgt); |
| char *c2_handle_get(int argc, char **argv, char *val, |
| int val_len_max); |
| int c2_handle_set(int argc, char **argv, char *val); |
| int c2_handle_export(void (*cb)(char *name, char *value), |
| enum conf_export_tgt tgt); |
| char *c3_handle_get(int argc, char **argv, char *val, |
| int val_len_max); |
| int c3_handle_set(int argc, char **argv, char *val); |
| int c3_handle_export(void (*cb)(char *name, char *value), |
| enum conf_export_tgt tgt); |
| |
| struct conf_handler config_test_handler = { |
| .ch_name = "myfoo", |
| .ch_get = ctest_handle_get, |
| .ch_set = ctest_handle_set, |
| .ch_commit = ctest_handle_commit, |
| .ch_export = ctest_handle_export |
| }; |
| |
| char * |
| ctest_handle_get(int argc, char **argv, char *val, int val_len_max) |
| { |
| test_get_called = 1; |
| if (argc == 1 && !strcmp(argv[0], "mybar")) { |
| return conf_str_from_value(CONF_INT8, &val8, val, val_len_max); |
| } |
| if (argc == 1 && !strcmp(argv[0], "mybar64")) { |
| return conf_str_from_value(CONF_INT64, &val64, val, val_len_max); |
| } |
| return NULL; |
| } |
| |
| int |
| ctest_handle_set(int argc, char **argv, char *val) |
| { |
| uint8_t newval; |
| uint64_t newval64; |
| int rc; |
| |
| test_set_called = 1; |
| if (argc == 1 && !strcmp(argv[0], "mybar")) { |
| rc = CONF_VALUE_SET(val, CONF_INT8, newval); |
| TEST_ASSERT(rc == 0); |
| val8 = newval; |
| return 0; |
| } |
| if (argc == 1 && !strcmp(argv[0], "mybar64")) { |
| rc = CONF_VALUE_SET(val, CONF_INT64, newval64); |
| TEST_ASSERT(rc == 0); |
| val64 = newval64; |
| return 0; |
| } |
| return OS_ENOENT; |
| } |
| |
| int |
| ctest_handle_commit(void) |
| { |
| test_commit_called = 1; |
| return 0; |
| } |
| |
| int |
| ctest_handle_export(void (*cb)(char *name, char *value), |
| enum conf_export_tgt tgt) |
| { |
| char value[32]; |
| |
| if (test_export_block) { |
| return 0; |
| } |
| conf_str_from_value(CONF_INT8, &val8, value, sizeof(value)); |
| cb("myfoo/mybar", value); |
| |
| conf_str_from_value(CONF_INT64, &val64, value, sizeof(value)); |
| cb("myfoo/mybar64", value); |
| |
| return 0; |
| } |
| |
| struct conf_handler c2_test_handler = { |
| .ch_name = "2nd", |
| .ch_get = c2_handle_get, |
| .ch_set = c2_handle_set, |
| .ch_commit = NULL, |
| .ch_export = c2_handle_export |
| }; |
| |
| char * |
| c2_var_find(char *name) |
| { |
| int idx = 0; |
| int len; |
| char *eptr; |
| |
| len = strlen(name); |
| TEST_ASSERT(!strncmp(name, "string", 6)); |
| TEST_ASSERT(len > 6); |
| |
| idx = strtoul(&name[6], &eptr, 10); |
| TEST_ASSERT(*eptr == '\0'); |
| TEST_ASSERT(idx < c2_var_count); |
| return val_string[idx]; |
| } |
| |
| char * |
| c2_handle_get(int argc, char **argv, char *val, int val_len_max) |
| { |
| int len; |
| char *valptr; |
| |
| if (argc == 1) { |
| valptr = c2_var_find(argv[0]); |
| if (!valptr) { |
| return NULL; |
| } |
| len = strlen(val_string[0]); |
| if (len > val_len_max) { |
| len = val_len_max; |
| } |
| strncpy(val, valptr, len); |
| } |
| return NULL; |
| } |
| |
| int |
| c2_handle_set(int argc, char **argv, char *val) |
| { |
| char *valptr; |
| |
| if (argc == 1) { |
| valptr = c2_var_find(argv[0]); |
| if (!valptr) { |
| return OS_ENOENT; |
| } |
| if (val) { |
| strncpy(valptr, val, sizeof(val_string[0])); |
| } else { |
| memset(valptr, 0, sizeof(val_string[0])); |
| } |
| return 0; |
| } |
| return OS_ENOENT; |
| } |
| |
| int |
| c2_handle_export(void (*cb)(char *name, char *value), |
| enum conf_export_tgt tgt) |
| { |
| int i; |
| char name[32]; |
| |
| for (i = 0; i < c2_var_count; i++) { |
| snprintf(name, sizeof(name), "2nd/string%d", i); |
| cb(name, val_string[i]); |
| } |
| return 0; |
| } |
| |
| struct conf_handler c3_test_handler = { |
| .ch_name = "3", |
| .ch_get = c3_handle_get, |
| .ch_set = c3_handle_set, |
| .ch_commit = NULL, |
| .ch_export = c3_handle_export |
| }; |
| |
| char * |
| c3_handle_get(int argc, char **argv, char *val, int val_len_max) |
| { |
| if (argc == 1 && !strcmp(argv[0], "v")) { |
| return conf_str_from_value(CONF_INT32, &val32, val, val_len_max); |
| } |
| return NULL; |
| } |
| |
| int |
| c3_handle_set(int argc, char **argv, char *val) |
| { |
| uint32_t newval; |
| int rc; |
| |
| if (argc == 1 && !strcmp(argv[0], "v")) { |
| rc = CONF_VALUE_SET(val, CONF_INT32, newval); |
| TEST_ASSERT(rc == 0); |
| val32 = newval; |
| return 0; |
| } |
| return OS_ENOENT; |
| } |
| |
| int |
| c3_handle_export(void (*cb)(char *name, char *value), |
| enum conf_export_tgt tgt) |
| { |
| char value[32]; |
| |
| conf_str_from_value(CONF_INT32, &val32, value, sizeof(value)); |
| cb("3/v", value); |
| |
| 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) |
| { |
| SLIST_INIT(&conf_load_srcs); |
| conf_save_dst = NULL; |
| } |
| |
| void config_wipe_fcb(struct flash_area *fa, int cnt) |
| { |
| int rc; |
| int i; |
| |
| for (i = 0; i < cnt; i++) { |
| rc = flash_area_erase(&fa[i], 0, fa[i].fa_size); |
| TEST_ASSERT(rc == 0); |
| } |
| } |
| |
| struct flash_area fcb_areas[] = { |
| [0] = { |
| .fa_off = 0x00000000, |
| .fa_size = 16 * 1024 |
| }, |
| [1] = { |
| .fa_off = 0x00004000, |
| .fa_size = 16 * 1024 |
| }, |
| [2] = { |
| .fa_off = 0x00008000, |
| .fa_size = 16 * 1024 |
| }, |
| [3] = { |
| .fa_off = 0x0000c000, |
| .fa_size = 16 * 1024 |
| } |
| }; |
| |
| void |
| config_test_fill_area( |
| char test_value[CONF_TEST_FCB_VAL_STR_CNT][CONF_MAX_VAL_LEN], |
| int iteration) |
| { |
| int i, j; |
| |
| for (j = 0; j < CONF_TEST_FCB_VAL_STR_CNT; j++) { |
| for (i = 0; i < CONF_MAX_VAL_LEN; i++) { |
| test_value[j][i] = ((j * 2) + i + iteration) % 10 + '0'; |
| } |
| test_value[j][sizeof(test_value[j]) - 1] = '\0'; |
| } |
| } |
| |
| TEST_CASE_DECL(config_empty_lookups) |
| TEST_CASE_DECL(config_test_insert) |
| TEST_CASE_DECL(config_test_getset_unknown) |
| TEST_CASE_DECL(config_test_getset_int) |
| TEST_CASE_DECL(config_test_getset_bytes) |
| TEST_CASE_DECL(config_test_getset_int64) |
| TEST_CASE_DECL(config_test_commit) |
| TEST_CASE_DECL(config_test_empty_fcb) |
| TEST_CASE_DECL(config_test_save_1_fcb) |
| TEST_CASE_DECL(config_test_insert2) |
| TEST_CASE_DECL(config_test_save_2_fcb) |
| TEST_CASE_DECL(config_test_insert3) |
| TEST_CASE_DECL(config_test_save_3_fcb) |
| TEST_CASE_DECL(config_test_compress_reset) |
| TEST_CASE_DECL(config_test_save_one_fcb) |
| TEST_CASE_DECL(config_test_custom_compress) |
| TEST_CASE_DECL(config_test_get_stored_fcb) |
| |
| TEST_SUITE(config_test_all) |
| { |
| /* |
| * Config tests. |
| */ |
| config_empty_lookups(); |
| config_test_insert(); |
| config_test_getset_unknown(); |
| config_test_getset_int(); |
| config_test_getset_bytes(); |
| config_test_getset_int64(); |
| |
| config_test_commit(); |
| |
| /* |
| * FCB as backing storage. |
| */ |
| config_test_empty_fcb(); |
| config_test_save_1_fcb(); |
| |
| config_test_insert2(); |
| |
| config_test_save_2_fcb(); |
| |
| config_test_insert3(); |
| config_test_save_3_fcb(); |
| |
| config_test_compress_reset(); |
| config_test_custom_compress(); |
| |
| config_test_save_one_fcb(); |
| config_test_get_stored_fcb(); |
| } |
| |
| #if MYNEWT_VAL(SELFTEST) |
| |
| int |
| main(int argc, char **argv) |
| { |
| sysinit(); |
| |
| conf_init(); |
| config_test_all(); |
| |
| return tu_any_failed; |
| } |
| |
| #endif |