| /* |
| * 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 <testutil/testutil.h> |
| #include <nffs/nffs.h> |
| #include <fs/fs.h> |
| #include <fs/fsutil.h> |
| #include "config/config.h" |
| #include "config/config_file.h" |
| #include "config_priv.h" |
| |
| uint8_t val8; |
| int c2_var_count = 1; |
| char val_string[64][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; |
| } |
| |
| const struct nffs_area_desc config_nffs[] = { |
| { 0x00000000, 16 * 1024 }, |
| { 0x00004000, 16 * 1024 }, |
| { 0x00008000, 16 * 1024 }, |
| { 0x0000c000, 16 * 1024 }, |
| { 0, 0 } |
| }; |
| |
| void |
| config_wipe_srcs(void) |
| { |
| SLIST_INIT(&conf_load_srcs); |
| conf_save_dst = NULL; |
| } |
| |
| int |
| conf_test_file_strstr(const char *fname, char *string) |
| { |
| int rc; |
| uint32_t len; |
| uint32_t rlen; |
| char *buf; |
| struct fs_file *file; |
| |
| rc = fs_open(fname, FS_ACCESS_READ, &file); |
| if (rc) { |
| return rc; |
| } |
| rc = fs_filelen(file, &len); |
| fs_close(file); |
| if (rc) { |
| return rc; |
| } |
| |
| buf = (char *)malloc(len + 1); |
| TEST_ASSERT(buf); |
| |
| rc = fsutil_read_file(fname, 0, len, buf, &rlen); |
| TEST_ASSERT(rc == 0); |
| TEST_ASSERT(rlen == len); |
| buf[rlen] = '\0'; |
| |
| if (strstr(buf, string)) { |
| return 0; |
| } else { |
| return -1; |
| } |
| } |
| |
| void config_test_fill_area(char test_value[64][CONF_MAX_VAL_LEN], |
| int iteration) |
| { |
| int i, j; |
| |
| for (j = 0; j < 64; 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_setup_nffs) |
| TEST_CASE_DECL(config_test_empty_file) |
| TEST_CASE_DECL(config_test_small_file) |
| TEST_CASE_DECL(config_test_multiple_in_file) |
| TEST_CASE_DECL(config_test_save_in_file) |
| TEST_CASE_DECL(config_test_save_one_file) |
| TEST_CASE_DECL(config_test_get_stored_file) |
| |
| 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(); |
| |
| /* |
| * NFFS as backing storage. |
| */ |
| config_setup_nffs(); |
| config_test_empty_file(); |
| config_test_small_file(); |
| config_test_multiple_in_file(); |
| |
| config_test_save_in_file(); |
| |
| config_test_save_one_file(); |
| config_test_get_stored_file(); |
| } |
| |
| #if MYNEWT_VAL(SELFTEST) |
| |
| int |
| main(int argc, char **argv) |
| { |
| sysinit(); |
| |
| conf_init(); |
| config_test_all(); |
| |
| return tu_any_failed; |
| } |
| |
| #endif |