blob: 63e72c90381a37f7076c6ea4bae44fdb04d61e93 [file] [log] [blame]
// Copyright 2018 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 "parent.h"
#include <getopt.h>
#include <unittest/unittest.h>
constexpr char kUsageMessage[] = R"""(
Basic functionality test for a nand device.
WARNING: Will write to the nand device.
Broker unit test:
./nand-test
Creates a ram-nand device and runs all the test against it.
Existing nand device:
./nand-test --device path_to_device --first-block 100 --num-blocks 10
Opens the provided nand device and uses blocks [100, 109] to perform tests.
Note that this doesn't verify all the blocks in the given range, just makes
sure no block outside of that range is modified.
Existing broker device:
./nand-test --device path_to_device --broker --first-block 100 --num-blocks 10
Opens the provided broker device and uses blocks [100, 109] to perform tests.
Note that this doesn't verify all the blocks in the given range, just makes
sure no block outside of that range is modified.
--device path_to_device
Performs tests over an existing stack.
--broker
The device to attach to is not a nand device, but a broker.
--first-block n
The fist block that can be written from an existing device.
--num-blocks n
The number of blocks that can be written, after first-block.
)""";
const fuchsia_hardware_nand_Info kDefaultNandInfo = {.page_size = 4096,
.pages_per_block = 4,
.num_blocks = 5,
.ecc_bits = 6,
.oob_size = 4,
.nand_class = fuchsia_hardware_nand_Class_TEST,
.partition_guid = {}};
// The test can operate over either a ram-nand, or a real device. The simplest
// way to control what's going on is to have a place outside the test framework
// that controls where to execute, as "creation / teardown" of the external
// device happens at the process level.
ParentDevice* g_parent_device_;
int main(int argc, char** argv) {
ParentDevice::TestConfig config = {};
config.info = kDefaultNandInfo;
while (true) {
struct option options[] = {
{"device", required_argument, nullptr, 'd'},
{"broker", no_argument, nullptr, 'b'},
{"first-block", required_argument, nullptr, 'f'},
{"num-blocks", required_argument, nullptr, 'n'},
{"help", no_argument, nullptr, 'h'},
{"list", no_argument, nullptr, 'l'},
{"case", required_argument, nullptr, 'c'},
{"test", required_argument, nullptr, 't'},
{nullptr, 0, nullptr, 0},
};
int opt_index;
int c = getopt_long(argc, argv, "d:bhlc:t:", options, &opt_index);
if (c < 0) {
break;
}
switch (c) {
case 'd':
config.path = optarg;
break;
case 'b':
config.is_broker = true;
break;
case 'f':
config.first_block = static_cast<uint32_t>(strtoul(optarg, NULL, 0));
break;
case 'n':
config.num_blocks = static_cast<uint32_t>(strtoul(optarg, NULL, 0));
break;
case 'h':
printf("%s\n", kUsageMessage);
break;
}
}
if (config.first_block && !config.num_blocks) {
printf("num-blocks required when first-block is set\n");
return -1;
}
ParentDevice parent(config);
if (!parent.IsValid()) {
printf("Unable to open the nand device\n");
return -1;
}
if (config.path && !config.first_block) {
printf("About to overwrite device. Press y to confirm.\n");
int c = getchar();
if (c != 'y') {
return -1;
}
}
g_parent_device_ = &parent;
return unittest_run_all_tests(argc, argv) ? 0 : -1;
}