// Copyright (c) 2012 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/homedirs.h"

#include <memory>
#include <vector>

#include <base/files/file_path.h>
#include <base/files/scoped_temp_dir.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/stringprintf.h>
#include <brillo/cryptohome.h>
#include <brillo/data_encoding.h>
#include <brillo/secure_blob.h>
#include <chromeos/constants/cryptohome.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <policy/mock_device_policy.h>

#include "cryptohome/cryptolib.h"
#include "cryptohome/make_tests.h"
#include "cryptohome/mock_crypto.h"
#include "cryptohome/mock_platform.h"
#include "cryptohome/mock_tpm.h"
#include "cryptohome/mock_user_oldest_activity_timestamp_cache.h"
#include "cryptohome/mock_vault_keyset.h"
#include "cryptohome/mock_vault_keyset_factory.h"
#include "cryptohome/mount.h"
#include "cryptohome/username_passkey.h"

#include "signed_secret.pb.h"  // NOLINT(build/include)

using base::FilePath;
using base::StringPrintf;
using brillo::SecureBlob;
using ::testing::DoAll;
using ::testing::EndsWith;
using ::testing::HasSubstr;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::InvokeWithoutArgs;
using ::testing::MatchesRegex;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::ReturnRef;
using ::testing::SetArgPointee;
using ::testing::SetArrayArgument;
using ::testing::StartsWith;
using ::testing::StrEq;
using ::testing::_;

namespace cryptohome {

extern const char kKeyFile[];
extern const int kKeyFileMax;
extern const char kKeyLegacyPrefix[];

ACTION_P2(SetOwner, owner_known, owner) {
  if (owner_known)
    *arg0 = owner;
  return owner_known;
}

ACTION_P(SetEphemeralUsersEnabled, ephemeral_users_enabled) {
  *arg0 = ephemeral_users_enabled;
  return true;
}

ACTION_P(SetCleanUpStrategy, clean_up_strategy) {
  if (!clean_up_strategy.empty()) {
    *arg0 = clean_up_strategy;
    return true;
  }
  return false;
}

namespace {
const FilePath kTestRoot("alt_test_home_dir");

struct homedir {
  const char *name;
  base::Time::Exploded time;
};

const char *kOwner = "<<OWNER>>";
// Note, the order is important. These should be oldest to newest.
const struct homedir kHomedirs[] = {
  { "d5510a8dda6d743c46dadd979a61ae5603529742", { 2011, 1, 6, 1 } },
  { "8f995cdee8f0711fd32e1cf6246424002c483d47", { 2011, 2, 2, 1 } },
  { "973b9640e86f6073c6b6e2759ff3cf3084515e61", { 2011, 3, 2, 1 } },
  { kOwner, { 2011, 4, 5, 1 } }
};

NiceMock<MockFileEnumerator>* CreateMockFileEnumerator() {
  return new NiceMock<MockFileEnumerator>;
}

FileEnumerator::FileInfo CreateFileInfo(const FilePath& path, ino_t inode) {
  struct stat file_stat;
  file_stat.st_ino = inode;
  return FileEnumerator::FileInfo(path, file_stat);
}
}  // namespace

class HomeDirsTest
    : public ::testing::TestWithParam<bool /* should_test_ecryptfs */> {
 public:
  HomeDirsTest() : crypto_(&platform_) { }
  virtual ~HomeDirsTest() { }

  void SetUp() {
    test_helper_.SetUpSystemSalt();
    // TODO(wad) Only generate the user data we need. This is time consuming.
    test_helper_.InitTestData(kTestRoot, kDefaultUsers, kDefaultUserCount,
                              ShouldTestEcryptfs());
    homedirs_.set_shadow_root(kTestRoot);
    test_helper_.InjectSystemSalt(&platform_, kTestRoot.Append("salt"));
    set_policy(true, kOwner, false, "");

    homedirs_.Init(&platform_, &crypto_, &timestamp_cache_);
    FilePath fp = FilePath(kTestRoot);
    for (const auto& hd : kHomedirs) {
      FilePath path = fp.Append(hd.name);
      std::string user;
      if (hd.name == std::string(kOwner))
        homedirs_.GetOwner(&user);
      else
        user = hd.name;
      homedir_paths_.push_back(fp.Append(user));
      user_paths_.push_back(brillo::cryptohome::home::GetHashedUserPath(user));
      base::Time t;
      CHECK(base::Time::FromUTCExploded(hd.time, &t));
      homedir_times_.push_back(t);
    }
    EXPECT_CALL(platform_, HasExtendedFileAttribute(_, kRemovableFileAttribute))
        .WillRepeatedly(Return(false));
  }

  void TearDown() {
    test_helper_.TearDownSystemSalt();
  }

  void set_policy(bool owner_known,
                  const std::string& owner,
                  bool ephemeral_users_enabled,
                  const std::string& clean_up_strategy) {
    policy::MockDevicePolicy* device_policy = new policy::MockDevicePolicy();
    EXPECT_CALL(*device_policy, LoadPolicy())
        .WillRepeatedly(Return(true));
    EXPECT_CALL(*device_policy, GetOwner(_))
        .WillRepeatedly(SetOwner(owner_known, owner));
    EXPECT_CALL(*device_policy, GetEphemeralUsersEnabled(_))
        .WillRepeatedly(SetEphemeralUsersEnabled(ephemeral_users_enabled));
    homedirs_.own_policy_provider(new policy::PolicyProvider(
        std::unique_ptr<policy::MockDevicePolicy>(device_policy)));
  }

  // Create an enumerator that will enumerate the given child_directories.
  NiceMock<MockFileEnumerator>* CreateFileEnumerator(
      const std::vector<FilePath>& child_directories) {
    auto* mock = new NiceMock<MockFileEnumerator>;
    for (const auto& child : child_directories) {
      struct stat stat = {};
      mock->entries_.push_back(FileEnumerator::FileInfo(child, stat));
    }
    return mock;
  }

  // Sets up expectations for the given tracked directories which belong to the
  // same parent directory.
  void ExpectTrackedDirectoryEnumeration(
      const std::vector<FilePath>& child_directories) {
    DCHECK(!child_directories.empty());
    FilePath parent_directory = child_directories[0].DirName();
    // xattr is used to track directories.
    for (const auto& child : child_directories) {
      DCHECK_EQ(parent_directory.value(), child.DirName().value());
      EXPECT_CALL(platform_, GetExtendedFileAttributeAsString(
          child, kTrackedDirectoryNameAttribute, _))
          .WillRepeatedly(DoAll(SetArgPointee<2>(child.BaseName().value()),
                                Return(true)));
      EXPECT_CALL(platform_, HasExtendedFileAttribute(
          child, kTrackedDirectoryNameAttribute))
          .WillRepeatedly(Return(true));
    }
    // |child_directories| should be enumerated as the parent's children.
    auto create_file_enumerator_function = [child_directories]() {
      auto* mock = new NiceMock<MockFileEnumerator>;
      for (const auto& child : child_directories) {
        struct stat stat = {};
        mock->entries_.push_back(FileEnumerator::FileInfo(child, stat));
      }
      return mock;
    };
    EXPECT_CALL(platform_, GetFileEnumerator(
        parent_directory, false, base::FileEnumerator::DIRECTORIES))
        .WillRepeatedly(InvokeWithoutArgs(create_file_enumerator_function));
  }

  // Returns true if the test is running for eCryptfs, false if for dircrypto.
  bool ShouldTestEcryptfs() const { return GetParam(); }

 protected:
  MakeTests test_helper_;
  NiceMock<MockPlatform> platform_;
  Crypto crypto_;
  std::vector<FilePath> homedir_paths_;
  std::vector<FilePath> user_paths_;
  MockUserOldestActivityTimestampCache timestamp_cache_;
  std::vector<base::Time> homedir_times_;
  MockVaultKeysetFactory vault_keyset_factory_;
  HomeDirs homedirs_;

  static const uid_t kAndroidSystemRealUid =
      HomeDirs::kAndroidSystemUid + kArcContainerShiftUid;

 private:
  DISALLOW_COPY_AND_ASSIGN(HomeDirsTest);
};

INSTANTIATE_TEST_CASE_P(WithEcryptfs, HomeDirsTest, ::testing::Values(true));
INSTANTIATE_TEST_CASE_P(WithDircrypto, HomeDirsTest, ::testing::Values(false));

TEST_P(HomeDirsTest, RemoveNonOwnerCryptohomes) {
  // Ensure that RemoveNonOwnerCryptohomes does.
  EXPECT_CALL(platform_, EnumerateDirectoryEntries(kTestRoot, false, _))
    .WillOnce(
        DoAll(SetArgPointee<2>(homedir_paths_),
              Return(true)));
  FilePath user_prefix = brillo::cryptohome::home::GetUserPathPrefix();
  FilePath root_prefix = brillo::cryptohome::home::GetRootPathPrefix();
  EXPECT_CALL(platform_, EnumerateDirectoryEntries(user_prefix, _, _))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_, EnumerateDirectoryEntries(root_prefix, _, _))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(Property(&FilePath::value,
                                                  EndsWith(kEcryptfsVaultDir))))
      .WillRepeatedly(Return(ShouldTestEcryptfs()));
  EXPECT_CALL(platform_, IsDirectoryMounted(_))
    .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[0], true))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[1], true))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[2], true))
    .WillOnce(Return(true));

  homedirs_.RemoveNonOwnerCryptohomes();
}

TEST_P(HomeDirsTest, RenameCryptohome) {
  ASSERT_TRUE(
      base::CreateDirectory(FilePath(test_helper_.users[0].base_path)));
  ASSERT_TRUE(
      base::CreateDirectory(FilePath(test_helper_.users[1].base_path)));
  ASSERT_TRUE(
      base::CreateDirectory(FilePath(test_helper_.users[2].base_path)));

  const char kNewUserId[] = "some_new_user";
  EXPECT_TRUE(homedirs_.Rename(kDefaultUsers[0].username, kNewUserId));

  // If source directory doesn't exist, assume renamed.
  EXPECT_TRUE(homedirs_.Rename(kDefaultUsers[0].username, kNewUserId));

  // This should fail as target directory already exists.
  EXPECT_FALSE(
      homedirs_.Rename(kDefaultUsers[1].username, kDefaultUsers[2].username));

  // Rename back.
  EXPECT_TRUE(homedirs_.Rename(kNewUserId, kDefaultUsers[0].username));
}

TEST_P(HomeDirsTest, ComputeSize) {
  FilePath base_path(test_helper_.users[0].base_path);
  FilePath user_path = brillo::cryptohome::home::GetUserPathPrefix()
      .Append(test_helper_.users[0].obfuscated_username);
  FilePath root_path = brillo::cryptohome::home::GetRootPathPrefix()
      .Append(test_helper_.users[0].obfuscated_username);

  ASSERT_TRUE(base::CreateDirectory(base_path));

  // Put test files under base_path and user_path.
  const char kTestFileName0[] = "test.txt";
  const char kExpectedData0[] = "file content";
  int expected_bytes_0 = arraysize(kExpectedData0);
  ASSERT_EQ(expected_bytes_0,
            base::WriteFile(base_path.Append(kTestFileName0),
                            kExpectedData0, expected_bytes_0));
  const char kTestFileName1[] = "test1.txt";
  const char kExpectedData1[] = "file content";
  int expected_bytes_1 = arraysize(kExpectedData1);
  ASSERT_EQ(expected_bytes_1,
            base::WriteFile(base_path.Append(kTestFileName1),
                            kExpectedData1, expected_bytes_1));

  EXPECT_CALL(platform_, ComputeDirectorySize(base_path))
    .WillOnce(Return(expected_bytes_0));
  EXPECT_CALL(platform_, ComputeDirectorySize(user_path))
    .WillOnce(Return(expected_bytes_1));
  EXPECT_CALL(platform_, ComputeDirectorySize(root_path))
    .WillOnce(Return(0));

  EXPECT_EQ(expected_bytes_0 + expected_bytes_1,
            homedirs_.ComputeSize(kDefaultUsers[0].username));
}

TEST_P(HomeDirsTest, ComputeSizeWithNonexistentUser) {
  // If the specified user doesn't exist, there is no directory for the user, so
  // ComputeSize should return 0.
  const char kNonExistentUserId[] = "non_existent_user";
  EXPECT_EQ(0, homedirs_.ComputeSize(kNonExistentUserId));
}

