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 "parent.h"
6
7 #include <getopt.h>
8
9 #include <unittest/unittest.h>
10
11 constexpr char kUsageMessage[] = R"""(
12 Basic functionality test for a nand device.
13 WARNING: Will write to the nand device.
14
15 Broker unit test:
16 ./nand-test
17
18 Creates a ram-nand device and runs all the test against it.
19
20 Existing nand device:
21 ./nand-test --device path_to_device --first-block 100 --num-blocks 10
22
23 Opens the provided nand device and uses blocks [100, 109] to perform tests.
24 Note that this doesn't verify all the blocks in the given range, just makes
25 sure no block outside of that range is modified.
26
27 Existing broker device:
28 ./nand-test --device path_to_device --broker --first-block 100 --num-blocks 10
29
30 Opens the provided broker device and uses blocks [100, 109] to perform tests.
31 Note that this doesn't verify all the blocks in the given range, just makes
32 sure no block outside of that range is modified.
33
34 --device path_to_device
35 Performs tests over an existing stack.
36
37 --broker
38 The device to attach to is not a nand device, but a broker.
39
40 --first-block n
41 The fist block that can be written from an existing device.
42
43 --num-blocks n
44 The number of blocks that can be written, after first-block.
45
46 )""";
47
48 const fuchsia_hardware_nand_Info kDefaultNandInfo = {.page_size = 4096,
49 .pages_per_block = 4,
50 .num_blocks = 5,
51 .ecc_bits = 6,
52 .oob_size = 4,
53 .nand_class = fuchsia_hardware_nand_Class_TEST,
54 .partition_guid = {}};
55
56 // The test can operate over either a ram-nand, or a real device. The simplest
57 // way to control what's going on is to have a place outside the test framework
58 // that controls where to execute, as "creation / teardown" of the external
59 // device happens at the process level.
60 ParentDevice* g_parent_device_;
61
main(int argc,char ** argv)62 int main(int argc, char** argv) {
63 ParentDevice::TestConfig config = {};
64 config.info = kDefaultNandInfo;
65
66 while (true) {
67 struct option options[] = {
68 {"device", required_argument, nullptr, 'd'},
69 {"broker", no_argument, nullptr, 'b'},
70 {"first-block", required_argument, nullptr, 'f'},
71 {"num-blocks", required_argument, nullptr, 'n'},
72 {"help", no_argument, nullptr, 'h'},
73 {"list", no_argument, nullptr, 'l'},
74 {"case", required_argument, nullptr, 'c'},
75 {"test", required_argument, nullptr, 't'},
76 {nullptr, 0, nullptr, 0},
77 };
78 int opt_index;
79 int c = getopt_long(argc, argv, "d:bhlc:t:", options, &opt_index);
80 if (c < 0) {
81 break;
82 }
83 switch (c) {
84 case 'd':
85 config.path = optarg;
86 break;
87 case 'b':
88 config.is_broker = true;
89 break;
90 case 'f':
91 config.first_block = static_cast<uint32_t>(strtoul(optarg, NULL, 0));
92 break;
93 case 'n':
94 config.num_blocks = static_cast<uint32_t>(strtoul(optarg, NULL, 0));
95 break;
96 case 'h':
97 printf("%s\n", kUsageMessage);
98 break;
99 }
100 }
101
102 if (config.first_block && !config.num_blocks) {
103 printf("num-blocks required when first-block is set\n");
104 return -1;
105 }
106
107 ParentDevice parent(config);
108 if (!parent.IsValid()) {
109 printf("Unable to open the nand device\n");
110 return -1;
111 }
112
113 if (config.path && !config.first_block) {
114 printf("About to overwrite device. Press y to confirm.\n");
115 int c = getchar();
116 if (c != 'y') {
117 return -1;
118 }
119 }
120
121 g_parent_device_ = &parent;
122
123 return unittest_run_all_tests(argc, argv) ? 0 : -1;
124 }
125