1 /*
2 * Copyright (c) 2018 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include "settings_test.h"
8 #include "settings/settings_fcb.h"
9
10 #define NAME_DELETABLE "4/deletable"
11
12 struct flash_sector fcb_small_sectors[2] = {
13 [0] = {
14 .fs_off = 0x00000000,
15 .fs_size = 4 * 1024
16 },
17 [1] = {
18 .fs_off = 0x00001000,
19 .fs_size = 4 * 1024
20 }
21 };
22
23 struct deletable_s {
24 bool valid;
25 uint32_t val32;
26 } deletable_val;
27
28 uint32_t val4v2;
29
30 int c4_handle_export(int (*cb)(const char *name, const void *value, size_t val_len));
31 int c4_handle_set(const char *name, size_t len, settings_read_cb read_cb,
32 void *cb_arg);
33
34 struct settings_handler c4_test_handler = {
35 .name = "4",
36 .h_get = NULL,
37 .h_set = c4_handle_set,
38 .h_commit = NULL,
39 .h_export = c4_handle_export
40 };
41
c4_handle_set(const char * name,size_t len,settings_read_cb read_cb,void * cb_arg)42 int c4_handle_set(const char *name, size_t len, settings_read_cb read_cb,
43 void *cb_arg)
44 {
45 return 0;
46 }
47
c4_handle_export(int (* cb)(const char * name,const void * value,size_t val_len))48 int c4_handle_export(int (*cb)(const char *name, const void *value, size_t val_len))
49 {
50 if (deletable_val.valid) {
51 (void)cb(NAME_DELETABLE, &deletable_val.val32,
52 sizeof(deletable_val.val32));
53 } else {
54 (void)cb(NAME_DELETABLE, NULL, 0);
55 }
56
57 (void)cb("4/dummy", &val4v2, sizeof(val4v2));
58
59 return 0;
60 }
61
check_compressed_cb(struct fcb_entry_ctx * entry_ctx,void * arg)62 static int check_compressed_cb(struct fcb_entry_ctx *entry_ctx, void *arg)
63 {
64 char buf[SETTINGS_MAX_NAME_LEN + SETTINGS_MAX_VAL_LEN +
65 SETTINGS_EXTRA_LEN];
66 int rc;
67 int len;
68
69 len = entry_ctx->loc.fe_data_len;
70 if (len >= sizeof(buf)) {
71 len = sizeof(buf) - 1;
72 }
73
74 rc = flash_area_read(entry_ctx->fap,
75 FCB_ENTRY_FA_DATA_OFF(entry_ctx->loc), buf, len);
76
77 if (rc) {
78 return 0;
79 }
80 buf[len] = '\0';
81
82 rc = strncmp(buf, NAME_DELETABLE, sizeof(NAME_DELETABLE)-1);
83 zassert_true(rc != 0, "The deleted settings shouldn be compressed.");
84
85 return 0;
86 }
87
ZTEST(settings_config_fcb,test_config_compress_deleted)88 ZTEST(settings_config_fcb, test_config_compress_deleted)
89 {
90 int rc;
91 struct settings_fcb cf;
92 int i;
93
94 config_wipe_srcs();
95 config_wipe_fcb(fcb_small_sectors, ARRAY_SIZE(fcb_small_sectors));
96
97 cf.cf_fcb.f_magic = CONFIG_SETTINGS_FCB_MAGIC;
98 cf.cf_fcb.f_sectors = fcb_small_sectors;
99 cf.cf_fcb.f_sector_cnt = ARRAY_SIZE(fcb_small_sectors);
100
101 rc = settings_fcb_src(&cf);
102 zassert_true(rc == 0, "can't register FCB as configuration source");
103 settings_mount_fcb_backend(&cf);
104
105 rc = settings_fcb_dst(&cf);
106 zassert_true(rc == 0,
107 "can't register FCB as configuration destination");
108
109 rc = settings_register(&c4_test_handler);
110 zassert_true(rc == 0, "settings_register fail");
111
112 deletable_val.valid = true;
113 deletable_val.val32 = 2018U;
114 val4v2 = 0U;
115
116 rc = settings_save();
117 zassert_true(rc == 0, "fcb write error");
118
119 deletable_val.valid = false;
120
121 for (i = 0; ; i++) {
122 val4v2++;
123
124 rc = settings_save();
125 zassert_true(rc == 0, "fcb write error");
126
127 if (cf.cf_fcb.f_active.fe_sector == &fcb_small_sectors[1]) {
128 /*
129 * The compression should happened while the active
130 * sector was changing.
131 */
132 break;
133 }
134 }
135
136 rc = fcb_walk(&cf.cf_fcb, &fcb_small_sectors[1], check_compressed_cb,
137 NULL);
138 settings_unregister(&c4_test_handler);
139 }
140