// 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_, FileExists(base::FilePath(kLockedToSingleUserFile)))
    .WillRepeatedly(Return(false));
  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_);
  EXPECT_CALL(platform_, FileExists(base::FilePath(kLockedToSingleUserFile)))
      .WillRepeatedly(Return(false));
  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_);
  EXPECT_CALL(platform_, FileExists(base::FilePath(kLockedToSingleUserFile)))
      .WillRepeatedly(Return(false));
  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_, FileExists(base::FilePath(kLockedToSingleUserFile)))
      .WillRepeatedly(Return(false));
    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
