blob: 84f749de05cd909c58bc51fa9f26be96b31f8cd7 [file] [log] [blame]
// Copyright 2020 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 "src/storage/extractor/bin/parse.h"
#include <fcntl.h>
#include <stdio.h>
#include <zircon/errors.h>
#include <cstdint>
#include <cstdlib>
#include <string>
#include <vector>
#include <gtest/gtest.h>
namespace extractor {
namespace {
struct TestArguments {
static constexpr uint8_t kLength = 64;
char command[kLength] = "command";
char type[kLength] = "--type";
char type_arg[kLength] = "minfs";
char disk[kLength] = "--disk";
char disk_arg[kLength] = "/tmp/extract-input.XXXXXX";
char image[kLength] = "--image";
char image_arg[kLength] = "/tmp/extract-output.XXXXXX";
char pii_dump[kLength] = "--dump-pii";
char help[kLength] = "--help";
char extra[kLength] = "--extra";
};
TestArguments setup(bool create_disk, bool create_image_file) {
TestArguments args;
if (create_image_file) {
fbl::unique_fd input_fd(mkostemp(args.image_arg, O_RDONLY | O_CREAT | O_EXCL));
EXPECT_TRUE(input_fd);
}
if (!create_disk) {
return args;
}
fbl::unique_fd output_fd(mkostemp(args.disk_arg, O_RDWR | O_CREAT | O_EXCL));
EXPECT_TRUE(output_fd);
return args;
}
TEST(Parse, NoArgument) {
auto args = setup(/*create_disk=*/false, /*create_image_file=*/false);
std::vector<char*> argv{args.command};
ASSERT_EQ(extractor::ParseCommandLineArguments(argv.size(), argv.data()).error_value(),
ZX_ERR_INVALID_ARGS);
}
TEST(Parse, AllArgument) {
auto args = setup(/*create_disk=*/true, /*create_image_file=*/true);
EXPECT_EQ(remove(args.image_arg), 0);
std::vector<char*> argv{args.command, args.type, args.type_arg, args.disk, args.disk_arg,
args.image, args.image_arg, args.pii_dump, args.help};
ASSERT_EQ(extractor::ParseCommandLineArguments(argv.size(), argv.data()).error_value(),
ZX_ERR_INVALID_ARGS);
}
TEST(Parse, MissingType) {
auto args = setup(/*create_disk=*/true, /*create_image_file=*/true);
EXPECT_EQ(remove(args.image_arg), 0);
std::vector<char*> argv{args.command, args.disk, args.disk_arg,
args.image, args.image_arg, args.pii_dump};
ASSERT_EQ(extractor::ParseCommandLineArguments(argv.size(), argv.data()).error_value(),
ZX_ERR_INVALID_ARGS);
}
TEST(Parse, InvalidType) {
auto args = setup(/*create_disk=*/true, /*create_image_file=*/true);
strncpy(args.type_arg, "blobfs", sizeof(args.type_arg));
EXPECT_EQ(remove(args.image_arg), 0);
std::vector<char*> argv{args.command, args.type, args.type_arg, args.disk,
args.disk_arg, args.image, args.image_arg, args.pii_dump};
ASSERT_EQ(extractor::ParseCommandLineArguments(argv.size(), argv.data()).error_value(),
ZX_ERR_INVALID_ARGS);
}
TEST(Parse, MissingDisk) {
auto args = setup(/*create_disk=*/true, /*create_image_file=*/true);
EXPECT_EQ(remove(args.image_arg), 0);
std::vector<char*> argv{args.command, args.type, args.type_arg,
args.image, args.image_arg, args.pii_dump};
ASSERT_EQ(extractor::ParseCommandLineArguments(argv.size(), argv.data()).error_value(),
ZX_ERR_INVALID_ARGS);
}
TEST(Parse, MissingImage) {
auto args = setup(/*create_disk=*/true, /*create_image_file=*/false);
std::vector<char*> argv{args.command, args.type, args.type_arg,
args.disk, args.disk_arg, args.pii_dump};
ASSERT_EQ(extractor::ParseCommandLineArguments(argv.size(), argv.data()).error_value(),
ZX_ERR_INVALID_ARGS);
}
TEST(Parse, DiskDoesNotExists) {
auto args = setup(/*create_disk=*/true, /*create_image_file=*/true);
EXPECT_EQ(remove(args.disk_arg), 0);
std::vector<char*> argv{args.command, args.type, args.type_arg, args.disk,
args.disk_arg, args.image, args.image_arg, args.pii_dump};
ASSERT_EQ(extractor::ParseCommandLineArguments(argv.size(), argv.data()).error_value(),
ZX_ERR_IO);
}
TEST(Parse, ImageFileAlreadyExists) {
auto args = setup(/*create_disk=*/true, /*create_image_file=*/true);
std::vector<char*> argv{args.command, args.type, args.type_arg, args.disk,
args.disk_arg, args.image, args.image_arg, args.pii_dump};
ASSERT_EQ(extractor::ParseCommandLineArguments(argv.size(), argv.data()).error_value(),
ZX_ERR_ALREADY_EXISTS);
}
TEST(Parse, FailureToCreateImageFile) {
auto args = setup(/*create_disk=*/true, /*create_image_file=*/true);
auto len = strlen(args.image_arg);
args.image_arg[len] = '/';
args.image_arg[len + 1] = '\0';
std::vector<char*> argv{args.command, args.type, args.type_arg, args.disk,
args.disk_arg, args.image, args.image_arg, args.pii_dump};
ASSERT_EQ(extractor::ParseCommandLineArguments(argv.size(), argv.data()).error_value(),
ZX_ERR_IO);
}
TEST(Parse, ExtraArgument) {
auto args = setup(/*create_disk=*/true, /*create_image_file=*/true);
EXPECT_EQ(remove(args.image_arg), 0);
std::vector<char*> argv{args.command, args.type, args.type_arg, args.disk, args.disk_arg,
args.image, args.image_arg, args.pii_dump, args.extra};
ASSERT_EQ(extractor::ParseCommandLineArguments(argv.size(), argv.data()).error_value(),
ZX_ERR_INVALID_ARGS);
}
TEST(Parse, DumpPii) {
auto args = setup(/*create_disk=*/true, /*create_image_file=*/true);
EXPECT_EQ(remove(args.image_arg), 0);
std::vector<char*> argv{args.command, args.type, args.type_arg, args.disk,
args.disk_arg, args.image, args.image_arg, args.pii_dump};
ASSERT_EQ(extractor::ParseCommandLineArguments(argv.size(), argv.data()).value().dump_pii, true);
}
TEST(Parse, DontDumpPii) {
auto args = setup(/*create_disk=*/true, /*create_image_file=*/true);
EXPECT_EQ(remove(args.image_arg), 0);
std::vector<char*> argv{args.command, args.type, args.type_arg, args.disk,
args.disk_arg, args.image, args.image_arg};
ASSERT_EQ(extractor::ParseCommandLineArguments(argv.size(), argv.data()).value().dump_pii, false);
}
} // namespace
} // namespace extractor