| /* |
| * Copyright (c) 2018 Nordic Semiconductor ASA |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include "settings_test.h" |
| #include "settings_priv.h" |
| |
| static char enc_buf[128]; |
| static int enc_buf_cnt; |
| static uint8_t test_rwbs = 1U; |
| #define ENC_CTX_VAL 0x2018 |
| |
| static int write_handler(void *ctx, off_t off, char const *buf, size_t len) |
| { |
| zassert_equal(ctx, (void *)ENC_CTX_VAL, "bad write callback context\n"); |
| |
| if (off % test_rwbs || len % test_rwbs) { |
| return -EIO; |
| } |
| |
| memcpy(&enc_buf[off], buf, len); |
| enc_buf_cnt += len; |
| return 0; |
| } |
| |
| static void test_encoding_iteration(char const *name, char const *value, |
| char const *pattern, int exp_len, uint8_t wbs) |
| { |
| int rc; |
| |
| test_rwbs = wbs; |
| |
| settings_line_io_init(NULL, write_handler, NULL, wbs); |
| |
| enc_buf_cnt = 0; |
| |
| rc = settings_line_write(name, value, strlen(value), 0, |
| (void *)ENC_CTX_VAL); |
| |
| zassert_equal(rc, 0, "Can't encode the line %d.\n", rc); |
| |
| zassert_equal(enc_buf_cnt, exp_len, "Wrote more than expected\n"); |
| |
| zassert_true(memcmp(pattern, enc_buf, exp_len) == 0, |
| "encoding defect, was : %s\nexpected: %s\n", enc_buf, |
| pattern); |
| } |
| |
| void test_settings_encode(void) |
| { |
| char const name[] = "nordic"; |
| char const value[] = "Doubt. Only an evil man, master Geralt," |
| " is without it. And no one escapes his destiny"; |
| char const pattern[] = "nordic=RG91YnQuIE9ubHkgYW4gZXZpbCBtYW4sIG1hc3Rl" |
| "ciBHZXJhbHQsIGlzIHdpdGhvdXQgaXQuIEFuZCBubyBvbmU" |
| "gZXNjYXBlcyBoaXMgZGVzdGlueQ==\0"; |
| char const pattern2[] = "nordic=RG91YnQuIE9ubHkgYW4gZXZpbCBtYW4sIG1hc3R" |
| "lciBHZXJhbHQsIGlzIHdpdGhvdXQgaXQuIEFuZCBubyBvb" |
| "mUgZXNjYXBlcyBoaXMgZGVzdGlueQ==\0\0\0\0\0"; |
| char const name2[] = "nord"; |
| char const value2[] = "123"; |
| char const pattern3[] = "nord=MTIz\0\0\0"; |
| |
| test_encoding_iteration(name, value, pattern, 124, 4); |
| test_encoding_iteration(name, value, pattern, 123, 1); |
| test_encoding_iteration(name, value, pattern2, 128, 8); |
| test_encoding_iteration(name2, value2, pattern3, 12, 4); |
| test_encoding_iteration(name2, value2, pattern3, 9, 1); |
| } |
| |
| static int read_handle(void *ctx, off_t off, char *buf, size_t *len) |
| { |
| int r_len; |
| |
| zassert_equal(ctx, (void *)ENC_CTX_VAL, "bad write callback context\n"); |
| |
| if (off % test_rwbs || *len % test_rwbs) { |
| return -EIO; |
| } |
| |
| r_len = MIN(sizeof(enc_buf) - off, *len); |
| if (r_len <= 0) { |
| *len = 0; |
| return 0; |
| } |
| |
| memcpy(buf, &enc_buf[off], r_len); |
| *len = r_len; |
| return 0; |
| } |
| |
| char read_buf[128+10]; |
| |
| static void test_raw_read_iteration(uint8_t rbs, size_t off, size_t len) |
| { |
| test_rwbs = rbs; |
| size_t len_read; |
| int rc; |
| size_t expected; |
| |
| memset(read_buf, 0x00, sizeof(read_buf)); |
| |
| settings_line_io_init(read_handle, write_handler, NULL, rbs); |
| |
| rc = settings_line_raw_read(off, &read_buf[4], len, &len_read, |
| (void *)ENC_CTX_VAL); |
| |
| zassert_equal(rc, 0, "Can't read the line %d.\n", rc); |
| |
| expected = MIN((sizeof(enc_buf) - off), len); |
| zassert_equal(expected, len_read, "Unexpected read size\n"); |
| |
| zassert_true(memcmp(&enc_buf[off], &read_buf[4], len_read) == 0, |
| "read defect\n"); |
| |
| for (rc = 0; rc < 4; rc++) { |
| zassert_equal(read_buf[rc], 0, "buffer lickage\n"); |
| } |
| |
| for (rc = len_read + 4; rc < sizeof(read_buf); rc++) { |
| zassert_equal(read_buf[rc], 0, "buffer lickage\n"); |
| } |
| } |
| |
| void test_setting_raw_read(void) |
| { |
| int i; |
| |
| for (i = 0; i < sizeof(enc_buf); i++) { |
| enc_buf[i] = i + 1; |
| } |
| |
| test_raw_read_iteration(1, 0, 56); |
| test_raw_read_iteration(1, 5, 128); |
| test_raw_read_iteration(4, 1, 56); |
| test_raw_read_iteration(4, 0, 128); |
| test_raw_read_iteration(4, 3, 128); |
| test_raw_read_iteration(8, 3, 128); |
| test_raw_read_iteration(8, 0, 128); |
| test_raw_read_iteration(8, 77, 3); |
| } |
| |
| |
| |
| |
| static void test_val_read_iteration(char const *src, size_t src_len, |
| char const *pattern, size_t pattern_len, |
| size_t len, uint8_t rbs, size_t off, |
| size_t val_off) |
| { |
| size_t len_read; |
| int rc; |
| |
| memcpy(enc_buf, src, src_len); |
| |
| test_rwbs = rbs; |
| |
| settings_line_io_init(read_handle, write_handler, NULL, rbs); |
| |
| rc = settings_line_val_read(val_off, off, read_buf, len, &len_read, |
| (void *)ENC_CTX_VAL); |
| |
| zassert_equal(rc, 0, "Can't read the value.\n"); |
| |
| zassert_equal(len_read, pattern_len, "Bad length (was %d).\n", |
| len_read); |
| read_buf[len_read] = 0; |
| zassert_true(memcmp(pattern, read_buf, pattern_len) == 0, |
| "encoding defect, was :\n%s\nexpected :\n%s\n", read_buf, |
| pattern); |
| } |
| |
| void test_setting_val_read(void) |
| { |
| char const val_src[] = "V2FzIHdyaXR0ZW4gaW4gS3Jha293AA=="; |
| char const val_src2[] = "jozef/pilsodski=" |
| "V2FzIHdyaXR0ZW4gaW4gS3Jha293AA=="; |
| char const val_pattern[] = "Was written in Krakow"; |
| |
| test_val_read_iteration(val_src, sizeof(val_src), val_pattern, |
| sizeof(val_pattern), 128, 1, 0, 0); |
| test_val_read_iteration(val_src, sizeof(val_src), &val_pattern[1], |
| sizeof(val_pattern) - 1, 128, 1, 1, 0); |
| test_val_read_iteration(val_src, sizeof(val_src), val_pattern, |
| sizeof(val_pattern), sizeof(val_pattern), 1, 0, |
| 0); |
| |
| for (int j = 1; j < sizeof(val_pattern); j++) { |
| for (int i = 0; i < sizeof(val_pattern) - j; i++) { |
| test_val_read_iteration(val_src, sizeof(val_src), |
| &val_pattern[i], j, j, 1, i, 0); |
| } |
| } |
| |
| for (int j = 1; j < sizeof(val_pattern); j++) { |
| for (int i = 0; i < sizeof(val_pattern) - j; i++) { |
| test_val_read_iteration(val_src2, sizeof(val_src2), |
| &val_pattern[i], j, j, 1, i, |
| 16); |
| } |
| } |
| |
| test_val_read_iteration(val_src, sizeof(val_src), val_pattern, |
| sizeof(val_pattern), 128, 4, 0, 0); |
| test_val_read_iteration(val_src, sizeof(val_src), &val_pattern[1], |
| sizeof(val_pattern) - 1, 128, 4, 1, 0); |
| test_val_read_iteration(val_src, sizeof(val_src), val_pattern, |
| sizeof(val_pattern), sizeof(val_pattern), 4, 0, |
| 0); |
| |
| for (int j = 1; j < sizeof(val_pattern); j++) { |
| for (int i = 0; i < sizeof(val_pattern) - j; i++) { |
| test_val_read_iteration(val_src, sizeof(val_src), |
| &val_pattern[i], j, j, 4, i, 0); |
| } |
| } |
| |
| test_val_read_iteration(val_src, sizeof(val_src), val_pattern, |
| sizeof(val_pattern), 128, 8, 0, 0); |
| test_val_read_iteration(val_src, sizeof(val_src), &val_pattern[1], |
| sizeof(val_pattern) - 1, 128, 8, 1, 0); |
| test_val_read_iteration(val_src, sizeof(val_src), val_pattern, |
| sizeof(val_pattern), sizeof(val_pattern), 8, 0, |
| 0); |
| |
| for (int j = 1; j < sizeof(val_pattern); j++) { |
| for (int i = 0; i < sizeof(val_pattern) - j; i++) { |
| test_val_read_iteration(val_src, sizeof(val_src), |
| &val_pattern[i], j, j, 8, i, 0); |
| } |
| } |
| |
| |
| } |