TEST_P(HomeDirsTest, GetTrackedDirectoryForDirCrypto) {
  Platform real_platform;
  // Use real PathExists.
  EXPECT_CALL(platform_, FileExists(_)).WillRepeatedly(
      Invoke(&real_platform, &Platform::FileExists));
  // Use real FileEnumerator.
  EXPECT_CALL(platform_, GetFileEnumerator(_, _, _)).WillRepeatedly(
      Invoke(&real_platform, &Platform::GetFileEnumerator));
  // Use real HasExtendedFileAttribute.
  EXPECT_CALL(platform_, HasExtendedFileAttribute(_, _))
      .WillRepeatedly(Invoke(&real_platform,
                             &Platform::HasExtendedFileAttribute));
  // Use real GetExtendedFileAttributeAsString.
  EXPECT_CALL(platform_, GetExtendedFileAttributeAsString(_, _, _))
      .WillRepeatedly(Invoke(&real_platform,
                             &Platform::GetExtendedFileAttributeAsString));

  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  const FilePath mount_dir = temp_dir.GetPath().Append(FilePath(kMountDir));
  ASSERT_TRUE(base::CreateDirectory(mount_dir));

  const char* const kDirectories[] = {
    "aaa",
    "bbb",
    "bbb/ccc",
    "bbb/ccc/ddd",
  };
  // Prepare directories.
  for (const auto& directory : kDirectories) {
    const FilePath path = mount_dir.Append(FilePath(directory));
    ASSERT_TRUE(base::CreateDirectory(path));
    std::string name = path.BaseName().value();
    ASSERT_TRUE(real_platform.SetExtendedFileAttribute(
        path, kTrackedDirectoryNameAttribute, name.data(), name.length()));
  }

  // Use GetTrackedDirectoryForDirCrypto() to get the path.
  // When dircrypto is being used and we don't have the key, the returned path
  // will be encrypted, but here we just get the same path.
  for (const auto& directory : kDirectories) {
    SCOPED_TRACE(directory);
    FilePath result;
    EXPECT_TRUE(homedirs_.GetTrackedDirectory(temp_dir.GetPath(),
                                              FilePath(directory), &result));
    EXPECT_EQ(mount_dir.Append(FilePath(directory)).value(), result.value());
  }
  // Return false for unknown directories.
  FilePath result;
  EXPECT_FALSE(homedirs_.GetTrackedDirectory(
      temp_dir.GetPath(), FilePath("zzz"), &result));
  EXPECT_FALSE(homedirs_.GetTrackedDirectory(
      temp_dir.GetPath(), FilePath("aaa/zzz"), &result));
}

TEST_P(HomeDirsTest, GetUnmountedAndroidDataCount) {
  EXPECT_CALL(platform_, EnumerateDirectoryEntries(kTestRoot, false, _))
      .WillOnce(DoAll(SetArgPointee<2>(homedir_paths_), Return(true)));
  if (ShouldTestEcryptfs()) {
    // We don't support Ecryptfs.
    for (int i = 0; i < homedir_paths_.size(); i++) {
      FilePath vault_path = homedir_paths_[i].Append(kEcryptfsVaultDir);
      EXPECT_CALL(platform_, DirectoryExists(vault_path))
          .WillOnce(Return(true));
    }
    EXPECT_EQ(0, homedirs_.GetUnmountedAndroidDataCount());
    return;
  }

  // Basic setup.
  for (size_t i = 0; i < homedir_paths_.size(); i++) {
    // Set up tracked root directory under DirCrypto's home.
    FilePath vault_path = homedir_paths_[i].Append(kEcryptfsVaultDir);
    EXPECT_CALL(platform_, DirectoryExists(vault_path))
        .WillRepeatedly(Return(false));
    FilePath mount = homedir_paths_[i].Append(kMountDir);
    FilePath root = mount.Append(kRootHomeSuffix);

    ExpectTrackedDirectoryEnumeration({root});
  }

  // Set up a root hierarchy for the encrypted version of homedir_paths_[0]
  // (added a suffix _encrypted in the code to mark them encrypted).
  // root
  //     |-android-data
  //     |    |-cache
  //     |    |-data
  //     |-session_manager
  FilePath root = homedir_paths_[0].Append(kMountDir).Append(kRootHomeSuffix);
  FilePath android_data = root.Append("android-data_encrypted");
  FilePath session_manager = root.Append("session_manager_encrypted");
  EXPECT_CALL(platform_,
              GetFileEnumerator(root, false, base::FileEnumerator::DIRECTORIES))
      .WillOnce(Return(CreateFileEnumerator({android_data, session_manager})));
  FilePath data = android_data.Append("data_encrypted");
  FilePath cache = android_data.Append("cache_encrypted");
  EXPECT_CALL(platform_, GetFileEnumerator(android_data, false,
                                           base::FileEnumerator::DIRECTORIES))
      .WillOnce(Return(CreateFileEnumerator({cache, data})));

  // This marks dir2 directory under homedir_paths_[0] as android-data by
  // assigning System UID as the uid owner of dir4 (dir2's children).
  EXPECT_CALL(platform_, GetOwnership(cache, _, _, false))
      .WillOnce(DoAll(SetArgPointee<1>(kAndroidSystemRealUid), Return(true)));

  // Other homedir_paths_ shouldn't have android-data.
  for (size_t i = 1; i < homedir_paths_.size(); i++) {
    // Set up a root hierarchy for the encrypted version of homedir_paths
    // without android-data (added a suffix _encrypted in the code to mark them
    // encrypted).
    // root
    //     |-session_manager
    //          |-policy
    FilePath root = homedir_paths_[i].Append(kMountDir).Append(kRootHomeSuffix);
    FilePath session_manager = root.Append("session_manager_encrypted");
    EXPECT_CALL(platform_, GetFileEnumerator(root, false,
                                             base::FileEnumerator::DIRECTORIES))
        .WillOnce(Return(CreateFileEnumerator({session_manager})));
    FilePath policy = session_manager.Append("policy_encrypted");
    EXPECT_CALL(platform_, GetFileEnumerator(session_manager, false,
                                             base::FileEnumerator::DIRECTORIES))
        .WillOnce(Return(CreateFileEnumerator({policy})));
    EXPECT_CALL(platform_, GetOwnership(policy, _, _, false))
        .WillOnce(Return(false));
  }

  // Expect 1 home directory with android-data: homedir_paths_[0].
  EXPECT_EQ(1, homedirs_.GetUnmountedAndroidDataCount());
}

class FreeDiskSpaceTest : public HomeDirsTest {
 public:
  FreeDiskSpaceTest() { }
  virtual ~FreeDiskSpaceTest() { }

  // Sets up expectaions for tracked directories.
  void ExpectTrackedDirectoriesEnumeration() {
    if (ShouldTestEcryptfs())  // No expecations needed for eCryptfs.
      return;

    for (const auto& path : homedir_paths_) {
      FilePath mount = path.Append(kMountDir);
      FilePath user = mount.Append(kUserHomeSuffix);
      FilePath root = mount.Append(kRootHomeSuffix);
      FilePath cache = user.Append(kCacheDir);
      FilePath gcache = user.Append(kGCacheDir);
      FilePath gcache_version1 = gcache.Append(kGCacheVersion1Dir);
      FilePath gcache_version2 = gcache.Append(kGCacheVersion2Dir);
      FilePath gcache_tmp = gcache_version1.Append(kGCacheTmpDir);
      ExpectTrackedDirectoryEnumeration({user, root});
      ExpectTrackedDirectoryEnumeration({cache, gcache});
      ExpectTrackedDirectoryEnumeration({gcache_version1, gcache_version2});
      ExpectTrackedDirectoryEnumeration({gcache_tmp});
    }
  }

  // The first half of HomeDirs::FreeDiskSpace does a purge of the Cache and
  // GCached dirs.  Unless these are being explicitly tested, we want these to
  // always succeed for every test. Set those expectations here for the given
  // number of unmounted user directories (mounted dirs aren't processed by
  // the code under test).
  void ExpectCacheDirCleanupCalls(int user_count) {
    EXPECT_CALL(platform_, EnumerateDirectoryEntries(kTestRoot, false, _))
      .WillRepeatedly(
          DoAll(SetArgPointee<2>(homedir_paths_),
                Return(true)));
    EXPECT_CALL(platform_, AmountOfFreeDiskSpace(kTestRoot))
      .Times(4).WillRepeatedly(Return(0))
      .RetiresOnSaturation();
    EXPECT_CALL(platform_, DirectoryExists(_))
      .WillRepeatedly(Return(true));
    EXPECT_CALL(platform_, DirectoryExists(Property(
                               &FilePath::value, EndsWith(kEcryptfsVaultDir))))
        .WillRepeatedly(Return(ShouldTestEcryptfs()));
    // N users * (1 Cache dir + 1 GCache tmp dir)
    EXPECT_CALL(platform_, GetFileEnumerator(_, false, _))
      .Times(user_count * 2)
      .WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));
    // N users * (2 GCache files dir + 1 Android cache dir)
    EXPECT_CALL(platform_, GetFileEnumerator(_, true, _))
        .Times(user_count * 3)
        .WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));

    ExpectTrackedDirectoriesEnumeration();
  }

  // Whenever a user is removed, its shadow directory is searched for LE
  // credentials so that they can be removed from the LE backend as well.
  void ExpectDeletedLECredentialEnumeration(
      const base::FilePath& homedir_path) {
    EXPECT_CALL(platform_,
                GetFileEnumerator(homedirs_.shadow_root().Append(
                                      homedir_path.BaseName().value()),
                                  false, _))
        .WillOnce(InvokeWithoutArgs(CreateMockFileEnumerator));
  }
};

INSTANTIATE_TEST_CASE_P(WithEcryptfs, FreeDiskSpaceTest,
                        ::testing::Values(true));
INSTANTIATE_TEST_CASE_P(WithDircrypto, FreeDiskSpaceTest,
                        ::testing::Values(false));

TEST_P(FreeDiskSpaceTest, InitializeTimeCacheWithNoTime) {
  // To get to the init logic, we need to fail
  // |kTargetFreeSpaceAfterCleanup| checks.
  EXPECT_CALL(platform_, AmountOfFreeDiskSpace(kTestRoot))
      .WillRepeatedly(Return(0));

  // Expect cache clean ups.
  EXPECT_CALL(platform_, EnumerateDirectoryEntries(kTestRoot, false, _))
    .WillRepeatedly(
        DoAll(SetArgPointee<2>(homedir_paths_),
              Return(true)));
  EXPECT_CALL(platform_, DirectoryExists(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(Property(&FilePath::value,
                                                  EndsWith(kEcryptfsVaultDir))))
      .WillRepeatedly(Return(ShouldTestEcryptfs()));
  EXPECT_CALL(platform_, IsDirectoryMounted(_))
    .WillRepeatedly(Return(false));

  // The master.* enumerators (wildcard matcher first)
  EXPECT_CALL(platform_, GetFileEnumerator(_, false, _))
    .Times(4).WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));
  // Empty enumerators per-user per-cache dirs plus
  // enumerators for empty vaults.
  EXPECT_CALL(platform_, GetFileEnumerator(
        Property(&FilePath::value, HasSubstr("user/Cache")),
        false, _))
    .Times(4)
    .WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));
  EXPECT_CALL(platform_, GetFileEnumerator(
        Property(&FilePath::value, EndsWith("user/GCache/v1/tmp")),
        false, _))
    .Times(4)
    .WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));
  EXPECT_CALL(platform_, GetFileEnumerator(
        Property(&FilePath::value, EndsWith("user/GCache/v1")),
        true, _))
    .Times(4)
    .WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));
  EXPECT_CALL(platform_, GetFileEnumerator(Property(&FilePath::value,
                                                    EndsWith("user/GCache/v2")),
                                           true, _))
      .Times(4)
      .WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));
  EXPECT_CALL(
      platform_,
      GetFileEnumerator(
          Property(&FilePath::value,
                   EndsWith(std::string(ShouldTestEcryptfs() ? kEcryptfsVaultDir
                                                             : kMountDir) +
                            "/root")),
          true, _))
      .Times(4)
      .WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));

  ExpectTrackedDirectoriesEnumeration();

  // Now cover the actual initialization piece
  EXPECT_CALL(timestamp_cache_, initialized())
    .WillOnce(Return(false));
  EXPECT_CALL(timestamp_cache_, Initialize())
    .Times(1);

  // It then walks the user vault to populate.
  MockVaultKeyset* vk[arraysize(kHomedirs)];
  EXPECT_CALL(vault_keyset_factory_, New(_, _))
    .WillOnce(Return(vk[0] = new MockVaultKeyset()))
    .WillOnce(Return(vk[1] = new MockVaultKeyset()))
    .WillOnce(Return(vk[2] = new MockVaultKeyset()))
    .WillOnce(Return(vk[3] = new MockVaultKeyset()));
  for (size_t i = 0; i < arraysize(vk); ++i) {
    EXPECT_CALL(*vk[i], Load(_))
      .WillRepeatedly(Return(false));
  }
  homedirs_.set_vault_keyset_factory(&vault_keyset_factory_);

  // Expect an addition for all users with no time.
  EXPECT_CALL(timestamp_cache_, AddExistingUserNotime(_))
    .Times(4);

  // Now skip the deletion steps by not having a legit owner.
  set_policy(false, "", false, "");

  homedirs_.FreeDiskSpace();

  // Could not delete user, so it doesn't have enough space yet.
  EXPECT_FALSE(homedirs_.HasTargetFreeSpace());
}

