blob: 2165168e595a29fc1b8828e5fab6a3f640b96504 [file] [log] [blame]
// Copyright 2019 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 <fcntl.h>
#include <sys/stat.h>
#include <functional>
#include <string>
#include <vector>
#include "src/storage/fs_test/fs_test_fixture.h"
namespace minfs {
namespace {
class PowerTest : public fs_test::BaseFilesystemTest {
public:
PowerTest() : BaseFilesystemTest(fs_test::OptionsWithDescription("MinfsWithFvm")) {}
};
TEST_F(PowerTest, Basics) {
RunSimulatedPowerCutTest(
fs_test::PowerCutOptions{
.stride = 5, // Chosen so test does not run for too long.
},
[&] {
ASSERT_EQ(mkdir(GetPath("alpha").c_str(), 0755), 0);
ASSERT_EQ(mkdir(GetPath("alpha/bravo").c_str(), 0755), 0);
ASSERT_EQ(mkdir(GetPath("alpha/bravo/charlie").c_str(), 0755), 0);
ASSERT_EQ(mkdir(GetPath("alpha/bravo/charlie/delta").c_str(), 0755), 0);
ASSERT_EQ(mkdir(GetPath("alpha/bravo/charlie/delta/echo").c_str(), 0755), 0);
std::string file = GetPath("alpha/bravo/charlie/delta/echo/foxtrot");
fbl::unique_fd fd1(open(file.c_str(), O_CREAT | O_RDWR, 0666));
ASSERT_TRUE(fd1);
fbl::unique_fd fd2(open(file.c_str(), O_RDWR));
ASSERT_TRUE(fd2);
ASSERT_EQ(write(fd1.get(), "Hello, World!\n", 14), 14);
fd1.reset();
fd2.reset();
file = GetPath("file.txt");
fd1 = fbl::unique_fd(open(file.c_str(), O_CREAT | O_RDWR, 0666));
ASSERT_TRUE(fd1);
ASSERT_EQ(unlink(file.c_str()), 0);
std::string dir = GetPath("emptydir");
ASSERT_EQ(mkdir(dir.c_str(), 0755), 0);
fd1 = fbl::unique_fd(open(dir.c_str(), O_RDONLY));
ASSERT_TRUE(fd1);
ASSERT_EQ(rmdir(dir.c_str()), 0);
});
}
constexpr int kDataSize = 16 * 1024;
void* GetData() {
static void* s_data_block = nullptr;
if (!s_data_block) {
s_data_block = new char[kDataSize];
memset(s_data_block, 'y', kDataSize);
}
return s_data_block;
}
TEST_F(PowerTest, DeleteAndWrite) {
RunSimulatedPowerCutTest(
fs_test::PowerCutOptions{
.stride = 43, // Chosen so test does not run for too long.
},
[&] {
ASSERT_EQ(mkdir(GetPath("alpha").c_str(), 0755), 0);
std::vector<std::string> names = {
GetPath("alpha/bravo"), GetPath("alpha/charlie"), GetPath("alpha/delta"),
GetPath("alpha/echo"), GetPath("alpha/foxtrot"),
};
std::vector<fbl::unique_fd> files;
for (size_t i = 0; i < 10; i++) {
fbl::unique_fd file(open(names[i % names.size()].c_str(), O_CREAT | O_RDWR, 0666));
ASSERT_TRUE(file);
ASSERT_EQ(write(file.get(), GetData(), kDataSize), static_cast<ssize_t>(kDataSize));
files.push_back(std::move(file));
if (i % 2) {
// Create a directory over a file.
ASSERT_EQ(unlink(names[i % names.size()].c_str()), 0);
ASSERT_EQ(mkdir(names[i % names.size()].c_str(), 0755), 0);
}
if (i < 2) {
continue;
}
// May or may nor succeed.
write(files[i - 1].get(), GetData(), kDataSize);
files[i - 2].reset();
unlink(names[(i - 2) % names.size()].c_str());
}
});
}
TEST_F(PowerTest, LargeWrite) {
RunSimulatedPowerCutTest(fs_test::PowerCutOptions({
.stride = 92771, // Chosen so test does not run for too long.
}),
[&] {
std::string name = GetPath("the name");
for (int n = 0; n < 10; n++) {
fbl::unique_fd file(open(name.c_str(), O_CREAT | O_RDWR, 0666));
ASSERT_TRUE(file);
const int kBufferSize = 1024 * 1024 * 4;
std::vector<char> buffer(kBufferSize, 'p');
ASSERT_EQ(write(file.get(), buffer.data(), kBufferSize),
static_cast<ssize_t>(kBufferSize));
ASSERT_EQ(unlink(name.c_str()), 0);
}
});
}
} // namespace
} // namespace minfs