// Copyright 2020 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

#include "pw_kvs/internal/entry.h"

#include <span>
#include <string_view>

#include "gtest/gtest.h"
#include "pw_bytes/array.h"
#include "pw_kvs/alignment.h"
#include "pw_kvs/checksum.h"
#include "pw_kvs/crc16_checksum.h"
#include "pw_kvs/fake_flash_memory.h"
#include "pw_kvs/flash_memory.h"
#include "pw_kvs/format.h"

namespace pw::kvs::internal {
namespace {

using std::byte;
using std::string_view;

// For magic value always use a random 32 bit integer rather than a human
// readable 4 bytes. See pw_kvs/format.h for more information.
constexpr EntryFormat kFormat{0x961c2ff9, nullptr};

TEST(Entry, Size_RoundsUpToAlignment) {
  // Use FakeFlashMemory, rather than FakeFlashMemoryBuffer, so the class gets
  // tested/used directly.
  std::array<std::byte, 64 * 2> buffer;

  // Flash alignment needs to be 1 due to how the partition is used in this
  // test.
  FakeFlashMemory flash(buffer, 64, 2, 1);

  for (size_t alignment_bytes = 1; alignment_bytes <= 4096; ++alignment_bytes) {
    FlashPartition partition(&flash, 0, flash.sector_count(), alignment_bytes);
    const size_t align = AlignUp(alignment_bytes, Entry::kMinAlignmentBytes);

    for (size_t value : {size_t(0), align - 1, align, align + 1, 2 * align}) {
      Entry entry =
          Entry::Valid(partition, 0, kFormat, "k", {nullptr, value}, 0);

      ASSERT_EQ(AlignUp(sizeof(EntryHeader) + 1 /* key */ + value, align),
                entry.size());
    }

    Entry entry = Entry::Tombstone(partition, 0, kFormat, "k", 0);
    ASSERT_EQ(AlignUp(sizeof(EntryHeader) + 1 /* key */, align), entry.size());
  }
}

TEST(Entry, Construct_ValidEntry) {
  FakeFlashMemoryBuffer<64, 2> flash(16);
  FlashPartition partition(&flash, 0, flash.sector_count());

  auto entry = Entry::Valid(
      partition, 1, kFormat, "k", std::as_bytes(std::span("123")), 9876);

  EXPECT_FALSE(entry.deleted());
  EXPECT_EQ(entry.magic(), kFormat.magic);
  EXPECT_EQ(entry.value_size(), sizeof("123"));
  EXPECT_EQ(entry.transaction_id(), 9876u);
}

TEST(Entry, Construct_Tombstone) {
  FakeFlashMemoryBuffer<64, 2> flash(16);
  FlashPartition partition(&flash, 0, flash.sector_count());

  auto entry = Entry::Tombstone(partition, 1, kFormat, "key", 123);

  EXPECT_TRUE(entry.deleted());
  EXPECT_EQ(entry.magic(), kFormat.magic);
  EXPECT_EQ(entry.value_size(), 0u);
  EXPECT_EQ(entry.transaction_id(), 123u);
}

// For magic value always use a unique random 32 bit integer rather than a human
// readable 4 bytes. See pw_kvs/format.h for more information.
constexpr uint32_t kMagicWithChecksum = 0xad165142;
constexpr uint32_t kTransactionId1 = 0x96979899;

constexpr auto kKey1 = bytes::String("key45");
constexpr auto kValue1 = bytes::String("VALUE!");
constexpr auto kPadding1 = bytes::String("\0\0\0\0\0");

constexpr auto kHeader1 = bytes::Concat(kMagicWithChecksum,
                                        uint32_t(0x23aa),  // checksum (CRC16)
                                        uint8_t(1),        // alignment (32 B)
                                        uint8_t(kKey1.size()),     // key length
                                        uint16_t(kValue1.size()),  // value size
                                        kTransactionId1  // transaction ID
);

constexpr auto kEntryWithoutPadding1 = bytes::Concat(kHeader1, kKey1, kValue1);
constexpr auto kEntry1 = bytes::Concat(kEntryWithoutPadding1, kPadding1);
static_assert(kEntry1.size() == 32);

ChecksumCrc16 default_checksum;
constexpr EntryFormat kFormatWithChecksum{kMagicWithChecksum,
                                          &default_checksum};
constexpr internal::EntryFormats kFormats(kFormatWithChecksum);

class ValidEntryInFlash : public ::testing::Test {
 protected:
  ValidEntryInFlash() : flash_(kEntry1), partition_(&flash_) {
    EXPECT_EQ(OkStatus(), Entry::Read(partition_, 0, kFormats, &entry_));
  }

