blob: cd7e09566471685ad0c52690d1f06d1bbae867a6 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <gtest/gtest.h>
#include "ftl_private.h"
#include "lib/ftl/ndm-driver.h"
namespace {
class MockDriver final : public ftl::NdmBaseDriver {
public:
MockDriver() : NdmBaseDriver(ftl::DefaultLogger()) {}
~MockDriver() final {}
void set_incomplete(bool value) { incomplete_ = value; }
void set_result(int result) { result_ = result; }
void set_empty(bool value) { empty_ = value; }
void GetNdmDriver(NDMDrvr* driver) { FillNdmDriver({}, true, driver); }
// NdmDriver interface:
const char* Init() final { return nullptr; }
const char* Attach(const ftl::Volume* ftl_volume) final { return nullptr; }
bool Detach() final { return true; }
int NandRead(uint32_t start_page, uint32_t page_count, void* page_buffer, void* oob_buffer) final;
int NandWrite(uint32_t start_page, uint32_t page_count, const void* page_buffer,
const void* oob_buffer) final;
int NandErase(uint32_t page_num) final;
int IsBadBlock(uint32_t page_num) final { return ftl::kFalse; }
bool IsEmptyPage(uint32_t page_num, const uint8_t* data, const uint8_t* spare) final;
bool IncompletePageWrite(uint8_t* spare, uint8_t* data) final { return incomplete_; }
uint32_t PageSize() final { return 4096; }
uint8_t SpareSize() final { return 16; }
private:
int result_ = ftl::kNdmOk;
bool empty_ = true;
bool incomplete_ = false;
};
int MockDriver::NandRead(uint32_t start_page, uint32_t page_count, void* page_buffer,
void* oob_buffer) {
return result_;
}
int MockDriver::NandWrite(uint32_t start_page, uint32_t page_count, const void* page_buffer,
const void* oob_buffer) {
return result_;
}
int MockDriver::NandErase(uint32_t page_num) { return result_; }
bool MockDriver::IsEmptyPage(uint32_t page_num, const uint8_t* data, const uint8_t* spare) {
return empty_;
}
TEST(NdmDriverTest, CheckPageEccError) {
MockDriver driver;
NDMDrvr ndm;
driver.GetNdmDriver(&ndm);
ASSERT_NE(nullptr, ndm.data_and_spare_check);
driver.set_result(ftl::kNdmUncorrectableEcc);
int status;
EXPECT_EQ(ftl::kNdmOk, ndm.data_and_spare_check(0, nullptr, nullptr, &status, &driver));
EXPECT_EQ(NDM_PAGE_INVALID, status);
}
TEST(NdmDriverTest, CheckPageFatalError) {
MockDriver driver;
NDMDrvr ndm;
driver.GetNdmDriver(&ndm);
ASSERT_NE(nullptr, ndm.data_and_spare_check);
driver.set_result(ftl::kNdmFatalError);
int status;
EXPECT_EQ(ftl::kNdmOk, ndm.data_and_spare_check(0, nullptr, nullptr, &status, &driver));
EXPECT_EQ(NDM_PAGE_INVALID, status);
}
TEST(NdmDriverTest, CheckPageEmpty) {
MockDriver driver;
NDMDrvr ndm;
driver.GetNdmDriver(&ndm);
ASSERT_NE(nullptr, ndm.data_and_spare_check);
int status;
EXPECT_EQ(ftl::kNdmOk, ndm.data_and_spare_check(0, nullptr, nullptr, &status, &driver));
EXPECT_EQ(NDM_PAGE_ERASED, status);
}
TEST(NdmDriverTest, CheckPageValid) {
MockDriver driver;
NDMDrvr ndm;
driver.GetNdmDriver(&ndm);
ASSERT_NE(nullptr, ndm.data_and_spare_check);
driver.set_result(ftl::kNdmUnsafeEcc);
driver.set_empty(false);
int status;
EXPECT_EQ(ftl::kNdmOk, ndm.data_and_spare_check(0, nullptr, nullptr, &status, &driver));
EXPECT_EQ(NDM_PAGE_VALID, status);
}
TEST(NdmDriverTest, CheckPageValidIncompleteWrite) {
MockDriver driver;
NDMDrvr ndm;
driver.GetNdmDriver(&ndm);
ASSERT_NE(nullptr, ndm.data_and_spare_check);
driver.set_result(ftl::kNdmUnsafeEcc);
driver.set_incomplete(true);
int status;
EXPECT_EQ(ftl::kNdmOk, ndm.data_and_spare_check(0, nullptr, nullptr, &status, &driver));
EXPECT_EQ(NDM_PAGE_INVALID, status);
}
} // namespace