Public Access
Debug Console put: verify the card's copy, never zero-fill after a failed write
Found by M3's shared-bus test: when the card refused a write, the retry closed the file (losing up to 3 KB of earlier chunks still in the write buffer), then truncate() extended it back with zeros. The checksum only covered the received bytes, so `put` reported success with 3 KB of zeros on the card. Now a retry gives up if the card lost data, and the finished file is read back and must hash the same before it's renamed. The card refuses a write about once in five 1.7 MB uploads, with the radio asleep as often as listening. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
@@ -184,6 +184,34 @@ void test_reset_returns_to_idle() {
|
||||
TEST_ASSERT_FALSE(r.active());
|
||||
}
|
||||
|
||||
// The received bytes can be right and the card's copy wrong: read back, it must hash the same.
|
||||
void test_card_check() {
|
||||
auto data = bytes(10);
|
||||
FileReceiver r;
|
||||
r.begin(args("/a.bin", data), 0);
|
||||
r.feed(data.data(), data.size(), 0);
|
||||
r.chunkWritten(true, 0);
|
||||
TEST_ASSERT_TRUE(r.state() == FileReceiver::State::Finishing);
|
||||
uint8_t good[32];
|
||||
Sha256::hash(data.data(), data.size(), good);
|
||||
r.cardChecked(good);
|
||||
TEST_ASSERT_TRUE(r.state() == FileReceiver::State::Finishing);
|
||||
r.finished(true);
|
||||
TEST_ASSERT_TRUE(r.state() == FileReceiver::State::Done);
|
||||
|
||||
FileReceiver bad;
|
||||
bad.begin(args("/a.bin", data), 0);
|
||||
bad.feed(data.data(), data.size(), 0);
|
||||
bad.chunkWritten(true, 0);
|
||||
auto zeroed = data;
|
||||
zeroed[4] = 0;
|
||||
uint8_t wrong[32];
|
||||
Sha256::hash(zeroed.data(), zeroed.size(), wrong);
|
||||
bad.cardChecked(wrong);
|
||||
TEST_ASSERT_TRUE(bad.state() == FileReceiver::State::Failed);
|
||||
TEST_ASSERT_EQUAL_STRING("the copy on the card differs", bad.error().c_str());
|
||||
}
|
||||
|
||||
int main() {
|
||||
UNITY_BEGIN();
|
||||
RUN_TEST(test_begin_accepts_path_size_and_checksum);
|
||||
@@ -198,5 +226,6 @@ int main() {
|
||||
RUN_TEST(test_wanted_counts_down_within_a_chunk);
|
||||
RUN_TEST(test_a_rename_that_never_completes_times_out);
|
||||
RUN_TEST(test_reset_returns_to_idle);
|
||||
RUN_TEST(test_card_check);
|
||||
return UNITY_END();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user