src/devices/nand/drivers/skip-block/test/skip-block-test.cc
// This test attempts to write 4 copies of a single block to a partition that is 4 blocks wide.
// The copies of logical block 0, live in blocks 0, 1, 2, and 3. Since there are no extra copies of
// the blocks, a write/erase failure doesn't result in a new physical block for that copy being
// written. Instead we just continue to next copy. Despite only one copy of the block being written
// successfully, the write request succeeds. We validate all failed blocks are bad blocks grown.
This test attempts to write 4 copies of a single block to a partition that is 4 blocks wide.
The copies of logical block 0, live in blocks 0, 1, 2, and 3. Since there are no extra copies of
the blocks, a write/erase failure doesn't result in a new physical block for that copy being
written. Instead we just continue to next copy. Despite only one copy of the block being written
successfully, the write request succeeds. We validate all failed blocks are bad blocks grown.
This test attempts to write 4 copies of a single block to a partition that is 4 blocks wide . The copies of logical block 0 live in blocks 0 1 2 and 3 . Since there are no extra copies of the blocks a write / erase failure doesn ' t result in a new physical block for that copy being written . Instead we just continue to next copy . Despite only one copy of the block being written successfully the write request succeeds . We validate all failed blocks are bad blocks grown .
TEST_F(SkipBlockTest, WriteMultipleCopiesOneSucceeds) {
  const uint32_t count_ = 4;
  ddk().SetMetadata(&count_, sizeof(count_));
  ddk().SetSize(kPageSize * kNumPages * 4);
  nand().set_block_count(4);
  ASSERT_OK(nand::SkipBlockDevice::Create(nullptr, parent()));
  nand().set_result(ZX_OK);
  nand().set_result(ZX_ERR_IO);
  nand().set_result(ZX_ERR_IO);
  nand().set_result(ZX_OK);
  nand().set_result(ZX_OK);
  nand().set_result(ZX_OK);
  nand().set_result(ZX_ERR_IO);
  zx::vmo vmo;
  ASSERT_NO_FATAL_FAILURES(CreatePayload(kBlockSize, &vmo));
  nand::ReadWriteOperation op = {};
  op.vmo = std::move(vmo);
  op.block = 0;
  op.block_count = 1;
  bool bad_block_grown;
  ASSERT_NO_FATAL_FAILURES(Write(std::move(op), &bad_block_grown));
  ASSERT_TRUE(bad_block_grown);
  ASSERT_EQ(bad_block().grown_bad_blocks().size(), 3);
  ASSERT_EQ(bad_block().grown_bad_blocks()[0], 0);
  ASSERT_EQ(bad_block().grown_bad_blocks()[1], 1);
  ASSERT_EQ(bad_block().grown_bad_blocks()[2], 3);
  ASSERT_EQ(nand().last_op(), NAND_OP_WRITE);
  ASSERT_NO_FATAL_FAILURES(ValidateUnwritten(0, kBlockSize * 2));
  ASSERT_NO_FATAL_FAILURES(ValidateWritten(kBlockSize * 2, kBlockSize));
  ASSERT_NO_FATAL_FAILURES(ValidateUnwritten(kBlockSize * 3, kBlockSize));
}
TEST_F ( SkipBlockTest , WriteMultipleCopiesOneSucceeds ) { const uint32_t count_ = 4 ; ddk ( ) . SetMetadata ( & count_ , sizeof ( count_ ) ) ; ddk ( ) . SetSize ( kPageSize * kNumPages * 4 ) ; nand ( ) . set_block_count ( 4 ) ; ASSERT_OK ( nand :: SkipBlockDevice :: Create ( nullptr , parent ( ) ) ) ; nand ( ) . set_result ( ZX_OK ) ; nand ( ) . set_result ( ZX_ERR_IO ) ; nand ( ) . set_result ( ZX_ERR_IO ) ; nand ( ) . set_result ( ZX_OK ) ; nand ( ) . set_result ( ZX_OK ) ; nand ( ) . set_result ( ZX_OK ) ; nand ( ) . set_result ( ZX_ERR_IO ) ; zx :: vmo vmo ; ASSERT_NO_FATAL_FAILURES ( CreatePayload ( kBlockSize , & vmo ) ) ; nand :: ReadWriteOperation op = { } ; op . vmo = std :: move ( vmo ) ; op . block = 0 ; op . block_count = 1 ; bool bad_block_grown ; ASSERT_NO_FATAL_FAILURES ( Write ( std :: move ( op ) , & bad_block_grown ) ) ; ASSERT_TRUE ( bad_block_grown ) ; ASSERT_EQ ( bad_block ( ) . grown_bad_blocks ( ) . size ( ) , 3 ) ; ASSERT_EQ ( bad_block ( ) . grown_bad_blocks ( ) [ 0 ] , 0 ) ; ASSERT_EQ ( bad_block ( ) . grown_bad_blocks ( ) [ 1 ] , 1 ) ; ASSERT_EQ ( bad_block ( ) . grown_bad_blocks ( ) [ 2 ] , 3 ) ; ASSERT_EQ ( nand ( ) . last_op ( ) , NAND_OP_WRITE ) ; ASSERT_NO_FATAL_FAILURES ( ValidateUnwritten ( 0 , kBlockSize * 2 ) ) ; ASSERT_NO_FATAL_FAILURES ( ValidateWritten ( kBlockSize * 2 , kBlockSize ) ) ; ASSERT_NO_FATAL_FAILURES ( ValidateUnwritten ( kBlockSize * 3 , kBlockSize ) ) ; }
This test attempts to write 4 copies of a single block to a partition that is 4 blocks wide.
This test attempts to write 4 copies of a single block to a partition that is 4 blocks wide .
// Erase Block 0 // Write Block 0 // Erase Block 1 // Erase Block 2 // Write Block 2 // Erase Block 3 // Write Block 3