  FakeFlashMemoryBuffer<1024, 4> flash_;
  FlashPartition partition_;
  Entry entry_;
};

TEST_F(ValidEntryInFlash, PassesChecksumVerification) {
  EXPECT_EQ(OkStatus(), entry_.VerifyChecksumInFlash());
  EXPECT_EQ(OkStatus(), entry_.VerifyChecksum("key45", kValue1));
}

TEST_F(ValidEntryInFlash, HeaderContents) {
  EXPECT_EQ(entry_.magic(), kMagicWithChecksum);
  EXPECT_EQ(entry_.key_length(), 5u);
  EXPECT_EQ(entry_.value_size(), 6u);
  EXPECT_EQ(entry_.transaction_id(), kTransactionId1);
  EXPECT_FALSE(entry_.deleted());
}

TEST_F(ValidEntryInFlash, ReadKey) {
  Entry::KeyBuffer key = {};
  auto result = entry_.ReadKey(key);

  ASSERT_EQ(OkStatus(), result.status());
  EXPECT_EQ(result.size(), entry_.key_length());
  EXPECT_STREQ(key.data(), "key45");
}

TEST_F(ValidEntryInFlash, ReadValue) {
  char value[32] = {};
  auto result = entry_.ReadValue(std::as_writable_bytes(std::span(value)));

  ASSERT_EQ(OkStatus(), result.status());
  EXPECT_EQ(result.size(), entry_.value_size());
  EXPECT_STREQ(value, "VALUE!");
}

TEST_F(ValidEntryInFlash, ReadValue_BufferTooSmall) {
  char value[3] = {};
  auto result = entry_.ReadValue(std::as_writable_bytes(std::span(value)));

  ASSERT_EQ(Status::ResourceExhausted(), result.status());
  EXPECT_EQ(3u, result.size());
  EXPECT_EQ(value[0], 'V');
  EXPECT_EQ(value[1], 'A');
  EXPECT_EQ(value[2], 'L');
}

TEST_F(ValidEntryInFlash, ReadValue_WithOffset) {
  char value[3] = {};
  auto result = entry_.ReadValue(std::as_writable_bytes(std::span(value)), 3);

  ASSERT_EQ(OkStatus(), result.status());
  EXPECT_EQ(3u, result.size());
  EXPECT_EQ(value[0], 'U');
  EXPECT_EQ(value[1], 'E');
  EXPECT_EQ(value[2], '!');
}

TEST_F(ValidEntryInFlash, ReadValue_WithOffset_BufferTooSmall) {
  char value[1] = {};
  auto result = entry_.ReadValue(std::as_writable_bytes(std::span(value)), 4);

  ASSERT_EQ(Status::ResourceExhausted(), result.status());
  EXPECT_EQ(1u, result.size());
  EXPECT_EQ(value[0], 'E');
}

TEST_F(ValidEntryInFlash, ReadValue_WithOffset_EmptyRead) {
  char value[16] = {'?'};
  auto result = entry_.ReadValue(std::as_writable_bytes(std::span(value)), 6);

  ASSERT_EQ(OkStatus(), result.status());
  EXPECT_EQ(0u, result.size());
  EXPECT_EQ(value[0], '?');
}

TEST_F(ValidEntryInFlash, ReadValue_WithOffset_PastEnd) {
  char value[16] = {};
  auto result = entry_.ReadValue(std::as_writable_bytes(std::span(value)), 7);

  EXPECT_EQ(Status::OutOfRange(), result.status());
  EXPECT_EQ(0u, result.size());
}

TEST(ValidEntry, Write) {
  FakeFlashMemoryBuffer<1024, 4> flash;
  FlashPartition partition(&flash, 0, flash.sector_count(), 32);

  Entry entry = Entry::Valid(
      partition, 64, kFormatWithChecksum, "key45", kValue1, kTransactionId1);

  auto result = entry.Write("key45", kValue1);
  EXPECT_EQ(OkStatus(), result.status());
  EXPECT_EQ(32u, result.size());
  EXPECT_EQ(std::memcmp(&flash.buffer()[64], kEntry1.data(), kEntry1.size()),
            0);
}

constexpr auto kHeader2 = bytes::String(
    "\x42\x51\x16\xad"  // magic
    "\xba\xb3\x00\x00"  // checksum (CRC16)
    "\x00"              // alignment
    "\x01"              // key length
    "\xff\xff"          // value size
    "\x00\x01\x02\x03"  // transaction ID
);

constexpr auto kKeyAndPadding2 =
    bytes::String("K\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");

class TombstoneEntryInFlash : public ::testing::Test {
 protected:
  TombstoneEntryInFlash()
      : flash_(bytes::Concat(kHeader2, kKeyAndPadding2)), partition_(&flash_) {
    EXPECT_EQ(OkStatus(), Entry::Read(partition_, 0, kFormats, &entry_));
  }

