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