1 /*
2 * Copyright (c) 2020 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <string.h>
8 #include <zephyr/types.h>
9 #include <stdbool.h>
10 #include <zephyr/ztest.h>
11 #include <zephyr/drivers/flash.h>
12 #include <zephyr/settings/settings.h>
13
14 #include <zephyr/storage/stream_flash.h>
15
16 #define BUF_LEN 512
17 #define MAX_PAGE_SIZE 0x1000 /* Max supported page size to run test on */
18 #define MAX_NUM_PAGES 4 /* Max number of pages used in these tests */
19 #define TESTBUF_SIZE (MAX_PAGE_SIZE * MAX_NUM_PAGES)
20 #define SOC_NV_FLASH_NODE DT_INST(0, soc_nv_flash)
21 #define FLASH_SIZE DT_REG_SIZE(SOC_NV_FLASH_NODE)
22
23 /* so that we don't overwrite the application when running on hw */
24 #define FLASH_BASE (128*1024)
25 #define FLASH_AVAILABLE (FLASH_SIZE-FLASH_BASE)
26
27 static const struct device *const fdev = DEVICE_DT_GET(DT_CHOSEN(zephyr_flash_controller));
28 static const struct flash_driver_api *api;
29 static const struct flash_pages_layout *layout;
30 static size_t layout_size;
31 static struct stream_flash_ctx ctx;
32 static int page_size;
33 static uint8_t *cb_buf;
34 static size_t cb_len;
35 static size_t cb_offset;
36 static int cb_ret;
37
38 static const char progress_key[] = "sf-test/progress";
39
40 static uint8_t generic_buf[BUF_LEN];
41 static uint8_t read_buf[TESTBUF_SIZE];
42 const static uint8_t write_buf[TESTBUF_SIZE] = {[0 ... TESTBUF_SIZE - 1] = 0xaa};
43 static uint8_t written_pattern[TESTBUF_SIZE] = {[0 ... TESTBUF_SIZE - 1] = 0xaa};
44 #if defined(CONFIG_FLASH_HAS_EXPLICIT_ERASE)
45 static uint8_t erased_pattern[TESTBUF_SIZE] = {[0 ... TESTBUF_SIZE - 1] = 0xff};
46 #endif
47
48 #define VERIFY_BUF(start, size, buf) \
49 do { \
50 rc = flash_read(fdev, FLASH_BASE + start, read_buf, size); \
51 zassert_equal(rc, 0, "should succeed"); \
52 zassert_mem_equal(read_buf, buf, size, "should equal %s", #buf);\
53 } while (0)
54
55 #define VERIFY_WRITTEN(start, size) VERIFY_BUF(start, size, written_pattern)
56 #if defined(CONFIG_FLASH_HAS_EXPLICIT_ERASE)
57 #define VERIFY_ERASED(start, size) VERIFY_BUF(start, size, erased_pattern)
58 #else
59 #define VERIFY_ERASED(start, size)
60 #endif
61
stream_flash_callback(uint8_t * buf,size_t len,size_t offset)62 int stream_flash_callback(uint8_t *buf, size_t len, size_t offset)
63 {
64 if (cb_buf) {
65 zassert_equal(cb_buf, buf, "incorrect buf");
66 zassert_equal(cb_len, len, "incorrect length");
67 zassert_equal(cb_offset, offset, "incorrect offset");
68 }
69
70 return cb_ret;
71 }
72
erase_flash(void)73 static void erase_flash(void)
74 {
75 #if defined(CONFIG_FLASH_HAS_EXPLICIT_ERASE)
76 int rc;
77 #if defined(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE)
78 const struct flash_parameters *fparam = flash_get_parameters(fdev);
79
80 if (!(flash_params_get_erase_cap(fparam) & FLASH_ERASE_C_EXPLICIT)) {
81 return;
82 }
83 #endif
84
85 for (int i = 0; i < MAX_NUM_PAGES; i++) {
86 rc = flash_erase(fdev,
87 FLASH_BASE + (i * layout->pages_size),
88 layout->pages_size);
89 zassert_equal(rc, 0, "should succeed");
90 }
91 #endif
92 }
93
94
init_target(void)95 static void init_target(void)
96 {
97 int rc;
98
99 /* Ensure that target is clean */
100 memset(&ctx, 0, sizeof(ctx));
101 memset(generic_buf, 0, BUF_LEN);
102
103 /* Disable callback tests */
104 cb_len = 0;
105 cb_offset = 0;
106 cb_buf = NULL;
107 cb_ret = 0;
108
109 erase_flash();
110
111 rc = stream_flash_init(&ctx, fdev, generic_buf, BUF_LEN, FLASH_BASE, 0,
112 stream_flash_callback);
113 zassert_equal(rc, 0, "expected success");
114 }
115
ZTEST(lib_stream_flash,test_stream_flash_init)116 ZTEST(lib_stream_flash, test_stream_flash_init)
117 {
118 int rc;
119
120 init_target();
121
122 /* End address out of range */
123 rc = stream_flash_init(&ctx, fdev, generic_buf, BUF_LEN, FLASH_BASE,
124 FLASH_AVAILABLE + 4, NULL);
125 zassert_true(rc < 0, "should fail as size is more than available");
126
127 rc = stream_flash_init(NULL, fdev, generic_buf, BUF_LEN, FLASH_BASE, 0, NULL);
128 zassert_true(rc < 0, "should fail as ctx is NULL");
129
130 rc = stream_flash_init(&ctx, NULL, generic_buf, BUF_LEN, FLASH_BASE, 0, NULL);
131 zassert_true(rc < 0, "should fail as fdev is NULL");
132
133 rc = stream_flash_init(&ctx, fdev, NULL, BUF_LEN, FLASH_BASE, 0, NULL);
134 zassert_true(rc < 0, "should fail as buffer is NULL");
135
136 /* Entering '0' as flash size uses rest of flash. */
137 rc = stream_flash_init(&ctx, fdev, generic_buf, BUF_LEN, FLASH_BASE, 0, NULL);
138 zassert_equal(rc, 0, "should succeed");
139 zassert_equal(FLASH_AVAILABLE, ctx.available, "Wrong size");
140 }
141
ZTEST(lib_stream_flash,test_stream_flash_buffered_write)142 ZTEST(lib_stream_flash, test_stream_flash_buffered_write)
143 {
144 int rc;
145
146 init_target();
147
148 /* Don't fill up the buffer */
149 rc = stream_flash_buffered_write(&ctx, write_buf, BUF_LEN - 1, false);
150 zassert_equal(rc, 0, "expected success");
151
152 /* Verify that no data has been written */
153 VERIFY_ERASED(0, BUF_LEN);
154
155 /* Now, write the missing byte, which should trigger a dump to flash */
156 rc = stream_flash_buffered_write(&ctx, write_buf, 1, false);
157 zassert_equal(rc, 0, "expected success");
158
159 VERIFY_WRITTEN(0, BUF_LEN);
160 }
161
ZTEST(lib_stream_flash,test_stream_flash_buffered_write_cross_buf_border)162 ZTEST(lib_stream_flash, test_stream_flash_buffered_write_cross_buf_border)
163 {
164 int rc;
165
166 init_target();
167
168 /* Test when write crosses border of the buffer */
169 rc = stream_flash_buffered_write(&ctx, write_buf, BUF_LEN + 128, false);
170 zassert_equal(rc, 0, "expected success");
171
172 /* 1xBuffer should be dumped to flash */
173 VERIFY_WRITTEN(0, BUF_LEN);
174
175 /* Fill rest of the buffer */
176 rc = stream_flash_buffered_write(&ctx, write_buf, BUF_LEN - 128, false);
177 zassert_equal(rc, 0, "expected success");
178 VERIFY_WRITTEN(BUF_LEN, BUF_LEN);
179
180 /* Fill half of the buffer */
181 rc = stream_flash_buffered_write(&ctx, write_buf, BUF_LEN/2, false);
182 zassert_equal(rc, 0, "expected success");
183
184 /* Flush the buffer */
185 rc = stream_flash_buffered_write(&ctx, write_buf, 0, true);
186 zassert_equal(rc, 0, "expected success");
187
188 /* Two and a half buffers should be written */
189 VERIFY_WRITTEN(0, BUF_LEN * 2 + BUF_LEN / 2);
190 }
191
ZTEST(lib_stream_flash,test_stream_flash_buffered_write_unaligned)192 ZTEST(lib_stream_flash, test_stream_flash_buffered_write_unaligned)
193 {
194 int rc;
195
196 if (flash_get_write_block_size(fdev) == 1) {
197 ztest_test_skip();
198 }
199
200 init_target();
201
202 /* Test unaligned data size */
203 rc = stream_flash_buffered_write(&ctx, write_buf, 1, true);
204 zassert_equal(rc, 0, "expected success (%d)", rc);
205
206 /* 1 byte should be dumped to flash */
207 VERIFY_WRITTEN(0, 1);
208
209 rc = stream_flash_init(&ctx, fdev, generic_buf, BUF_LEN, FLASH_BASE + BUF_LEN,
210 0, stream_flash_callback);
211 zassert_equal(rc, 0, "expected success");
212
213 /* Trigger verification in callback */
214 cb_buf = generic_buf;
215 cb_len = BUF_LEN - 1;
216 cb_offset = FLASH_BASE + BUF_LEN;
217
218 /* Test unaligned data size */
219 rc = stream_flash_buffered_write(&ctx, write_buf, BUF_LEN - 1, true);
220 zassert_equal(rc, 0, "expected success");
221
222 /* BUF_LEN-1 bytes should be dumped to flash */
223 VERIFY_WRITTEN(BUF_LEN, BUF_LEN - 1);
224 }
225
ZTEST(lib_stream_flash,test_stream_flash_buffered_write_multi_page)226 ZTEST(lib_stream_flash, test_stream_flash_buffered_write_multi_page)
227 {
228 int rc;
229 int num_pages = MAX_NUM_PAGES - 1;
230
231 init_target();
232
233 /* Test when write spans multiple pages crosses border of page */
234 rc = stream_flash_buffered_write(&ctx, write_buf,
235 (page_size * num_pages) + 128, false);
236 zassert_equal(rc, 0, "expected success");
237
238 /* First three pages should be written */
239 VERIFY_WRITTEN(0, page_size * num_pages);
240
241 /* Fill rest of the page */
242 rc = stream_flash_buffered_write(&ctx, write_buf,
243 page_size - 128, false);
244 zassert_equal(rc, 0, "expected success");
245
246 /* First four pages should be written */
247 VERIFY_WRITTEN(0, BUF_LEN * (num_pages + 1));
248 }
249
ZTEST(lib_stream_flash,test_stream_flash_bytes_written)250 ZTEST(lib_stream_flash, test_stream_flash_bytes_written)
251 {
252 int rc;
253 size_t offset;
254
255 init_target();
256
257 /* Verify that the offset is retained across failed downloads */
258 rc = stream_flash_buffered_write(&ctx, write_buf, BUF_LEN + 128, false);
259 zassert_equal(rc, 0, "expected success");
260
261 /* First page should be written */
262 VERIFY_WRITTEN(0, BUF_LEN);
263
264 /* Fill rest of the page */
265 offset = stream_flash_bytes_written(&ctx);
266 zassert_equal(offset, BUF_LEN, "offset should match buf size");
267
268 /* Fill up the buffer MINUS 128 to verify that write_buf_pos is kept */
269 rc = stream_flash_buffered_write(&ctx, write_buf, BUF_LEN - 128, false);
270 zassert_equal(rc, 0, "expected success");
271
272 /* Second page should be written */
273 VERIFY_WRITTEN(BUF_LEN, BUF_LEN);
274 }
275
ZTEST(lib_stream_flash,test_stream_flash_buf_size_greater_than_page_size)276 ZTEST(lib_stream_flash, test_stream_flash_buf_size_greater_than_page_size)
277 {
278 int rc;
279
280 /* To illustrate that other params does not trigger error */
281 rc = stream_flash_init(&ctx, fdev, generic_buf, 0x10, 0, 0, NULL);
282 zassert_equal(rc, 0, "expected success");
283
284 /* Only change buf_len param */
285 rc = stream_flash_init(&ctx, fdev, generic_buf, 0x10000, 0, 0, NULL);
286 zassert_true(rc < 0, "expected failure");
287 }
288
bad_read(const struct device * dev,off_t off,void * data,size_t len)289 static int bad_read(const struct device *dev, off_t off, void *data, size_t len)
290 {
291 return -EINVAL;
292 }
293
fake_write(const struct device * dev,off_t off,const void * data,size_t len)294 static int fake_write(const struct device *dev, off_t off, const void *data, size_t len)
295 {
296 return 0;
297 }
298
bad_write(const struct device * dev,off_t off,const void * data,size_t len)299 static int bad_write(const struct device *dev, off_t off, const void *data, size_t len)
300 {
301 return -EINVAL;
302 }
303
ZTEST(lib_stream_flash,test_stream_flash_buffered_write_callback)304 ZTEST(lib_stream_flash, test_stream_flash_buffered_write_callback)
305 {
306 int rc;
307
308 init_target();
309
310 /* Trigger verification in callback */
311 cb_buf = generic_buf;
312 cb_len = BUF_LEN;
313 cb_offset = FLASH_BASE;
314
315 rc = stream_flash_buffered_write(&ctx, write_buf, BUF_LEN + 128, false);
316 zassert_equal(rc, 0, "expected success");
317
318 cb_len = BUF_LEN;
319 cb_offset = FLASH_BASE + BUF_LEN;
320
321 /* Fill rest of the buffer */
322 rc = stream_flash_buffered_write(&ctx, write_buf, BUF_LEN - 128, false);
323 zassert_equal(rc, 0, "expected success");
324 VERIFY_WRITTEN(BUF_LEN, BUF_LEN);
325
326 /* Fill half of the buffer and flush it to flash */
327 cb_len = BUF_LEN/2;
328 cb_offset = FLASH_BASE + (2 * BUF_LEN);
329
330 rc = stream_flash_buffered_write(&ctx, write_buf, BUF_LEN/2, true);
331 zassert_equal(rc, 0, "expected success");
332
333 /* Ensure that failing callback trickles up to caller */
334 cb_ret = -EFAULT;
335 cb_buf = NULL; /* Don't verify other parameters of the callback */
336 rc = stream_flash_buffered_write(&ctx, write_buf, BUF_LEN, true);
337 zassert_equal(rc, -EFAULT, "expected failure from callback");
338 /* Expect that the BUF_LEN of bytes got stuck in buffer as the verification callback
339 * failed.
340 */
341 zassert_equal(ctx.buf_bytes, BUF_LEN, "Expected bytes to be left in buffer");
342
343 struct device fake_dev = *ctx.fdev;
344 struct flash_driver_api fake_api = *(struct flash_driver_api *)ctx.fdev->api;
345 struct stream_flash_ctx bad_ctx = ctx;
346 struct stream_flash_ctx cmp_ctx;
347
348 fake_api.read = bad_read;
349 /* Using fake write here because after previous write, with faked callback failure,
350 * the flash is already written and real flash_write would cause failure.
351 */
352 fake_api.write = fake_write;
353 fake_dev.api = &fake_api;
354 bad_ctx.fdev = &fake_dev;
355 /* Trigger erase attempt */
356 cmp_ctx = bad_ctx;
357 /* Just flush buffer */
358 rc = stream_flash_buffered_write(&bad_ctx, write_buf, 0, true);
359 zassert_equal(rc, -EINVAL, "expected failure from flash_sync", rc);
360 zassert_equal(ctx.buf_bytes, BUF_LEN, "Expected bytes to be left in buffer");
361
362 /* Pretend flashed context and attempt write write block - 1 bytes to trigger unaligned
363 * write; the write needs to fail so that we could check that context does not get modified.
364 */
365 fake_api.write = bad_write;
366 bad_ctx.callback = NULL;
367 bad_ctx.buf_bytes = 0;
368 cmp_ctx = bad_ctx;
369 size_t wblock = flash_get_write_block_size(ctx.fdev);
370 size_t tow = (wblock == 1) ? 1 : wblock - 1;
371
372 rc = stream_flash_buffered_write(&bad_ctx, write_buf, tow, true);
373 zassert_equal(rc, -EINVAL, "expected failure from flash_sync", rc);
374 zassert_equal(cmp_ctx.bytes_written, bad_ctx.bytes_written,
375 "Expected bytes_written not modified");
376 /* The write failed but bytes have already been added to buffer and buffer offset
377 * increased.
378 */
379 zassert_equal(bad_ctx.buf_bytes, cmp_ctx.buf_bytes + tow,
380 "Expected %d bytes added to buffer", tow);
381 }
382
ZTEST(lib_stream_flash,test_stream_flash_flush)383 ZTEST(lib_stream_flash, test_stream_flash_flush)
384 {
385 int rc;
386
387 init_target();
388
389 /* Perform flush with NULL data pointer and 0 length */
390 rc = stream_flash_buffered_write(&ctx, NULL, 0, true);
391 zassert_equal(rc, 0, "expected success");
392 }
393
394 #ifdef CONFIG_STREAM_FLASH_ERASE
ZTEST(lib_stream_flash,test_stream_flash_buffered_write_whole_page)395 ZTEST(lib_stream_flash, test_stream_flash_buffered_write_whole_page)
396 {
397 int rc;
398
399 init_target();
400
401 /* Write all bytes of a page, verify that next page is not erased */
402
403 /* First fill two pages with data */
404 rc = stream_flash_buffered_write(&ctx, write_buf, page_size * 2, true);
405 zassert_equal(rc, 0, "expected success");
406
407 VERIFY_WRITTEN(0, page_size);
408 VERIFY_WRITTEN(page_size, page_size);
409
410 /* Reset stream_flash context */
411 memset(&ctx, 0, sizeof(ctx));
412 memset(generic_buf, 0, BUF_LEN);
413 rc = stream_flash_init(&ctx, fdev, generic_buf, BUF_LEN, FLASH_BASE, 0,
414 stream_flash_callback);
415 zassert_equal(rc, 0, "expected success");
416
417 /* Write all bytes of a page, verify that next page is not erased */
418 rc = stream_flash_buffered_write(&ctx, write_buf, page_size, true);
419 zassert_equal(rc, 0, "expected success");
420
421 /* Second page should not be erased */
422 VERIFY_WRITTEN(page_size, page_size);
423 }
424
425 /* Erase that never completes successfully */
bad_erase(const struct device * dev,off_t offset,size_t size)426 static int bad_erase(const struct device *dev, off_t offset, size_t size)
427 {
428 return -EINVAL;
429 }
430
ZTEST(lib_stream_flash,test_stream_flash_erase_page)431 ZTEST(lib_stream_flash, test_stream_flash_erase_page)
432 {
433 int rc;
434
435 init_target();
436
437 /* Write something to make page dirty */
438 rc = flash_write(ctx.fdev, FLASH_BASE, write_buf, BUF_LEN);
439 zassert_equal(rc, 0, "expected success");
440
441 rc = stream_flash_erase_page(&ctx, FLASH_BASE);
442 zassert_equal(rc, 0, "expected success");
443
444 VERIFY_ERASED(0, page_size);
445
446 /*
447 * Test failure in erase does not change context.
448 * The test is done by replacing erase function of device API with fake
449 * one that returns with an error, invoking the erase procedure
450 * and than comparing state of context prior to call to the one after.
451 */
452 struct device fake_dev = *ctx.fdev;
453 struct flash_driver_api fake_api = *(struct flash_driver_api *)ctx.fdev->api;
454 struct stream_flash_ctx bad_ctx = ctx;
455 struct stream_flash_ctx cmp_ctx;
456
457 fake_api.erase = bad_erase;
458 fake_dev.api = &fake_api;
459 bad_ctx.fdev = &fake_dev;
460 /* Triger erase attempt */
461 bad_ctx.last_erased_page_start_offset = FLASH_BASE - 16;
462 cmp_ctx = bad_ctx;
463
464 rc = stream_flash_erase_page(&bad_ctx, FLASH_BASE);
465 zassert_equal(memcmp(&bad_ctx, &cmp_ctx, sizeof(bad_ctx)), 0,
466 "Ctx should not get altered");
467 zassert_equal(rc, -EINVAL, "Expected failure");
468 }
469 #else
ZTEST(lib_stream_flash,test_stream_flash_erase_page)470 ZTEST(lib_stream_flash, test_stream_flash_erase_page)
471 {
472 ztest_test_skip();
473 }
474
ZTEST(lib_stream_flash,test_stream_flash_buffered_write_whole_page)475 ZTEST(lib_stream_flash, test_stream_flash_buffered_write_whole_page)
476 {
477 ztest_test_skip();
478 }
479 #endif
480
write_and_save_progress(size_t bytes,const char * save_key)481 static size_t write_and_save_progress(size_t bytes, const char *save_key)
482 {
483 int rc;
484 size_t bytes_written;
485
486 rc = stream_flash_buffered_write(&ctx, write_buf, bytes, true);
487 zassert_equal(rc, 0, "expected success");
488
489 bytes_written = stream_flash_bytes_written(&ctx);
490 zassert_true(bytes_written > 0, "expected bytes to be written");
491
492 if (save_key) {
493 rc = stream_flash_progress_save(&ctx, save_key);
494 zassert_equal(rc, 0, "expected success");
495 }
496
497 return bytes_written;
498 }
499
clear_all_progress(void)500 static void clear_all_progress(void)
501 {
502 (void) settings_delete(progress_key);
503 }
504
load_progress(const char * load_key)505 static size_t load_progress(const char *load_key)
506 {
507 int rc;
508
509 rc = stream_flash_progress_load(&ctx, progress_key);
510 zassert_equal(rc, 0, "expected success");
511
512 return stream_flash_bytes_written(&ctx);
513 }
514
ZTEST(lib_stream_flash,test_stream_flash_progress_api)515 ZTEST(lib_stream_flash, test_stream_flash_progress_api)
516 {
517 int rc;
518
519 clear_all_progress();
520 init_target();
521
522 /* Test save parameter validation */
523 rc = stream_flash_progress_save(NULL, progress_key);
524 zassert_true(rc < 0, "expected error since ctx is NULL");
525
526 rc = stream_flash_progress_save(&ctx, NULL);
527 zassert_true(rc < 0, "expected error since key is NULL");
528
529 rc = stream_flash_progress_save(&ctx, progress_key);
530 zassert_equal(rc, 0, "expected success");
531
532 (void) write_and_save_progress(BUF_LEN, progress_key);
533
534 /* Test load parameter validation */
535 rc = stream_flash_progress_load(NULL, progress_key);
536 zassert_true(rc < 0, "expected error since ctx is NULL");
537
538 rc = stream_flash_progress_load(&ctx, NULL);
539 zassert_true(rc < 0, "expected error since key is NULL");
540
541 rc = stream_flash_progress_load(&ctx, progress_key);
542 zassert_equal(rc, 0, "expected success");
543
544 /* Test clear parameter validation */
545 rc = stream_flash_progress_clear(NULL, progress_key);
546 zassert_true(rc < 0, "expected error since ctx is NULL");
547
548 rc = stream_flash_progress_clear(&ctx, NULL);
549 zassert_true(rc < 0, "expected error since key is NULL");
550
551 rc = stream_flash_progress_clear(&ctx, progress_key);
552 zassert_equal(rc, 0, "expected success");
553 }
554
ZTEST(lib_stream_flash,test_stream_flash_progress_resume)555 ZTEST(lib_stream_flash, test_stream_flash_progress_resume)
556 {
557 int rc;
558 size_t bytes_written_old;
559 size_t bytes_written;
560 #ifdef CONFIG_STREAM_FLASH_ERASE
561 off_t erase_offset_old;
562 off_t erase_offset;
563 #endif
564
565 clear_all_progress();
566 init_target();
567
568 bytes_written_old = stream_flash_bytes_written(&ctx);
569 #ifdef CONFIG_STREAM_FLASH_ERASE
570 erase_offset_old = ctx.last_erased_page_start_offset;
571 #endif
572
573 /* Test load with zero bytes_written */
574 rc = stream_flash_progress_save(&ctx, progress_key);
575 zassert_equal(rc, 0, "expected success");
576
577 rc = stream_flash_progress_load(&ctx, progress_key);
578 zassert_equal(rc, 0, "expected success");
579
580 bytes_written = stream_flash_bytes_written(&ctx);
581 zassert_equal(bytes_written, bytes_written_old,
582 "expected bytes_written to be unchanged");
583 #ifdef CONFIG_STREAM_FLASH_ERASE
584 erase_offset = ctx.last_erased_page_start_offset;
585 zassert_equal(erase_offset, erase_offset_old,
586 "expected erase offset to be unchanged");
587 #endif
588
589 clear_all_progress();
590 init_target();
591
592 /* Write some data and save the progress */
593 bytes_written_old = write_and_save_progress(page_size * 2,
594 progress_key);
595 #ifdef CONFIG_STREAM_FLASH_ERASE
596 erase_offset_old = ctx.last_erased_page_start_offset;
597 zassert_true(erase_offset_old != 0, "expected pages to be erased");
598 #endif
599
600 init_target();
601
602 /* Load the previous progress */
603 bytes_written = load_progress(progress_key);
604 zassert_equal(bytes_written, bytes_written_old,
605 "expected bytes_written to be loaded");
606 #if defined(CONFIG_STREAM_FLASH_ERASE)
607 zassert_equal(erase_offset_old, ctx.last_erased_page_start_offset,
608 "expected last erased page offset to be loaded");
609 #endif
610
611 /* Check that outdated progress does not overwrite current progress */
612 init_target();
613
614 (void) write_and_save_progress(BUF_LEN, progress_key);
615 bytes_written_old = write_and_save_progress(BUF_LEN, NULL);
616 bytes_written = load_progress(progress_key);
617 zassert_equal(bytes_written, bytes_written_old,
618 "expected bytes_written to not be overwritten");
619 }
620
ZTEST(lib_stream_flash,test_stream_flash_progress_clear)621 ZTEST(lib_stream_flash, test_stream_flash_progress_clear)
622 {
623 int rc;
624 size_t bytes_written_old;
625 size_t bytes_written;
626 #ifdef CONFIG_STREAM_FLASH_ERASE
627 off_t erase_offset_old;
628 off_t erase_offset;
629 #endif
630
631 clear_all_progress();
632 init_target();
633
634 /* Test that progress is cleared. */
635 (void) write_and_save_progress(BUF_LEN, progress_key);
636
637 rc = stream_flash_progress_clear(&ctx, progress_key);
638 zassert_equal(rc, 0, "expected success");
639
640 init_target();
641
642 bytes_written_old = stream_flash_bytes_written(&ctx);
643 #ifdef CONFIG_STREAM_FLASH_ERASE
644 erase_offset_old = ctx.last_erased_page_start_offset;
645 #endif
646
647 rc = stream_flash_progress_load(&ctx, progress_key);
648 zassert_equal(rc, 0, "expected success");
649
650 bytes_written = stream_flash_bytes_written(&ctx);
651 zassert_equal(bytes_written, bytes_written_old,
652 "expected bytes_written to be unchanged");
653
654 #ifdef CONFIG_STREAM_FLASH_ERASE
655 erase_offset = ctx.last_erased_page_start_offset;
656 zassert_equal(erase_offset, erase_offset_old,
657 "expected erase offset to be unchanged");
658 #endif
659 }
660
lib_stream_flash_before(void * data)661 void lib_stream_flash_before(void *data)
662 {
663 zassume_true(device_is_ready(fdev), "Device is not ready");
664
665 api = fdev->api;
666 api->page_layout(fdev, &layout, &layout_size);
667
668 page_size = layout->pages_size;
669 zassume_true((page_size > BUF_LEN), "page size is not enough");
670 }
671
672 ZTEST_SUITE(lib_stream_flash, NULL, NULL, lib_stream_flash_before, NULL, NULL);
673