1 /*
2 * Copyright (c) 2018 Laczen
3 * Copyright (c) 2025 Nordic Semiconductor ASA
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 /** @file
9 * @brief Settings functional test suite
10 *
11 */
12
13 #include <zephyr/kernel.h>
14 #include <zephyr/ztest.h>
15 #include <zephyr/settings/settings.h>
16 #include <zephyr/logging/log.h>
17 LOG_MODULE_REGISTER(settings_basic_test);
18
19 #if defined(CONFIG_SETTINGS_FCB) || defined(CONFIG_SETTINGS_NVS) || defined(CONFIG_SETTINGS_ZMS)
20 #include <zephyr/storage/flash_map.h>
21 #if DT_HAS_CHOSEN(zephyr_settings_partition)
22 #define TEST_FLASH_AREA_ID DT_FIXED_PARTITION_ID(DT_CHOSEN(zephyr_settings_partition))
23 #endif
24 #elif defined(CONFIG_SETTINGS_FILE)
25 #include <zephyr/fs/fs.h>
26 #include <zephyr/fs/littlefs.h>
27 #elif defined(CONFIG_SETTINGS_TFM_PSA)
28
29 #if defined(CONFIG_SETTINGS_TFM_PSA_BACKEND_PS)
30 #include <psa/protected_storage.h>
31 #include <zephyr/psa/ps_ids.h>
32
33 #define SETTINGS_PSA_MAX_ASSET_SIZE PS_MAX_ASSET_SIZE
34 #define SETTINGS_PSA_REMOVE psa_ps_remove
35 #define SETTINGS_PSA_ID_RANGE_START ZEPHYR_PSA_SETTINGS_TFM_PS_UID_RANGE_BEGIN
36
37 #elif defined(CONFIG_SETTINGS_TFM_PSA_BACKEND_ITS)
38 #include <psa/internal_trusted_storage.h>
39 #include <zephyr/psa/its_ids.h>
40
41 #define SETTINGS_PSA_MAX_ASSET_SIZE ITS_MAX_ASSET_SIZE
42 #define SETTINGS_PSA_REMOVE psa_its_remove
43 #define SETTINGS_PSA_ID_RANGE_START ZEPHYR_PSA_SETTINGS_TFM_ITS_UID_RANGE_BEGIN
44
45 #else
46 #error "No PSA backend selected"
47 #endif /* CONFIG_SETTINGS_TFM_PSA_BACKEND */
48
49 /* TF-M config file containing ITS_MAX_ASSET_SIZE */
50 #include <config_base.h>
51
52 #include <settings_tfm_psa_priv.h>
53 #else
54 #error "Settings backend not selected"
55 #endif
56
57 #ifndef TEST_FLASH_AREA_ID
58 #define TEST_FLASH_AREA storage_partition
59 #define TEST_FLASH_AREA_ID FIXED_PARTITION_ID(TEST_FLASH_AREA)
60 #endif
61
62 /* The standard test expects a cleared flash area. Make sure it has
63 * one.
64 */
ZTEST(settings_functional,test_clear_settings)65 ZTEST(settings_functional, test_clear_settings)
66 {
67 #if defined(CONFIG_SETTINGS_TFM_PSA)
68 psa_status_t status;
69
70 /* Remove all potentially accessed entries in the UID range */
71 for (int i = 0; i < sizeof(struct setting_entry) * CONFIG_SETTINGS_TFM_PSA_NUM_ENTRIES /
72 SETTINGS_PSA_MAX_ASSET_SIZE + 1; i++) {
73 status = SETTINGS_PSA_REMOVE(SETTINGS_PSA_ID_RANGE_START + i);
74 zassert_true((status == PSA_SUCCESS) || (status == PSA_ERROR_DOES_NOT_EXIST),
75 "psa_its_remove failed");
76 }
77 #elif !defined(CONFIG_SETTINGS_FILE)
78 const struct flash_area *fap;
79 int rc;
80
81 rc = flash_area_open(TEST_FLASH_AREA_ID, &fap);
82
83 if (rc == 0) {
84 rc = flash_area_flatten(fap, 0, fap->fa_size);
85 flash_area_close(fap);
86 }
87 zassert_true(rc == 0, "clear settings failed");
88 #else
89 FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(cstorage);
90
91 /* mounting info */
92 static struct fs_mount_t littlefs_mnt = {
93 .type = FS_LITTLEFS,
94 .fs_data = &cstorage,
95 .storage_dev = (void *)TEST_FLASH_AREA_ID,
96 .mnt_point = "/ff"
97 };
98
99 int rc;
100
101 rc = fs_mount(&littlefs_mnt);
102 zassert_true(rc == 0, "mounting littlefs [%d]\n", rc);
103
104 rc = fs_unlink(CONFIG_SETTINGS_FILE_PATH);
105 zassert_true(rc == 0 || rc == -ENOENT,
106 "can't delete config file%d\n", rc);
107 #endif
108 }
109
110 /*
111 * Test the two support routines that settings provides:
112 *
113 * settings_name_steq(name, key, next): compares the start of name with key
114 * settings_name_next(name, next): returns the location of the first
115 * separator
116 */
117
ZTEST(settings_functional,test_support_rtn)118 ZTEST(settings_functional, test_support_rtn)
119 {
120 const char test1[] = "bt/a/b/c/d";
121 const char test2[] = "bt/a/b/c/d=";
122 const char *next1, *next2;
123 int rc;
124
125 /* complete match: return 1, next = NULL */
126 rc = settings_name_steq(test1, "bt/a/b/c/d", &next1);
127 zassert_true(rc == 1, "_steq comparison failure");
128 zassert_is_null(next1, "_steq comparison next error");
129 rc = settings_name_steq(test2, "bt/a/b/c/d", &next2);
130 zassert_true(rc == 1, "_steq comparison failure");
131 zassert_is_null(next2, "_steq comparison next error");
132
133 /* partial match: return 1, next <> NULL */
134 rc = settings_name_steq(test1, "bt/a/b/c", &next1);
135 zassert_true(rc == 1, "_steq comparison failure");
136 zassert_not_null(next1, "_steq comparison next error");
137 zassert_equal_ptr(next1, test1+9, "next points to wrong location");
138 rc = settings_name_steq(test2, "bt/a/b/c", &next2);
139 zassert_true(rc == 1, "_steq comparison failure");
140 zassert_not_null(next2, "_steq comparison next error");
141 zassert_equal_ptr(next2, test2+9, "next points to wrong location");
142
143 /* no match: return 0, next = NULL */
144 rc = settings_name_steq(test1, "bta", &next1);
145 zassert_true(rc == 0, "_steq comparison failure");
146 zassert_is_null(next1, "_steq comparison next error");
147 rc = settings_name_steq(test2, "bta", &next2);
148 zassert_true(rc == 0, "_steq comparison failure");
149 zassert_is_null(next2, "_steq comparison next error");
150
151 /* no match: return 0, next = NULL */
152 rc = settings_name_steq(test1, "b", &next1);
153 zassert_true(rc == 0, "_steq comparison failure");
154 zassert_is_null(next1, "_steq comparison next error");
155 rc = settings_name_steq(test2, "b", &next2);
156 zassert_true(rc == 0, "_steq comparison failure");
157 zassert_is_null(next2, "_steq comparison next error");
158
159 /* first separator: return 2, next <> NULL */
160 rc = settings_name_next(test1, &next1);
161 zassert_true(rc == 2, "_next wrong return value");
162 zassert_not_null(next1, "_next wrong next");
163 zassert_equal_ptr(next1, test1+3, "next points to wrong location");
164 rc = settings_name_next(test2, &next2);
165 zassert_true(rc == 2, "_next wrong return value");
166 zassert_not_null(next2, "_next wrong next");
167 zassert_equal_ptr(next2, test2+3, "next points to wrong location");
168
169 /* second separator: return 1, next <> NULL */
170 rc = settings_name_next(next1, &next1);
171 zassert_true(rc == 1, "_next wrong return value");
172 zassert_not_null(next1, "_next wrong next");
173 zassert_equal_ptr(next1, test1+5, "next points to wrong location");
174 rc = settings_name_next(next2, &next2);
175 zassert_true(rc == 1, "_next wrong return value");
176 zassert_not_null(next2, "_next wrong next");
177 zassert_equal_ptr(next2, test2+5, "next points to wrong location");
178
179 /* third separator: return 1, next <> NULL */
180 rc = settings_name_next(next1, &next1);
181 zassert_true(rc == 1, "_next wrong return value");
182 zassert_not_null(next1, "_next wrong next");
183 rc = settings_name_next(next2, &next2);
184 zassert_true(rc == 1, "_next wrong return value");
185 zassert_not_null(next2, "_next wrong next");
186
187 /* fourth separator: return 1, next <> NULL */
188 rc = settings_name_next(next1, &next1);
189 zassert_true(rc == 1, "_next wrong return value");
190 zassert_not_null(next1, "_next wrong next");
191 rc = settings_name_next(next2, &next2);
192 zassert_true(rc == 1, "_next wrong return value");
193 zassert_not_null(next2, "_next wrong next");
194
195 /* fifth separator: return 1, next == NULL */
196 rc = settings_name_next(next1, &next1);
197 zassert_true(rc == 1, "_next wrong return value");
198 zassert_is_null(next1, "_next wrong next");
199 rc = settings_name_next(next2, &next2);
200 zassert_true(rc == 1, "_next wrong return value");
201 zassert_is_null(next2, "_next wrong next");
202
203 }
204
205 struct stored_data {
206 uint8_t val1;
207 uint8_t val2;
208 uint8_t val3;
209 bool en1;
210 bool en2;
211 bool en3;
212 };
213
214 struct stored_data data;
215
val1_set(const char * key,size_t len,settings_read_cb read_cb,void * cb_arg)216 int val1_set(const char *key, size_t len, settings_read_cb read_cb,
217 void *cb_arg)
218 {
219 data.val1 = 1;
220 return 0;
221 }
val1_commit(void)222 int val1_commit(void)
223 {
224 data.en1 = true;
225 return 0;
226 }
227 static struct settings_handler val1_settings = {
228 .name = "ps",
229 .h_set = val1_set,
230 .h_commit = val1_commit,
231 };
232
val2_set(const char * key,size_t len,settings_read_cb read_cb,void * cb_arg)233 int val2_set(const char *key, size_t len, settings_read_cb read_cb,
234 void *cb_arg)
235 {
236 data.val2 = 2;
237 return 0;
238 }
val2_commit(void)239 int val2_commit(void)
240 {
241 data.en2 = true;
242 return 0;
243 }
244 static struct settings_handler val2_settings = {
245 .name = "ps/ss/ss",
246 .h_set = val2_set,
247 .h_commit = val2_commit,
248 };
249
val3_set(const char * key,size_t len,settings_read_cb read_cb,void * cb_arg)250 int val3_set(const char *key, size_t len, settings_read_cb read_cb,
251 void *cb_arg)
252 {
253 data.val3 = 3;
254 return 0;
255 }
val3_commit(void)256 int val3_commit(void)
257 {
258 data.en3 = true;
259 return 0;
260 }
261 static struct settings_handler val3_settings = {
262 .name = "ps/ss",
263 .h_set = val3_set,
264 .h_commit = val3_commit,
265 };
266
267 /* helper routine to remove a handler from settings */
settings_deregister(struct settings_handler * handler)268 int settings_deregister(struct settings_handler *handler)
269 {
270 extern sys_slist_t settings_handlers;
271
272 return sys_slist_find_and_remove(&settings_handlers, &handler->node);
273 }
274
ZTEST(settings_functional,test_register_and_loading)275 ZTEST(settings_functional, test_register_and_loading)
276 {
277 int rc, err;
278 uint8_t val = 0;
279 ssize_t val_len = 0;
280
281 rc = settings_subsys_init();
282 zassert_true(rc == 0, "subsys init failed");
283
284
285 /* Check that key that corresponds to val2 do not exist in storage */
286 val_len = settings_get_val_len("ps/ss/ss/val2");
287 zassert_true((val_len == 0), "Failure: key should not exist");
288
289 settings_save_one("ps/ss/ss/val2", &val, sizeof(uint8_t));
290
291 /* Check that the key that corresponds to val2 exists in storage */
292 val_len = settings_get_val_len("ps/ss/ss/val2");
293 zassert_true((val_len == 1), "Failure: key should exist");
294
295 memset(&data, 0, sizeof(struct stored_data));
296
297 rc = settings_register(&val1_settings);
298 zassert_true(rc == 0, "register of val1 settings failed");
299
300 /* when we load settings now data.val1 should receive the value*/
301 rc = settings_load();
302 zassert_true(rc == 0, "settings_load failed");
303 err = (data.val1 == 1) && (data.val2 == 0) && (data.val3 == 0);
304 zassert_true(err, "wrong data value found");
305 /* commit is only called for val1_settings */
306 err = (data.en1) && (!data.en2) && (!data.en3);
307 zassert_true(err, "wrong data enable found");
308
309 /* Next register should be ok */
310 rc = settings_register(&val2_settings);
311 zassert_true(rc == 0, "register of val2 settings failed");
312
313 /* Next register should fail (same name) */
314 rc = settings_register(&val2_settings);
315 zassert_true(rc == -EEXIST, "double register of val2 settings allowed");
316
317 memset(&data, 0, sizeof(struct stored_data));
318 /* when we load settings now data.val2 should receive the value*/
319 rc = settings_load();
320 zassert_true(rc == 0, "settings_load failed");
321 err = (data.val1 == 0) && (data.val2 == 2) && (data.val3 == 0);
322 zassert_true(err, "wrong data value found");
323 /* commit is called for val1_settings and val2_settings*/
324 err = (data.en1) && (data.en2) && (!data.en3);
325 zassert_true(err, "wrong data enable found");
326
327 /* Check that key that corresponds to val3 do not exist in storage */
328 val_len = settings_get_val_len("ps/ss/val3");
329 zassert_true((val_len == 0), "Failure: key should not exist");
330
331 settings_save_one("ps/ss/val3", &val, sizeof(uint8_t));
332
333 /* Check that the key that corresponds to val3 exists in storage */
334 val_len = settings_get_val_len("ps/ss/val3");
335 zassert_true((val_len == 1), "Failure: key should exist");
336
337 memset(&data, 0, sizeof(struct stored_data));
338 /* when we load settings now data.val2 and data.val1 should receive a
339 * value
340 */
341 rc = settings_load();
342 zassert_true(rc == 0, "settings_load failed");
343 err = (data.val1 == 1) && (data.val2 == 2) && (data.val3 == 0);
344 zassert_true(err, "wrong data value found");
345 /* commit is called for val1_settings and val2_settings*/
346 err = (data.en1) && (data.en2) && (!data.en3);
347 zassert_true(err, "wrong data enable found");
348
349 /* val3 settings should be inserted in between val1_settings and
350 * val2_settings
351 */
352 rc = settings_register(&val3_settings);
353 zassert_true(rc == 0, "register of val3 settings failed");
354 memset(&data, 0, sizeof(struct stored_data));
355 /* when we load settings now data.val2 and data.val3 should receive a
356 * value
357 */
358 rc = settings_load();
359 zassert_true(rc == 0, "settings_load failed");
360 err = (data.val1 == 0) && (data.val2 == 2) && (data.val3 == 3);
361 zassert_true(err, "wrong data value found");
362 /* commit is called for val1_settings, val2_settings and val3_settings
363 */
364 err = (data.en1) && (data.en2) && (data.en3);
365 zassert_true(err, "wrong data enable found");
366
367 /* Check that key that corresponds to val1 do not exist in storage */
368 val_len = settings_get_val_len("ps/val1");
369 zassert_true((val_len == 0), "Failure: key should not exist");
370
371 settings_save_one("ps/val1", &val, sizeof(uint8_t));
372
373 /* Check that the key that corresponds to val1 exists in storage */
374 val_len = settings_get_val_len("ps/val1");
375 zassert_true((val_len == 1), "Failure: key should exist");
376
377 memset(&data, 0, sizeof(struct stored_data));
378 /* when we load settings all data should receive a value loaded */
379 rc = settings_load();
380 zassert_true(rc == 0, "settings_load failed");
381 err = (data.val1 == 1) && (data.val2 == 2) && (data.val3 == 3);
382 zassert_true(err, "wrong data value found");
383 /* commit is called for all settings*/
384 err = (data.en1) && (data.en2) && (data.en3);
385 zassert_true(err, "wrong data enable found");
386
387 memset(&data, 0, sizeof(struct stored_data));
388 /* test subtree loading: subtree "ps/ss" data.val2 and data.val3 should
389 * receive a value
390 */
391 rc = settings_load_subtree("ps/ss");
392 zassert_true(rc == 0, "settings_load failed");
393 err = (data.val1 == 0) && (data.val2 == 2) && (data.val3 == 3);
394 zassert_true(err, "wrong data value found");
395 /* commit is called for val2_settings and val3_settings */
396 err = (!data.en1) && (data.en2) && (data.en3);
397 zassert_true(err, "wrong data enable found");
398
399 memset(&data, 0, sizeof(struct stored_data));
400 /* test subtree loading: subtree "ps/ss/ss" only data.val2 should
401 * receive a value
402 */
403 rc = settings_load_subtree("ps/ss/ss");
404 zassert_true(rc == 0, "settings_load failed");
405 err = (data.val1 == 0) && (data.val2 == 2) && (data.val3 == 0);
406 zassert_true(err, "wrong data value found");
407 /* commit is called only for val2_settings */
408 err = (!data.en1) && (data.en2) && (!data.en3);
409 zassert_true(err, "wrong data enable found");
410
411 memset(&data, 0, sizeof(struct stored_data));
412 /* test load_one: path "ps/ss/ss/val2". Only data.val2 should
413 * receive a value
414 */
415 val = 2;
416 settings_save_one("ps/ss/ss/val2", &val, sizeof(uint8_t));
417 rc = settings_load_one("ps/ss/ss/val2", &data.val2, sizeof(uint8_t));
418 zassert_true(rc >= 0, "settings_load_one failed");
419 err = (data.val1 == 0) && (data.val2 == 2) && (data.val3 == 0);
420 zassert_true(err, "wrong data value found %u != 2", data.val2);
421
422 /* clean up by deregistering settings_handler */
423 rc = settings_deregister(&val1_settings);
424 zassert_true(rc, "deregistering val1_settings failed");
425
426 rc = settings_deregister(&val2_settings);
427 zassert_true(rc, "deregistering val2_settings failed");
428
429 rc = settings_deregister(&val3_settings);
430 zassert_true(rc, "deregistering val3_settings failed");
431 }
432
val123_set(const char * key,size_t len,settings_read_cb read_cb,void * cb_arg)433 int val123_set(const char *key, size_t len,
434 settings_read_cb read_cb, void *cb_arg)
435 {
436 int rc;
437 uint8_t val;
438
439 zassert_equal(1, len, "Unexpected size");
440
441 rc = read_cb(cb_arg, &val, sizeof(val));
442 zassert_equal(sizeof(val), rc, "read_cb failed");
443
444 if (!strcmp("1", key)) {
445 data.val1 = val;
446 data.en1 = true;
447 return 0;
448 }
449 if (!strcmp("2", key)) {
450 data.val2 = val;
451 data.en2 = true;
452 return 0;
453 }
454 if (!strcmp("3", key)) {
455 data.val3 = val;
456 data.en3 = true;
457 return 0;
458 }
459
460 zassert_unreachable("Unexpected key value: %s", key);
461
462 return 0;
463 }
464
465 static struct settings_handler val123_settings = {
466 .name = "val",
467 .h_set = val123_set,
468 };
469
470 unsigned int direct_load_cnt;
471 uint8_t val_directly_loaded;
472
direct_loader(const char * key,size_t len,settings_read_cb read_cb,void * cb_arg,void * param)473 int direct_loader(
474 const char *key,
475 size_t len,
476 settings_read_cb read_cb,
477 void *cb_arg,
478 void *param)
479 {
480 int rc;
481 uint8_t val;
482
483 zassert_equal(0x1234, (size_t)param);
484
485 zassert_equal(1, len);
486 zassert_is_null(key, "Unexpected key: %s", key);
487
488
489 zassert_not_null(cb_arg);
490 rc = read_cb(cb_arg, &val, sizeof(val));
491 zassert_equal(sizeof(val), rc);
492
493 val_directly_loaded = val;
494 direct_load_cnt += 1;
495 return 0;
496 }
497
498
ZTEST(settings_functional,test_direct_loading)499 ZTEST(settings_functional, test_direct_loading)
500 {
501 int rc;
502 uint8_t val;
503
504 settings_subsys_init();
505 val = 11;
506 settings_save_one("val/1", &val, sizeof(uint8_t));
507 val = 23;
508 settings_save_one("val/2", &val, sizeof(uint8_t));
509 val = 35;
510 settings_save_one("val/3", &val, sizeof(uint8_t));
511
512 rc = settings_register(&val123_settings);
513 zassert_true(rc == 0);
514 memset(&data, 0, sizeof(data));
515
516 rc = settings_load();
517 zassert_true(rc == 0);
518
519 zassert_equal(11, data.val1);
520 zassert_equal(23, data.val2);
521 zassert_equal(35, data.val3);
522
523 /* Load subtree */
524 memset(&data, 0, sizeof(data));
525
526 rc = settings_load_subtree("val/2");
527 zassert_true(rc == 0);
528
529 zassert_equal(0, data.val1);
530 zassert_equal(23, data.val2);
531 zassert_equal(0, data.val3);
532
533 /* Direct loading now */
534 memset(&data, 0, sizeof(data));
535 val_directly_loaded = 0;
536 direct_load_cnt = 0;
537 rc = settings_load_subtree_direct(
538 "val/2",
539 direct_loader,
540 (void *)0x1234);
541 zassert_true(rc == 0);
542 zassert_equal(0, data.val1);
543 zassert_equal(0, data.val2);
544 zassert_equal(0, data.val3);
545
546 zassert_equal(1, direct_load_cnt);
547 zassert_equal(23, val_directly_loaded);
548 settings_deregister(&val123_settings);
549 }
550
551 struct test_loading_data {
552 const char *n;
553 const char *v;
554 };
555
556 /* Final data */
557 static const struct test_loading_data data_final[] = {
558 { .n = "val/1", .v = "final 1" },
559 { .n = "val/2", .v = "final 2" },
560 { .n = "val/3", .v = "final 3" },
561 { .n = "val/4", .v = "final 4" },
562 { .n = NULL }
563 };
564
565 /* The counter of the callback called */
566 static unsigned int data_final_called[ARRAY_SIZE(data_final)];
567
568
filtered_loader(const char * key,size_t len,settings_read_cb read_cb,void * cb_arg)569 static int filtered_loader(
570 const char *key,
571 size_t len,
572 settings_read_cb read_cb,
573 void *cb_arg)
574 {
575 int rc;
576 const char *next;
577 char buf[32];
578 const struct test_loading_data *ldata;
579
580 printk("-- Called: %s\n", key);
581
582 /* Searching for a element in an array */
583 for (ldata = data_final; ldata->n; ldata += 1) {
584 if (settings_name_steq(key, ldata->n, &next)) {
585 break;
586 }
587 }
588 zassert_not_null(ldata->n, "Unexpected data name: %s", key);
589 zassert_is_null(next);
590 zassert_equal(strlen(ldata->v) + 1, len, "e: \"%s\", a:\"%s\"", ldata->v, buf);
591 zassert_true(len <= sizeof(buf));
592
593 rc = read_cb(cb_arg, buf, len);
594 zassert_equal(len, rc);
595
596 zassert_false(strcmp(ldata->v, buf), "e: \"%s\", a:\"%s\"", ldata->v, buf);
597
598 /* Count an element that was properly loaded */
599 data_final_called[ldata - data_final] += 1;
600
601 return 0;
602 }
603
604 static struct settings_handler filtered_loader_settings = {
605 .name = "filtered_test",
606 .h_set = filtered_loader,
607 };
608
609
direct_filtered_loader(const char * key,size_t len,settings_read_cb read_cb,void * cb_arg,void * param)610 static int direct_filtered_loader(
611 const char *key,
612 size_t len,
613 settings_read_cb read_cb,
614 void *cb_arg,
615 void *param)
616 {
617 zassert_equal(0x3456, (size_t)param);
618 return filtered_loader(key, len, read_cb, cb_arg);
619 }
620
621
ZTEST(settings_functional,test_direct_loading_filter)622 ZTEST(settings_functional, test_direct_loading_filter)
623 {
624 int rc;
625 const struct test_loading_data *ldata;
626 const char *prefix = filtered_loader_settings.name;
627 char buffer[48];
628 size_t n;
629
630 /* Duplicated data */
631 static const struct test_loading_data data_duplicates[] = {
632 { .n = "val/1", .v = "dup abc" },
633 { .n = "val/2", .v = "dup 123" },
634 { .n = "val/3", .v = "dup 11" },
635 { .n = "val/4", .v = "dup 34" },
636 { .n = "val/1", .v = "dup 56" },
637 { .n = "val/2", .v = "dup 7890" },
638 { .n = "val/4", .v = "dup niety" },
639 { .n = "val/3", .v = "dup er" },
640 { .n = "val/3", .v = "dup super" },
641 { .n = "val/3", .v = "dup xxx" },
642 { .n = NULL }
643 };
644
645 settings_subsys_init();
646 /* Data that is going to be deleted */
647 strcpy(buffer, prefix);
648 strcat(buffer, "/to_delete");
649 settings_save_one(buffer, "1", 2);
650 (void) settings_delete(buffer);
651
652 /* Saving all the data */
653 for (ldata = data_duplicates; ldata->n; ++ldata) {
654 strcpy(buffer, prefix);
655 strcat(buffer, "/");
656 strcat(buffer, ldata->n);
657 settings_save_one(buffer, ldata->v, strlen(ldata->v) + 1);
658 }
659 for (ldata = data_final; ldata->n; ++ldata) {
660 strcpy(buffer, prefix);
661 strcat(buffer, "/");
662 strcat(buffer, ldata->n);
663 settings_save_one(buffer, ldata->v, strlen(ldata->v) + 1);
664 }
665
666
667 memset(data_final_called, 0, sizeof(data_final_called));
668
669 rc = settings_load_subtree_direct(
670 prefix,
671 direct_filtered_loader,
672 (void *)0x3456);
673 zassert_equal(0, rc);
674
675 /* Check if all the data was called */
676 for (n = 0; data_final[n].n; ++n) {
677 zassert_equal(1, data_final_called[n],
678 "Unexpected number of calls (%u) of (%s) element",
679 n, data_final[n].n);
680 }
681
682 rc = settings_register(&filtered_loader_settings);
683 zassert_true(rc == 0);
684
685 rc = settings_load_subtree(prefix);
686 zassert_equal(0, rc);
687
688 /* Check if all the data was called */
689 for (n = 0; data_final[n].n; ++n) {
690 zassert_equal(2, data_final_called[n],
691 "Unexpected number of calls (%u) of (%s) element",
692 n, data_final[n].n);
693 }
694 settings_deregister(&filtered_loader_settings);
695 }
696
697 #if defined(CONFIG_SETTINGS_SAVE_SINGLE_SUBTREE_WITHOUT_MODIFICATION)
698 struct save_single_data {
699 uint8_t first_val;
700 uint8_t second_val;
701 uint8_t third_val;
702 uint8_t forth_val;
703
704 bool first_second_export_called;
705 bool first_second_commit_called;
706 bool first_get_called;
707 bool first_set_called;
708
709 bool second_get_called;
710 bool second_set_called;
711
712 bool third_export_called;
713 bool third_commit_called;
714 bool third_get_called;
715 bool third_set_called;
716
717 bool forth_export_called;
718 bool forth_commit_called;
719 bool forth_get_called;
720 bool forth_set_called;
721 };
722
723 struct save_single_data single_data;
724
first_set(const char * name,size_t len,settings_read_cb read_cb,void * cb_arg)725 int first_set(const char *name, size_t len, settings_read_cb read_cb, void *cb_arg)
726 {
727 const char *next;
728
729 if (settings_name_steq(name, "value1", &next) && !next) {
730 if (len != sizeof(single_data.first_val)) {
731 return -EINVAL;
732 }
733 (void)read_cb(cb_arg, &single_data.first_val, sizeof(single_data.first_val));
734 single_data.first_set_called = true;
735 return 0;
736 }
737 if (settings_name_steq(name, "value2", &next) && !next) {
738 if (len != sizeof(single_data.second_val)) {
739 return -EINVAL;
740 }
741 (void)read_cb(cb_arg, &single_data.second_val, sizeof(single_data.second_val));
742 single_data.second_set_called = true;
743 return 0;
744 }
745
746 return -ENOENT;
747 }
748
first_get(const char * name,char * val,int val_len_max)749 int first_get(const char *name, char *val, int val_len_max)
750 {
751 const char *next;
752
753 if (val_len_max < 0) {
754 return -EINVAL;
755 }
756
757 if (settings_name_steq(name, "value1", &next) && !next) {
758 val_len_max = MIN(val_len_max, sizeof(single_data.first_val));
759 memcpy(val, &single_data.first_val, val_len_max);
760 single_data.first_get_called = true;
761 return val_len_max;
762 } else if (settings_name_steq(name, "value2", &next) && !next) {
763 val_len_max = MIN(val_len_max, sizeof(single_data.second_val));
764 memcpy(val, &single_data.second_val, val_len_max);
765 single_data.second_get_called = true;
766 return val_len_max;
767 }
768
769 return -ENOENT;
770 }
771
first_commit(void)772 int first_commit(void)
773 {
774 single_data.first_second_commit_called = true;
775 return 0;
776 }
777
first_export(int (* cb)(const char * name,const void * value,size_t val_len))778 int first_export(int (*cb)(const char *name, const void *value, size_t val_len))
779 {
780 (void)cb("first/value1", &single_data.first_val, sizeof(single_data.first_val));
781 (void)cb("first/value2", &single_data.second_val, sizeof(single_data.second_val));
782
783 single_data.first_second_export_called = true;
784 return 0;
785 }
786
787 static struct settings_handler first_settings = {
788 .name = "first",
789 .h_set = first_set,
790 .h_get = first_get,
791 .h_commit = first_commit,
792 .h_export = first_export,
793 };
794
third_set(const char * name,size_t len,settings_read_cb read_cb,void * cb_arg)795 int third_set(const char *name, size_t len, settings_read_cb read_cb, void *cb_arg)
796 {
797 const char *next;
798
799 if (settings_name_steq(name, "value3", &next) && !next) {
800 if (len != sizeof(single_data.third_val)) {
801 return -EINVAL;
802 }
803 (void)read_cb(cb_arg, &single_data.third_val, sizeof(single_data.third_val));
804 single_data.third_set_called = true;
805 return 0;
806 }
807
808 return -ENOENT;
809 }
810
third_get(const char * name,char * val,int val_len_max)811 int third_get(const char *name, char *val, int val_len_max)
812 {
813 const char *next;
814
815 if (val_len_max < 0) {
816 return -EINVAL;
817 }
818
819 if (settings_name_steq(name, "value3", &next) && !next) {
820 val_len_max = MIN(val_len_max, sizeof(single_data.third_val));
821 memcpy(val, &single_data.third_val, val_len_max);
822 single_data.third_get_called = true;
823 return val_len_max;
824 }
825
826 return -ENOENT;
827 }
828
third_commit(void)829 int third_commit(void)
830 {
831 single_data.third_commit_called = true;
832 return 0;
833 }
834
third_export(int (* cb)(const char * name,const void * value,size_t val_len))835 int third_export(int (*cb)(const char *name, const void *value, size_t val_len))
836 {
837 (void)cb("first/other/value3", &single_data.third_val, sizeof(single_data.third_val));
838
839 single_data.third_export_called = true;
840 return 0;
841 }
842
843 static struct settings_handler third_settings = {
844 .name = "first/other",
845 .h_set = third_set,
846 .h_get = third_get,
847 .h_commit = third_commit,
848 .h_export = third_export,
849 };
850
forth_set(const char * name,size_t len,settings_read_cb read_cb,void * cb_arg)851 int forth_set(const char *name, size_t len, settings_read_cb read_cb, void *cb_arg)
852 {
853 const char *next;
854
855 if (settings_name_steq(name, "value4", &next) && !next) {
856 if (len != sizeof(single_data.forth_val)) {
857 return -EINVAL;
858 }
859 (void)read_cb(cb_arg, &single_data.forth_val, sizeof(single_data.forth_val));
860 single_data.forth_set_called = true;
861 return 0;
862 }
863
864 return -ENOENT;
865 }
866
forth_commit(void)867 int forth_commit(void)
868 {
869 single_data.forth_commit_called = true;
870 return 0;
871 }
872
forth_export(int (* cb)(const char * name,const void * value,size_t val_len))873 int forth_export(int (*cb)(const char *name, const void *value, size_t val_len))
874 {
875 (void)cb("first/expected_fail/value4", &single_data.forth_val,
876 sizeof(single_data.forth_val));
877
878 single_data.forth_export_called = true;
879 return 0;
880 }
881
882 static struct settings_handler forth_settings = {
883 .name = "first/expected_fail",
884 .h_set = forth_set,
885 .h_get = NULL,
886 .h_commit = forth_commit,
887 .h_export = forth_export,
888 };
889
single_modification_reset(void)890 static void single_modification_reset(void)
891 {
892 single_data.first_second_export_called = false;
893 single_data.first_second_commit_called = false;
894 single_data.first_get_called = false;
895 single_data.first_set_called = false;
896 single_data.second_get_called = false;
897 single_data.second_set_called = false;
898 single_data.third_export_called = false;
899 single_data.third_commit_called = false;
900 single_data.third_get_called = false;
901 single_data.third_set_called = false;
902 single_data.forth_export_called = false;
903 single_data.forth_commit_called = false;
904 single_data.forth_get_called = false;
905 single_data.forth_set_called = false;
906 }
907 #endif
908
ZTEST(settings_functional,test_single_save)909 ZTEST(settings_functional, test_single_save)
910 {
911 Z_TEST_SKIP_IFNDEF(CONFIG_SETTINGS_SAVE_SINGLE_SUBTREE_WITHOUT_MODIFICATION);
912
913 #if defined(CONFIG_SETTINGS_SAVE_SINGLE_SUBTREE_WITHOUT_MODIFICATION)
914 int rc;
915 uint8_t dummy_value = 0xff;
916
917 settings_subsys_init();
918
919 rc = settings_register(&first_settings);
920 zassert_true(rc == 0);
921 rc = settings_register(&third_settings);
922 zassert_true(rc == 0);
923 rc = settings_register(&forth_settings);
924 zassert_true(rc == 0);
925
926 settings_save_one("first/value1", &dummy_value, sizeof(dummy_value));
927 settings_save_one("first/value2", &dummy_value, sizeof(dummy_value));
928 settings_save_one("first/other/value3", &dummy_value, sizeof(dummy_value));
929 settings_save_one("first/expected_fail/value4", &dummy_value, sizeof(dummy_value));
930 rc = settings_load();
931 zassert_true(rc == 0);
932
933 /* Test that options return errors with invalid parameters */
934 single_modification_reset();
935 single_data.first_val = 0x08;
936 single_data.second_val = 0x09;
937 single_data.third_val = 0x0a;
938 single_data.forth_val = 0x0b;
939 rc = settings_save_subtree_or_single_without_modification("first/value1", true, false);
940 zassert_true(rc == -EPERM);
941 zassert_equal(single_data.first_val, 0x08);
942 zassert_equal(single_data.second_val, 0x09);
943 zassert_equal(single_data.third_val, 0x0a);
944 zassert_equal(single_data.forth_val, 0x0b);
945 zassert_false(single_data.first_second_export_called);
946 zassert_false(single_data.first_second_commit_called);
947 zassert_false(single_data.first_get_called);
948 zassert_false(single_data.first_set_called);
949 zassert_false(single_data.second_get_called);
950 zassert_false(single_data.second_set_called);
951 zassert_false(single_data.third_export_called);
952 zassert_false(single_data.third_commit_called);
953 zassert_false(single_data.third_get_called);
954 zassert_false(single_data.third_set_called);
955 zassert_false(single_data.forth_export_called);
956 zassert_false(single_data.forth_commit_called);
957 zassert_false(single_data.forth_get_called);
958 zassert_false(single_data.forth_set_called);
959
960 rc = settings_save_subtree_or_single_without_modification("first", false, true);
961 zassert_true(rc == -EPERM);
962 zassert_equal(single_data.first_val, 0x08);
963 zassert_equal(single_data.second_val, 0x09);
964 zassert_equal(single_data.third_val, 0x0a);
965 zassert_equal(single_data.forth_val, 0x0b);
966 zassert_false(single_data.first_second_export_called);
967 zassert_false(single_data.first_second_commit_called);
968 zassert_false(single_data.first_get_called);
969 zassert_false(single_data.first_set_called);
970 zassert_false(single_data.second_get_called);
971 zassert_false(single_data.second_set_called);
972 zassert_false(single_data.third_export_called);
973 zassert_false(single_data.third_commit_called);
974 zassert_false(single_data.third_get_called);
975 zassert_false(single_data.third_set_called);
976 zassert_false(single_data.forth_export_called);
977 zassert_false(single_data.forth_commit_called);
978 zassert_false(single_data.forth_get_called);
979 zassert_false(single_data.forth_set_called);
980
981 rc = settings_save_subtree_or_single_without_modification("first/other/value1", true,
982 false);
983 zassert_true(rc == -EPERM);
984 zassert_equal(single_data.first_val, 0x08);
985 zassert_equal(single_data.second_val, 0x09);
986 zassert_equal(single_data.third_val, 0x0a);
987 zassert_equal(single_data.forth_val, 0x0b);
988 zassert_false(single_data.first_second_export_called);
989 zassert_false(single_data.first_second_commit_called);
990 zassert_false(single_data.first_get_called);
991 zassert_false(single_data.first_set_called);
992 zassert_false(single_data.second_get_called);
993 zassert_false(single_data.second_set_called);
994 zassert_false(single_data.third_export_called);
995 zassert_false(single_data.third_commit_called);
996 zassert_false(single_data.third_get_called);
997 zassert_false(single_data.third_set_called);
998 zassert_false(single_data.forth_export_called);
999 zassert_false(single_data.forth_commit_called);
1000 zassert_false(single_data.forth_get_called);
1001 zassert_false(single_data.forth_set_called);
1002
1003 rc = settings_save_subtree_or_single_without_modification("first/other", false, true);
1004 zassert_true(rc == -EPERM);
1005 zassert_equal(single_data.first_val, 0x08);
1006 zassert_equal(single_data.second_val, 0x09);
1007 zassert_equal(single_data.third_val, 0x0a);
1008 zassert_equal(single_data.forth_val, 0x0b);
1009 zassert_false(single_data.first_second_export_called);
1010 zassert_false(single_data.first_second_commit_called);
1011 zassert_false(single_data.first_get_called);
1012 zassert_false(single_data.first_set_called);
1013 zassert_false(single_data.second_get_called);
1014 zassert_false(single_data.second_set_called);
1015 zassert_false(single_data.third_export_called);
1016 zassert_false(single_data.third_commit_called);
1017 zassert_false(single_data.third_get_called);
1018 zassert_false(single_data.third_set_called);
1019 zassert_false(single_data.forth_export_called);
1020 zassert_false(single_data.forth_commit_called);
1021 zassert_false(single_data.forth_get_called);
1022 zassert_false(single_data.forth_set_called);
1023
1024 /* Test that it saves single values */
1025 rc = settings_load();
1026 zassert_true(rc == 0);
1027 single_modification_reset();
1028 single_data.first_val = 0x01;
1029 rc = settings_save_subtree_or_single_without_modification("first/value1", false, true);
1030 zassert_true(rc == 0);
1031 zassert_equal(single_data.first_val, 0x01);
1032 zassert_equal(single_data.second_val, 0xff);
1033 zassert_equal(single_data.third_val, 0xff);
1034 zassert_equal(single_data.forth_val, 0xff);
1035 zassert_false(single_data.first_second_export_called);
1036 zassert_false(single_data.first_second_commit_called);
1037 zassert_true(single_data.first_get_called);
1038 zassert_false(single_data.first_set_called);
1039 zassert_false(single_data.second_get_called);
1040 zassert_false(single_data.second_set_called);
1041 zassert_false(single_data.third_export_called);
1042 zassert_false(single_data.third_commit_called);
1043 zassert_false(single_data.third_get_called);
1044 zassert_false(single_data.third_set_called);
1045 zassert_false(single_data.forth_export_called);
1046 zassert_false(single_data.forth_commit_called);
1047 zassert_false(single_data.forth_get_called);
1048 zassert_false(single_data.forth_set_called);
1049
1050 single_modification_reset();
1051 single_data.first_val = 0x02;
1052 rc = settings_load_subtree("first");
1053 zassert_true(rc == 0);
1054 zassert_equal(single_data.first_val, 0x01);
1055 zassert_equal(single_data.second_val, 0xff);
1056 zassert_equal(single_data.third_val, 0xff);
1057 zassert_equal(single_data.forth_val, 0xff);
1058 zassert_false(single_data.first_second_export_called);
1059 zassert_false(single_data.third_export_called);
1060 zassert_false(single_data.forth_export_called);
1061 zassert_true(single_data.first_second_commit_called);
1062 zassert_true(single_data.third_commit_called);
1063 zassert_true(single_data.forth_commit_called);
1064 zassert_false(single_data.first_get_called);
1065 zassert_false(single_data.second_get_called);
1066 zassert_false(single_data.third_get_called);
1067 zassert_false(single_data.forth_get_called);
1068 zassert_true(single_data.first_set_called);
1069 zassert_true(single_data.second_set_called);
1070 zassert_true(single_data.third_set_called);
1071 zassert_true(single_data.forth_set_called);
1072
1073 single_modification_reset();
1074 single_data.first_val = 0x02;
1075 rc = settings_save_subtree_or_single_without_modification("first/value1", false, true);
1076 zassert_true(rc == 0);
1077 zassert_equal(single_data.first_val, 0x02);
1078 zassert_equal(single_data.second_val, 0xff);
1079 zassert_equal(single_data.third_val, 0xff);
1080 zassert_equal(single_data.forth_val, 0xff);
1081 zassert_false(single_data.first_second_export_called);
1082 zassert_false(single_data.first_second_commit_called);
1083 zassert_true(single_data.first_get_called);
1084 zassert_false(single_data.first_set_called);
1085 zassert_false(single_data.second_get_called);
1086 zassert_false(single_data.second_set_called);
1087 zassert_false(single_data.third_export_called);
1088 zassert_false(single_data.third_commit_called);
1089 zassert_false(single_data.third_get_called);
1090 zassert_false(single_data.third_set_called);
1091 zassert_false(single_data.forth_export_called);
1092 zassert_false(single_data.forth_commit_called);
1093 zassert_false(single_data.forth_get_called);
1094 zassert_false(single_data.forth_set_called);
1095
1096 single_modification_reset();
1097 single_data.first_val = 0x03;
1098 rc = settings_load_subtree("first");
1099 zassert_true(rc == 0);
1100 zassert_equal(single_data.first_val, 0x02);
1101 zassert_equal(single_data.second_val, 0xff);
1102 zassert_equal(single_data.third_val, 0xff);
1103 zassert_equal(single_data.forth_val, 0xff);
1104 zassert_false(single_data.first_second_export_called);
1105 zassert_false(single_data.third_export_called);
1106 zassert_false(single_data.forth_export_called);
1107 zassert_true(single_data.first_second_commit_called);
1108 zassert_true(single_data.third_commit_called);
1109 zassert_true(single_data.forth_commit_called);
1110 zassert_false(single_data.first_get_called);
1111 zassert_false(single_data.second_get_called);
1112 zassert_false(single_data.third_get_called);
1113 zassert_false(single_data.forth_get_called);
1114 zassert_true(single_data.first_set_called);
1115 zassert_true(single_data.second_set_called);
1116 zassert_true(single_data.third_set_called);
1117 zassert_true(single_data.forth_set_called);
1118
1119 /* Check changing second value and doing one write */
1120 single_modification_reset();
1121 single_data.first_val = 0x01;
1122 single_data.second_val = 0x20;
1123 rc = settings_save_subtree_or_single_without_modification("first/value2", false, true);
1124 zassert_true(rc == 0);
1125 zassert_equal(single_data.first_val, 0x01);
1126 zassert_equal(single_data.second_val, 0x20);
1127 zassert_equal(single_data.third_val, 0xff);
1128 zassert_equal(single_data.forth_val, 0xff);
1129 zassert_false(single_data.first_second_export_called);
1130 zassert_false(single_data.first_second_commit_called);
1131 zassert_false(single_data.first_get_called);
1132 zassert_false(single_data.first_set_called);
1133 zassert_true(single_data.second_get_called);
1134 zassert_false(single_data.second_set_called);
1135 zassert_false(single_data.third_export_called);
1136 zassert_false(single_data.third_commit_called);
1137 zassert_false(single_data.third_get_called);
1138 zassert_false(single_data.third_set_called);
1139 zassert_false(single_data.forth_export_called);
1140 zassert_false(single_data.forth_commit_called);
1141 zassert_false(single_data.forth_get_called);
1142 zassert_false(single_data.forth_set_called);
1143
1144 single_modification_reset();
1145 single_data.first_val = 0x00;
1146 single_data.second_val = 0x00;
1147 rc = settings_load_subtree("first");
1148 zassert_true(rc == 0);
1149 zassert_equal(single_data.first_val, 0x02);
1150 zassert_equal(single_data.second_val, 0x20);
1151 zassert_equal(single_data.third_val, 0xff);
1152 zassert_equal(single_data.forth_val, 0xff);
1153 zassert_false(single_data.first_second_export_called);
1154 zassert_false(single_data.third_export_called);
1155 zassert_false(single_data.forth_export_called);
1156 zassert_true(single_data.first_second_commit_called);
1157 zassert_true(single_data.third_commit_called);
1158 zassert_true(single_data.forth_commit_called);
1159 zassert_false(single_data.first_get_called);
1160 zassert_false(single_data.second_get_called);
1161 zassert_false(single_data.third_get_called);
1162 zassert_false(single_data.forth_get_called);
1163 zassert_true(single_data.first_set_called);
1164 zassert_true(single_data.second_set_called);
1165 zassert_true(single_data.third_set_called);
1166 zassert_true(single_data.forth_set_called);
1167
1168 /* Check doing a subtree update */
1169 single_modification_reset();
1170 single_data.first_val = 0x01;
1171 single_data.second_val = 0x20;
1172 single_data.third_val = 0x21;
1173 single_data.forth_val = 0x22;
1174 rc = settings_save_subtree_or_single_without_modification("first", true, false);
1175 zassert_true(rc == 0);
1176 zassert_equal(single_data.first_val, 0x01);
1177 zassert_equal(single_data.second_val, 0x20);
1178 zassert_equal(single_data.third_val, 0x21);
1179 zassert_equal(single_data.forth_val, 0x22);
1180 zassert_true(single_data.first_second_export_called);
1181 zassert_false(single_data.first_second_commit_called);
1182 zassert_false(single_data.first_get_called);
1183 zassert_false(single_data.first_set_called);
1184 zassert_false(single_data.second_get_called);
1185 zassert_false(single_data.second_set_called);
1186 zassert_true(single_data.third_export_called);
1187 zassert_false(single_data.third_commit_called);
1188 zassert_false(single_data.third_get_called);
1189 zassert_false(single_data.third_set_called);
1190 zassert_true(single_data.forth_export_called);
1191 zassert_false(single_data.forth_commit_called);
1192 zassert_false(single_data.forth_get_called);
1193 zassert_false(single_data.forth_set_called);
1194
1195 single_modification_reset();
1196 single_data.first_val = 0x00;
1197 single_data.second_val = 0x00;
1198 single_data.third_val = 0x00;
1199 single_data.forth_val = 0x00;
1200 rc = settings_load_subtree("first");
1201 zassert_true(rc == 0);
1202 zassert_equal(single_data.first_val, 0x01);
1203 zassert_equal(single_data.second_val, 0x20);
1204 zassert_equal(single_data.third_val, 0x21);
1205 zassert_equal(single_data.forth_val, 0x22);
1206 zassert_false(single_data.first_second_export_called);
1207 zassert_false(single_data.third_export_called);
1208 zassert_false(single_data.forth_export_called);
1209 zassert_true(single_data.first_second_commit_called);
1210 zassert_true(single_data.third_commit_called);
1211 zassert_true(single_data.forth_commit_called);
1212 zassert_false(single_data.first_get_called);
1213 zassert_false(single_data.second_get_called);
1214 zassert_false(single_data.third_get_called);
1215 zassert_false(single_data.forth_get_called);
1216 zassert_true(single_data.first_set_called);
1217 zassert_true(single_data.second_set_called);
1218 zassert_true(single_data.third_set_called);
1219 zassert_true(single_data.forth_set_called);
1220
1221 /* Check doing a limited subtree update */
1222 single_modification_reset();
1223 single_data.first_val = 0x41;
1224 single_data.second_val = 0x42;
1225 single_data.third_val = 0x43;
1226 single_data.forth_val = 0x44;
1227 rc = settings_save_subtree_or_single_without_modification("first/other", true, false);
1228 zassert_true(rc == 0);
1229 zassert_equal(single_data.first_val, 0x41);
1230 zassert_equal(single_data.second_val, 0x42);
1231 zassert_equal(single_data.third_val, 0x43);
1232 zassert_equal(single_data.forth_val, 0x44);
1233 zassert_false(single_data.first_second_export_called);
1234 zassert_false(single_data.first_second_commit_called);
1235 zassert_false(single_data.first_get_called);
1236 zassert_false(single_data.first_set_called);
1237 zassert_false(single_data.second_get_called);
1238 zassert_false(single_data.second_set_called);
1239 zassert_true(single_data.third_export_called);
1240 zassert_false(single_data.third_commit_called);
1241 zassert_false(single_data.third_get_called);
1242 zassert_false(single_data.third_set_called);
1243 zassert_false(single_data.forth_export_called);
1244 zassert_false(single_data.forth_commit_called);
1245 zassert_false(single_data.forth_get_called);
1246 zassert_false(single_data.forth_set_called);
1247
1248 single_modification_reset();
1249 single_data.first_val = 0x00;
1250 single_data.second_val = 0x00;
1251 single_data.third_val = 0x00;
1252 single_data.forth_val = 0x00;
1253 rc = settings_load_subtree("first");
1254 zassert_true(rc == 0);
1255 zassert_equal(single_data.first_val, 0x01);
1256 zassert_equal(single_data.second_val, 0x20);
1257 zassert_equal(single_data.third_val, 0x43);
1258 zassert_equal(single_data.forth_val, 0x22);
1259 zassert_false(single_data.first_second_export_called);
1260 zassert_false(single_data.third_export_called);
1261 zassert_false(single_data.forth_export_called);
1262 zassert_true(single_data.first_second_commit_called);
1263 zassert_true(single_data.third_commit_called);
1264 zassert_true(single_data.forth_commit_called);
1265 zassert_false(single_data.first_get_called);
1266 zassert_false(single_data.second_get_called);
1267 zassert_false(single_data.third_get_called);
1268 zassert_false(single_data.forth_get_called);
1269 zassert_true(single_data.first_set_called);
1270 zassert_true(single_data.second_set_called);
1271 zassert_true(single_data.third_set_called);
1272 zassert_true(single_data.forth_set_called);
1273
1274 /* Check that trying to save a single value without a get function does not work */
1275 single_modification_reset();
1276 single_data.first_val = 0x11;
1277 single_data.second_val = 0x22;
1278 single_data.third_val = 0x33;
1279 single_data.forth_val = 0x44;
1280 rc = settings_save_subtree_or_single_without_modification("first/expected_fail/value4",
1281 false, true);
1282 zassert_true(rc == -ENOSYS);
1283 zassert_equal(single_data.first_val, 0x11);
1284 zassert_equal(single_data.second_val, 0x22);
1285 zassert_equal(single_data.third_val, 0x33);
1286 zassert_equal(single_data.forth_val, 0x44);
1287 zassert_false(single_data.first_second_export_called);
1288 zassert_false(single_data.first_second_commit_called);
1289 zassert_false(single_data.first_get_called);
1290 zassert_false(single_data.first_set_called);
1291 zassert_false(single_data.second_get_called);
1292 zassert_false(single_data.second_set_called);
1293 zassert_false(single_data.third_export_called);
1294 zassert_false(single_data.third_commit_called);
1295 zassert_false(single_data.third_get_called);
1296 zassert_false(single_data.third_set_called);
1297 zassert_false(single_data.forth_export_called);
1298 zassert_false(single_data.forth_commit_called);
1299 zassert_false(single_data.forth_get_called);
1300 zassert_false(single_data.forth_set_called);
1301
1302 single_modification_reset();
1303 rc = settings_load_subtree("first");
1304 zassert_true(rc == 0);
1305 zassert_equal(single_data.first_val, 0x01);
1306 zassert_equal(single_data.second_val, 0x20);
1307 zassert_equal(single_data.third_val, 0x43);
1308 zassert_equal(single_data.forth_val, 0x22);
1309 zassert_false(single_data.first_second_export_called);
1310 zassert_false(single_data.third_export_called);
1311 zassert_false(single_data.forth_export_called);
1312 zassert_true(single_data.first_second_commit_called);
1313 zassert_true(single_data.third_commit_called);
1314 zassert_true(single_data.forth_commit_called);
1315 zassert_false(single_data.first_get_called);
1316 zassert_false(single_data.second_get_called);
1317 zassert_false(single_data.third_get_called);
1318 zassert_false(single_data.forth_get_called);
1319 zassert_true(single_data.first_set_called);
1320 zassert_true(single_data.second_set_called);
1321 zassert_true(single_data.third_set_called);
1322 zassert_true(single_data.forth_set_called);
1323
1324 settings_deregister(&forth_settings);
1325 settings_deregister(&third_settings);
1326 settings_deregister(&first_settings);
1327 #endif
1328 }
1329