1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "nand_operation.h"
6 
7 #include <ddktl/protocol/nand.h>
8 #include <unittest/unittest.h>
9 
10 namespace {
11 
TrivialLifetimeTest()12 bool TrivialLifetimeTest() {
13     BEGIN_TEST;
14     ftl::NandOperation operation(sizeof(nand_operation_t));
15     END_TEST;
16 }
17 
SetDataVmoTest()18 bool SetDataVmoTest() {
19     BEGIN_TEST;
20     ftl::NandOperation operation(sizeof(nand_operation_t));
21 
22     nand_operation_t* op = operation.GetOperation();
23     EXPECT_EQ(0, op->rw.data_vmo);
24 
25     ASSERT_EQ(ZX_OK, operation.SetDataVmo(55));
26 
27     EXPECT_NE(0, op->rw.data_vmo);
28     EXPECT_NE(ZX_HANDLE_INVALID, op->rw.data_vmo);
29     EXPECT_EQ(55, operation.buffer_size());
30     EXPECT_NE(nullptr, operation.buffer());
31     END_TEST;
32 }
33 
SetOobVmoTest()34 bool SetOobVmoTest() {
35     BEGIN_TEST;
36     ftl::NandOperation operation(sizeof(nand_operation_t));
37 
38     nand_operation_t* op = operation.GetOperation();
39     EXPECT_EQ(0, op->rw.oob_vmo);
40 
41     ASSERT_EQ(ZX_OK, operation.SetOobVmo(66));
42 
43     EXPECT_NE(0, op->rw.oob_vmo);
44     EXPECT_NE(ZX_HANDLE_INVALID, op->rw.oob_vmo);
45     EXPECT_EQ(66, operation.buffer_size());
46     EXPECT_NE(nullptr, operation.buffer());
47     END_TEST;
48 }
49 
50 class NandTester : public ddk::NandProtocol<NandTester> {
51   public:
NandTester()52     NandTester() : proto_({&nand_protocol_ops_, this}), doubler_(&proto_, false) {}
53 
doubler()54     ftl::OobDoubler* doubler() { return &doubler_; }
operation()55     nand_operation_t* operation() { return operation_; }
56 
set_result(zx_status_t result)57     void set_result(zx_status_t result) { result_ = result; }
58 
NandQuery(fuchsia_hardware_nand_Info * out_info,size_t * out_nand_op_size)59     void NandQuery(fuchsia_hardware_nand_Info* out_info, size_t* out_nand_op_size) {
60         *out_info = {};
61         *out_nand_op_size = 0;
62     }
63 
NandQueue(nand_operation_t * operation,nand_queue_callback callback,void * cookie)64     void NandQueue(nand_operation_t* operation, nand_queue_callback callback, void* cookie) {
65         operation_ = operation;
66         callback(cookie, result_, operation);
67     }
68 
NandGetFactoryBadBlockList(uint32_t * out_bad_blocks_list,size_t bad_blocks_count,size_t * out_bad_blocks_actual)69     zx_status_t NandGetFactoryBadBlockList(uint32_t* out_bad_blocks_list, size_t bad_blocks_count,
70                                            size_t* out_bad_blocks_actual) {
71       return ZX_OK;
72     }
73 
74   private:
75     nand_protocol_t proto_;
76     nand_operation_t* operation_;
77     ftl::OobDoubler doubler_;
78     zx_status_t result_ = ZX_OK;
79 };
80 
ExecuteSuccessTest()81 bool ExecuteSuccessTest() {
82     BEGIN_TEST;
83     ftl::NandOperation operation(sizeof(nand_operation_t));
84     nand_operation_t* op = operation.GetOperation();
85 
86     NandTester tester;
87     ASSERT_EQ(ZX_OK, operation.Execute(tester.doubler()));
88 
89     EXPECT_EQ(op, tester.operation());
90     END_TEST;
91 }
92 
ExecuteFailureTest()93 bool ExecuteFailureTest() {
94     BEGIN_TEST;
95     ftl::NandOperation operation(sizeof(nand_operation_t));
96     nand_operation_t* op = operation.GetOperation();
97 
98     NandTester tester;
99     tester.set_result(ZX_HANDLE_INVALID);
100     ASSERT_EQ(ZX_HANDLE_INVALID, operation.Execute(tester.doubler()));
101 
102     EXPECT_EQ(op, tester.operation());
103     END_TEST;
104 }
105 
106 }  // namespace
107 
108 BEGIN_TEST_CASE(NandOperationTests)
109 RUN_TEST_SMALL(TrivialLifetimeTest)
110 RUN_TEST_SMALL(SetDataVmoTest)
111 RUN_TEST_SMALL(SetOobVmoTest)
112 RUN_TEST_SMALL(ExecuteSuccessTest)
113 RUN_TEST_SMALL(ExecuteFailureTest)
114 END_TEST_CASE(NandOperationTests)
115