1 /*
2  * Copyright (c) 2019 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /*
8  * This test is designed to be run using flash-simulator which provide
9  * functionality for flash property customization and emulating errors in
10  * flash opperation in parallel to regular flash API.
11  * Test should be run on qemu_x86 target.
12  */
13 
14 #ifndef CONFIG_BOARD_QEMU_X86
15 #error "Run on qemu_x86 only"
16 #endif
17 
18 #include <stdio.h>
19 #include <string.h>
20 #include <ztest.h>
21 
22 #include <drivers/flash.h>
23 #include <storage/flash_map.h>
24 #include <stats/stats.h>
25 #include <sys/crc.h>
26 #include <fs/nvs.h>
27 #include "nvs_priv.h"
28 
29 #define TEST_FLASH_AREA_STORAGE_OFFSET	FLASH_AREA_OFFSET(storage)
30 #define TEST_DATA_ID			1
31 #define TEST_SECTOR_COUNT		5U
32 
33 static struct nvs_fs fs;
34 struct stats_hdr *sim_stats;
35 struct stats_hdr *sim_thresholds;
36 
setup(void)37 void setup(void)
38 {
39 	sim_stats = stats_group_find("flash_sim_stats");
40 	sim_thresholds = stats_group_find("flash_sim_thresholds");
41 
42 	/* Verify if NVS is initialized. */
43 	if (fs.sector_count != 0) {
44 		int err;
45 
46 		err = nvs_clear(&fs);
47 		zassert_true(err == 0,  "nvs_clear call failure: %d", err);
48 	}
49 }
50 
teardown(void)51 void teardown(void)
52 {
53 	if (sim_stats) {
54 		stats_reset(sim_stats);
55 	}
56 	if (sim_thresholds) {
57 		stats_reset(sim_thresholds);
58 	}
59 }
60 
test_nvs_init(void)61 void test_nvs_init(void)
62 {
63 	int err;
64 	const struct flash_area *fa;
65 	struct flash_pages_info info;
66 
67 	err = flash_area_open(FLASH_AREA_ID(storage), &fa);
68 	zassert_true(err == 0, "flash_area_open() fail: %d", err);
69 
70 	fs.offset = TEST_FLASH_AREA_STORAGE_OFFSET;
71 	err = flash_get_page_info_by_offs(flash_area_get_device(fa), fs.offset,
72 					  &info);
73 	zassert_true(err == 0,  "Unable to get page info: %d", err);
74 
75 	fs.sector_size = info.size;
76 	fs.sector_count = TEST_SECTOR_COUNT;
77 
78 	err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
79 	zassert_true(err == 0,  "nvs_init call failure: %d", err);
80 }
81 
execute_long_pattern_write(uint16_t id)82 static void execute_long_pattern_write(uint16_t id)
83 {
84 	char rd_buf[512];
85 	char wr_buf[512];
86 	char pattern[] = {0xDE, 0xAD, 0xBE, 0xEF};
87 	size_t len;
88 
89 	len = nvs_read(&fs, id, rd_buf, sizeof(rd_buf));
90 	zassert_true(len == -ENOENT,  "nvs_read unexpected failure: %d", len);
91 
92 	BUILD_ASSERT((sizeof(wr_buf) % sizeof(pattern)) == 0);
93 	for (int i = 0; i < sizeof(wr_buf); i += sizeof(pattern)) {
94 		memcpy(wr_buf + i, pattern, sizeof(pattern));
95 	}
96 
97 	len = nvs_write(&fs, id, wr_buf, sizeof(wr_buf));
98 	zassert_true(len == sizeof(wr_buf), "nvs_write failed: %d", len);
99 
100 	len = nvs_read(&fs, id, rd_buf, sizeof(rd_buf));
101 	zassert_true(len == sizeof(rd_buf),  "nvs_read unexpected failure: %d",
102 			len);
103 	zassert_mem_equal(wr_buf, rd_buf, sizeof(rd_buf),
104 			"RD buff should be equal to the WR buff");
105 }
106 
test_nvs_write(void)107 void test_nvs_write(void)
108 {
109 	int err;
110 
111 	err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
112 	zassert_true(err == 0,  "nvs_init call failure: %d", err);
113 
114 	execute_long_pattern_write(TEST_DATA_ID);
115 }
116 
flash_sim_write_calls_find(struct stats_hdr * hdr,void * arg,const char * name,uint16_t off)117 static int flash_sim_write_calls_find(struct stats_hdr *hdr, void *arg,
118 				      const char *name, uint16_t off)
119 {
120 	if (!strcmp(name, "flash_write_calls")) {
121 		uint32_t **flash_write_stat = (uint32_t **) arg;
122 		*flash_write_stat = (uint32_t *)((uint8_t *)hdr + off);
123 	}
124 
125 	return 0;
126 }
127 
flash_sim_max_write_calls_find(struct stats_hdr * hdr,void * arg,const char * name,uint16_t off)128 static int flash_sim_max_write_calls_find(struct stats_hdr *hdr, void *arg,
129 					  const char *name, uint16_t off)
130 {
131 	if (!strcmp(name, "max_write_calls")) {
132 		uint32_t **max_write_calls = (uint32_t **) arg;
133 		*max_write_calls = (uint32_t *)((uint8_t *)hdr + off);
134 	}
135 
136 	return 0;
137 }
138 
test_nvs_corrupted_write(void)139 void test_nvs_corrupted_write(void)
140 {
141 	int err;
142 	size_t len;
143 	char rd_buf[512];
144 	char wr_buf_1[512];
145 	char wr_buf_2[512];
146 	char pattern_1[] = {0xDE, 0xAD, 0xBE, 0xEF};
147 	char pattern_2[] = {0x03, 0xAA, 0x85, 0x6F};
148 	uint32_t *flash_write_stat;
149 	uint32_t *flash_max_write_calls;
150 
151 	err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
152 	zassert_true(err == 0,  "nvs_init call failure: %d", err);
153 
154 	err = nvs_read(&fs, TEST_DATA_ID, rd_buf, sizeof(rd_buf));
155 	zassert_true(err == -ENOENT,  "nvs_read unexpected failure: %d", err);
156 
157 	BUILD_ASSERT((sizeof(wr_buf_1) % sizeof(pattern_1)) == 0);
158 	for (int i = 0; i < sizeof(wr_buf_1); i += sizeof(pattern_1)) {
159 		memcpy(wr_buf_1 + i, pattern_1, sizeof(pattern_1));
160 	}
161 
162 	len = nvs_write(&fs, TEST_DATA_ID, wr_buf_1, sizeof(wr_buf_1));
163 	zassert_true(len == sizeof(wr_buf_1), "nvs_write failed: %d", len);
164 
165 	len = nvs_read(&fs, TEST_DATA_ID, rd_buf, sizeof(rd_buf));
166 	zassert_true(len == sizeof(rd_buf),  "nvs_read unexpected failure: %d",
167 			len);
168 	zassert_mem_equal(wr_buf_1, rd_buf, sizeof(rd_buf),
169 			"RD buff should be equal to the first WR buff");
170 
171 	BUILD_ASSERT((sizeof(wr_buf_2) % sizeof(pattern_2)) == 0);
172 	for (int i = 0; i < sizeof(wr_buf_2); i += sizeof(pattern_2)) {
173 		memcpy(wr_buf_2 + i, pattern_2, sizeof(pattern_2));
174 	}
175 
176 	/* Set the maximum number of writes that the flash simulator can
177 	 * execute.
178 	 */
179 	stats_walk(sim_thresholds, flash_sim_max_write_calls_find,
180 		   &flash_max_write_calls);
181 	stats_walk(sim_stats, flash_sim_write_calls_find, &flash_write_stat);
182 
183 	*flash_max_write_calls = *flash_write_stat - 1;
184 	*flash_write_stat = 0;
185 
186 	/* Flash simulator will lose part of the data at the end of this write.
187 	 * This should simulate power down during flash write. The written data
188 	 * are corrupted at this point and should be discarded by the NVS.
189 	 */
190 	len = nvs_write(&fs, TEST_DATA_ID, wr_buf_2, sizeof(wr_buf_2));
191 	zassert_true(len == sizeof(wr_buf_2), "nvs_write failed: %d", len);
192 
193 	/* Reinitialize the NVS. */
194 	memset(&fs, 0, sizeof(fs));
195 	test_nvs_init();
196 
197 	len = nvs_read(&fs, TEST_DATA_ID, rd_buf, sizeof(rd_buf));
198 	zassert_true(len == sizeof(rd_buf),  "nvs_read unexpected failure: %d",
199 			len);
200 	zassert_true(memcmp(wr_buf_2, rd_buf, sizeof(rd_buf)) != 0,
201 			"RD buff should not be equal to the second WR buff because of "
202 			"corrupted write operation");
203 	zassert_mem_equal(wr_buf_1, rd_buf, sizeof(rd_buf),
204 			"RD buff should be equal to the first WR buff because subsequent "
205 			"write operation has failed");
206 }
207 
test_nvs_gc(void)208 void test_nvs_gc(void)
209 {
210 	int err;
211 	int len;
212 	uint8_t buf[32];
213 	uint8_t rd_buf[32];
214 
215 	const uint16_t max_id = 10;
216 	/* 25th write will trigger GC. */
217 	const uint16_t max_writes = 26;
218 
219 	fs.sector_count = 2;
220 
221 	err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
222 	zassert_true(err == 0,  "nvs_init call failure: %d", err);
223 
224 	for (uint16_t i = 0; i < max_writes; i++) {
225 		uint8_t id = (i % max_id);
226 		uint8_t id_data = id + max_id * (i / max_id);
227 
228 		memset(buf, id_data, sizeof(buf));
229 
230 		len = nvs_write(&fs, id, buf, sizeof(buf));
231 		zassert_true(len == sizeof(buf), "nvs_write failed: %d", len);
232 	}
233 
234 	for (uint16_t id = 0; id < max_id; id++) {
235 		len = nvs_read(&fs, id, rd_buf, sizeof(buf));
236 		zassert_true(len == sizeof(rd_buf),
237 			     "nvs_read unexpected failure: %d", len);
238 
239 		for (uint16_t i = 0; i < sizeof(rd_buf); i++) {
240 			rd_buf[i] = rd_buf[i] % max_id;
241 			buf[i] = id;
242 		}
243 		zassert_mem_equal(buf, rd_buf, sizeof(rd_buf),
244 				"RD buff should be equal to the WR buff");
245 
246 	}
247 
248 	err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
249 	zassert_true(err == 0,  "nvs_init call failure: %d", err);
250 
251 	for (uint16_t id = 0; id < max_id; id++) {
252 		len = nvs_read(&fs, id, rd_buf, sizeof(buf));
253 		zassert_true(len == sizeof(rd_buf),
254 			     "nvs_read unexpected failure: %d", len);
255 
256 		for (uint16_t i = 0; i < sizeof(rd_buf); i++) {
257 			rd_buf[i] = rd_buf[i] % max_id;
258 			buf[i] = id;
259 		}
260 		zassert_mem_equal(buf, rd_buf, sizeof(rd_buf),
261 				"RD buff should be equal to the WR buff");
262 
263 	}
264 }
265 
write_content(uint16_t max_id,uint16_t begin,uint16_t end,struct nvs_fs * fs)266 static void write_content(uint16_t max_id, uint16_t begin, uint16_t end,
267 			     struct nvs_fs *fs)
268 {
269 	uint8_t buf[32];
270 	ssize_t len;
271 
272 	for (uint16_t i = begin; i < end; i++) {
273 		uint8_t id = (i % max_id);
274 		uint8_t id_data = id + max_id * (i / max_id);
275 
276 		memset(buf, id_data, sizeof(buf));
277 
278 		len = nvs_write(fs, id, buf, sizeof(buf));
279 		zassert_true(len == sizeof(buf), "nvs_write failed: %d", len);
280 	}
281 }
282 
check_content(uint16_t max_id,struct nvs_fs * fs)283 static void check_content(uint16_t max_id, struct nvs_fs *fs)
284 {
285 	uint8_t rd_buf[32];
286 	uint8_t buf[32];
287 	ssize_t len;
288 
289 	for (uint16_t id = 0; id < max_id; id++) {
290 		len = nvs_read(fs, id, rd_buf, sizeof(buf));
291 		zassert_true(len == sizeof(rd_buf),
292 			     "nvs_read unexpected failure: %d", len);
293 
294 		for (uint16_t i = 0; i < ARRAY_SIZE(rd_buf); i++) {
295 			rd_buf[i] = rd_buf[i] % max_id;
296 			buf[i] = id;
297 		}
298 		zassert_mem_equal(buf, rd_buf, sizeof(rd_buf),
299 				  "RD buff should be equal to the WR buff");
300 
301 	}
302 }
303 
304 /**
305  * Full round of GC over 3 sectors
306  */
test_nvs_gc_3sectors(void)307 void test_nvs_gc_3sectors(void)
308 {
309 	int err;
310 
311 	const uint16_t max_id = 10;
312 	/* 50th write will trigger 1st GC. */
313 	const uint16_t max_writes = 51;
314 	/* 75th write will trigger 2st GC. */
315 	const uint16_t max_writes_2 = 51 + 25;
316 	/* 100th write will trigger 3st GC. */
317 	const uint16_t max_writes_3 = 51 + 25 + 25;
318 	/* 125th write will trigger 4st GC. */
319 	const uint16_t max_writes_4 = 51 + 25 + 25 + 25;
320 
321 	fs.sector_count = 3;
322 
323 	err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
324 	zassert_true(err == 0,  "nvs_init call failure: %d", err);
325 	zassert_equal(fs.ate_wra >> ADDR_SECT_SHIFT, 0,
326 		     "unexpected write sector");
327 
328 	/* Trigger 1st GC */
329 	write_content(max_id, 0, max_writes, &fs);
330 
331 	/* sector sequence: empty,closed, write */
332 	zassert_equal(fs.ate_wra >> ADDR_SECT_SHIFT, 2,
333 		     "unexpected write sector");
334 	check_content(max_id, &fs);
335 
336 	err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
337 	zassert_true(err == 0,  "nvs_init call failure: %d", err);
338 
339 	zassert_equal(fs.ate_wra >> ADDR_SECT_SHIFT, 2,
340 		     "unexpected write sector");
341 	check_content(max_id, &fs);
342 
343 	/* Trigger 2nd GC */
344 	write_content(max_id, max_writes, max_writes_2, &fs);
345 
346 	/* sector sequence: write, empty, closed */
347 	zassert_equal(fs.ate_wra >> ADDR_SECT_SHIFT, 0,
348 		     "unexpected write sector");
349 	check_content(max_id, &fs);
350 
351 	err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
352 	zassert_true(err == 0,  "nvs_init call failure: %d", err);
353 
354 	zassert_equal(fs.ate_wra >> ADDR_SECT_SHIFT, 0,
355 		     "unexpected write sector");
356 	check_content(max_id, &fs);
357 
358 	/* Trigger 3rd GC */
359 	write_content(max_id, max_writes_2, max_writes_3, &fs);
360 
361 	/* sector sequence: closed, write, empty */
362 	zassert_equal(fs.ate_wra >> ADDR_SECT_SHIFT, 1,
363 		     "unexpected write sector");
364 	check_content(max_id, &fs);
365 
366 	err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
367 	zassert_true(err == 0,  "nvs_init call failure: %d", err);
368 
369 	zassert_equal(fs.ate_wra >> ADDR_SECT_SHIFT, 1,
370 		     "unexpected write sector");
371 	check_content(max_id, &fs);
372 
373 	/* Trigger 4th GC */
374 	write_content(max_id, max_writes_3, max_writes_4, &fs);
375 
376 	/* sector sequence: empty,closed, write */
377 	zassert_equal(fs.ate_wra >> ADDR_SECT_SHIFT, 2,
378 		     "unexpected write sector");
379 	check_content(max_id, &fs);
380 
381 	err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
382 	zassert_true(err == 0,  "nvs_init call failure: %d", err);
383 
384 	zassert_equal(fs.ate_wra >> ADDR_SECT_SHIFT, 2,
385 		     "unexpected write sector");
386 	check_content(max_id, &fs);
387 }
388 
flash_sim_erase_calls_find(struct stats_hdr * hdr,void * arg,const char * name,uint16_t off)389 static int flash_sim_erase_calls_find(struct stats_hdr *hdr, void *arg,
390 				      const char *name, uint16_t off)
391 {
392 	if (!strcmp(name, "flash_erase_calls")) {
393 		uint32_t **flash_erase_stat = (uint32_t **) arg;
394 		*flash_erase_stat = (uint32_t *)((uint8_t *)hdr + off);
395 	}
396 
397 	return 0;
398 }
399 
flash_sim_max_erase_calls_find(struct stats_hdr * hdr,void * arg,const char * name,uint16_t off)400 static int flash_sim_max_erase_calls_find(struct stats_hdr *hdr, void *arg,
401 					  const char *name, uint16_t off)
402 {
403 	if (!strcmp(name, "max_erase_calls")) {
404 		uint32_t **max_erase_calls = (uint32_t **) arg;
405 		*max_erase_calls = (uint32_t *)((uint8_t *)hdr + off);
406 	}
407 
408 	return 0;
409 }
410 
flash_sim_max_len_find(struct stats_hdr * hdr,void * arg,const char * name,uint16_t off)411 static int flash_sim_max_len_find(struct stats_hdr *hdr, void *arg,
412 				  const char *name, uint16_t off)
413 {
414 	if (!strcmp(name, "max_len")) {
415 		uint32_t **max_len = (uint32_t **) arg;
416 		*max_len = (uint32_t *)((uint8_t *)hdr + off);
417 	}
418 
419 	return 0;
420 }
421 
test_nvs_corrupted_sector_close_operation(void)422 void test_nvs_corrupted_sector_close_operation(void)
423 {
424 	int err;
425 	int len;
426 	uint8_t buf[32];
427 	uint32_t *flash_write_stat;
428 	uint32_t *flash_erase_stat;
429 	uint32_t *flash_max_write_calls;
430 	uint32_t *flash_max_erase_calls;
431 	uint32_t *flash_max_len;
432 
433 	const uint16_t max_id = 10;
434 	/* 25th write will trigger GC. */
435 	const uint16_t max_writes = 26;
436 
437 	/* Get the address of simulator parameters. */
438 	stats_walk(sim_thresholds, flash_sim_max_write_calls_find,
439 		   &flash_max_write_calls);
440 	stats_walk(sim_thresholds, flash_sim_max_erase_calls_find,
441 		   &flash_max_erase_calls);
442 	stats_walk(sim_thresholds, flash_sim_max_len_find,
443 		   &flash_max_len);
444 	stats_walk(sim_stats, flash_sim_write_calls_find, &flash_write_stat);
445 	stats_walk(sim_stats, flash_sim_erase_calls_find, &flash_erase_stat);
446 
447 	err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
448 	zassert_true(err == 0,  "nvs_init call failure: %d", err);
449 
450 	for (uint16_t i = 0; i < max_writes; i++) {
451 		uint8_t id = (i % max_id);
452 		uint8_t id_data = id + max_id * (i / max_id);
453 
454 		memset(buf, id_data, sizeof(buf));
455 
456 		if (i == max_writes - 1) {
457 			/* Reset stats. */
458 			*flash_write_stat = 0;
459 			*flash_erase_stat = 0;
460 
461 			/* Block write calls and simulate power down during
462 			 * sector closing operation, so only a part of a NVS
463 			 * closing ate will be written.
464 			 */
465 			*flash_max_write_calls = 1;
466 			*flash_max_erase_calls = 1;
467 			*flash_max_len = 4;
468 		}
469 
470 		len = nvs_write(&fs, id, buf, sizeof(buf));
471 		zassert_true(len == sizeof(buf), "nvs_write failed: %d", len);
472 	}
473 
474 	/* Make the flash simulator functional again. */
475 	*flash_max_write_calls = 0;
476 	*flash_max_erase_calls = 0;
477 	*flash_max_len = 0;
478 
479 	err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
480 	zassert_true(err == 0,  "nvs_init call failure: %d", err);
481 
482 	check_content(max_id, &fs);
483 
484 	/* Ensure that the NVS is able to store new content. */
485 	execute_long_pattern_write(max_id);
486 }
487 
488 /**
489  * @brief Test case when storage become full, so only deletion is possible.
490  */
test_nvs_full_sector(void)491 void test_nvs_full_sector(void)
492 {
493 	int err;
494 	ssize_t len;
495 	uint16_t filling_id = 0;
496 	uint16_t i, data_read;
497 
498 	fs.sector_count = 3;
499 
500 	err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
501 	zassert_true(err == 0,  "nvs_init call failure: %d", err);
502 
503 	while (1) {
504 		len = nvs_write(&fs, filling_id, &filling_id,
505 				sizeof(filling_id));
506 		if (len == -ENOSPC) {
507 			break;
508 		}
509 		zassert_true(len == sizeof(filling_id), "nvs_write failed: %d",
510 			     len);
511 		filling_id++;
512 	}
513 
514 	/* check whether can delete whatever from full storage */
515 	err = nvs_delete(&fs, 1);
516 	zassert_true(err == 0,  "nvs_delete call failure: %d", err);
517 
518 	/* the last sector is full now, test re-initialization */
519 	err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
520 	zassert_true(err == 0,  "nvs_init call failure: %d", err);
521 
522 	len = nvs_write(&fs, filling_id, &filling_id, sizeof(filling_id));
523 	zassert_true(len == sizeof(filling_id), "nvs_write failed: %d", len);
524 
525 	/* sanitycheck on NVS content */
526 	for (i = 0; i <= filling_id; i++) {
527 		len = nvs_read(&fs, i, &data_read, sizeof(data_read));
528 		if (i == 1) {
529 			zassert_true(len == -ENOENT,
530 				     "nvs_read shouldn't found the entry: %d",
531 				     len);
532 		} else {
533 			zassert_true(len == sizeof(data_read),
534 				     "nvs_read failed: %d", i, len);
535 			zassert_equal(data_read, i,
536 				      "read unexpected data: %d instead of %d",
537 				      data_read, i);
538 		}
539 	}
540 }
541 
test_delete(void)542 void test_delete(void)
543 {
544 	int err;
545 	ssize_t len;
546 	uint16_t filling_id, data_read;
547 	uint32_t ate_wra, data_wra;
548 
549 	fs.sector_count = 3;
550 
551 	err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
552 	zassert_true(err == 0,  "nvs_init call failure: %d", err);
553 
554 	for (filling_id = 0; filling_id < 10; filling_id++) {
555 		len = nvs_write(&fs, filling_id, &filling_id,
556 				sizeof(filling_id));
557 
558 		zassert_true(len == sizeof(filling_id), "nvs_write failed: %d",
559 			     len);
560 
561 		if (filling_id != 0) {
562 			continue;
563 		}
564 
565 		/* delete the first entry while it is the most recent one */
566 		err = nvs_delete(&fs, filling_id);
567 		zassert_true(err == 0,  "nvs_delete call failure: %d", err);
568 
569 		len = nvs_read(&fs, filling_id, &data_read, sizeof(data_read));
570 		zassert_true(len == -ENOENT,
571 			     "nvs_read shouldn't found the entry: %d", len);
572 	}
573 
574 	/* delete existing entry */
575 	err = nvs_delete(&fs, 1);
576 	zassert_true(err == 0,  "nvs_delete call failure: %d", err);
577 
578 	len = nvs_read(&fs, 1, &data_read, sizeof(data_read));
579 	zassert_true(len == -ENOENT, "nvs_read shouldn't found the entry: %d",
580 		     len);
581 
582 	ate_wra = fs.ate_wra;
583 	data_wra = fs.data_wra;
584 
585 	/* delete already deleted entry */
586 	err = nvs_delete(&fs, 1);
587 	zassert_true(err == 0,  "nvs_delete call failure: %d", err);
588 	zassert_true(ate_wra == fs.ate_wra && data_wra == fs.data_wra,
589 		     "delete already deleted entry should not make"
590 		     " any footprint in the storage");
591 
592 	/* delete nonexisting entry */
593 	err = nvs_delete(&fs, filling_id);
594 	zassert_true(err == 0,  "nvs_delete call failure: %d", err);
595 	zassert_true(ate_wra == fs.ate_wra && data_wra == fs.data_wra,
596 		     "delete nonexistent entry should not make"
597 		     " any footprint in the storage");
598 }
599 
600 /*
601  * Test that garbage-collection can recover all ate's even when the last ate,
602  * ie close_ate, is corrupt. In this test the close_ate is set to point to the
603  * last ate at -5. A valid ate is however present at -6. Since the close_ate
604  * has an invalid crc8, the offset should not be used and a recover of the
605  * last ate should be done instead.
606  */
test_nvs_gc_corrupt_close_ate(void)607 void test_nvs_gc_corrupt_close_ate(void)
608 {
609 	struct nvs_ate ate, close_ate;
610 	const struct device *flash_dev;
611 	uint32_t data;
612 	ssize_t len;
613 	int err;
614 
615 	flash_dev = device_get_binding(DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
616 	zassert_true(flash_dev != NULL,  "device_get_binding failure");
617 
618 	close_ate.id = 0xffff;
619 	close_ate.offset = fs.sector_size - sizeof(struct nvs_ate) * 5;
620 	close_ate.len = 0;
621 	close_ate.crc8 = 0xff; /* Incorrect crc8 */
622 
623 	ate.id = 0x1;
624 	ate.offset = 0;
625 	ate.len = sizeof(data);
626 	ate.crc8 = crc8_ccitt(0xff, &ate,
627 			      offsetof(struct nvs_ate, crc8));
628 
629 	/* Mark sector 0 as closed */
630 	err = flash_write(flash_dev, fs.offset + fs.sector_size -
631 			  sizeof(struct nvs_ate), &close_ate,
632 			  sizeof(close_ate));
633 	zassert_true(err == 0,  "flash_write failed: %d", err);
634 
635 	/* Write valid ate at -6 */
636 	err = flash_write(flash_dev, fs.offset + fs.sector_size -
637 			  sizeof(struct nvs_ate) * 6, &ate, sizeof(ate));
638 	zassert_true(err == 0,  "flash_write failed: %d", err);
639 
640 	/* Write data for previous ate */
641 	data = 0xaa55aa55;
642 	err = flash_write(flash_dev, fs.offset, &data, sizeof(data));
643 	zassert_true(err == 0,  "flash_write failed: %d", err);
644 
645 	/* Mark sector 1 as closed */
646 	err = flash_write(flash_dev, fs.offset + (2 * fs.sector_size) -
647 			  sizeof(struct nvs_ate), &close_ate,
648 			  sizeof(close_ate));
649 	zassert_true(err == 0,  "flash_write failed: %d", err);
650 
651 	fs.sector_count = 3;
652 
653 	err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
654 	zassert_true(err == 0,  "nvs_init call failure: %d", err);
655 
656 	data = 0;
657 	len = nvs_read(&fs, 1, &data, sizeof(data));
658 	zassert_true(len == sizeof(data),
659 		     "nvs_read should have read %d bytes", sizeof(data));
660 	zassert_true(data == 0xaa55aa55, "unexpected value %d", data);
661 }
662 
663 /*
664  * Test that garbage-collection correctly handles corrupt ate's.
665  */
test_nvs_gc_corrupt_ate(void)666 void test_nvs_gc_corrupt_ate(void)
667 {
668 	struct nvs_ate corrupt_ate, close_ate;
669 	const struct device *flash_dev;
670 	int err;
671 
672 	flash_dev = device_get_binding(DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
673 	zassert_true(flash_dev != NULL,  "device_get_binding failure");
674 
675 	close_ate.id = 0xffff;
676 	close_ate.offset = fs.sector_size / 2;
677 	close_ate.len = 0;
678 	close_ate.crc8 = crc8_ccitt(0xff, &close_ate,
679 				    offsetof(struct nvs_ate, crc8));
680 
681 	corrupt_ate.id = 0xdead;
682 	corrupt_ate.offset = 0;
683 	corrupt_ate.len = 20;
684 	corrupt_ate.crc8 = 0xff; /* Incorrect crc8 */
685 
686 	/* Mark sector 0 as closed */
687 	err = flash_write(flash_dev, fs.offset + fs.sector_size -
688 			  sizeof(struct nvs_ate), &close_ate,
689 			  sizeof(close_ate));
690 	zassert_true(err == 0,  "flash_write failed: %d", err);
691 
692 	/* Write a corrupt ate */
693 	err = flash_write(flash_dev, fs.offset + (fs.sector_size / 2),
694 			  &corrupt_ate, sizeof(corrupt_ate));
695 	zassert_true(err == 0,  "flash_write failed: %d", err);
696 
697 	/* Mark sector 1 as closed */
698 	err = flash_write(flash_dev, fs.offset + (2 * fs.sector_size) -
699 			  sizeof(struct nvs_ate), &close_ate,
700 			  sizeof(close_ate));
701 	zassert_true(err == 0,  "flash_write failed: %d", err);
702 
703 	fs.sector_count = 3;
704 
705 	err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
706 	zassert_true(err == 0,  "nvs_init call failure: %d", err);
707 }
708 
test_main(void)709 void test_main(void)
710 {
711 	ztest_test_suite(test_nvs,
712 			 ztest_unit_test_setup_teardown(test_nvs_init, setup,
713 				 teardown),
714 			 ztest_unit_test_setup_teardown(test_nvs_write, setup,
715 				 teardown),
716 			 ztest_unit_test_setup_teardown(
717 				 test_nvs_corrupted_write, setup, teardown),
718 			 ztest_unit_test_setup_teardown(
719 				 test_nvs_gc, setup, teardown),
720 			 ztest_unit_test_setup_teardown(
721 				 test_nvs_gc_3sectors, setup, teardown),
722 			 ztest_unit_test_setup_teardown(
723 				 test_nvs_corrupted_sector_close_operation,
724 				 setup, teardown),
725 			 ztest_unit_test_setup_teardown(test_nvs_full_sector,
726 				 setup, teardown),
727 			 ztest_unit_test_setup_teardown(test_delete, setup,
728 				 teardown),
729 			 ztest_unit_test_setup_teardown(
730 				 test_nvs_gc_corrupt_close_ate, setup, teardown),
731 			 ztest_unit_test_setup_teardown(
732 				 test_nvs_gc_corrupt_ate, setup, teardown)
733 			);
734 
735 	ztest_run_test_suite(test_nvs);
736 }
737