|
12 | 12 |
|
13 | 13 | #include <cerrno> |
14 | 14 | #include <cstring> |
| 15 | +#include <sys/stat.h> |
15 | 16 |
|
16 | 17 | #include "FileUplinkTester.hpp" |
17 | 18 | #include "Fw/Com/ComPacket.hpp" |
@@ -529,4 +530,142 @@ void FileUplinkTester ::removeFile(const char* const path) { |
529 | 530 | } |
530 | 531 | } |
531 | 532 |
|
| 533 | +void FileUplinkTester ::verifyFileSize(const char* const path, const size_t expectedSize) { |
| 534 | + struct stat st; |
| 535 | + ASSERT_EQ(0, ::stat(path, &st)) << "Could not stat " << path; |
| 536 | + ASSERT_EQ(static_cast<size_t>(st.st_size), expectedSize) |
| 537 | + << "File has " << st.st_size << " bytes on disk; expected " << expectedSize |
| 538 | + << ". Os::File::open is likely not truncating stale content."; |
| 539 | +} |
| 540 | + |
| 541 | +// ---------------------------------------------------------------------- |
| 542 | +// Overwrite truncation tests |
| 543 | +// Regression coverage for the change in File.cpp: |
| 544 | +// Os::File::open(path, Os::File::OPEN_CREATE, Os::File::OverwriteType::OVERWRITE) |
| 545 | +// Without truncation, stale bytes from a previously-larger file survive |
| 546 | +// past the new logical EOF and corrupt the uplinked content. |
| 547 | +// ---------------------------------------------------------------------- |
| 548 | + |
| 549 | +void FileUplinkTester ::overwriteWithSmallerFile() { |
| 550 | + const char* const sourcePath = "source.bin"; |
| 551 | + const char* const destPath = "overwrite_test.bin"; |
| 552 | + |
| 553 | + // --- First upload: 4 packets * PACKET_SIZE = 20 bytes of 0xAA --- |
| 554 | + const U32 numLargePackets = 4; |
| 555 | + const size_t largeFileSize = numLargePackets * PACKET_SIZE; |
| 556 | + U8 largeData[largeFileSize]; |
| 557 | + memset(largeData, 0xAA, largeFileSize); |
| 558 | + |
| 559 | + this->sendStartPacket(sourcePath, destPath, largeFileSize); |
| 560 | + for (U32 i = 0; i < numLargePackets; ++i) { |
| 561 | + this->sendDataPacket(i * PACKET_SIZE, &largeData[i * PACKET_SIZE]); |
| 562 | + } |
| 563 | + CFDP::Checksum largeChecksum; |
| 564 | + largeChecksum.update(largeData, 0, largeFileSize); |
| 565 | + this->sendEndPacket(largeChecksum); |
| 566 | + |
| 567 | + this->verifyFileData(destPath, largeData, largeFileSize); |
| 568 | + this->verifyFileSize(destPath, largeFileSize); |
| 569 | + |
| 570 | + // --- Second upload: 1 packet * PACKET_SIZE = 5 bytes of 0xBB --- |
| 571 | + const U32 numSmallPackets = 1; |
| 572 | + const size_t smallFileSize = numSmallPackets * PACKET_SIZE; |
| 573 | + U8 smallData[smallFileSize]; |
| 574 | + memset(smallData, 0xBB, smallFileSize); |
| 575 | + |
| 576 | + this->sendStartPacket(sourcePath, destPath, smallFileSize); |
| 577 | + for (U32 i = 0; i < numSmallPackets; ++i) { |
| 578 | + this->sendDataPacket(i * PACKET_SIZE, &smallData[i * PACKET_SIZE]); |
| 579 | + } |
| 580 | + CFDP::Checksum smallChecksum; |
| 581 | + smallChecksum.update(smallData, 0, smallFileSize); |
| 582 | + this->sendEndPacket(smallChecksum); |
| 583 | + |
| 584 | + // Content must be the new data only — no 0xAA stale tail |
| 585 | + this->verifyFileData(destPath, smallData, smallFileSize); |
| 586 | + this->verifyFileSize(destPath, smallFileSize); |
| 587 | + |
| 588 | + this->removeFile(destPath); |
| 589 | +} |
| 590 | + |
| 591 | +void FileUplinkTester ::overwriteSameSizeFile() { |
| 592 | + const char* const sourcePath = "source.bin"; |
| 593 | + const char* const destPath = "overwrite_test.bin"; |
| 594 | + |
| 595 | + const U32 numPackets = 2; |
| 596 | + const size_t fileSize = numPackets * PACKET_SIZE; |
| 597 | + |
| 598 | + // --- First upload: 0x11 fill --- |
| 599 | + U8 firstData[fileSize]; |
| 600 | + memset(firstData, 0x11, fileSize); |
| 601 | + |
| 602 | + this->sendStartPacket(sourcePath, destPath, fileSize); |
| 603 | + for (U32 i = 0; i < numPackets; ++i) { |
| 604 | + this->sendDataPacket(i * PACKET_SIZE, &firstData[i * PACKET_SIZE]); |
| 605 | + } |
| 606 | + CFDP::Checksum firstChecksum; |
| 607 | + firstChecksum.update(firstData, 0, fileSize); |
| 608 | + this->sendEndPacket(firstChecksum); |
| 609 | + |
| 610 | + this->verifyFileData(destPath, firstData, fileSize); |
| 611 | + |
| 612 | + // --- Second upload: 0x22 fill, same path and size --- |
| 613 | + U8 secondData[fileSize]; |
| 614 | + memset(secondData, 0x22, fileSize); |
| 615 | + |
| 616 | + this->sendStartPacket(sourcePath, destPath, fileSize); |
| 617 | + for (U32 i = 0; i < numPackets; ++i) { |
| 618 | + this->sendDataPacket(i * PACKET_SIZE, &secondData[i * PACKET_SIZE]); |
| 619 | + } |
| 620 | + CFDP::Checksum secondChecksum; |
| 621 | + secondChecksum.update(secondData, 0, fileSize); |
| 622 | + this->sendEndPacket(secondChecksum); |
| 623 | + |
| 624 | + // All bytes must reflect the new upload |
| 625 | + this->verifyFileData(destPath, secondData, fileSize); |
| 626 | + this->verifyFileSize(destPath, fileSize); |
| 627 | + |
| 628 | + this->removeFile(destPath); |
| 629 | +} |
| 630 | + |
| 631 | +void FileUplinkTester ::overwriteWithLargerFile() { |
| 632 | + const char* const sourcePath = "source.bin"; |
| 633 | + const char* const destPath = "overwrite_test.bin"; |
| 634 | + |
| 635 | + // --- First upload: 1 packet * PACKET_SIZE = 5 bytes of 0x33 --- |
| 636 | + const U32 numSmallPackets = 1; |
| 637 | + const size_t smallFileSize = numSmallPackets * PACKET_SIZE; |
| 638 | + U8 smallData[smallFileSize]; |
| 639 | + memset(smallData, 0x33, smallFileSize); |
| 640 | + |
| 641 | + this->sendStartPacket(sourcePath, destPath, smallFileSize); |
| 642 | + for (U32 i = 0; i < numSmallPackets; ++i) { |
| 643 | + this->sendDataPacket(i * PACKET_SIZE, &smallData[i * PACKET_SIZE]); |
| 644 | + } |
| 645 | + CFDP::Checksum smallChecksum; |
| 646 | + smallChecksum.update(smallData, 0, smallFileSize); |
| 647 | + this->sendEndPacket(smallChecksum); |
| 648 | + |
| 649 | + this->verifyFileData(destPath, smallData, smallFileSize); |
| 650 | + |
| 651 | + // --- Second upload: 4 packets * PACKET_SIZE = 20 bytes of 0x44 --- |
| 652 | + const U32 numLargePackets = 4; |
| 653 | + const size_t largeFileSize = numLargePackets * PACKET_SIZE; |
| 654 | + U8 largeData[largeFileSize]; |
| 655 | + memset(largeData, 0x44, largeFileSize); |
| 656 | + |
| 657 | + this->sendStartPacket(sourcePath, destPath, largeFileSize); |
| 658 | + for (U32 i = 0; i < numLargePackets; ++i) { |
| 659 | + this->sendDataPacket(i * PACKET_SIZE, &largeData[i * PACKET_SIZE]); |
| 660 | + } |
| 661 | + CFDP::Checksum largeChecksum; |
| 662 | + largeChecksum.update(largeData, 0, largeFileSize); |
| 663 | + this->sendEndPacket(largeChecksum); |
| 664 | + |
| 665 | + this->verifyFileData(destPath, largeData, largeFileSize); |
| 666 | + this->verifyFileSize(destPath, largeFileSize); |
| 667 | + |
| 668 | + this->removeFile(destPath); |
| 669 | +} |
| 670 | + |
532 | 671 | } // namespace Svc |
0 commit comments