TEST_P(FreeDiskSpaceTest, InitializeTimeCacheWithOneTime) {
  // To get to the init logic, we need to fail five
  // |kTargetFreeSpaceAfterCleanup| checks.
  EXPECT_CALL(platform_, AmountOfFreeDiskSpace(kTestRoot))
      .WillRepeatedly(Return(0));

  // Expect cache clean ups.
  EXPECT_CALL(platform_, EnumerateDirectoryEntries(kTestRoot, false, _))
    .WillRepeatedly(
        DoAll(SetArgPointee<2>(homedir_paths_),
              Return(true)));
  EXPECT_CALL(platform_, DirectoryExists(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(Property(&FilePath::value,
                                                  EndsWith(kEcryptfsVaultDir))))
      .WillRepeatedly(Return(ShouldTestEcryptfs()));
  // The master.* enumerators (wildcard matcher first)
  EXPECT_CALL(platform_, GetFileEnumerator(_, false, _))
    .Times(3).WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));
  // Empty enumerators per-user per-cache dirs plus
  // enumerators for empty vaults.
  EXPECT_CALL(platform_,
      GetFileEnumerator(
        Property(&FilePath::value, HasSubstr("user/Cache")),
        false, _))
    .Times(4).WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));
  EXPECT_CALL(platform_,
      GetFileEnumerator(
        Property(&FilePath::value, EndsWith("user/GCache/v1/tmp")),
        false, _))
    .Times(4)
    .WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));
  EXPECT_CALL(
      platform_,
      GetFileEnumerator(
          Property(&FilePath::value,
                   EndsWith(std::string(ShouldTestEcryptfs() ? kEcryptfsVaultDir
                                                             : kMountDir) +
                            "/user/GCache/v1")),
          true, _))
      .Times(4)
      .WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));
  EXPECT_CALL(
      platform_,
      GetFileEnumerator(
          Property(&FilePath::value,
                   EndsWith(std::string(ShouldTestEcryptfs() ? kEcryptfsVaultDir
                                                             : kMountDir) +
                            "/user/GCache/v2")),
          true, _))
      .Times(4)
      .WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));
  EXPECT_CALL(
      platform_,
      GetFileEnumerator(
          Property(&FilePath::value,
                   EndsWith(std::string(ShouldTestEcryptfs() ? kEcryptfsVaultDir
                                                             : kMountDir) +
                            "/root")),
          true, _))
      .Times(4)
      .WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));

  ExpectTrackedDirectoriesEnumeration();

  // Now cover the actual initialization piece
  EXPECT_CALL(timestamp_cache_, initialized())
    .WillOnce(Return(false));
  EXPECT_CALL(timestamp_cache_, Initialize())
    .Times(1);
  // Skip vault keyset loading to cause "Notime".
  EXPECT_CALL(platform_,
      FileExists(
        Property(&FilePath::value, StartsWith(homedir_paths_[0].value()))))
    .WillRepeatedly(Return(true));

  MockVaultKeyset* vk[arraysize(kHomedirs)];
  EXPECT_CALL(vault_keyset_factory_, New(_, _))
    .WillOnce(Return(vk[0] = new MockVaultKeyset()))
    .WillOnce(Return(vk[1] = new MockVaultKeyset()))
    .WillOnce(Return(vk[2] = new MockVaultKeyset()))
    .WillOnce(Return(vk[3] = new MockVaultKeyset()));
  // The first three will have no time.
  size_t i;
  for (i = 0; i < arraysize(vk) - 1; ++i) {
    EXPECT_CALL(*vk[i], Load(_))
      .WillRepeatedly(Return(false));
  }
  // Owner will have a master.0
  NiceMock<MockFileEnumerator> *master0;
  EXPECT_CALL(platform_, GetFileEnumerator(homedir_paths_[3], false, _))
    .WillOnce(Return(master0 = new NiceMock<MockFileEnumerator>));
  EXPECT_CALL(*master0, Next())
    .WillOnce(Return(homedir_paths_[3].Append(kKeyFile).AddExtension("0")))
    .WillRepeatedly(Return(FilePath()));

  // The owner will have a time.
  EXPECT_CALL(*vk[i], Load(_))
    .WillOnce(Return(true));
  SerializedVaultKeyset serialized;
  serialized.set_last_activity_timestamp(homedir_times_[3].ToInternalValue());
  EXPECT_CALL(*vk[i], serialized())
    .Times(2)
    .WillRepeatedly(ReturnRef(serialized));
  homedirs_.set_vault_keyset_factory(&vault_keyset_factory_);

  // Expect an addition for all users with no time.
  EXPECT_CALL(timestamp_cache_, AddExistingUserNotime(_))
    .Times(3);
  // Adding the owner
  EXPECT_CALL(timestamp_cache_,
              AddExistingUser(homedir_paths_[3], homedir_times_[3]))
    .Times(1);

  // Now skip the deletion steps by not having a legit owner.
  set_policy(false, "", false, "");

  homedirs_.FreeDiskSpace();

  // Could not delete user, so it doesn't have enough space yet.
  EXPECT_FALSE(homedirs_.HasTargetFreeSpace());
}

TEST_P(FreeDiskSpaceTest, NoCacheCleanup) {
  // Pretend we have lots of free space
  EXPECT_CALL(platform_, AmountOfFreeDiskSpace(kTestRoot))
      .WillRepeatedly(Return(kTargetFreeSpaceAfterCleanup + 1));

  homedirs_.FreeDiskSpace();

  EXPECT_TRUE(homedirs_.HasTargetFreeSpace());
}

TEST_P(FreeDiskSpaceTest, OnlyCacheCleanup) {
  // Only clean up the Cache data. Not GCache, etc.
  EXPECT_CALL(platform_, EnumerateDirectoryEntries(kTestRoot, false, _))
    .WillRepeatedly(
        DoAll(SetArgPointee<2>(homedir_paths_),
              Return(true)));

  EXPECT_CALL(platform_, AmountOfFreeDiskSpace(kTestRoot))
      .WillOnce(Return(0))
      .WillRepeatedly(Return(kTargetFreeSpaceAfterCleanup + 1));
  EXPECT_CALL(platform_, DirectoryExists(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(Property(&FilePath::value,
                                                  EndsWith(kEcryptfsVaultDir))))
      .WillRepeatedly(Return(ShouldTestEcryptfs()));
  // Empty enumerators per-user per-cache dirs
  NiceMock<MockFileEnumerator>* fe[arraysize(kHomedirs)];
  EXPECT_CALL(platform_, GetFileEnumerator(_, false, _))
    .WillOnce(Return(fe[0] = new NiceMock<MockFileEnumerator>))
    .WillOnce(Return(fe[1] = new NiceMock<MockFileEnumerator>))
    .WillOnce(Return(fe[2] = new NiceMock<MockFileEnumerator>))
    .WillOnce(Return(fe[3] = new NiceMock<MockFileEnumerator>));
  // Exercise the delete file path.
  for (size_t f = 0; f < arraysize(fe); ++f) {
    EXPECT_CALL(*fe[f], Next())
      .WillOnce(Return(homedir_paths_[f].Append("Cache/foo")))
      .WillRepeatedly(Return(FilePath()));
  }
  EXPECT_CALL(platform_,
      DeleteFile(
        Property(&FilePath::value, EndsWith("/Cache/foo")),
        true))
    .Times(4)
    .WillRepeatedly(Return(true));

  ExpectTrackedDirectoriesEnumeration();

  homedirs_.FreeDiskSpace();

  EXPECT_TRUE(homedirs_.HasTargetFreeSpace());
}

TEST_P(FreeDiskSpaceTest, GCacheCleanup) {
  EXPECT_CALL(platform_, EnumerateDirectoryEntries(kTestRoot, false, _))
    .WillRepeatedly(
        DoAll(SetArgPointee<2>(homedir_paths_),
              Return(true)));
  EXPECT_CALL(platform_, AmountOfFreeDiskSpace(kTestRoot))
      .WillOnce(Return(0))
      .WillOnce(Return(0))
      .WillRepeatedly(Return(kTargetFreeSpaceAfterCleanup + 1));
  EXPECT_CALL(platform_, DirectoryExists(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(Property(&FilePath::value,
                                                  EndsWith(kEcryptfsVaultDir))))
      .WillRepeatedly(Return(ShouldTestEcryptfs()));
  // Empty enumerators per-user per-cache dirs
  EXPECT_CALL(platform_,
      GetFileEnumerator(
        Property(&FilePath::value, EndsWith("/Cache")),
        false, _))
    .Times(4)
    .WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));

  EXPECT_CALL(platform_,
      GetFileEnumerator(
        Property(&FilePath::value, EndsWith("/GCache/v1/tmp")),
        false, _))
      .Times(4)
      .WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));

  // Irrelevant directory without +d file attribute.
  EXPECT_CALL(platform_, HasNoDumpFileAttribute(Property(
                             &FilePath::value, EndsWith("irrelevant_dir"))))
      .WillRepeatedly(Return(false));

  // Enumerate user 0, do nothing for users 1-3.
  NiceMock<MockFileEnumerator>* fe_v1_2 = new NiceMock<MockFileEnumerator>;
  NiceMock<MockFileEnumerator>* fe_v2_2 = new NiceMock<MockFileEnumerator>;
  // The cache directory contains removable (having +d) and unremovable files.
  EXPECT_CALL(platform_, GetFileEnumerator(
                             Property(&FilePath::value, EndsWith("GCache/v1")),
                             true, base::FileEnumerator::FILES))
      .WillOnce(Return(fe_v1_2))
      .WillOnce(InvokeWithoutArgs(CreateMockFileEnumerator))
      .WillOnce(InvokeWithoutArgs(CreateMockFileEnumerator))
      .WillOnce(InvokeWithoutArgs(CreateMockFileEnumerator));
  EXPECT_CALL(platform_, GetFileEnumerator(
                             Property(&FilePath::value, EndsWith("GCache/v2")),
                             true, base::FileEnumerator::FILES))
      .WillOnce(Return(fe_v2_2))
      .WillOnce(InvokeWithoutArgs(CreateMockFileEnumerator))
      .WillOnce(InvokeWithoutArgs(CreateMockFileEnumerator))
      .WillOnce(InvokeWithoutArgs(CreateMockFileEnumerator));
  EXPECT_CALL(*fe_v1_2, Next())
      .WillOnce(Return(homedir_paths_[0].Append("GCache/v1/files/removable")))
      .WillOnce(Return(homedir_paths_[0].Append("GCache/v1/files/unremovable")))
      .WillRepeatedly(Return(FilePath()));
  EXPECT_CALL(platform_,
      HasNoDumpFileAttribute(
        Property(&FilePath::value,
          EndsWith("GCache/v1/files/removable"))))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      HasNoDumpFileAttribute(
        Property(&FilePath::value,
          EndsWith("GCache/v1/files/unremovable"))))
    .WillOnce(Return(false));
  EXPECT_CALL(*fe_v2_2, Next())
      .WillOnce(Return(homedir_paths_[0].Append("GCache/v2/foobar/removable")))
      .WillOnce(
          Return(homedir_paths_[0].Append("GCache/v2/foobar/unremovable")))
      .WillRepeatedly(Return(FilePath()));
  EXPECT_CALL(platform_,
              HasNoDumpFileAttribute(Property(
                  &FilePath::value, EndsWith("GCache/v2/foobar/removable"))))
      .WillOnce(Return(true));
  EXPECT_CALL(platform_,
              HasNoDumpFileAttribute(Property(
                  &FilePath::value, EndsWith("GCache/v2/foobar/unremovable"))))
      .WillOnce(Return(false));

  ExpectTrackedDirectoriesEnumeration();

  // Confirm removable file is removed.
  EXPECT_CALL(platform_,
      DeleteFile(
        Property(&FilePath::value,
          EndsWith("/GCache/v1/files/removable")),
        _))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
              DeleteFile(Property(&FilePath::value,
                                  EndsWith("/GCache/v2/foobar/removable")),
                         _))
      .WillOnce(Return(true));

  homedirs_.FreeDiskSpace();

  EXPECT_TRUE(homedirs_.HasTargetFreeSpace());
}

TEST_P(FreeDiskSpaceTest, CacheAndGCacheCleanup) {
  EXPECT_CALL(platform_, EnumerateDirectoryEntries(kTestRoot, false, _))
    .WillRepeatedly(
        DoAll(SetArgPointee<2>(homedir_paths_),
              Return(true)));
  EXPECT_CALL(platform_, AmountOfFreeDiskSpace(kTestRoot))
      .WillOnce(Return(0))  // Before cleanup
      .WillOnce(Return(0))  // After removing cache
      .WillRepeatedly(
          Return(kMinFreeSpaceInBytes + 1));  // After removing gcache
  EXPECT_CALL(platform_, DirectoryExists(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(Property(&FilePath::value,
                                                  EndsWith(kEcryptfsVaultDir))))
      .WillRepeatedly(Return(ShouldTestEcryptfs()));

  // Skip per-cache and Cache enumerations done per user in order to
  // test cache and GCache deletion.
  EXPECT_CALL(platform_, GetFileEnumerator(
        Property(&FilePath::value, EndsWith("/user/Cache")),
        false, _))
    .Times(4)
    .WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));

  // DeleteGCacheTmpCallback enumerate all GCache directories to find removable
  // files.
  EXPECT_CALL(
      platform_,
      GetFileEnumerator(
          Property(&FilePath::value,
                   EndsWith(std::string(ShouldTestEcryptfs() ? kEcryptfsVaultDir
                                                             : kMountDir) +
                            "/user/GCache/v1")),
          true, base::FileEnumerator::FILES))
      .Times(4)
      .WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));
  EXPECT_CALL(
      platform_,
      GetFileEnumerator(
          Property(&FilePath::value,
                   EndsWith(std::string(ShouldTestEcryptfs() ? kEcryptfsVaultDir
                                                             : kMountDir) +
                            "/user/GCache/v2")),
          true, base::FileEnumerator::FILES))
      .Times(4)
      .WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));
  EXPECT_CALL(platform_, GetFileEnumerator(
        Property(&FilePath::value, EndsWith("user/GCache/v1/tmp")),
        false, _))
    .Times(4)
    .WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));

  // Should not attempt to remove Android cache. (by getting enumerator first)
  EXPECT_CALL(
      platform_,
      GetFileEnumerator(
          Property(&FilePath::value,
                   EndsWith(std::string(ShouldTestEcryptfs() ? kEcryptfsVaultDir
                                                             : kMountDir) +
                            "/root")),
          true, _))
      .Times(0);

  ExpectTrackedDirectoriesEnumeration();

  homedirs_.FreeDiskSpace();

  // Should finish cleaning up because the free space size exceeds
  // |kMinFreeSpaceInBytes| after deleting gcache, although it's still
  // below |kTargetFreeSpaceAfterCleanup|.
  EXPECT_FALSE(homedirs_.HasTargetFreeSpace());
}

