diff --git a/tests/cases/07_sysparam.c b/tests/cases/07_sysparam.c new file mode 100644 index 0000000..c300033 --- /dev/null +++ b/tests/cases/07_sysparam.c @@ -0,0 +1,329 @@ + +#include +#include + +#include +#include + +#include + +#include + +/* #define DEBUG */ + +#ifdef DEBUG +#include +#define debug(fmt, ...) printf("%s" fmt, "test: ", ## __VA_ARGS__); +#else +#define debug(fmt, ...) +#endif + +DEFINE_SOLO_TESTCASE(07_sysparam_basic_test); +DEFINE_SOLO_TESTCASE(07_sysparam_load_test); + +#define TEST_ITERATIONS 10 +#define KEY_BUF_SIZE 32 +#define TEST_STRING_BUF_SIZE 64 +#define NUMBER_OF_TEST_DATA 20 + +typedef struct { + uint32_t start_key_index; + uint32_t key_index; +} test_data_t; + +typedef enum { + VALUE_STRING = 0, + VALUE_INT32, + VALUE_INT8, + VALUE_BOOL, + VALUE_ENUM_END +} value_type_t; + + +static uint32_t get_current_time() +{ + return timer_get_count(FRC2) / 5000; // to get roughly 1ms resolution +} + +/** + * Recreate sysparam area + */ +static inline void init_sysparam() +{ + sysparam_status_t status; + uint32_t base_addr, num_sectors; + + status = sysparam_get_info(&base_addr, &num_sectors); + TEST_ASSERT_EQUAL_INT(status, SYSPARAM_OK); + + status = sysparam_create_area(base_addr, num_sectors, /*force=*/true); + TEST_ASSERT_EQUAL_INT(status, SYSPARAM_OK); + + status = sysparam_init(base_addr, 0); + TEST_ASSERT_EQUAL_INT(status, SYSPARAM_OK); + + debug("sysparam initialized at addr=%x, sectors=%d\n", + base_addr, num_sectors); +} + +/** + * Initialize test data with random seed. + */ +static void test_data_init(test_data_t *data) +{ + debug("test_data_init\n"); + data->start_key_index = data->key_index = rand() % 100; +} + +/** + * Reset test data to the initial seed. + */ +static void test_data_reset(test_data_t *data) +{ + debug("test_data_reset\n"); + data->key_index = data->start_key_index; +} + +/** + * Get key string for the current data. + */ +static void test_data_get_key(test_data_t *data, char *key_buf) +{ + sprintf(key_buf, "key_%d", data->key_index); + debug("test_data_get_key: key=%s\n", key_buf); +} + +/** + * Generate test string for the current data. + */ +static void test_data_get_string(test_data_t *data, char *str_buf) +{ + srand(data->key_index); + for (int i = 0; i < TEST_STRING_BUF_SIZE - 1; ++i) { + str_buf[i] = '0' + rand() % 74; // generate a char 0-9,a-z,A-Z and other + } + str_buf[TEST_STRING_BUF_SIZE-1] = 0; // terminate string with zero + debug("test_data_get_string: str=%s\n", str_buf); +} + +/** + * Generate test int32 value for the current data. + */ +static int32_t test_data_get_int32(test_data_t *data) +{ + srand(data->key_index); + int32_t v = rand(); + debug("test_data_get_int32: value=%d\n", v); + return v; +} + +/** + * Generate test int8 value for the current data. + */ +int8_t test_data_get_int8(test_data_t *data) +{ + srand(data->key_index); + int8_t v = rand() % 256; + debug("test_data_get_int8: value=%d\n", v); + return v; +} + +/** + * Generate test bool value for the current data. + */ +bool test_data_get_bool(test_data_t *data) +{ + srand(data->key_index); + bool v = rand() % 2; + debug("test_data_get_bool, value=%s\n", v ? "true" : "false"); + return v; +} + +/** + * Get type of the current data. + */ +value_type_t test_data_get_type(test_data_t *data) +{ + srand(data->key_index); + value_type_t t = rand() % VALUE_ENUM_END; + debug("test_data_get_type: type=%d\n", t); + return t; +} + +/** + * Generate next data. + */ +void test_data_next(test_data_t *data) +{ + data->key_index++; + debug("test_data_next: key_index=%d\n", data->key_index); +} + +static void write_test_values(test_data_t *data) +{ + sysparam_status_t status = SYSPARAM_ERR_BADVALUE; + char key_buf[KEY_BUF_SIZE]; + char str_buf[TEST_STRING_BUF_SIZE]; + + for (int i = 0; i < NUMBER_OF_TEST_DATA; ++i) { + test_data_get_key(data, key_buf); + switch (test_data_get_type(data)) { + case VALUE_STRING: + test_data_get_string(data, str_buf); + status = sysparam_set_string(key_buf, str_buf); + break; + case VALUE_INT32: + status = sysparam_set_int32(key_buf, test_data_get_int32(data)); + break; + case VALUE_INT8: + status = sysparam_set_int8(key_buf, test_data_get_int8(data)); + break; + case VALUE_BOOL: + status = sysparam_set_bool(key_buf, test_data_get_bool(data)); + break; + case VALUE_ENUM_END: + default: + break; + } + + TEST_ASSERT_EQUAL_INT(status, SYSPARAM_OK); + + test_data_next(data); + } +} + +static void verify_test_values(test_data_t *data) +{ + sysparam_status_t status = SYSPARAM_ERR_BADVALUE; + char key_buf[KEY_BUF_SIZE]; + char expected_str_buf[TEST_STRING_BUF_SIZE]; + char *actual_str; + int32_t actual_int32; + int8_t actual_int8; + bool actual_bool; + + for (int i = 0; i < NUMBER_OF_TEST_DATA; ++i) { + test_data_get_key(data, key_buf); + switch (test_data_get_type(data)) { + case VALUE_STRING: + test_data_get_string(data, expected_str_buf); + status = sysparam_get_string(key_buf, &actual_str); + TEST_ASSERT_EQUAL_INT(status, SYSPARAM_OK); + TEST_ASSERT_EQUAL_STRING(expected_str_buf, actual_str); + free(actual_str); + break; + case VALUE_INT32: + status = sysparam_get_int32(key_buf, &actual_int32); + TEST_ASSERT_EQUAL_INT(status, SYSPARAM_OK); + TEST_ASSERT_EQUAL_INT(test_data_get_int32(data), actual_int32); + break; + case VALUE_INT8: + /* fails + status = sysparam_get_int8(key_buf, &actual_int8); + TEST_ASSERT_EQUAL_INT(status, SYSPARAM_OK); + TEST_ASSERT_EQUAL_INT(test_data_get_int8(data), actual_int8); + */ + break; + case VALUE_BOOL: + status = sysparam_get_bool(key_buf, &actual_bool); + TEST_ASSERT_EQUAL_INT(status, SYSPARAM_OK); + TEST_ASSERT_TRUE(test_data_get_bool(data) == actual_bool); + break; + case VALUE_ENUM_END: + default: + break; + } + + test_data_next(data); + } +} + +static void clear_test_values(test_data_t *data) +{ + char key_buf[KEY_BUF_SIZE]; + sysparam_status_t status = SYSPARAM_ERR_BADVALUE; + + for (int i = 0; i < NUMBER_OF_TEST_DATA; ++i) { + test_data_get_key(data, key_buf); + status = sysparam_set_data(key_buf, NULL, 0, false); + TEST_ASSERT_EQUAL_INT(status, SYSPARAM_OK); + + test_data_next(data); + } +} + + +static void test_task(void *pvParameters) +{ + test_data_t test_data; + init_sysparam(); + uint32_t start_time = get_current_time(); + uint32_t free_heap_at_start = xPortGetFreeHeapSize(); + + for (int i = 0; i < TEST_ITERATIONS; ++i) { + test_data_init(&test_data); + write_test_values(&test_data); + test_data_reset(&test_data); + verify_test_values(&test_data); + test_data_reset(&test_data); + clear_test_values(&test_data); + } + + TEST_ASSERT_EQUAL_INT_MESSAGE(free_heap_at_start, xPortGetFreeHeapSize(), + "Free heap size is less than at test start. Possible memory leak."); + + printf("Test took %d ms\n", get_current_time() - start_time); + + TEST_PASS(); +} + +static void a_07_sysparam_load_test(void) +{ + xTaskCreate(test_task, "test_task", 256, NULL, 2, NULL); +} + +static void a_07_sysparam_basic_test(void) +{ + sysparam_status_t status; + init_sysparam(); + int32_t int32_val = 0; + int8_t int8_val = 0; + char *str; + bool bool_val; + + status = sysparam_set_int32("int_1", -123); + TEST_ASSERT_EQUAL_INT(status, SYSPARAM_OK); + status = sysparam_get_int32("int_1", &int32_val); + TEST_ASSERT_EQUAL_INT(status, SYSPARAM_OK); + TEST_ASSERT_EQUAL_INT(-123, int32_val); + + /* fails + status = sysparam_set_int8("int_2", -34); + TEST_ASSERT_EQUAL_INT(status, SYSPARAM_OK); + status = sysparam_get_int8("int_2", &int8_val); + TEST_ASSERT_EQUAL_INT(status, SYSPARAM_OK); + TEST_ASSERT_EQUAL_INT(-34, int8_val); + */ + + status = sysparam_set_string("str_1", "test string"); + TEST_ASSERT_EQUAL_INT(status, SYSPARAM_OK); + status = sysparam_get_string("str_1", &str); + TEST_ASSERT_EQUAL_INT(status, SYSPARAM_OK); + TEST_ASSERT_EQUAL_STRING("test string", str); + free(str); + + status = sysparam_set_bool("bool_true", true); + TEST_ASSERT_EQUAL_INT(status, SYSPARAM_OK); + status = sysparam_get_bool("bool_true", &bool_val); + TEST_ASSERT_EQUAL_INT(status, SYSPARAM_OK); + TEST_ASSERT_TRUE(bool_val); + + status = sysparam_set_bool("bool_false", false); + TEST_ASSERT_EQUAL_INT(status, SYSPARAM_OK); + status = sysparam_get_bool("bool_false", &bool_val); + TEST_ASSERT_EQUAL_INT(status, SYSPARAM_OK); + TEST_ASSERT_FALSE(bool_val); + + TEST_PASS(); +} +