  FakeFlashMemoryBuffer<1024, 4> flash_;
  FlashPartition partition_;
  Entry entry_;
};

TEST_F(TombstoneEntryInFlash, PassesChecksumVerification) {
  EXPECT_EQ(OkStatus(), entry_.VerifyChecksumInFlash());
  EXPECT_EQ(OkStatus(), entry_.VerifyChecksum("K", {}));
}

TEST_F(TombstoneEntryInFlash, HeaderContents) {
  EXPECT_EQ(entry_.magic(), kMagicWithChecksum);
  EXPECT_EQ(entry_.key_length(), 1u);
  EXPECT_EQ(entry_.value_size(), 0u);
  EXPECT_EQ(entry_.transaction_id(), 0x03020100u);
  EXPECT_TRUE(entry_.deleted());
}

TEST_F(TombstoneEntryInFlash, ReadKey) {
  Entry::KeyBuffer key = {};
  auto result = entry_.ReadKey(key);

  ASSERT_EQ(OkStatus(), result.status());
  EXPECT_EQ(result.size(), entry_.key_length());
  EXPECT_STREQ(key.data(), "K");
}

TEST_F(TombstoneEntryInFlash, ReadValue) {
  char value[32] = {};
  auto result = entry_.ReadValue(std::as_writable_bytes(std::span(value)));

  ASSERT_EQ(OkStatus(), result.status());
  EXPECT_EQ(0u, result.size());
}

TEST(TombstoneEntry, Write) {
  FakeFlashMemoryBuffer<1024, 4> flash;
  FlashPartition partition(&flash);
  ChecksumCrc16 checksum;

  Entry entry =
      Entry::Tombstone(partition, 16, kFormatWithChecksum, "K", 0x03020100);

  auto result = entry.Write("K", {});
  EXPECT_EQ(OkStatus(), result.status());
  EXPECT_EQ(32u, result.size());
  EXPECT_EQ(std::memcmp(&flash.buffer()[16],
                        bytes::Concat(kHeader2, kKeyAndPadding2).data(),
                        kEntry1.size()),
            0);
}

TEST(Entry, Checksum_NoChecksumRequiresZero) {
  FakeFlashMemoryBuffer<1024, 4> flash(kEntry1);
  FlashPartition partition(&flash);
  Entry entry;

  const EntryFormat format{kMagicWithChecksum, nullptr};
  const internal::EntryFormats formats(format);

  ASSERT_EQ(OkStatus(), Entry::Read(partition, 0, formats, &entry));

  EXPECT_EQ(Status::DataLoss(), entry.VerifyChecksumInFlash());
  EXPECT_EQ(Status::DataLoss(), entry.VerifyChecksum({}, {}));

  std::memset(&flash.buffer()[4], 0, 4);  // set the checksum field to 0
  ASSERT_EQ(OkStatus(), Entry::Read(partition, 0, formats, &entry));
  EXPECT_EQ(OkStatus(), entry.VerifyChecksumInFlash());
  EXPECT_EQ(OkStatus(), entry.VerifyChecksum({}, {}));
}

TEST(Entry, Checksum_ChecksPadding) {
  FakeFlashMemoryBuffer<1024, 4> flash(
      bytes::Concat(kHeader1, kKey1, kValue1, bytes::String("\0\0\0\0\1")));
  FlashPartition partition(&flash);
  Entry entry;
  ASSERT_EQ(OkStatus(), Entry::Read(partition, 0, kFormats, &entry));

  // Last byte in padding is a 1; should fail.
  EXPECT_EQ(Status::DataLoss(), entry.VerifyChecksumInFlash());

  // The in-memory verification fills in 0s for the padding.
  EXPECT_EQ(OkStatus(), entry.VerifyChecksum("key45", kValue1));

  flash.buffer()[kEntry1.size() - 1] = byte{0};
  EXPECT_EQ(OkStatus(), entry.VerifyChecksumInFlash());
}

TEST_F(ValidEntryInFlash, Update_SameFormat_TransactionIdIsUpdated) {
  ASSERT_EQ(OkStatus(),
            entry_.Update(kFormatWithChecksum, kTransactionId1 + 3));

  EXPECT_EQ(kFormatWithChecksum.magic, entry_.magic());
  EXPECT_EQ(0u, entry_.address());
  EXPECT_EQ(kTransactionId1 + 3, entry_.transaction_id());
  EXPECT_FALSE(entry_.deleted());
}

TEST_F(ValidEntryInFlash,
       Update_DifferentFormat_MagicAndTransactionIdAreUpdated) {
  ASSERT_EQ(OkStatus(), entry_.Update(kFormat, kTransactionId1 + 6));

  EXPECT_EQ(kFormat.magic, entry_.magic());
  EXPECT_EQ(0u, entry_.address());
  EXPECT_EQ(kTransactionId1 + 6, entry_.transaction_id());
  EXPECT_FALSE(entry_.deleted());
}

TEST_F(ValidEntryInFlash, Update_ReadError_WithChecksumIsError) {
  flash_.InjectReadError(FlashError::Unconditional(Status::Aborted()));

  EXPECT_EQ(Status::Aborted(),
            entry_.Update(kFormatWithChecksum, kTransactionId1 + 1));
}

// For magic value always use a random 32 bit integer rather than a human
// readable 4 bytes. See pw_kvs/format.h for more information.
constexpr EntryFormat kNoChecksumFormat{.magic = 0x721bad24,
                                        .checksum = nullptr};

TEST_F(ValidEntryInFlash, Update_ReadError_NoChecksumIsOkay) {
  flash_.InjectReadError(FlashError::Unconditional(Status::Aborted()));

  EXPECT_EQ(OkStatus(), entry_.Update(kNoChecksumFormat, kTransactionId1 + 1));
}

TEST_F(ValidEntryInFlash, Copy) {
  auto result = entry_.Copy(123);

  EXPECT_EQ(OkStatus(), result.status());
  EXPECT_EQ(entry_.size(), result.size());
  EXPECT_EQ(0,
            std::memcmp(
                &flash_.buffer().data()[123], kEntry1.data(), kEntry1.size()));
}

TEST_F(ValidEntryInFlash, Copy_ReadError) {
  flash_.InjectReadError(FlashError::Unconditional(Status::Unimplemented()));
  auto result = entry_.Copy(kEntry1.size());
  EXPECT_EQ(Status::Unimplemented(), result.status());
  EXPECT_EQ(0u, result.size());
}

constexpr uint32_t ByteSum(std::span<const byte> bytes, uint32_t value = 0) {
  for (byte b : bytes) {
    value += unsigned(b);
  }
  return value;
}

// Sums the bytes, adding one to each byte so that zeroes change the checksum.
class ChecksumSummation final : public ChecksumAlgorithm {
 public:
  ChecksumSummation()
      : ChecksumAlgorithm(std::as_bytes(std::span(&sum_, 1))), sum_(0) {}

