blob: fcf740cf77cc94d97d2574e287dd3b1e9f6f6b4b [file] [log] [blame]
// Copyright 2018 The Chromium OS 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 "cryptohome/arc_disk_quota.h"
#include "cryptohome/mock_homedirs.h"
#include "cryptohome/mock_platform.h"
#include <memory>
#include <string>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <sys/quota.h>
#include <sys/types.h>
using ::testing::_;
using ::testing::DoAll;
using ::testing::Ne;
using ::testing::Return;
using ::testing::SetArgPointee;
using ::testing::SetArrayArgument;
namespace cryptohome {
namespace {
constexpr char kDev[] = "/dev/mmcblk0p1";
} // namespace
class ArcDiskQuotaTest : public ::testing::Test {
public:
ArcDiskQuotaTest()
: arc_disk_quota_(&homedirs_, &platform_, base::FilePath(kArcDiskHome)) {}
~ArcDiskQuotaTest() override {}
protected:
MockHomeDirs homedirs_;
MockPlatform platform_;
ArcDiskQuota arc_disk_quota_;
static const uid_t kAndroidUidStart = ArcDiskQuota::kAndroidUidStart;
static const uid_t kAndroidUidEnd = ArcDiskQuota::kAndroidUidEnd;
static const gid_t kAndroidGidStart = ArcDiskQuota::kAndroidGidStart;
static const gid_t kAndroidGidEnd = ArcDiskQuota::kAndroidGidEnd;
static const uid_t kValidAndroidUid = (kAndroidUidStart + kAndroidUidEnd) / 2;
static const gid_t kValidAndroidGid = (kAndroidGidStart + kAndroidGidEnd) / 2;
DISALLOW_COPY_AND_ASSIGN(ArcDiskQuotaTest);
};
TEST_F(ArcDiskQuotaTest, QuotaIsSupported) {
EXPECT_CALL(platform_, FindFilesystemDevice(base::FilePath(kArcDiskHome), _))
.WillOnce(DoAll(SetArgPointee<1>(kDev), Return(true)));
EXPECT_CALL(platform_, GetQuotaCurrentSpaceForUid(base::FilePath(kDev), 0))
.WillOnce(Return(0));
// Exactly 1 Android user.
EXPECT_CALL(homedirs_, GetUnmountedAndroidDataCount()).WillOnce(Return(0));
arc_disk_quota_.Initialize();
EXPECT_EQ(true, arc_disk_quota_.IsQuotaSupported());
}
TEST_F(ArcDiskQuotaTest, QuotaIsNotSupported_NoDevice) {
EXPECT_CALL(platform_, FindFilesystemDevice(base::FilePath(kArcDiskHome), _))
.WillOnce(DoAll(SetArgPointee<1>(""), Return(false)));
arc_disk_quota_.Initialize();
EXPECT_EQ(false, arc_disk_quota_.IsQuotaSupported());
}
TEST_F(ArcDiskQuotaTest, QuotaIsNotSupported_NoQuotaMountedDevice) {
EXPECT_CALL(platform_, FindFilesystemDevice(base::FilePath(kArcDiskHome), _))
.WillOnce(DoAll(SetArgPointee<1>(kDev), Return(true)));
EXPECT_CALL(platform_, GetQuotaCurrentSpaceForUid(base::FilePath(kDev), 0))
.WillOnce(Return(-1));
arc_disk_quota_.Initialize();
EXPECT_EQ(false, arc_disk_quota_.IsQuotaSupported());
}
TEST_F(ArcDiskQuotaTest, QuotaIsNotSupported_MultipleAndroidUser) {
EXPECT_CALL(platform_, FindFilesystemDevice(base::FilePath(kArcDiskHome), _))
.WillOnce(DoAll(SetArgPointee<1>(kDev), Return(true)));
EXPECT_CALL(platform_, GetQuotaCurrentSpaceForUid(base::FilePath(kDev), 0))
.WillOnce(Return(0));
// Multiple Android users.
EXPECT_CALL(homedirs_, GetUnmountedAndroidDataCount()).WillOnce(Return(2));
arc_disk_quota_.Initialize();
EXPECT_EQ(false, arc_disk_quota_.IsQuotaSupported());
}
TEST_F(ArcDiskQuotaTest, GetCurrentSpaceForUid_Succeeds) {
EXPECT_CALL(platform_, FindFilesystemDevice(base::FilePath(kArcDiskHome), _))
.WillOnce(DoAll(SetArgPointee<1>(kDev), Return(true)));
EXPECT_CALL(platform_, GetQuotaCurrentSpaceForUid(base::FilePath(kDev), 0))
.WillOnce(Return(0));
EXPECT_CALL(platform_, GetQuotaCurrentSpaceForUid(
base::FilePath(kDev),
kValidAndroidUid + kArcContainerShiftUid))
.WillOnce(Return(5));
arc_disk_quota_.Initialize();
EXPECT_EQ(5, arc_disk_quota_.GetCurrentSpaceForUid(kValidAndroidUid));
}
TEST_F(ArcDiskQuotaTest, GetCurrentSpaceForUid_UidTooSmall) {
EXPECT_CALL(platform_, FindFilesystemDevice(base::FilePath(kArcDiskHome), _))
.WillOnce(DoAll(SetArgPointee<1>(kDev), Return(true)));
EXPECT_CALL(platform_, GetQuotaCurrentSpaceForUid(base::FilePath(kDev), 0))
.WillOnce(Return(0));
arc_disk_quota_.Initialize();
EXPECT_EQ(-1, arc_disk_quota_.GetCurrentSpaceForUid(kAndroidUidStart - 1));
}
TEST_F(ArcDiskQuotaTest, GetCurrentSpaceForUid_UidTooLarge) {
EXPECT_CALL(platform_, FindFilesystemDevice(base::FilePath(kArcDiskHome), _))
.WillOnce(DoAll(SetArgPointee<1>(kDev), Return(true)));
EXPECT_CALL(platform_, GetQuotaCurrentSpaceForUid(base::FilePath(kDev), 0))
.WillOnce(Return(0));
arc_disk_quota_.Initialize();
EXPECT_EQ(-1, arc_disk_quota_.GetCurrentSpaceForUid(kAndroidUidEnd + 1));
}
TEST_F(ArcDiskQuotaTest, GetCurrentSpaceForUid_NoDevice) {
EXPECT_CALL(platform_, FindFilesystemDevice(base::FilePath(kArcDiskHome), _))
.WillOnce(DoAll(SetArgPointee<1>(""), Return(false)));
EXPECT_CALL(platform_, GetQuotaCurrentSpaceForUid(_, _)).Times(0);
arc_disk_quota_.Initialize();
EXPECT_EQ(-1, arc_disk_quota_.GetCurrentSpaceForUid(kValidAndroidUid));
}
TEST_F(ArcDiskQuotaTest, GetCurrentSpaceForUid_NoQuotaMountedDevice) {
EXPECT_CALL(platform_, FindFilesystemDevice(base::FilePath(kArcDiskHome), _))
.WillOnce(DoAll(SetArgPointee<1>(kDev), Return(true)));
EXPECT_CALL(platform_, GetQuotaCurrentSpaceForUid(base::FilePath(kDev), 0))
.WillOnce(Return(-1));
EXPECT_CALL(platform_,
GetQuotaCurrentSpaceForUid(Ne(base::FilePath(kDev)), Ne(0)))
.Times(0);
arc_disk_quota_.Initialize();
EXPECT_EQ(-1, arc_disk_quota_.GetCurrentSpaceForUid(kValidAndroidUid));
}
TEST_F(ArcDiskQuotaTest, GetCurrentSpaceForUid_QuotactlFails) {
EXPECT_CALL(platform_, FindFilesystemDevice(base::FilePath(kArcDiskHome), _))
.WillOnce(DoAll(SetArgPointee<1>(kDev), Return(true)));
EXPECT_CALL(platform_, GetQuotaCurrentSpaceForUid(base::FilePath(kDev), 0))
.WillOnce(Return(0));
EXPECT_CALL(platform_, GetQuotaCurrentSpaceForUid(
base::FilePath(kDev),
kValidAndroidUid + kArcContainerShiftUid))
.WillOnce(Return(-1));
arc_disk_quota_.Initialize();
EXPECT_EQ(-1, arc_disk_quota_.GetCurrentSpaceForUid(kValidAndroidUid));
}
TEST_F(ArcDiskQuotaTest, GetCurrentSpaceForGid_Succeeds) {
EXPECT_CALL(platform_, FindFilesystemDevice(base::FilePath(kArcDiskHome), _))
.WillOnce(DoAll(SetArgPointee<1>(kDev), Return(true)));
EXPECT_CALL(platform_, GetQuotaCurrentSpaceForUid(base::FilePath(kDev), 0))
.WillOnce(Return(0));
EXPECT_CALL(platform_, GetQuotaCurrentSpaceForGid(
base::FilePath(kDev),
kValidAndroidGid + kArcContainerShiftGid))
.WillOnce(Return(5));
arc_disk_quota_.Initialize();
EXPECT_EQ(5, arc_disk_quota_.GetCurrentSpaceForGid(kValidAndroidGid));
}
TEST_F(ArcDiskQuotaTest, GetCurrentSpaceForGid_GidTooSmall) {
EXPECT_CALL(platform_, FindFilesystemDevice(base::FilePath(kArcDiskHome), _))
.WillOnce(DoAll(SetArgPointee<1>(kDev), Return(true)));
EXPECT_CALL(platform_, GetQuotaCurrentSpaceForUid(base::FilePath(kDev), 0))
.WillOnce(Return(0));
arc_disk_quota_.Initialize();
EXPECT_EQ(-1, arc_disk_quota_.GetCurrentSpaceForGid(kAndroidGidStart - 1));
}
TEST_F(ArcDiskQuotaTest, GetCurrentSpaceForGid_GidTooLarge) {
EXPECT_CALL(platform_, FindFilesystemDevice(base::FilePath(kArcDiskHome), _))
.WillOnce(DoAll(SetArgPointee<1>(kDev), Return(true)));
EXPECT_CALL(platform_, GetQuotaCurrentSpaceForUid(base::FilePath(kDev), 0))
.WillOnce(Return(0));
arc_disk_quota_.Initialize();
EXPECT_EQ(-1, arc_disk_quota_.GetCurrentSpaceForGid(kAndroidGidEnd + 1));
}
TEST_F(ArcDiskQuotaTest, GetCurrentSpaceForGid_NoDevice) {
EXPECT_CALL(platform_, FindFilesystemDevice(base::FilePath(kArcDiskHome), _))
.WillOnce(DoAll(SetArgPointee<1>(""), Return(false)));
EXPECT_CALL(platform_, GetQuotaCurrentSpaceForGid(_, _)).Times(0);
arc_disk_quota_.Initialize();
EXPECT_EQ(-1, arc_disk_quota_.GetCurrentSpaceForGid(kValidAndroidGid));
}
TEST_F(ArcDiskQuotaTest, GetCurrentSpaceForGid_NoQuotaMountedDevice) {
EXPECT_CALL(platform_, FindFilesystemDevice(base::FilePath(kArcDiskHome), _))
.WillOnce(DoAll(SetArgPointee<1>(kDev), Return(true)));
EXPECT_CALL(platform_, GetQuotaCurrentSpaceForUid(base::FilePath(kDev), 0))
.WillOnce(Return(-1));
EXPECT_CALL(platform_,
GetQuotaCurrentSpaceForUid(Ne(base::FilePath(kDev)), Ne(0)))
.Times(0);
arc_disk_quota_.Initialize();
EXPECT_EQ(-1, arc_disk_quota_.GetCurrentSpaceForGid(kValidAndroidGid));
}
TEST_F(ArcDiskQuotaTest, GetCurrentSpaceForGid_QuotactlFails) {
EXPECT_CALL(platform_, FindFilesystemDevice(base::FilePath(kArcDiskHome), _))
.WillOnce(DoAll(SetArgPointee<1>(kDev), Return(true)));
EXPECT_CALL(platform_, GetQuotaCurrentSpaceForUid(base::FilePath(kDev), 0))
.WillOnce(Return(0));
EXPECT_CALL(platform_, GetQuotaCurrentSpaceForGid(
base::FilePath(kDev),
kValidAndroidGid + kArcContainerShiftGid))
.WillOnce(Return(-1));
arc_disk_quota_.Initialize();
EXPECT_EQ(-1, arc_disk_quota_.GetCurrentSpaceForGid(kValidAndroidGid));
}
} // namespace cryptohome