TEST_P(FreeDiskSpaceTest, CacheAndGCacheAndAndroidCleanup) {
  EXPECT_CALL(platform_, EnumerateDirectoryEntries(kTestRoot, false, _))
    .WillRepeatedly(
        DoAll(SetArgPointee<2>(homedir_paths_),
              Return(true)));
  EXPECT_CALL(platform_, AmountOfFreeDiskSpace(kTestRoot))
      .WillOnce(Return(0))
      .WillOnce(Return(0))
      .WillOnce(Return(kMinFreeSpaceInBytes - 1))
      .WillRepeatedly(Return(kMinFreeSpaceInBytes + 1));
  EXPECT_CALL(platform_, DirectoryExists(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(Property(&FilePath::value,
                                                  EndsWith(kEcryptfsVaultDir))))
      .WillRepeatedly(Return(ShouldTestEcryptfs()));

  // Skip per-cache and Cache enumerations done per user in order to
  // test Android cache deletions.
  EXPECT_CALL(platform_, GetFileEnumerator(
        Property(&FilePath::value, EndsWith("/user/Cache")),
        false, _))
    .Times(4)
    .WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));

  // DeleteGCacheTmpCallback enumerate all directories to find GCache files
  // directory.
  EXPECT_CALL(
      platform_,
      GetFileEnumerator(
          Property(&FilePath::value,
                   EndsWith(std::string(ShouldTestEcryptfs() ? kEcryptfsVaultDir
                                                             : kMountDir) +
                            "/user/GCache/v1")),
          true, base::FileEnumerator::FILES))
      .Times(4)
      .WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));
  EXPECT_CALL(
      platform_,
      GetFileEnumerator(
          Property(&FilePath::value,
                   EndsWith(std::string(ShouldTestEcryptfs() ? kEcryptfsVaultDir
                                                             : kMountDir) +
                            "/user/GCache/v2")),
          true, base::FileEnumerator::FILES))
      .Times(4)
      .WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));
  EXPECT_CALL(platform_, GetFileEnumerator(
        Property(&FilePath::value, EndsWith("user/GCache/v1/tmp")),
        false, _))
    .Times(4)
    .WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));

  ExpectTrackedDirectoriesEnumeration();

  // Now test for the Android user, just test for the first user.
  NiceMock<MockFileEnumerator>* fe = new NiceMock<MockFileEnumerator>;
  FilePath app_dir =
      homedir_paths_[0].Append("android-data/data/data/com.google.hogehoge");
  FilePath cache_dir = app_dir.Append("cache");
  FilePath data_dir = app_dir.Append("data");
  FilePath code_cache_dir = app_dir.Append("code_cache");
  uint64_t code_cache_inode = 4;
  fe->entries_.push_back(CreateFileInfo(app_dir, 1));
  fe->entries_.push_back(CreateFileInfo(cache_dir, 2));
  fe->entries_.push_back(CreateFileInfo(data_dir, 3));
  fe->entries_.push_back(CreateFileInfo(code_cache_dir, code_cache_inode));
  EXPECT_CALL(
      platform_,
      GetFileEnumerator(
          Property(&FilePath::value,
                   EndsWith(std::string(ShouldTestEcryptfs() ? kEcryptfsVaultDir
                                                             : kMountDir) +
                            "/root")),
          true, _))
      .WillOnce(Return(fe))
      .WillOnce(InvokeWithoutArgs(CreateMockFileEnumerator))
      .WillOnce(InvokeWithoutArgs(CreateMockFileEnumerator))
      .WillOnce(InvokeWithoutArgs(CreateMockFileEnumerator));

  EXPECT_CALL(platform_,
              HasExtendedFileAttribute(_, kAndroidCacheFilesAttribute))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_,
              HasExtendedFileAttribute(_, kAndroidCodeCacheInodeAttribute))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_,
              HasExtendedFileAttribute(_, kAndroidCacheInodeAttribute))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(platform_,
              HasExtendedFileAttribute(cache_dir, kAndroidCacheFilesAttribute))
      .WillOnce(Return(true));
  EXPECT_CALL(
      platform_,
      HasExtendedFileAttribute(app_dir, kAndroidCodeCacheInodeAttribute))
      .WillOnce(Return(true));
  char* code_cache_array = reinterpret_cast<char*>(&code_cache_inode);
  EXPECT_CALL(
      platform_,
      GetExtendedFileAttribute(app_dir, kAndroidCodeCacheInodeAttribute, _, _))
      .WillOnce(DoAll(
          SetArrayArgument<2>(code_cache_array,
                              code_cache_array + sizeof(code_cache_inode)),
          Return(true)));
  std::vector<FilePath> cache_entries = {cache_dir.Append("foo")};
  EXPECT_CALL(platform_, EnumerateDirectoryEntries(cache_dir, false, _))
      .WillOnce(DoAll(SetArgPointee<2>(cache_entries), Return(true)));
  std::vector<FilePath> code_cache_entries = {code_cache_dir.Append("bar")};
  EXPECT_CALL(platform_, EnumerateDirectoryEntries(code_cache_dir, false, _))
      .WillOnce(DoAll(SetArgPointee<2>(code_cache_entries), Return(true)));

  // Confirm android cache dir is removed and data directory is not.
  EXPECT_CALL(platform_, DeleteFile(cache_dir.Append("foo"), true))
      .WillOnce(Return(true));
  EXPECT_CALL(platform_, DeleteFile(code_cache_dir.Append("bar"), true))
      .WillOnce(Return(true));

  homedirs_.FreeDiskSpace();

  // Should finish cleaning up because the free space size exceeds
  // |kMinFreeSpaceInBytes| after deleting Android cache, although it's still
  // below |kTargetFreeSpaceAfterCleanup|.
  EXPECT_FALSE(homedirs_.HasTargetFreeSpace());
}

TEST_P(FreeDiskSpaceTest, CleanUpOneUser) {
  // Ensure that the oldest user directory deleted, but not any
  // others, if the first deletion frees enough space.
  EXPECT_CALL(timestamp_cache_, initialized())
    .WillRepeatedly(Return(true));

  EXPECT_CALL(timestamp_cache_, empty())
    .WillOnce(Return(false));

  EXPECT_CALL(timestamp_cache_, RemoveOldestUser())
    .WillOnce(Return(homedir_paths_[0]));

  EXPECT_CALL(platform_, AmountOfFreeDiskSpace(kTestRoot))
      .WillRepeatedly(Return(kTargetFreeSpaceAfterCleanup + 1));

  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[0], true))
    .WillOnce(Return(true));

  ExpectCacheDirCleanupCalls(4);
  ExpectDeletedLECredentialEnumeration(homedir_paths_[0]);

  homedirs_.FreeDiskSpace();

  EXPECT_TRUE(homedirs_.HasTargetFreeSpace());
}

TEST_P(FreeDiskSpaceTest, CleanUpMultipleUsers) {
  // Ensure that the two oldest user directories are deleted, but not any
  // others, if the second deletion frees enough space.
  EXPECT_CALL(timestamp_cache_, initialized())
    .WillRepeatedly(Return(true));

  EXPECT_CALL(timestamp_cache_, empty())
    .WillOnce(Return(false))
    .WillOnce(Return(false));

  EXPECT_CALL(timestamp_cache_, RemoveOldestUser())
    .WillOnce(Return(homedir_paths_[0]))
    .WillOnce(Return(homedir_paths_[1]));

  EXPECT_CALL(platform_, AmountOfFreeDiskSpace(kTestRoot))
      .WillOnce(Return(kTargetFreeSpaceAfterCleanup - 1))
      .WillRepeatedly(Return(kTargetFreeSpaceAfterCleanup + 1));

  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[0], true))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[1], true))
    .WillOnce(Return(true));

  ExpectCacheDirCleanupCalls(4);
  ExpectDeletedLECredentialEnumeration(homedir_paths_[0]);
  ExpectDeletedLECredentialEnumeration(homedir_paths_[1]);

  homedirs_.FreeDiskSpace();

  EXPECT_TRUE(homedirs_.HasTargetFreeSpace());
}

TEST_P(FreeDiskSpaceTest, EnterpriseCleanUpAllUsersButLast_LoginScreen) {
  set_policy(true, "", false, "");
  homedirs_.set_enterprise_owned(true);
  UserOldestActivityTimestampCache cache;
  cache.Initialize();
  homedirs_.Init(&platform_, &crypto_, &cache);

  cache.AddExistingUser(homedir_paths_[0], homedir_times_[0]);
  cache.AddExistingUser(homedir_paths_[1], homedir_times_[1]);
  cache.AddExistingUser(homedir_paths_[2], homedir_times_[2]);
  cache.AddExistingUser(homedir_paths_[3], homedir_times_[3]);

  EXPECT_CALL(platform_, AmountOfFreeDiskSpace(kTestRoot))
    .WillRepeatedly(Return(0));

  EXPECT_CALL(platform_, DeleteFile(_, _)).WillRepeatedly(Return(true));

  // Most-recent user isn't deleted.
  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[3], true)).Times(0);

  EXPECT_CALL(platform_,
              IsDirectoryMounted(_)).WillRepeatedly(Return(false));

  ExpectCacheDirCleanupCalls(4);
  ExpectDeletedLECredentialEnumeration(homedir_paths_[0]);
  ExpectDeletedLECredentialEnumeration(homedir_paths_[1]);
  ExpectDeletedLECredentialEnumeration(homedir_paths_[2]);

  homedirs_.FreeDiskSpace();

  EXPECT_FALSE(homedirs_.HasTargetFreeSpace());

  // Last user is re-inserted into cache, to be a candidate for deletion
  // next time.
  EXPECT_FALSE(cache.empty());
  EXPECT_EQ(homedir_times_[3], cache.oldest_known_timestamp());
}


TEST_P(FreeDiskSpaceTest, EnterpriseCleanUpAllUsersButLast_UserLoggedIn) {
  set_policy(true, "", false, "");
  homedirs_.set_enterprise_owned(true);
  UserOldestActivityTimestampCache cache;
  cache.Initialize();
  homedirs_.Init(&platform_, &crypto_, &cache);

  cache.AddExistingUser(homedir_paths_[0], homedir_times_[0]);
  cache.AddExistingUser((homedir_paths_[1]), homedir_times_[1]);
  // User 2 is logged in, and hence not added to cache during initialization.
  cache.AddExistingUser((homedir_paths_[3]), homedir_times_[3]);

  EXPECT_CALL(platform_, AmountOfFreeDiskSpace(kTestRoot))
    .WillRepeatedly(Return(0));

  // Oldest user (#0) in cache IS deleted, since most-recent user #2 isn't in
  // the cache at all (they are logged in).
  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[0], true))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[1], true))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[2], true)).Times(0);
  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[3], true))
    .WillOnce(Return(true));

  EXPECT_CALL(platform_,
      IsDirectoryMounted(_))
    .WillRepeatedly(Return(false));
  // Catch /home/usr/<uid> mount.
  EXPECT_CALL(platform_,
      IsDirectoryMounted(
        Property(&FilePath::value, StrEq(user_paths_[2].value()))))
    .WillRepeatedly(Return(true));

  ExpectCacheDirCleanupCalls(3);

  ExpectDeletedLECredentialEnumeration(homedir_paths_[0]);
  ExpectDeletedLECredentialEnumeration(homedir_paths_[1]);
  ExpectDeletedLECredentialEnumeration(homedir_paths_[3]);

  homedirs_.FreeDiskSpace();

  EXPECT_FALSE(homedirs_.HasTargetFreeSpace());

  // Cache is empty (oldest user only re-inserted if no one is logged in).
  EXPECT_TRUE(cache.empty());
}

TEST_P(FreeDiskSpaceTest, CleanUpMultipleNonadjacentUsers) {
  // Ensure that the two oldest user directories are deleted, but not any
  // others.  The owner is inserted in the middle.
  EXPECT_CALL(timestamp_cache_, initialized())
    .WillRepeatedly(Return(true));

  EXPECT_CALL(timestamp_cache_, empty())
    .WillOnce(Return(false))
    .WillOnce(Return(false))
    .WillOnce(Return(false));

  EXPECT_CALL(timestamp_cache_, RemoveOldestUser())
    .WillOnce(Return((homedir_paths_[0])))
    .WillOnce(Return((homedir_paths_[3])))
    .WillOnce(Return((homedir_paths_[1])));

  EXPECT_CALL(platform_, AmountOfFreeDiskSpace(kTestRoot))
      .WillOnce(Return(0))
      // Loop continued before we check disk space for owner.
      .WillRepeatedly(Return(kTargetFreeSpaceAfterCleanup + 1));

  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[0], true))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[1], true))
    .WillOnce(Return(true));
  // Ensure the owner isn't deleted!
  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[3], true))
    .Times(0);

  ExpectCacheDirCleanupCalls(4);

  ExpectDeletedLECredentialEnumeration(homedir_paths_[0]);
  ExpectDeletedLECredentialEnumeration(homedir_paths_[1]);
  homedirs_.FreeDiskSpace();

  EXPECT_TRUE(homedirs_.HasTargetFreeSpace());
}

