Skip to content

Commit 5a96a1c

Browse files
JordanYatesrghaddab
authored andcommitted
[nrf fromtree] tests: kvss: zms: regression test for ATE in data
Add a regression test for data that looks like an ATE in ZMS data. Assisted-by: GPT-5.6 Signed-off-by: Jordan Yates <jordan@embeint.com> (cherry picked from commit a36aeac2b1d770b6eebfe2df0c76cc5da4c099dd)
1 parent 5594d04 commit 5a96a1c

1 file changed

Lines changed: 56 additions & 0 deletions

File tree

  • tests/subsys/kvss/zms/src

‎tests/subsys/kvss/zms/src/main.c‎

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,62 @@ ZTEST_F(zms, test_zms_write)
176176
execute_long_pattern_write(TEST_DATA_ID, &fixture->fs);
177177
}
178178

179+
/*
180+
* zms_recover_last_ate() scans allocation table slots downwards from the end
181+
* of a sector. As it finds external-data ATEs, their offset and aligned data
182+
* length establish the lower bound of that scan: slots below this boundary
183+
* belong to the data area and must not be interpreted as ATEs.
184+
*
185+
* An inline-data ATE following an external-data ATE must preserve that lower
186+
* bound. This test creates that sequence, embeds a CRC-valid ATE-shaped
187+
* pattern in the payload, and verifies that recovery does not scan far enough
188+
* to let the payload alter the recovered data write address.
189+
*/
190+
ZTEST_F(zms, test_zms_mount_fake_ate)
191+
{
192+
struct zms_ate fake_ate;
193+
uint8_t data[64];
194+
uint32_t inline_data = 0;
195+
int err;
196+
ssize_t len;
197+
198+
err = zms_mount(&fixture->fs);
199+
zassert_ok(err, "zms_mount failed: %d", err);
200+
201+
/* Fill the data record with erased bytes, then embed a valid-looking ATE. */
202+
memset(data, fixture->fs.flash_parameters->erase_value, sizeof(data));
203+
memset(&fake_ate, 0, sizeof(fake_ate));
204+
fake_ate.cycle_cnt = fixture->fs.sector_cycle;
205+
fake_ate.len = 256;
206+
fake_ate.id = 0x01000100;
207+
fake_ate.offset = UINT32_MAX;
208+
fake_ate.crc8 = crc8_ccitt(0xff,
209+
(uint8_t *)&fake_ate + SIZEOF_FIELD(struct zms_ate, crc8),
210+
sizeof(fake_ate) - SIZEOF_FIELD(struct zms_ate, crc8));
211+
memcpy(data + sizeof(fake_ate), &fake_ate, sizeof(fake_ate));
212+
213+
len = zms_write(&fixture->fs, TEST_DATA_ID, data, sizeof(data));
214+
zassert_equal(len, sizeof(data), "zms_write failed: %zd", len);
215+
216+
/*
217+
* The newer inline-data ATE is visited after the external-data ATE during
218+
* the downward scan. It verifies that this inline ATE preserves the data
219+
* boundary established by the external-data ATE.
220+
*/
221+
len = zms_write(&fixture->fs, TEST_DATA_ID + 1, &inline_data, sizeof(inline_data));
222+
zassert_equal(len, sizeof(inline_data), "zms_write of inline data failed: %zd", len);
223+
224+
/* Simulate a reboot so recovery, rather than the live cursors, is used. */
225+
memset(&fixture->fs, 0, sizeof(fixture->fs));
226+
(void)setup();
227+
err = zms_mount(&fixture->fs);
228+
zassert_ok(err, "zms_mount after reboot failed: %d", err);
229+
230+
zassert_equal(fixture->fs.data_wra, sizeof(data),
231+
"data payload was mistaken for an ATE: data_wra=%llx",
232+
fixture->fs.data_wra);
233+
}
234+
179235
#ifdef CONFIG_TEST_ZMS_SIMULATOR
180236
static int flash_sim_write_calls_find(struct stats_hdr *hdr, void *arg, const char *name,
181237
uint16_t off)

0 commit comments

Comments
 (0)