  void Reset() override { sum_ = 0; }

  void Update(std::span<const byte> data) override {
    for (byte b : data) {
      sum_ += unsigned(b) + 1;  // Add 1 so zero-value bytes affect checksum.
    }
  }

 private:
  uint32_t sum_;
} sum_checksum;

// For magic value always use a random 32 bit integer rather than a human
// readable 4 bytes. See pw_kvs/format.h for more information.
constexpr uint32_t kMagicWithSum = 0x6093aadb;
constexpr EntryFormat kFormatWithSum{kMagicWithSum, &sum_checksum};
constexpr internal::EntryFormats kFormatsWithSum(kFormatWithSum);

template <size_t alignment>
constexpr auto MakeNewFormatWithSumEntry() {
  constexpr uint8_t alignment_units = (alignment + 15) / 16 - 1;
  constexpr size_t size = AlignUp(kEntryWithoutPadding1.size(), alignment);

  constexpr uint32_t checksum =
      ByteSum(bytes::Concat(kFormatWithSum.magic)) + 0 /* checksum */ +
      alignment_units + kKey1.size() + kValue1.size() +
      ByteSum(bytes::Concat(kTransactionId1 + 1)) + ByteSum(kKey1) +
      ByteSum(kValue1) + size /* +1 for each byte in the checksum */;

  constexpr auto kNewHeader1 =
      bytes::Concat(kFormatWithSum.magic,      // magic
                    checksum,                  // checksum (byte sum)
                    alignment_units,           // alignment (in 16 B units)
                    uint8_t(kKey1.size()),     // key length
                    uint16_t(kValue1.size()),  // value size
                    kTransactionId1 + 1);      // transaction ID
  constexpr size_t padding = Padding(kEntryWithoutPadding1.size(), alignment);
  return bytes::Concat(
      kNewHeader1, kKey1, kValue1, bytes::Initialized<padding>(0));
}

TEST_F(ValidEntryInFlash, UpdateAndCopy_DifferentFormatSmallerAlignment) {
  // Uses 16-bit alignment, smaller than the original entry's alignment.
  ASSERT_EQ(OkStatus(), entry_.Update(kFormatWithSum, kTransactionId1 + 1));

  StatusWithSize result = entry_.Copy(kEntry1.size());
  ASSERT_EQ(OkStatus(), result.status());
  EXPECT_EQ(kEntry1.size(), result.size());

  constexpr auto new_data = MakeNewFormatWithSumEntry<16>();
  static_assert(new_data.size() == 32);

  EXPECT_EQ(
      0,
      std::memcmp(
          &flash_.buffer()[kEntry1.size()], new_data.data(), new_data.size()));
  Entry new_entry;
  ASSERT_EQ(OkStatus(),
            Entry::Read(partition_, 32, kFormatsWithSum, &new_entry));
  EXPECT_EQ(OkStatus(), new_entry.VerifyChecksumInFlash());
  EXPECT_EQ(kFormatWithSum.magic, new_entry.magic());
  EXPECT_EQ(kTransactionId1 + 1, new_entry.transaction_id());
}

TEST(ValidEntryInFlash, UpdateAndCopy_DifferentFormatSameAlignment) {
  // Use 32-bit alignment, the same as the original entry's alignment.
  FakeFlashMemoryBuffer<1024, 4> flash(kEntry1);
  FlashPartition partition(&flash, 0, 4, 32);
  Entry entry;
  ASSERT_EQ(OkStatus(), Entry::Read(partition, 0, kFormats, &entry));

  ASSERT_EQ(OkStatus(), entry.Update(kFormatWithSum, kTransactionId1 + 1));

  StatusWithSize result = entry.Copy(32);
  ASSERT_EQ(OkStatus(), result.status());
  EXPECT_EQ(AlignUp(kEntry1.size(), 32), result.size());

  constexpr auto new_data = MakeNewFormatWithSumEntry<32>();
  static_assert(new_data.size() == 32);

  EXPECT_EQ(0,
            std::memcmp(&flash.buffer()[32], new_data.data(), new_data.size()));

  Entry new_entry;
  ASSERT_EQ(OkStatus(),
            Entry::Read(partition, 32, kFormatsWithSum, &new_entry));
  EXPECT_EQ(OkStatus(), new_entry.VerifyChecksumInFlash());
  EXPECT_EQ(kTransactionId1 + 1, new_entry.transaction_id());
}

TEST(ValidEntryInFlash, UpdateAndCopy_DifferentFormatLargerAlignment) {
  // Use 64-bit alignment, larger than the original entry's alignment.
  FakeFlashMemoryBuffer<1024, 4> flash(kEntry1);
  FlashPartition partition(&flash, 0, 4, 64);
  Entry entry;
  ASSERT_EQ(OkStatus(), Entry::Read(partition, 0, kFormats, &entry));

  ASSERT_EQ(OkStatus(), entry.Update(kFormatWithSum, kTransactionId1 + 1));

  StatusWithSize result = entry.Copy(64);
  ASSERT_EQ(OkStatus(), result.status());
  EXPECT_EQ(AlignUp(kEntry1.size(), 64), result.size());

  constexpr auto new_data = MakeNewFormatWithSumEntry<64>();
  static_assert(new_data.size() == 64);

  EXPECT_EQ(0,
            std::memcmp(&flash.buffer()[64], new_data.data(), new_data.size()));

  Entry new_entry;
  ASSERT_EQ(OkStatus(),
            Entry::Read(partition, 64, kFormatsWithSum, &new_entry));
  EXPECT_EQ(OkStatus(), new_entry.VerifyChecksumInFlash());
  EXPECT_EQ(kTransactionId1 + 1, new_entry.transaction_id());
}

TEST_F(ValidEntryInFlash, UpdateAndCopy_NoChecksum_UpdatesToNewFormat) {
  // For magic value always use a random 32 bit integer rather than a human
  // readable 4 bytes. See pw_kvs/format.h for more information.
  constexpr EntryFormat no_checksum{.magic = 0x43fae18f, .checksum = nullptr};

  ASSERT_EQ(OkStatus(), entry_.Update(no_checksum, kTransactionId1 + 1));

  auto result = entry_.Copy(kEntry1.size());
  ASSERT_EQ(OkStatus(), result.status());
  EXPECT_EQ(kEntry1.size(), result.size());

  constexpr auto kNewHeader1 =
      bytes::Concat(no_checksum.magic,  // magic
                    uint32_t(0),        // checksum (none)
                    uint8_t(0),         // alignment (changed to 16 B from 32)
                    uint8_t(kKey1.size()),     // key length
                    uint16_t(kValue1.size()),  // value size
                    kTransactionId1 + 1);      // transaction ID
  constexpr auto kNewEntry1 =
      bytes::Concat(kNewHeader1, kKey1, kValue1, kPadding1);

  EXPECT_EQ(0,
            std::memcmp(&flash_.buffer()[kEntry1.size()],
                        kNewEntry1.data(),
                        kNewEntry1.size()));
}

TEST_F(ValidEntryInFlash, UpdateAndCopyMultple_DifferentFormat) {
  ASSERT_EQ(OkStatus(), entry_.Update(kFormatWithSum, kTransactionId1 + 6));

  FlashPartition::Address new_address = entry_.size();

  for (int i = 0; i < 10; i++) {
    StatusWithSize copy_result = entry_.Copy(new_address + (i * entry_.size()));
    ASSERT_EQ(OkStatus(), copy_result.status());
    ASSERT_EQ(kEntry1.size(), copy_result.size());
  }

  for (int j = 0; j < 10; j++) {
    Entry entry;
    FlashPartition::Address read_address = (new_address + (j * entry_.size()));
    ASSERT_EQ(OkStatus(),
              Entry::Read(partition_, read_address, kFormatsWithSum, &entry));

    EXPECT_EQ(OkStatus(), entry.VerifyChecksumInFlash());
    EXPECT_EQ(kFormatWithSum.magic, entry.magic());
    EXPECT_EQ(read_address, entry.address());
    EXPECT_EQ(kTransactionId1 + 6, entry.transaction_id());
    EXPECT_FALSE(entry.deleted());
  }
}

TEST_F(ValidEntryInFlash, DifferentFormat_UpdatedCopy_FailsWithWrongMagic) {
  ASSERT_EQ(OkStatus(), entry_.Update(kFormatWithSum, kTransactionId1 + 6));

  FlashPartition::Address new_address = entry_.size();

  StatusWithSize copy_result = entry_.Copy(new_address);
  ASSERT_EQ(OkStatus(), copy_result.status());
  ASSERT_EQ(kEntry1.size(), copy_result.size());

  Entry entry;
  ASSERT_EQ(Status::DataLoss(),
            Entry::Read(partition_, new_address, kFormats, &entry));
}

TEST_F(ValidEntryInFlash, UpdateAndCopy_WriteError) {
  flash_.InjectWriteError(FlashError::Unconditional(Status::Cancelled()));

  ASSERT_EQ(OkStatus(), entry_.Update(kNoChecksumFormat, kTransactionId1 + 1));

  auto result = entry_.Copy(kEntry1.size());
  EXPECT_EQ(Status::Cancelled(), result.status());
  EXPECT_EQ(kEntry1.size(), result.size());
}

}  // namespace
}  // namespace pw::kvs::internal