TEST_P(FreeDiskSpaceTest, NoOwnerNoEnterpriseNoCleanup) {
  // Ensure that no users are deleted with no owner/enterprise-owner.
  EXPECT_CALL(platform_, AmountOfFreeDiskSpace(kTestRoot))
    .WillRepeatedly(Return(0));

  // Skip re-init
  EXPECT_CALL(timestamp_cache_, initialized())
    .WillOnce(Return(true));

  // No user deletions!
  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[0], true))
    .Times(0);
  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[1], true))
    .Times(0);
  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[2], true))
    .Times(0);
  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[3], true))
    .Times(0);

  // Now skip the deletion steps by not having a legit owner.
  set_policy(false, "", false, "");

  ExpectCacheDirCleanupCalls(4);

  homedirs_.FreeDiskSpace();

  EXPECT_FALSE(homedirs_.HasTargetFreeSpace());
}

TEST_P(FreeDiskSpaceTest, ConsumerEphemeralUsers) {
  // When ephemeral users are enabled, no cryptohomes are kept except the owner.
  set_policy(true, kOwner, true, "");

  EXPECT_CALL(platform_, EnumerateDirectoryEntries(kTestRoot, false, _))
    .WillRepeatedly(
        DoAll(SetArgPointee<2>(homedir_paths_),
              Return(true)));
  EXPECT_CALL(platform_,
      EnumerateDirectoryEntries(brillo::cryptohome::home::GetUserPathPrefix(),
          false, _))
    .WillRepeatedly(
        DoAll(SetArgPointee<2>(homedir_paths_),
              Return(true)));
  EXPECT_CALL(platform_,
      EnumerateDirectoryEntries(brillo::cryptohome::home::GetRootPathPrefix(),
          false, _))
    .WillRepeatedly(
        DoAll(SetArgPointee<2>(homedir_paths_),
              Return(true)));

  EXPECT_CALL(platform_, AmountOfFreeDiskSpace(kTestRoot))
      .WillOnce(Return(kFreeSpaceThresholdToTriggerCleanup - 1))
      .WillRepeatedly(Return(kTargetFreeSpaceAfterCleanup + 1));

  EXPECT_CALL(platform_, DirectoryExists(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(Property(&FilePath::value,
                                                  EndsWith(kEcryptfsVaultDir))))
      .WillRepeatedly(Return(ShouldTestEcryptfs()));
  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[0], true))
    .WillOnce(Return(true))  // vault
    .WillOnce(Return(true))  // user
    .WillOnce(Return(true));  // root
  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[1], true))
    .WillOnce(Return(true))
    .WillOnce(Return(true))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[2], true))
    .WillOnce(Return(true))
    .WillOnce(Return(true))
    .WillOnce(Return(true));
  // Ensure the owner isn't deleted!
  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[3], true))
    .Times(0);

  homedirs_.FreeDiskSpace();

  EXPECT_TRUE(homedirs_.HasTargetFreeSpace());
}

TEST_P(FreeDiskSpaceTest, EnterpriseEphemeralUsers) {
  // When ephemeral users are enabled, no cryptohomes are kept except the owner.
  set_policy(true, "", true, "");
  homedirs_.set_enterprise_owned(true);

  EXPECT_CALL(platform_, EnumerateDirectoryEntries(kTestRoot, false, _))
    .WillRepeatedly(
        DoAll(SetArgPointee<2>(homedir_paths_),
              Return(true)));
  EXPECT_CALL(platform_,
      EnumerateDirectoryEntries(brillo::cryptohome::home::GetUserPathPrefix(),
          false, _))
    .WillRepeatedly(
        DoAll(SetArgPointee<2>(homedir_paths_),
              Return(true)));
  EXPECT_CALL(platform_,
      EnumerateDirectoryEntries(brillo::cryptohome::home::GetRootPathPrefix(),
          false, _))
    .WillRepeatedly(
        DoAll(SetArgPointee<2>(homedir_paths_),
              Return(true)));

  EXPECT_CALL(platform_, AmountOfFreeDiskSpace(kTestRoot))
      .WillOnce(Return(kFreeSpaceThresholdToTriggerCleanup - 1))
      .WillRepeatedly(Return(kTargetFreeSpaceAfterCleanup + 1));

  EXPECT_CALL(platform_, DirectoryExists(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(Property(&FilePath::value,
                                                  EndsWith(kEcryptfsVaultDir))))
      .WillRepeatedly(Return(ShouldTestEcryptfs()));
  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[0], true))
    .WillOnce(Return(true))  // vault
    .WillOnce(Return(true))  // user
    .WillOnce(Return(true));  // root
  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[1], true))
    .WillOnce(Return(true))
    .WillOnce(Return(true))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[2], true))
    .WillOnce(Return(true))
    .WillOnce(Return(true))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_, DeleteFile(homedir_paths_[3], true))
    .WillOnce(Return(true))
    .WillOnce(Return(true))
    .WillOnce(Return(true));

  homedirs_.FreeDiskSpace();

  EXPECT_TRUE(homedirs_.HasTargetFreeSpace());
}

TEST_P(FreeDiskSpaceTest, DontCleanUpMountedUser) {
  // Ensure that a user isn't deleted if it appears to be mounted.
  EXPECT_CALL(timestamp_cache_, initialized())
    .WillRepeatedly(Return(true));
  EXPECT_CALL(timestamp_cache_, empty())
    .WillOnce(Return(false))
    .WillOnce(Return(true));

  // This will only be called once (see time below).
  EXPECT_CALL(timestamp_cache_, RemoveOldestUser())
    .WillOnce(Return((homedir_paths_[0])));

  EXPECT_CALL(platform_, EnumerateDirectoryEntries(kTestRoot, false, _))
    .WillRepeatedly(
        DoAll(SetArgPointee<2>(homedir_paths_),
              Return(true)));
  EXPECT_CALL(platform_, AmountOfFreeDiskSpace(kTestRoot))
    .WillRepeatedly(Return(0));
  EXPECT_CALL(platform_, DirectoryExists(_))
    .WillRepeatedly(Return(true));
  EXPECT_CALL(platform_, DirectoryExists(Property(&FilePath::value,
                                                  EndsWith(kEcryptfsVaultDir))))
      .WillRepeatedly(Return(ShouldTestEcryptfs()));

  // Ensure the mounted user never has (G)Cache traversed!
  EXPECT_CALL(platform_, GetFileEnumerator(
        Property(&FilePath::value,
          StartsWith(homedir_paths_[0].value())),
        false, _))
    .Times(0);

  // 3 users * (1 Cache dir + 1 GCache tmp dir)
  EXPECT_CALL(platform_, GetFileEnumerator(_, false, _))
    .Times(6).WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));
  // 3 users * (2 GCache files dir + 1 Android cache)
  EXPECT_CALL(platform_, GetFileEnumerator(_, true, _))
      .Times(9)
      .WillRepeatedly(InvokeWithoutArgs(CreateMockFileEnumerator));

  ExpectTrackedDirectoriesEnumeration();

  EXPECT_CALL(platform_, IsDirectoryMounted(Property(
                             &FilePath::value, StrEq(user_paths_[0].value()))))
      .Times(6)  // count, Cache, GCache, android, count, user removal
      .WillRepeatedly(Return(true));
  for (size_t i = 1; i < arraysize(kHomedirs); ++i) {
    EXPECT_CALL(platform_,
                IsDirectoryMounted(
                    Property(&FilePath::value, StrEq(user_paths_[i].value()))))
        .Times(5)  // count, Cache, GCache, android, count
        .WillRepeatedly(Return(false));
  }

  homedirs_.FreeDiskSpace();

  EXPECT_FALSE(homedirs_.HasTargetFreeSpace());
}

TEST_P(HomeDirsTest, GoodDecryptTest) {
  // create a HomeDirs instance that points to a good shadow root, test that it
  // properly authenticates against the first key.
  SecureBlob system_salt;
  NiceMock<MockTpm> tpm;
  homedirs_.crypto()->set_tpm(&tpm);
  homedirs_.crypto()->set_use_tpm(false);
  ASSERT_TRUE(homedirs_.GetSystemSalt(&system_salt));
  set_policy(false, "", false, "");

  test_helper_.users[1].InjectKeyset(&platform_);
  SecureBlob passkey;
  cryptohome::Crypto::PasswordToPasskey(test_helper_.users[1].password,
                                        system_salt, &passkey);
  UsernamePasskey up(test_helper_.users[1].username, passkey);

  ASSERT_TRUE(homedirs_.AreCredentialsValid(up));
}

TEST_P(HomeDirsTest, BadDecryptTest) {
  // create a HomeDirs instance that points to a good shadow root, test that it
  // properly denies access with a bad passkey
  SecureBlob system_salt;
  NiceMock<MockTpm> tpm;
  homedirs_.crypto()->set_tpm(&tpm);
  homedirs_.crypto()->set_use_tpm(false);
  set_policy(false, "", false, "");

  test_helper_.users[4].InjectKeyset(&platform_);

  SecureBlob passkey;
  cryptohome::Crypto::PasswordToPasskey("bogus", system_salt, &passkey);
  UsernamePasskey up(test_helper_.users[4].username, passkey);

  ASSERT_FALSE(homedirs_.AreCredentialsValid(up));
}

#define MAX_VKS 5
class KeysetManagementTest : public HomeDirsTest {
 public:
  KeysetManagementTest() { }
  virtual ~KeysetManagementTest() { }

  void SetUp() {
    HomeDirsTest::SetUp();
    last_vk_ = -1;
    active_vk_ = NULL;
    memset(active_vks_, 0, sizeof(active_vks_));
  }

  void TearDown() {
    HomeDirsTest::TearDown();
    last_vk_++;
    for ( ; last_vk_ < MAX_VKS; ++last_vk_) {
      if (active_vks_[last_vk_])
        delete active_vks_[last_vk_];
      active_vks_[last_vk_] = NULL;
    }
    last_vk_ = -1;
    active_vk_ = NULL;
  }

  virtual bool VkDecrypt0(const brillo::SecureBlob& key,
                          bool is_pcr_extended,
                          Crypto::CryptoError* crypto_error) {
    return memcmp(key.data(), keys_[0].data(), key.size()) == 0;
  }

  virtual const SerializedVaultKeyset& FakeSerialized() const {
    return serialized_;
  }

  virtual SerializedVaultKeyset* FakeMutableSerialized() {
    return &serialized_;
  }

  virtual MockFileEnumerator* NewKeysetFileEnumerator() {
    MockFileEnumerator* files = new MockFileEnumerator();
    {
      InSequence s;
      // Single key.
      EXPECT_CALL(*files, Next())
        .WillOnce(Return(keyset_paths_[0]));
      EXPECT_CALL(*files, Next())
        .WillOnce(Return(FilePath()));
    }
    return files;
  }

  virtual MockVaultKeyset* NewActiveVaultKeyset() {
    last_vk_++;
    CHECK(last_vk_ < MAX_VKS);
    active_vk_ = active_vks_[last_vk_];
    EXPECT_CALL(*active_vk_, Decrypt(_, _, _))
        .WillRepeatedly(Invoke(this, &KeysetManagementTest::VkDecrypt0));

    EXPECT_CALL(*active_vk_, serialized())
      .WillRepeatedly(
          Invoke(this, &KeysetManagementTest::FakeSerialized));
    EXPECT_CALL(*active_vk_, mutable_serialized())
      .WillRepeatedly(
          Invoke(this, &KeysetManagementTest::FakeMutableSerialized));
    return active_vk_;
  }

  virtual void KeysetSetUp() {
    serialized_.Clear();
    NiceMock<MockTpm> tpm;
    homedirs_.crypto()->set_tpm(&tpm);
    homedirs_.crypto()->set_use_tpm(false);
    ASSERT_TRUE(homedirs_.GetSystemSalt(&system_salt_));
    set_policy(false, "", false, "");

    // Setup the base keyset files for users[1]
    keyset_paths_.push_back(test_helper_.users[1].keyset_path);
    keys_.push_back(test_helper_.users[1].passkey);

    EXPECT_CALL(platform_, GetFileEnumerator(
        test_helper_.users[1].base_path, false, _))
      .WillRepeatedly(
        InvokeWithoutArgs(this,
                          &KeysetManagementTest::NewKeysetFileEnumerator));

    homedirs_.set_vault_keyset_factory(&vault_keyset_factory_);
    // Pre-allocate VKs so that each call can advance
    // but expectations can be set.
    for (int i = 0; i < MAX_VKS; ++i) {
      active_vks_[i] = new MockVaultKeyset();
      // Move this particular expectation setting here instead of
      // NewActiveVaultKeyset, since this allows us to make some modifications
      // to the expectation in the test itself, if necessary.
      // Also change the cardinality to be WillRepeatedly, since this makes it
      // more forgiving even if we don't make an invocation for a VaultKeyset
      // which isn't used in a test.
      EXPECT_CALL(*active_vks_[i], Load(keyset_paths_[0]))
          .WillRepeatedly(Return(true));
    }
    active_vk_ = active_vks_[0];

    EXPECT_CALL(vault_keyset_factory_, New(_, _))
      .WillRepeatedly(
          InvokeWithoutArgs(this, &KeysetManagementTest::NewActiveVaultKeyset));
    SecureBlob passkey;
    cryptohome::Crypto::PasswordToPasskey(test_helper_.users[1].password,
                                          system_salt_, &passkey);
    up_.reset(new UsernamePasskey(test_helper_.users[1].username, passkey));

    // Since most of the tests were written without reset_seed in mind,
    // it is tedious to add expectations to every test, for the situation
    // where a wrapped_reset_seed is not present.
    // So, we instead set the wrapped_reset_seed by default,
    // and have a separate test case where it is not set.
    std::string dummy_reset_seed("DEADBEEF");
    serialized_.set_wrapped_reset_seed(dummy_reset_seed);
  }

