blob: d3e1ad0555821d0bc830f27009b5a6ff06725cf2 [file] [log] [blame]
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "brillo/storage_balloon.h"
#include <sys/statvfs.h>
#include <sys/vfs.h>
#include <string>
#include <unordered_map>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <gtest/gtest.h>
namespace brillo {
class FakeStorageBalloon : public StorageBalloon {
public:
FakeStorageBalloon(uint64_t remaining_size, const base::FilePath& path)
: StorageBalloon(path), remaining_size_(remaining_size) {}
std::string Getxattr(const char* name) {
return xattr_map_[std::string(name)];
}
protected:
bool Fallocate(int64_t offset, int64_t len) override {
file_size_ += len;
remaining_size_ -= len;
return true;
}
bool Ftruncate(int64_t len) override {
remaining_size_ += (file_size_ - len);
file_size_ = len;
return true;
}
bool FstatFs(struct statfs* buf) override {
buf->f_bsize = 4096;
buf->f_blocks = (remaining_size_ + file_size_) / 4096;
buf->f_bfree = remaining_size_ / 4096;
return true;
}
bool Fstat(struct stat* buf) override {
buf->st_blocks = file_size_ / 512;
return true;
}
bool Setxattr(const char* name, const std::string& value) override {
xattr_map_[std::string(name)] = value;
return true;
}
private:
uint64_t file_size_ = 0;
uint64_t remaining_size_;
std::unordered_map<std::string, std::string> xattr_map_;
};
TEST(StorageBalloon, InvalidPath) {
FakeStorageBalloon f(4096, base::FilePath("/a/b/c"));
EXPECT_EQ(f.IsValid(), false);
}
TEST(StorageBalloon, ValidPath) {
base::ScopedTempDir dir;
ASSERT_TRUE(dir.CreateUniqueTempDir());
FakeStorageBalloon f(4096, dir.GetPath());
EXPECT_EQ(f.IsValid(), true);
}
TEST(StorageBalloonTest, FullInflation) {
base::ScopedTempDir dir;
ASSERT_TRUE(dir.CreateUniqueTempDir());
FakeStorageBalloon f(100 * 4096, dir.GetPath());
EXPECT_EQ(f.IsValid(), true);
EXPECT_TRUE(f.Adjust(5 * 4096));
EXPECT_EQ(f.GetCurrentBalloonSize(), 95 * 4096);
EXPECT_TRUE(f.Adjust(4096));
EXPECT_EQ(f.GetCurrentBalloonSize(), 99 * 4096);
}
TEST(StorageBalloonTest, FullDeflation) {
base::ScopedTempDir dir;
ASSERT_TRUE(dir.CreateUniqueTempDir());
FakeStorageBalloon f(100 * 4096, dir.GetPath());
EXPECT_EQ(f.IsValid(), true);
EXPECT_TRUE(f.Adjust(5 * 4096));
EXPECT_EQ(f.GetCurrentBalloonSize(), 95 * 4096);
EXPECT_TRUE(f.Deflate());
EXPECT_EQ(f.GetCurrentBalloonSize(), 0);
}
TEST(StorageBalloonTest, Adjustment) {
base::ScopedTempDir dir;
ASSERT_TRUE(dir.CreateUniqueTempDir());
FakeStorageBalloon f(100 * 4096, dir.GetPath());
EXPECT_EQ(f.IsValid(), true);
EXPECT_TRUE(f.Adjust(1 * 4096));
EXPECT_EQ(f.GetCurrentBalloonSize(), 99 * 4096);
EXPECT_TRUE(f.Adjust(95 * 4096));
EXPECT_EQ(f.GetCurrentBalloonSize(), 5 * 4096);
}
TEST(StorageBalloonTest, DisableProvisioning) {
base::ScopedTempDir dir;
ASSERT_TRUE(dir.CreateUniqueTempDir());
FakeStorageBalloon f(100 * 4096, dir.GetPath());
EXPECT_EQ(f.IsValid(), true);
EXPECT_TRUE(f.DisableProvisioning());
EXPECT_EQ(f.Getxattr("trusted.provision"), "n");
}
} // namespace brillo