blob: 9ce6b5fab05aa3321e3827219043e82f8796b8a7 [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/factory/factoryfs/format.h"
#include <block-client/cpp/fake-device.h>
#include <zxtest/zxtest.h>
#include "src/storage/factory/factoryfs/factoryfs.h"
#include "src/storage/factory/factoryfs/mkfs.h"
using block_client::FakeBlockDevice;
namespace factoryfs {
namespace {
zx_status_t CheckMountability(std::unique_ptr<BlockDevice> device) {
MountOptions options = {};
options.metrics = false;
std::unique_ptr<Factoryfs> factoryfs = nullptr;
return Factoryfs::Create(nullptr, std::move(device), &options, &factoryfs);
}
// Formatting filesystems should fail on devices that cannot be written.
TEST(FormatFilesystemTest, CannotFormatReadOnlyDevice) {
auto device = std::make_unique<FakeBlockDevice>(1 << 20, 512);
device->SetInfoFlags(fuchsia_hardware_block_FLAG_READONLY);
ASSERT_EQ(ZX_ERR_ACCESS_DENIED, FormatFilesystem(device.get()));
}
// Formatting filesystems should fail on devices that don't contain any blocks.
TEST(FormatFilesystemTest, CannotFormatEmptyDevice) {
auto device = std::make_unique<FakeBlockDevice>(0, 0);
ASSERT_EQ(ZX_ERR_NO_SPACE, FormatFilesystem(device.get()));
}
// Formatting filesystems should fail on devices which have a block size that
// does not cleanly divide the factoryfs block size.
TEST(FormatFilesystemTest, CannotFormatDeviceWithNonDivisorBlockSize) {
const uint64_t kBlockCount = 1 << 20;
uint64_t kBlockSize = 511;
EXPECT_NE(kFactoryfsBlockSize % kBlockSize, 0, "Expected non-divisor block size");
auto device = std::make_unique<FakeBlockDevice>(kBlockCount, kBlockSize);
ASSERT_EQ(ZX_ERR_IO_INVALID, FormatFilesystem(device.get()));
}
// Factoryfs can be formatted on devices that have "trailing device block(s)" that
// cannot be fully addressed by factoryfs blocks.
TEST(FormatFilesystemTest, FormatDeviceWithTrailingDiskBlock) {
const uint64_t kBlockCount = (1 << 20) + 1;
const uint32_t kBlockSize = 512;
auto device = std::make_unique<FakeBlockDevice>(kBlockCount, kBlockSize);
ASSERT_OK(FormatFilesystem(device.get()));
ASSERT_OK(CheckMountability(std::move(device)));
}
// Factoryfs can be formatted on devices that have block sizes up to and including
// the factoryfs block size itself.
TEST(FormatFilesystemTest, FormatDeviceWithLargestBlockSize) {
const uint64_t kBlockCount = 1 << 20;
const uint32_t kBlockSize = kFactoryfsBlockSize;
auto device = std::make_unique<FakeBlockDevice>(kBlockCount, kBlockSize);
ASSERT_OK(FormatFilesystem(device.get()));
ASSERT_OK(CheckMountability(std::move(device)));
}
// After formatting a filesystem with valid block size N, mounting on
// a device with an invalid block size should fail.
TEST(FormatFilesystemTest, CreateFactoryfsFailureOnUnalignedBlockSize) {
const uint64_t kBlockCount = 1 << 20;
const uint32_t kBlockSize = 512;
auto device = std::make_unique<FakeBlockDevice>(kBlockCount, kBlockSize);
ASSERT_OK(FormatFilesystem(device.get()));
device->SetBlockSize(kBlockSize + 1);
ASSERT_EQ(ZX_ERR_IO, CheckMountability(std::move(device)));
}
} // namespace
} // namespace factoryfs