  void ClearFakeSerializedResetSeed() {
    serialized_.clear_wrapped_reset_seed();
  }

  int last_vk_;
  MockVaultKeyset* active_vk_;
  MockVaultKeyset* active_vks_[MAX_VKS];
  std::vector<FilePath> keyset_paths_;
  std::vector<brillo::SecureBlob> keys_;
  std::unique_ptr<UsernamePasskey> up_;
  SecureBlob system_salt_;
  SerializedVaultKeyset serialized_;
};

INSTANTIATE_TEST_CASE_P(WithEcryptfs, KeysetManagementTest,
                        ::testing::Values(true));
INSTANTIATE_TEST_CASE_P(WithDircrypto, KeysetManagementTest,
                        ::testing::Values(false));

TEST_P(KeysetManagementTest, AddKeysetSuccess) {
  KeysetSetUp();

  SecureBlob newkey;
  cryptohome::Crypto::PasswordToPasskey("why not", system_salt_, &newkey);
  int index = -1;
  // The injected keyset in the fixture handles the up_ validation.
  EXPECT_CALL(platform_,
      OpenFile(
        Property(&FilePath::value, EndsWith("master.0")),
        StrEq("wx")))
    .WillOnce(Return(reinterpret_cast<FILE*>(NULL)));
  EXPECT_CALL(platform_,
      OpenFile(
        Property(&FilePath::value, EndsWith("master.1")),
        StrEq("wx")))
    .WillOnce(Return(reinterpret_cast<FILE*>(0xbeefbeef)));
  EXPECT_CALL(*active_vk_, Encrypt(newkey, _))
    .WillOnce(Return(true));
  EXPECT_CALL(*active_vk_,
      Save(Property(&FilePath::value, EndsWith("master.1"))))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_, DeleteFile(_, _))
    .Times(0);

  EXPECT_EQ(CRYPTOHOME_ERROR_NOT_SET,
            homedirs_.AddKeyset(*up_, newkey, NULL, false, &index));
  EXPECT_EQ(index, 1);
}

TEST_P(KeysetManagementTest, AddKeysetClobber) {
  KeysetSetUp();

  SecureBlob newkey;
  cryptohome::Crypto::PasswordToPasskey("why not", system_salt_, &newkey);
  serialized_.mutable_key_data()->set_label("current label");
  KeyData key_data;
  key_data.set_label("current label");
  FilePath vk_path("/some/path/master.0");
  // Show that 0 is taken.
  EXPECT_CALL(platform_,
      OpenFile(
        Property(&FilePath::value, EndsWith("master.0")),
        StrEq("wx")))
    .WillOnce(Return(reinterpret_cast<FILE*>(NULL)));
  // Let it claim 1 until it searches the labels.
  EXPECT_CALL(platform_,
      OpenFile(
        Property(&FilePath::value, EndsWith("master.1")),
        StrEq("wx")))
    .WillOnce(Return(reinterpret_cast<FILE*>(0xbeefbeef)));
  EXPECT_CALL(*active_vk_, Encrypt(newkey, _))
    .WillOnce(Return(true));
  EXPECT_CALL(*active_vks_[1], set_legacy_index(_));
  EXPECT_CALL(*active_vks_[1], legacy_index())
    .WillOnce(Return(0));
  EXPECT_CALL(*active_vks_[1], source_file())
    .WillOnce(ReturnRef(vk_path));
  EXPECT_CALL(*active_vk_, Save(vk_path))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      DeleteFile(
        Property(&FilePath::value, EndsWith("master.1")),
        _))
    .Times(1);

  int index = -1;
  EXPECT_EQ(CRYPTOHOME_ERROR_NOT_SET,
            homedirs_.AddKeyset(*up_, newkey, &key_data, true, &index));
  EXPECT_EQ(index, 0);
}


TEST_P(KeysetManagementTest, AddKeysetNoClobber) {
  KeysetSetUp();

  SecureBlob newkey;
  cryptohome::Crypto::PasswordToPasskey("why not", system_salt_, &newkey);
  int index = -1;
  serialized_.mutable_key_data()->set_label("current label");
  KeyData key_data;
  key_data.set_label("current label");
  // The injected keyset in the fixture handles the up_ validation.
  EXPECT_CALL(platform_,
      OpenFile(
        Property(&FilePath::value, EndsWith("master.0")),
        StrEq("wx")))
    .WillOnce(Return(reinterpret_cast<FILE*>(NULL)));
  EXPECT_CALL(platform_,
      OpenFile(
        Property(&FilePath::value, EndsWith("master.1")),
        StrEq("wx")))
    .WillOnce(Return(reinterpret_cast<FILE*>(0xbeefbeef)));

  EXPECT_EQ(CRYPTOHOME_ERROR_KEY_LABEL_EXISTS,
            homedirs_.AddKeyset(*up_, newkey, &key_data, false, &index));
  EXPECT_EQ(index, -1);
}


TEST_P(KeysetManagementTest, UpdateKeysetSuccess) {
  KeysetSetUp();

  // No need to do PasswordToPasskey as that is the
  // external callers job.
  SecureBlob new_secret("why not");
  Key new_key;
  new_key.set_secret("why not");
  new_key.mutable_data()->set_label("new label");
  // The injected keyset in the fixture handles the up_ validation.
  serialized_.mutable_key_data()->set_label("current label");
  FilePath vk_path("/some/path/master.0");
  EXPECT_CALL(*active_vk_, source_file())
    .WillOnce(ReturnRef(vk_path));
  EXPECT_CALL(*active_vk_, Encrypt(new_secret, _))
    .WillOnce(Return(true));
  EXPECT_CALL(*active_vk_, Save(vk_path))
    .WillOnce(Return(true));

  EXPECT_EQ(CRYPTOHOME_ERROR_NOT_SET,
            homedirs_.UpdateKeyset(*up_,
                                   const_cast<const Key *>(&new_key),
                                   ""));
  EXPECT_EQ(serialized_.key_data().label(), new_key.data().label());
}

TEST_P(KeysetManagementTest, UpdateKeysetAuthorizedNoSignature) {
  KeysetSetUp();

  // No need to do PasswordToPasskey as that is the
  // external callers job.
  Key new_key;
  new_key.set_secret("why not");
  new_key.mutable_data()->set_label("new label");
  new_key.mutable_data()->set_revision(1);
  // The injected keyset in the fixture handles the up_ validation.
  KeyData* key_data = serialized_.mutable_key_data();
  key_data->set_label("current label");
  // Allow the default override on the revision.
  key_data->mutable_privileges()->set_update(false);
  key_data->mutable_privileges()->set_authorized_update(true);
  KeyAuthorizationData* auth_data = key_data->add_authorization_data();
  auth_data->set_type(KeyAuthorizationData::KEY_AUTHORIZATION_TYPE_HMACSHA256);
  KeyAuthorizationSecret* auth_secret = auth_data->add_secrets();
  auth_secret->mutable_usage()->set_sign(true);
  const std::string kSomeHMACKey("abc123");
  auth_secret->set_symmetric_key(kSomeHMACKey);

  EXPECT_EQ(CRYPTOHOME_ERROR_UPDATE_SIGNATURE_INVALID,
            homedirs_.UpdateKeyset(*up_,
                                   const_cast<const Key *>(&new_key),
                                   ""));
  EXPECT_NE(serialized_.key_data().label(), new_key.data().label());
}

TEST_P(KeysetManagementTest, UpdateKeysetAuthorizedSuccess) {
  KeysetSetUp();

  // No need to do PasswordToPasskey as that is the
  // external callers job.
  SecureBlob new_pass("why not");
  Key new_key;
  new_key.set_secret("why not");
  new_key.mutable_data()->set_label("new label");
  // Allow updating over an undefined revision.
  new_key.mutable_data()->set_revision(0);
  // The injected keyset in the fixture handles the up_ validation.
  KeyData* key_data = serialized_.mutable_key_data();
  key_data->set_label("current label");
  key_data->mutable_privileges()->set_update(false);
  key_data->mutable_privileges()->set_authorized_update(true);
  KeyAuthorizationData* auth_data = key_data->add_authorization_data();
  auth_data->set_type(KeyAuthorizationData::KEY_AUTHORIZATION_TYPE_HMACSHA256);
  KeyAuthorizationSecret* auth_secret = auth_data->add_secrets();
  auth_secret->mutable_usage()->set_sign(true);
  const std::string kSomeHMACKey("abc123");
  auth_secret->set_symmetric_key(kSomeHMACKey);

  FilePath vk_path("/some/path/master.0");
  EXPECT_CALL(*active_vk_, source_file())
    .WillOnce(ReturnRef(vk_path));
  EXPECT_CALL(*active_vk_, Encrypt(new_pass, _))
    .WillOnce(Return(true));
  EXPECT_CALL(*active_vk_, Save(vk_path))
    .WillOnce(Return(true));

  std::string changes_str;
  ac::chrome::managedaccounts::account::Secret new_secret;
  new_secret.set_revision(new_key.data().revision());
  new_secret.set_secret(new_key.secret());
  ASSERT_TRUE(new_secret.SerializeToString(&changes_str));

  brillo::SecureBlob hmac_key(auth_secret->symmetric_key());
  brillo::SecureBlob hmac_data(changes_str.begin(), changes_str.end());
  SecureBlob hmac = CryptoLib::HmacSha256(hmac_key, hmac_data);
  EXPECT_EQ(CRYPTOHOME_ERROR_NOT_SET,
            homedirs_.UpdateKeyset(*up_,
                                   const_cast<const Key *>(&new_key),
                                   hmac.to_string()));
  EXPECT_EQ(serialized_.key_data().revision(), new_key.data().revision());
}

// Ensure signing matches the test vectors in Chrome.
TEST_P(KeysetManagementTest, UpdateKeysetAuthorizedCompatVector) {
  KeysetSetUp();

  // The salted password passed in from Chrome.
  const char kPassword[] = "OSL3HZZSfK+mDQTYUh3lXhgAzJNWhYz52ax0Bleny7Q=";
  // A no-op encryption key.
  const char kB64CipherKey[] = "QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUE=\n";
  // The signing key pre-installed.
  const char kB64SigningKey[] =
    "p5TR/34XX0R7IMuffH14BiL1vcdSD8EajPzdIg09z9M=\n";
  // The HMAC-256 signature over kPassword using kSigningKey.
  const char kB64Signature[] = "KOPQmmJcMr9iMkr36N1cX+G9gDdBBu7zutAxNayPMN4=\n";

  // No need to do PasswordToPasskey as that is the
  // external callers job.
  SecureBlob new_pass(kPassword);
  Key new_key;
  new_key.set_secret(std::string(kPassword, sizeof(kPassword)-1));
  new_key.mutable_data()->set_label("new label");
  // The compat revision to test is '1'.
  new_key.mutable_data()->set_revision(1);
  // The injected keyset in the fixture handles the up_ validation.
  KeyData* key_data = serialized_.mutable_key_data();
  key_data->set_label("current label");
  key_data->set_revision(0);
  key_data->mutable_privileges()->set_update(false);
  key_data->mutable_privileges()->set_authorized_update(true);
  KeyAuthorizationData* auth_data = key_data->add_authorization_data();
  auth_data->set_type(KeyAuthorizationData::KEY_AUTHORIZATION_TYPE_HMACSHA256);
  KeyAuthorizationSecret* auth_secret = auth_data->add_secrets();
  // Add an encryption secret to ensure later upgrades are viable.
  auth_secret->mutable_usage()->set_encrypt(true);
  std::string cipher_key;
  ASSERT_TRUE(brillo::data_encoding::Base64Decode(kB64CipherKey,
                                                    &cipher_key));
  auth_secret->set_symmetric_key(cipher_key);
  // Add the signing key
  auth_secret = auth_data->add_secrets();
  auth_secret->mutable_usage()->set_sign(true);
  std::string signing_key;
  ASSERT_TRUE(brillo::data_encoding::Base64Decode(kB64SigningKey,
                                                    &signing_key));
  auth_secret->set_symmetric_key(signing_key);

  FilePath vk_path("/some/path/master.0");
  EXPECT_CALL(*active_vk_, source_file())
    .WillOnce(ReturnRef(vk_path));
  EXPECT_CALL(*active_vk_, Encrypt(new_pass, _))
    .WillOnce(Return(true));
  EXPECT_CALL(*active_vk_, Save(vk_path))
    .WillOnce(Return(true));

  std::string signature;
  ASSERT_TRUE(brillo::data_encoding::Base64Decode(kB64Signature, &signature));
  EXPECT_EQ(CRYPTOHOME_ERROR_NOT_SET,
            homedirs_.UpdateKeyset(*up_,
                                   const_cast<const Key *>(&new_key),
                                   signature));
  EXPECT_EQ(new_key.data().revision(), serialized_.key_data().revision());
}

