blob: aab2db3488fa85b1cc6ce32c96ab5513379b4cfd [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 <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <gtest/gtest.h>
#include "src/storage/lib/block_client/cpp/fake_block_device.h"
#include "src/storage/minfs/format.h"
#include "src/storage/minfs/runner.h"
namespace minfs {
namespace {
using ::block_client::FakeBlockDevice;
constexpr uint64_t kBlockCount = 1 << 15;
constexpr uint32_t kBlockSize = 512;
TEST(MountTest, OldestRevisionUpdatedOnMount) {
async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
auto device = std::make_unique<FakeBlockDevice>(kBlockCount, kBlockSize);
auto bcache_or = Bcache::Create(std::move(device), kBlockCount);
ASSERT_TRUE(bcache_or.is_ok());
ASSERT_TRUE(Mkfs(bcache_or.value().get()).is_ok());
auto superblock_or = LoadSuperblock(bcache_or.value().get());
ASSERT_TRUE(superblock_or.is_ok());
ASSERT_EQ(kMinfsCurrentMinorVersion, superblock_or->oldest_minor_version);
superblock_or->oldest_minor_version = kMinfsCurrentMinorVersion + 1;
UpdateChecksum(&superblock_or.value());
ASSERT_TRUE(bcache_or->Writeblk(kSuperblockStart, &superblock_or.value()).is_ok());
superblock_or = LoadSuperblock(bcache_or.value().get());
ASSERT_TRUE(superblock_or.is_ok());
ASSERT_EQ(kMinfsCurrentMinorVersion + 1, superblock_or->oldest_minor_version);
MountOptions options = {};
auto fs_or = Runner::Create(loop.dispatcher(), std::move(bcache_or.value()), options);
ASSERT_TRUE(fs_or.is_ok());
bcache_or = zx::ok(Runner::Destroy(std::move(fs_or.value())));
superblock_or = LoadSuperblock(bcache_or.value().get());
ASSERT_TRUE(superblock_or.is_ok());
ASSERT_EQ(kMinfsCurrentMinorVersion, superblock_or->oldest_minor_version);
}
TEST(MountTest, ReadsExceptForSuperBlockFail) {
auto device = std::make_unique<FakeBlockDevice>(kBlockCount, kBlockSize);
auto* device_ptr = device.get();
auto bcache_or = Bcache::Create(std::move(device), kBlockCount);
ASSERT_TRUE(bcache_or.is_ok());
ASSERT_TRUE(Mkfs(bcache_or.value().get()).is_ok());
// Fail request for block 8 which should be the first block of the inode bitmap.
device_ptr->set_hook([](const block_fifo_request_t& request, const zx::vmo*) {
return request.dev_offset == 8 * kMinfsBlockSize / kBlockSize ? ZX_ERR_IO : ZX_OK;
});
async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
auto fs_or = Runner::Create(loop.dispatcher(), std::move(bcache_or.value()), {});
EXPECT_EQ(fs_or.status_value(), ZX_ERR_IO);
}
} // namespace
} // namespace minfs