TEST_P(KeysetManagementTest, UpdateKeysetAuthorizedNoEqualReplay) {
  KeysetSetUp();

  // No need to do PasswordToPasskey as that is the
  // external callers job.
  Key new_key;
  new_key.set_secret("why not");
  new_key.mutable_data()->set_label("new label");
  new_key.mutable_data()->set_revision(100);
  // The injected keyset in the fixture handles the up_ validation.
  KeyData* key_data = serialized_.mutable_key_data();
  key_data->set_revision(100);
  key_data->set_label("current label");
  key_data->mutable_privileges()->set_update(false);
  key_data->mutable_privileges()->set_authorized_update(true);
  KeyAuthorizationData* auth_data = key_data->add_authorization_data();
  auth_data->set_type(KeyAuthorizationData::KEY_AUTHORIZATION_TYPE_HMACSHA256);
  KeyAuthorizationSecret* auth_secret = auth_data->add_secrets();
  auth_secret->mutable_usage()->set_sign(true);
  const std::string kSomeHMACKey("abc123");
  auth_secret->set_symmetric_key(kSomeHMACKey);

  std::string changes_str;
  ac::chrome::managedaccounts::account::Secret new_secret;
  new_secret.set_revision(new_key.data().revision());
  new_secret.set_secret(new_key.secret());
  ASSERT_TRUE(new_secret.SerializeToString(&changes_str));
  brillo::SecureBlob hmac_key(auth_secret->symmetric_key());
  brillo::SecureBlob hmac_data(changes_str.begin(), changes_str.end());
  SecureBlob hmac = CryptoLib::HmacSha256(hmac_key, hmac_data);
  EXPECT_EQ(CRYPTOHOME_ERROR_UPDATE_SIGNATURE_INVALID,
            homedirs_.UpdateKeyset(*up_,
                                   const_cast<const Key *>(&new_key),
                                   hmac.to_string()));
  EXPECT_NE(serialized_.key_data().label(), new_key.data().label());
}


TEST_P(KeysetManagementTest, UpdateKeysetAuthorizedNoLessReplay) {
  KeysetSetUp();

  // No need to do PasswordToPasskey as that is the
  // external callers job.
  Key new_key;
  new_key.set_secret("why not");
  new_key.mutable_data()->set_label("new label");
  new_key.mutable_data()->set_revision(0);
  // The injected keyset in the fixture handles the up_ validation.
  KeyData* key_data = serialized_.mutable_key_data();
  key_data->set_revision(1);
  key_data->set_label("current label");
  key_data->mutable_privileges()->set_update(false);
  key_data->mutable_privileges()->set_authorized_update(true);
  KeyAuthorizationData* auth_data = key_data->add_authorization_data();
  auth_data->set_type(KeyAuthorizationData::KEY_AUTHORIZATION_TYPE_HMACSHA256);
  KeyAuthorizationSecret* auth_secret = auth_data->add_secrets();
  auth_secret->mutable_usage()->set_sign(true);
  const std::string kSomeHMACKey("abc123");
  auth_secret->set_symmetric_key(kSomeHMACKey);

  std::string changes_str;
  ac::chrome::managedaccounts::account::Secret new_secret;
  new_secret.set_revision(new_key.data().revision());
  new_secret.set_secret(new_key.secret());
  ASSERT_TRUE(new_secret.SerializeToString(&changes_str));

  brillo::SecureBlob hmac_key(auth_secret->symmetric_key());
  brillo::SecureBlob hmac_data(changes_str.begin(), changes_str.end());
  SecureBlob hmac = CryptoLib::HmacSha256(hmac_key, hmac_data);
  EXPECT_EQ(CRYPTOHOME_ERROR_UPDATE_SIGNATURE_INVALID,
            homedirs_.UpdateKeyset(*up_,
                                   const_cast<const Key *>(&new_key),
                                   hmac.to_string()));
  EXPECT_NE(serialized_.key_data().label(), new_key.data().label());
}

TEST_P(KeysetManagementTest, UpdateKeysetAuthorizedBadSignature) {
  KeysetSetUp();

  // No need to do PasswordToPasskey as that is the
  // external callers job.
  Key new_key;
  new_key.set_secret("why not");
  new_key.mutable_data()->set_label("new label");
  new_key.mutable_data()->set_revision(0);
  // The injected keyset in the fixture handles the up_ validation.
  KeyData* key_data = serialized_.mutable_key_data();
  key_data->set_label("current label");
  key_data->mutable_privileges()->set_update(false);
  key_data->mutable_privileges()->set_authorized_update(true);
  KeyAuthorizationData* auth_data = key_data->add_authorization_data();
  auth_data->set_type(KeyAuthorizationData::KEY_AUTHORIZATION_TYPE_HMACSHA256);
  KeyAuthorizationSecret* auth_secret = auth_data->add_secrets();
  auth_secret->mutable_usage()->set_sign(true);
  const std::string kSomeHMACKey("abc123");
  auth_secret->set_symmetric_key(kSomeHMACKey);

  std::string changes_str;
  ac::chrome::managedaccounts::account::Secret bad_secret;
  bad_secret.set_revision(new_key.data().revision());
  bad_secret.set_secret("something else");
  ASSERT_TRUE(bad_secret.SerializeToString(&changes_str));

  brillo::SecureBlob hmac_key(auth_secret->symmetric_key());
  brillo::SecureBlob hmac_data(changes_str.begin(), changes_str.end());
  SecureBlob hmac = CryptoLib::HmacSha256(hmac_key, hmac_data);
  EXPECT_EQ(CRYPTOHOME_ERROR_UPDATE_SIGNATURE_INVALID,
            homedirs_.UpdateKeyset(*up_,
                                   const_cast<const Key *>(&new_key),
                                   hmac.to_string()));
  EXPECT_NE(serialized_.key_data().label(), new_key.data().label());
}

TEST_P(KeysetManagementTest, UpdateKeysetBadSecret) {
  KeysetSetUp();

  // No need to do PasswordToPasskey as that is the
  // external callers job.
  SecureBlob new_secret("why not");
  Key new_key;
  new_key.set_secret("why not");
  new_key.mutable_data()->set_label("new label");
  // The injected keyset in the fixture handles the up_ validation.
  serialized_.mutable_key_data()->set_label("current label");

  SecureBlob bad_pass("not it");
  up_.reset(new UsernamePasskey(test_helper_.users[1].username, bad_pass));
  EXPECT_EQ(CRYPTOHOME_ERROR_AUTHORIZATION_KEY_FAILED,
            homedirs_.UpdateKeyset(*up_,
                                   const_cast<const Key *>(&new_key),
                                   ""));
  EXPECT_NE(serialized_.key_data().label(), new_key.data().label());
}

TEST_P(KeysetManagementTest, UpdateKeysetNotFoundWithLabel) {
  KeysetSetUp();

  KeyData some_label;
  some_label.set_label("key that doesn't exist");
  up_->set_key_data(some_label);
  const Key new_key;
  EXPECT_EQ(CRYPTOHOME_ERROR_AUTHORIZATION_KEY_NOT_FOUND,
            homedirs_.UpdateKeyset(*up_,
                                   &new_key,
                                   ""));
}

TEST_P(KeysetManagementTest, RemoveKeysetSuccess) {
  KeysetSetUp();

  Key remove_key;
  remove_key.mutable_data()->set_label("remove me");

  // Expect the 0 slot since it'll match all the fake keys.
  EXPECT_CALL(*active_vks_[0], set_legacy_index(0));
  // Return a different slot to make sure the code is using the right object.
  EXPECT_CALL(*active_vks_[0], legacy_index())
    .WillOnce(Return(1));
  // The VaultKeyset which will be removed will get index 2.
  EXPECT_CALL(*active_vks_[2],
              Load(keyset_paths_[0].ReplaceExtension(std::to_string(1))))
      .WillOnce(Return(true));

  serialized_.mutable_key_data()->mutable_privileges()->set_remove(true);
  serialized_.mutable_key_data()->set_label("remove me");
  EXPECT_EQ(CRYPTOHOME_ERROR_NOT_SET,
            homedirs_.RemoveKeyset(*up_, remove_key.data()));
}

TEST_P(KeysetManagementTest, RemoveKeysetNotFound) {
  KeysetSetUp();

  Key remove_key;
  remove_key.mutable_data()->set_label("remove me please");

  serialized_.mutable_key_data()->mutable_privileges()->set_remove(true);
  serialized_.mutable_key_data()->set_label("the only key in town");
  EXPECT_EQ(CRYPTOHOME_ERROR_KEY_NOT_FOUND,
            homedirs_.RemoveKeyset(*up_, remove_key.data()));
}

TEST_P(KeysetManagementTest, GetVaultKeysetLabelsOneLabeled) {
  KeysetSetUp();

  serialized_.mutable_key_data()->set_label("a labeled key");
  std::vector<std::string> labels;
  EXPECT_TRUE(homedirs_.GetVaultKeysetLabels(
      up_->GetObfuscatedUsername(system_salt_), &labels));
  ASSERT_NE(0, labels.size());
  EXPECT_EQ(serialized_.key_data().label(),
            labels[0]);
}

TEST_P(KeysetManagementTest, GetVaultKeysetLabelsOneLegacyLabeled) {
  KeysetSetUp();

  serialized_.clear_key_data();
  std::vector<std::string> labels;
  EXPECT_TRUE(homedirs_.GetVaultKeysetLabels(
      up_->GetObfuscatedUsername(system_salt_), &labels));
  ASSERT_NE(0, labels.size());
  EXPECT_EQ(StringPrintf("%s%d", kKeyLegacyPrefix, 0),
            labels[0]);
}

TEST_P(KeysetManagementTest, AddKeysetInvalidCreds) {
  KeysetSetUp();

  SecureBlob newkey;
  cryptohome::Crypto::PasswordToPasskey("why not", system_salt_, &newkey);
  int index = -1;

  EXPECT_CALL(platform_, DeleteFile(_, _))
    .Times(0);
  // Try to authenticate with an unknown key.
  UsernamePasskey bad_p(test_helper_.users[1].username, newkey);
  ASSERT_EQ(CRYPTOHOME_ERROR_AUTHORIZATION_KEY_FAILED,
            homedirs_.AddKeyset(bad_p, newkey, NULL, false, &index));
  EXPECT_EQ(index, -1);
}

TEST_P(KeysetManagementTest, AddKeysetInvalidPrivileges) {
  // Check for key use that lacks valid add privileges
  KeysetSetUp();

  // The injected keyset in the fixture handles the up_ validation.
  SecureBlob newkey;
  cryptohome::Crypto::PasswordToPasskey("why not", system_salt_, &newkey);

  serialized_.mutable_key_data()->mutable_privileges()->set_add(false);
  int index = -1;
  // Tery to authenticate with a key that cannot add keys.
  ASSERT_EQ(CRYPTOHOME_ERROR_AUTHORIZATION_KEY_DENIED,
            homedirs_.AddKeyset(*up_, newkey, NULL, false, &index));
  EXPECT_EQ(index, -1);
}

TEST_P(KeysetManagementTest, AddKeyset0Available) {
  // While this doesn't affect the hole-finding logic, it's good to cover the
  // full logical behavior by changing which key auths too.
  // master.0 -> master.1
  FilePath new_keyset = test_helper_.users[1].keyset_path
    .ReplaceExtension("1");
  test_helper_.users[1].keyset_path = new_keyset;
  KeysetSetUp();

  // The injected keyset in the fixture handles the up_ validation.
  SecureBlob newkey;
  cryptohome::Crypto::PasswordToPasskey("why not", system_salt_, &newkey);

  EXPECT_CALL(platform_,
      OpenFile(
        Property(&FilePath::value, EndsWith("master.0")),
        StrEq("wx")))
    .WillOnce(Return(reinterpret_cast<FILE*>(0xbeefbeef)));
  EXPECT_CALL(*active_vk_, Encrypt(newkey, _))
    .WillOnce(Return(true));
  EXPECT_CALL(*active_vk_,
      Save(Property(&FilePath::value, EndsWith("master.0"))))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_, DeleteFile(_, _))
    .Times(0);

  int index = -1;
  // Try to authenticate with an unknown key.
  ASSERT_EQ(CRYPTOHOME_ERROR_NOT_SET,
            homedirs_.AddKeyset(*up_, newkey, NULL, false, &index));
  EXPECT_EQ(index, 0);
}

TEST_P(KeysetManagementTest, AddKeyset10Available) {
  KeysetSetUp();

  // The injected keyset in the fixture handles the up_ validation.
  SecureBlob newkey;
  cryptohome::Crypto::PasswordToPasskey("why not", system_salt_, &newkey);

  EXPECT_CALL(platform_,
      OpenFile(
        Property(&FilePath::value,
          MatchesRegex(".*/master\\..$")),
        StrEq("wx")))
    .Times(10)
    .WillRepeatedly(Return(reinterpret_cast<FILE*>(NULL)));
  EXPECT_CALL(platform_,
      OpenFile(
        Property(&FilePath::value, EndsWith("master.10")),
        StrEq("wx")))
    .WillOnce(Return(reinterpret_cast<FILE*>(0xbeefbeef)));
  EXPECT_CALL(platform_, DeleteFile(_, _))
    .Times(0);
  EXPECT_CALL(*active_vk_, Encrypt(newkey, _))
    .WillOnce(Return(true));
  EXPECT_CALL(*active_vk_,
      Save(Property(&FilePath::value, EndsWith("master.10"))))
    .WillOnce(Return(true));

  int index = -1;
  ASSERT_EQ(CRYPTOHOME_ERROR_NOT_SET,
            homedirs_.AddKeyset(*up_, newkey, NULL, false, &index));
  EXPECT_EQ(index, 10);
}

TEST_P(KeysetManagementTest, AddKeysetNoFreeIndices) {
  KeysetSetUp();

  // The injected keyset in the fixture handles the up_ validation.
  SecureBlob newkey;
  cryptohome::Crypto::PasswordToPasskey("why not", system_salt_, &newkey);

  EXPECT_CALL(platform_, OpenFile(
        Property(&FilePath::value, MatchesRegex(".*/master\\..*$")),
        StrEq("wx")))
    .Times(kKeyFileMax)
    .WillRepeatedly(Return(reinterpret_cast<FILE*>(NULL)));
  EXPECT_CALL(platform_, DeleteFile(_, _))
    .Times(0);

  int index = -1;
  ASSERT_EQ(CRYPTOHOME_ERROR_KEY_QUOTA_EXCEEDED,
            homedirs_.AddKeyset(*up_, newkey, NULL, false, &index));
  EXPECT_EQ(index, -1);
}

TEST_P(KeysetManagementTest, AddKeysetEncryptFail) {
  KeysetSetUp();

  SecureBlob newkey;
  cryptohome::Crypto::PasswordToPasskey("why not", system_salt_, &newkey);
  int index = -1;
  // The injected keyset in the fixture handles the up_ validation.
  EXPECT_CALL(platform_,
      OpenFile(
        Property(&FilePath::value, EndsWith("master.0")),
        StrEq("wx")))
    .WillOnce(Return(reinterpret_cast<FILE*>(0xbeefbeef)));
  EXPECT_CALL(*active_vk_, Encrypt(newkey, _))
    .WillOnce(Return(false));
  EXPECT_CALL(platform_, CloseFile(reinterpret_cast<FILE*>(0xbeefbeef)))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      DeleteFile(
        Property(&FilePath::value, EndsWith("master.0")),
        false))
    .WillOnce(Return(true));
  ASSERT_EQ(CRYPTOHOME_ERROR_BACKING_STORE_FAILURE,
            homedirs_.AddKeyset(*up_, newkey, NULL, false, &index));
  EXPECT_EQ(index, -1);
}

TEST_P(KeysetManagementTest, AddKeysetSaveFail) {
  KeysetSetUp();

  SecureBlob newkey;
  cryptohome::Crypto::PasswordToPasskey("why not", system_salt_, &newkey);
  int index = -1;
  // The injected keyset in the fixture handles the up_ validation.
  EXPECT_CALL(platform_,
      OpenFile(
        Property(&FilePath::value, EndsWith("master.0")), StrEq("wx")))
    .WillOnce(Return(reinterpret_cast<FILE*>(0xbeefbeef)));
  EXPECT_CALL(*active_vk_, Encrypt(newkey, _))
    .WillOnce(Return(true));
  EXPECT_CALL(*active_vk_,
      Save(Property(&FilePath::value, EndsWith("master.0"))))
    .WillOnce(Return(false));
  EXPECT_CALL(platform_, CloseFile(reinterpret_cast<FILE*>(0xbeefbeef)))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      DeleteFile(
        Property(&FilePath::value, EndsWith("master.0")), false))
    .WillOnce(Return(true));
  ASSERT_EQ(CRYPTOHOME_ERROR_BACKING_STORE_FAILURE,
            homedirs_.AddKeyset(*up_, newkey, NULL, false, &index));
  EXPECT_EQ(index, -1);
}

TEST_P(KeysetManagementTest, AddKeysetNoResetSeedSuccess) {
  KeysetSetUp();
  ClearFakeSerializedResetSeed();

  std::string old_file_name("master.0");

  SecureBlob oldkey;
  SecureBlob newkey;
  up_->GetPasskey(&oldkey);
  cryptohome::Crypto::PasswordToPasskey("why not", system_salt_, &newkey);
  int index = -1;

  // Expectations for calls used to generate the reset_seed
  base::FilePath orig_file(old_file_name);
  EXPECT_CALL(*active_vk_, Encrypt(oldkey, _)).WillOnce(Return(true));
  EXPECT_CALL(*active_vk_,
              Save(Property(&FilePath::value, EndsWith(old_file_name))))
      .WillOnce(Return(true));
  EXPECT_CALL(*active_vk_, source_file()).WillOnce(ReturnRef(orig_file));

  // The injected keyset in the fixture handles the up_ validation.
  EXPECT_CALL(platform_,
              OpenFile(Property(&FilePath::value, EndsWith(old_file_name)),
                       StrEq("wx")))
      .WillOnce(Return(reinterpret_cast<FILE*>(NULL)));
  EXPECT_CALL(
      platform_,
      OpenFile(Property(&FilePath::value, EndsWith("master.1")), StrEq("wx")))
      .WillOnce(Return(reinterpret_cast<FILE*>(0xbeefbeef)));
  EXPECT_CALL(*active_vk_, Encrypt(newkey, _)).WillOnce(Return(true));
  EXPECT_CALL(*active_vk_,
              Save(Property(&FilePath::value, EndsWith("master.1"))))
      .WillOnce(Return(true));
  EXPECT_CALL(platform_, DeleteFile(_, _)).Times(0);

  EXPECT_EQ(CRYPTOHOME_ERROR_NOT_SET,
            homedirs_.AddKeyset(*up_, newkey, NULL, false, &index));
  EXPECT_EQ(index, 1);
}

TEST_P(KeysetManagementTest, ForceRemoveKeysetSuccess) {
  KeysetSetUp();
  EXPECT_CALL(platform_,
      DeleteFile(
        Property(&FilePath::value, EndsWith("master.0")), false))
    .WillOnce(Return(true));
  // There is only one call to VaultKeyset, so it gets the MockVaultKeyset
  // with index 0.
  EXPECT_CALL(*active_vks_[0], Load(_)).WillOnce(Return(true));
  ASSERT_TRUE(homedirs_.ForceRemoveKeyset("a0b0c0", 0));
}

TEST_P(KeysetManagementTest, ForceRemoveKeysetMissingKeyset) {
  KeysetSetUp();
  // There is only one call to VaultKeyset, so it gets the MockVaultKeyset
  // with index 0.
  // Set it to false, since there is no valid VaultKeyset.
  EXPECT_CALL(*active_vks_[0], Load(_)).WillOnce(Return(false));
  ASSERT_TRUE(homedirs_.ForceRemoveKeyset("a0b0c0", 0));
}

TEST_P(KeysetManagementTest, ForceRemoveKeysetNegativeIndex) {
  ASSERT_FALSE(homedirs_.ForceRemoveKeyset("a0b0c0", -1));
}

TEST_P(KeysetManagementTest, ForceRemoveKeysetOverMaxIndex) {
  ASSERT_FALSE(homedirs_.ForceRemoveKeyset("a0b0c0", kKeyFileMax));
}

TEST_P(KeysetManagementTest, ForceRemoveKeysetFailedDelete) {
  KeysetSetUp();
  EXPECT_CALL(platform_,
      DeleteFile(
        Property(&FilePath::value, EndsWith("master.0")),
        false))
    .WillOnce(Return(false));
  // There is only one call to VaultKeyset, so it gets the MockVaultKeyset
  // with index 0.
  EXPECT_CALL(*active_vks_[0], Load(_)).WillOnce(Return(true));
  ASSERT_FALSE(homedirs_.ForceRemoveKeyset("a0b0c0", 0));
}

TEST_P(KeysetManagementTest, MoveKeysetSuccess_0_to_1) {
  const std::string obfuscated = "a0b0c0";
  EXPECT_CALL(platform_,
      FileExists(Property(&FilePath::value, EndsWith("master.0"))))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      FileExists(Property(&FilePath::value, EndsWith("master.1"))))
    .WillOnce(Return(false));
  EXPECT_CALL(platform_,
      OpenFile(
        Property(&FilePath::value, EndsWith("master.1")), StrEq("wx")))
    .WillOnce(Return(reinterpret_cast<FILE*>(0xbeefbeef)));
  EXPECT_CALL(platform_,
      Rename(
        Property(&FilePath::value, EndsWith("master.0")),
        Property(&FilePath::value, EndsWith("master.1"))))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_, CloseFile(reinterpret_cast<FILE*>(0xbeefbeef)))
    .WillOnce(Return(true));
  ASSERT_TRUE(homedirs_.MoveKeyset(obfuscated, 0, 1));
}

TEST_P(KeysetManagementTest, MoveKeysetSuccess_1_to_99) {
  const std::string obfuscated = "a0b0c0";
  EXPECT_CALL(platform_,
      FileExists(Property(&FilePath::value, EndsWith("master.1"))))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      FileExists(Property(&FilePath::value, EndsWith("master.99"))))
    .WillOnce(Return(false));
  EXPECT_CALL(platform_,
      OpenFile(
        Property(&FilePath::value, EndsWith("master.99")),
        StrEq("wx")))
    .WillOnce(Return(reinterpret_cast<FILE*>(0xbeefbeef)));
  EXPECT_CALL(platform_,
      Rename(
        Property(&FilePath::value, EndsWith("master.1")),
        Property(&FilePath::value, EndsWith("master.99"))))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_, CloseFile(reinterpret_cast<FILE*>(0xbeefbeef)))
    .WillOnce(Return(true));
  ASSERT_TRUE(homedirs_.MoveKeyset(obfuscated, 1, 99));
}

TEST_P(KeysetManagementTest, MoveKeysetNegativeSource) {
  const std::string obfuscated = "a0b0c0";
  ASSERT_FALSE(homedirs_.MoveKeyset(obfuscated, -1, 1));
}

TEST_P(KeysetManagementTest, MoveKeysetNegativeDestination) {
  const std::string obfuscated = "a0b0c0";
  ASSERT_FALSE(homedirs_.MoveKeyset(obfuscated, 1, -1));
}

TEST_P(KeysetManagementTest, MoveKeysetTooLargeDestination) {
  const std::string obfuscated = "a0b0c0";
  ASSERT_FALSE(homedirs_.MoveKeyset(obfuscated, 1, kKeyFileMax));
}

TEST_P(KeysetManagementTest, MoveKeysetTooLargeSource) {
  const std::string obfuscated = "a0b0c0";
  ASSERT_FALSE(homedirs_.MoveKeyset(obfuscated, kKeyFileMax, 0));
}

TEST_P(KeysetManagementTest, MoveKeysetMissingSource) {
  const std::string obfuscated = "a0b0c0";
  EXPECT_CALL(platform_,
      FileExists(Property(&FilePath::value, EndsWith("master.0"))))
    .WillOnce(Return(false));
  ASSERT_FALSE(homedirs_.MoveKeyset(obfuscated, 0, 1));
}

TEST_P(KeysetManagementTest, MoveKeysetDestinationExists) {
  const std::string obfuscated = "a0b0c0";
  EXPECT_CALL(platform_,
      FileExists(Property(&FilePath::value, EndsWith("master.0"))))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      FileExists(Property(&FilePath::value, EndsWith("master.1"))))
    .WillOnce(Return(true));
  ASSERT_FALSE(homedirs_.MoveKeyset(obfuscated, 0, 1));
}

TEST_P(KeysetManagementTest, MoveKeysetExclusiveOpenFailed) {
  const std::string obfuscated = "a0b0c0";
  EXPECT_CALL(platform_,
      FileExists(Property(&FilePath::value, EndsWith("master.0"))))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      FileExists(Property(&FilePath::value, EndsWith("master.1"))))
    .WillOnce(Return(false));
  EXPECT_CALL(platform_,
      OpenFile(
        Property(&FilePath::value, EndsWith("master.1")),
        StrEq("wx")))
    .WillOnce(Return(reinterpret_cast<FILE*>(NULL)));
  ASSERT_FALSE(homedirs_.MoveKeyset(obfuscated, 0, 1));
}

TEST_P(KeysetManagementTest, MoveKeysetRenameFailed) {
  const std::string obfuscated = "a0b0c0";
  EXPECT_CALL(platform_,
      FileExists(Property(&FilePath::value, EndsWith("master.0"))))
    .WillOnce(Return(true));
  EXPECT_CALL(platform_,
      FileExists(Property(&FilePath::value, EndsWith("master.1"))))
    .WillOnce(Return(false));
  EXPECT_CALL(platform_,
      OpenFile(
        Property(&FilePath::value, EndsWith("master.1")),
        StrEq("wx")))
    .WillOnce(Return(reinterpret_cast<FILE*>(0xbeefbeef)));
  EXPECT_CALL(platform_,
      Rename(
        Property(&FilePath::value, EndsWith("master.0")),
        Property(&FilePath::value, EndsWith("master.1"))))
    .WillOnce(Return(false));
  EXPECT_CALL(platform_, CloseFile(reinterpret_cast<FILE*>(0xbeefbeef)))
    .WillOnce(Return(true));
  ASSERT_FALSE(homedirs_.MoveKeyset(obfuscated, 0, 1));
}

}  // namespace cryptohome
