blob: 2f5c1e351498837d4e1d351b065f6eac1b458347 [file] [log] [blame]
// Copyright 2021 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/fake_platform/fake_mount_mapper.h"
#include <list>
#include <map>
#include <memory>
#include <base/files/file_path.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "cryptohome/fake_platform/fake_fake_mount_mapping_redirect_factory.h"
#include "cryptohome/fake_platform/test_file_path.h"
namespace cryptohome {
namespace {
constexpr char kFile[] = "file";
constexpr char kDirectory[] = "directory";
} // namespace
class FakeMountMapperTest : public ::testing::Test {
public:
FakeMountMapperTest()
: fake_mapper_(std::make_unique<FakeMountMapper>(
kRoot,
std::make_unique<FakeFakeMountMappingRedirectFactory>(
std::list<base::FilePath>{kRedirect1, kRedirect2,
kRedirect3}))) {}
protected:
const base::FilePath kRoot{"/tmp/root"};
const base::FilePath kRedirect1{"/tmp/redirect1"};
const base::FilePath kRedirect2{"/tmp/redirect2"};
const base::FilePath kRedirect3{"/tmp/redirect3"};
const base::FilePath kSource1{"/home/.shadow/0001/mount"};
const base::FilePath kSource2{"/home/.shadow/0010/mount"};
const base::FilePath kSource3{"/home/.shadow/0100/mount"};
const base::FilePath kTarget0{"/home/user/chronos/"};
const base::FilePath kTarget0Directory{"/home/user/chronos/directory"};
const base::FilePath kTarget0File{"/home/user/chronos/file"};
const base::FilePath kTarget1{"/home/user/u-0001"};
const base::FilePath kTarget1File{"/home/user/u-0001/file"};
const base::FilePath kTarget2{"/home/user/u-0010"};
const base::FilePath kTarget2File{"/home/user/u-0010/file"};
const base::FilePath kTarget3{"/home/user/u-0100"};
const base::FilePath kTarget3File{"/home/user/u-0100/file"};
const base::FilePath kTarget4{"/home/user/u-1000"};
const base::FilePath kTarget4File{"/home/user/u-1000/file"};
const base::FilePath kTarget5{"/home/user/u-aaaa"};
const base::FilePath kTarget5File{"/home/user/u-aaaa/file"};
const std::unique_ptr<FakeMountMapper> fake_mapper_;
};
namespace {
using ::testing::UnorderedElementsAreArray;
TEST_F(FakeMountMapperTest, SimpleMountRedirectUnmountChecks) {
// Test that mount and unmount sequence works, and path resolution produces
// expected values.
// Mount
ASSERT_TRUE(fake_mapper_->Mount(kSource1, kTarget1));
ASSERT_TRUE(fake_mapper_->Mount(kSource2, kTarget2));
// Check redirects are correct (from the redirect factory)
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1), kRedirect1);
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1File), kRedirect1.Append(kFile));
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget2), kRedirect2);
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget2File), kRedirect2.Append(kFile));
// Mount the same source to a different target
ASSERT_TRUE(fake_mapper_->Mount(kSource1, kTarget0));
// Should appear on the same redirect
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget0), kRedirect1);
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget0File), kRedirect1.Append(kFile));
// Unmount
ASSERT_TRUE(fake_mapper_->Unmount(kTarget0));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget1));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget2));
// Now resolve should return the files itself
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget0File),
fake_platform::SpliceTestFilePath(kRoot, kTarget0File));
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1File),
fake_platform::SpliceTestFilePath(kRoot, kTarget1File));
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget2File),
fake_platform::SpliceTestFilePath(kRoot, kTarget2File));
// Another unmount should fail
ASSERT_FALSE(fake_mapper_->Unmount(kTarget0));
ASSERT_FALSE(fake_mapper_->Unmount(kTarget1));
ASSERT_FALSE(fake_mapper_->Unmount(kTarget2));
// Mount in a different order
ASSERT_TRUE(fake_mapper_->Mount(kSource1, kTarget0));
ASSERT_TRUE(fake_mapper_->Mount(kSource2, kTarget2));
ASSERT_TRUE(fake_mapper_->Mount(kSource1, kTarget1));
// Check redirects are still correct
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget0), kRedirect1);
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget0File), kRedirect1.Append(kFile));
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1), kRedirect1);
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1File), kRedirect1.Append(kFile));
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget2), kRedirect2);
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget2File), kRedirect2.Append(kFile));
// Unmount
ASSERT_TRUE(fake_mapper_->Unmount(kTarget0));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget1));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget2));
}
TEST_F(FakeMountMapperTest, SimpleBindRedirectUnmountChecks) {
// Test that bind and unmount sequence works, and path resolution produces
// expected values.
// Bind
ASSERT_TRUE(fake_mapper_->Bind(kSource1, kTarget1));
ASSERT_TRUE(fake_mapper_->Bind(kSource2, kTarget2));
// Check redirects are correct (tmpfs location of the source)
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1),
fake_platform::SpliceTestFilePath(kRoot, kSource1));
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1File),
fake_platform::SpliceTestFilePath(kRoot, kSource1).Append(kFile));
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget2),
fake_platform::SpliceTestFilePath(kRoot, kSource2));
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget2File),
fake_platform::SpliceTestFilePath(kRoot, kSource2).Append(kFile));
// Bind the same source to a different target
ASSERT_TRUE(fake_mapper_->Bind(kSource1, kTarget0));
// Should appear on the same redirect
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget0),
fake_platform::SpliceTestFilePath(kRoot, kSource1));
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget0File),
fake_platform::SpliceTestFilePath(kRoot, kSource1).Append(kFile));
// Unmount
ASSERT_TRUE(fake_mapper_->Unmount(kTarget0));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget1));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget2));
// Now resolve should return the files itself
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget0File),
fake_platform::SpliceTestFilePath(kRoot, kTarget0File));
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1File),
fake_platform::SpliceTestFilePath(kRoot, kTarget1File));
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget2File),
fake_platform::SpliceTestFilePath(kRoot, kTarget2File));
// Another unmount should fail
ASSERT_FALSE(fake_mapper_->Unmount(kTarget0));
ASSERT_FALSE(fake_mapper_->Unmount(kTarget1));
ASSERT_FALSE(fake_mapper_->Unmount(kTarget2));
// Bind in a different order
ASSERT_TRUE(fake_mapper_->Bind(kSource1, kTarget0));
ASSERT_TRUE(fake_mapper_->Bind(kSource2, kTarget2));
ASSERT_TRUE(fake_mapper_->Bind(kSource1, kTarget1));
// Check redirects are still correct
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget0),
fake_platform::SpliceTestFilePath(kRoot, kSource1));
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget0File),
fake_platform::SpliceTestFilePath(kRoot, kSource1).Append(kFile));
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1),
fake_platform::SpliceTestFilePath(kRoot, kSource1));
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1File),
fake_platform::SpliceTestFilePath(kRoot, kSource1).Append(kFile));
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget2),
fake_platform::SpliceTestFilePath(kRoot, kSource2));
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget2File),
fake_platform::SpliceTestFilePath(kRoot, kSource2).Append(kFile));
// Unmount
ASSERT_TRUE(fake_mapper_->Unmount(kTarget0));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget1));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget2));
}
TEST_F(FakeMountMapperTest, SourceRedirectMountConsistency) {
// Check the redirect stays the same across multiple mount/unmount calls.
// Mount
ASSERT_TRUE(fake_mapper_->Mount(kSource1, kTarget0));
// Check redirects is correct
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget0File), kRedirect1.Append(kFile));
// Unmount
ASSERT_TRUE(fake_mapper_->Unmount(kTarget0));
// Mount another source onto the same target
ASSERT_TRUE(fake_mapper_->Mount(kSource2, kTarget0));
// Check redirects is correct (different from the first case)
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget0File), kRedirect2.Append(kFile));
// Unmount
ASSERT_TRUE(fake_mapper_->Unmount(kTarget0));
// Mount the first source again
ASSERT_TRUE(fake_mapper_->Mount(kSource1, kTarget0));
// Check redirects is correct (the same with the first casE).
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget0File), kRedirect1.Append(kFile));
// Unmount
ASSERT_TRUE(fake_mapper_->Unmount(kTarget0));
}
TEST_F(FakeMountMapperTest, SourceRedirectBindConsistency) {
// Check the redirect stays the same across multiple bind/unmount calls.
// Bind
ASSERT_TRUE(fake_mapper_->Bind(kSource1, kTarget0));
// Check redirects is correct
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget0File),
fake_platform::SpliceTestFilePath(kRoot, kSource1).Append(kFile));
// Unmount
ASSERT_TRUE(fake_mapper_->Unmount(kTarget0));
// Bind another source onto the same target
ASSERT_TRUE(fake_mapper_->Bind(kSource2, kTarget0));
// Check redirects is correct (different from the first case)
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget0File),
fake_platform::SpliceTestFilePath(kRoot, kSource2).Append(kFile));
// Unmount
ASSERT_TRUE(fake_mapper_->Unmount(kTarget0));
// Bind the first source again
ASSERT_TRUE(fake_mapper_->Bind(kSource1, kTarget0));
// Check redirects is correct (the same with the first casE).
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget0File),
fake_platform::SpliceTestFilePath(kRoot, kSource1).Append(kFile));
// Unmount
ASSERT_TRUE(fake_mapper_->Unmount(kTarget0));
}
TEST_F(FakeMountMapperTest, BusyUnmount_DirectMapping) {
// Check that parent mount can not be unmounted before dependent one.
// In this test the target of parent is the exact source for child.
// Mount a chain
ASSERT_TRUE(fake_mapper_->Mount(kSource1, kTarget0));
ASSERT_TRUE(fake_mapper_->Bind(kTarget0, kTarget1));
// Verify redirect
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1File), kRedirect1.Append(kFile));
// Unmounting in the wrong order should fail
ASSERT_FALSE(fake_mapper_->Unmount(kTarget0));
// Verify redirect
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1File), kRedirect1.Append(kFile));
// Unmounting in the correct order succeeds
ASSERT_TRUE(fake_mapper_->Unmount(kTarget1));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget0));
}
TEST_F(FakeMountMapperTest, BusyUnmount_InnerPathMapping) {
// Check that parent mount can not be unmounted before dependent one.
// In this test a path within the target of parent is the source for child.
// Mount a chain
ASSERT_TRUE(fake_mapper_->Mount(kSource1, kTarget0));
ASSERT_TRUE(fake_mapper_->Bind(kTarget0Directory, kTarget1));
// Verify redirect
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1File),
kRedirect1.Append(kDirectory).Append(kFile));
// Unmounting in the wrong order should fail
ASSERT_FALSE(fake_mapper_->Unmount(kTarget0));
// Verify redirect
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1File),
kRedirect1.Append(kDirectory).Append(kFile));
// Unmounting in the correct order succeeds
ASSERT_TRUE(fake_mapper_->Unmount(kTarget1));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget0));
}
TEST_F(FakeMountMapperTest, MultipleMountsShouldFail) {
// Second mount to the same target should fail, but the first mount
// is still ok after that.
ASSERT_TRUE(fake_mapper_->Mount(kSource1, kTarget1));
ASSERT_FALSE(fake_mapper_->Mount(kSource2, kTarget1));
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1File), kRedirect1.Append(kFile));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget1));
// Repeat other way around
ASSERT_TRUE(fake_mapper_->Mount(kSource2, kTarget1));
ASSERT_FALSE(fake_mapper_->Mount(kSource1, kTarget1));
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1File), kRedirect2.Append(kFile));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget1));
}
TEST_F(FakeMountMapperTest, MultipleBindShouldFail) {
// Second bind to the same target should fail, but the first bind
// is still ok after that.
ASSERT_TRUE(fake_mapper_->Bind(kSource1, kTarget1));
ASSERT_FALSE(fake_mapper_->Bind(kSource2, kTarget1));
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1File),
fake_platform::SpliceTestFilePath(kRoot, kSource1).Append(kFile));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget1));
// Repeat other way around
ASSERT_TRUE(fake_mapper_->Bind(kSource2, kTarget1));
ASSERT_FALSE(fake_mapper_->Bind(kSource1, kTarget1));
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1File),
fake_platform::SpliceTestFilePath(kRoot, kSource2).Append(kFile));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget1));
}
TEST_F(FakeMountMapperTest, MultipleUnmountShouldFail) {
// Unmounting not mounted target should fail.
ASSERT_FALSE(fake_mapper_->Unmount(kTarget1));
ASSERT_FALSE(fake_mapper_->Unmount(kTarget2));
// Mount and Bind
ASSERT_TRUE(fake_mapper_->Mount(kSource1, kTarget1));
ASSERT_TRUE(fake_mapper_->Bind(kSource2, kTarget2));
// Now unmount.
ASSERT_TRUE(fake_mapper_->Unmount(kTarget1));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget2));
// Subsequent unmount should fail.
ASSERT_FALSE(fake_mapper_->Unmount(kTarget1));
ASSERT_FALSE(fake_mapper_->Unmount(kTarget2));
}
TEST_F(FakeMountMapperTest, ResolveMountBindChain) {
// Check the Mount->Bind->File chain is resolved correctly.
// Mount
ASSERT_TRUE(fake_mapper_->Mount(kSource1, kTarget0));
ASSERT_TRUE(fake_mapper_->Bind(kTarget0, kTarget1));
// File is on the factory created redirect of the first mount.
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1), kRedirect1);
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1File), kRedirect1.Append(kFile));
// Unmount
ASSERT_TRUE(fake_mapper_->Unmount(kTarget1));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget0));
}
TEST_F(FakeMountMapperTest, ResolveMountInnerBindChain) {
// Check the Mount->Subdirectory Bind->File chain is resolved correctly.
// Mount
ASSERT_TRUE(fake_mapper_->Mount(kSource1, kTarget0));
ASSERT_TRUE(fake_mapper_->Bind(kTarget0Directory, kTarget1));
// File is on the factory created redirect of the first mount with relative
// path.
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1), kRedirect1.Append(kDirectory));
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1File),
kRedirect1.Append(kDirectory).Append(kFile));
// Unmount
ASSERT_TRUE(fake_mapper_->Unmount(kTarget1));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget0));
}
TEST_F(FakeMountMapperTest, ResolveBindBindChain) {
// Check the Bind->Bind->File chain is resolved correctly.
// Mount
ASSERT_TRUE(fake_mapper_->Bind(kSource1, kTarget0));
ASSERT_TRUE(fake_mapper_->Bind(kTarget0, kTarget1));
// File is on the source location of the first mount.
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1),
fake_platform::SpliceTestFilePath(kRoot, kSource1));
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1File),
fake_platform::SpliceTestFilePath(kRoot, kSource1).Append(kFile));
// Unmount
ASSERT_TRUE(fake_mapper_->Unmount(kTarget1));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget0));
}
TEST_F(FakeMountMapperTest, ResolveBindInnerBindChain) {
// Check the Bind->Subdirectory Bind->File chain is resolved correctly.
// Mount
ASSERT_TRUE(fake_mapper_->Bind(kSource1, kTarget0));
ASSERT_TRUE(fake_mapper_->Bind(kTarget0Directory, kTarget1));
// File is on the source location of the first mount with relative path.
EXPECT_EQ(
fake_mapper_->ResolvePath(kTarget1),
fake_platform::SpliceTestFilePath(kRoot, kSource1).Append(kDirectory));
EXPECT_EQ(fake_mapper_->ResolvePath(kTarget1File),
fake_platform::SpliceTestFilePath(kRoot, kSource1)
.Append(kDirectory)
.Append(kFile));
// Unmount
ASSERT_TRUE(fake_mapper_->Unmount(kTarget1));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget0));
}
TEST_F(FakeMountMapperTest, Check_IsMounted) {
// Mount
ASSERT_TRUE(fake_mapper_->Mount(kSource1, kTarget0));
ASSERT_TRUE(fake_mapper_->Bind(kSource1, kTarget1));
ASSERT_TRUE(fake_mapper_->Bind(kSource2, kTarget2));
ASSERT_TRUE(fake_mapper_->Mount(kSource3, kTarget3));
ASSERT_TRUE(fake_mapper_->Mount(kTarget1, kTarget4));
// Check IsMounted returns true only for the target paths which are mapped
EXPECT_TRUE(fake_mapper_->IsMounted(kTarget0));
EXPECT_TRUE(fake_mapper_->IsMounted(kTarget1));
EXPECT_TRUE(fake_mapper_->IsMounted(kTarget2));
EXPECT_TRUE(fake_mapper_->IsMounted(kTarget3));
EXPECT_TRUE(fake_mapper_->IsMounted(kTarget4));
EXPECT_FALSE(fake_mapper_->IsMounted(kTarget5));
// Unmount
ASSERT_TRUE(fake_mapper_->Unmount(kTarget4));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget3));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget2));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget1));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget0));
}
TEST_F(FakeMountMapperTest, Check_IsOnMount) {
// Mount
ASSERT_TRUE(fake_mapper_->Mount(kSource1, kTarget0));
ASSERT_TRUE(fake_mapper_->Bind(kSource1, kTarget1));
ASSERT_TRUE(fake_mapper_->Bind(kSource2, kTarget2));
ASSERT_TRUE(fake_mapper_->Mount(kSource3, kTarget3));
ASSERT_TRUE(fake_mapper_->Mount(kTarget1, kTarget4));
// Check IsOnMount returns true for the mapped targets ...
EXPECT_TRUE(fake_mapper_->IsOnMount(kTarget0));
EXPECT_TRUE(fake_mapper_->IsOnMount(kTarget1));
EXPECT_TRUE(fake_mapper_->IsOnMount(kTarget2));
EXPECT_TRUE(fake_mapper_->IsOnMount(kTarget3));
EXPECT_TRUE(fake_mapper_->IsOnMount(kTarget4));
EXPECT_FALSE(fake_mapper_->IsOnMount(kTarget5));
// ... and the paths under them
EXPECT_TRUE(fake_mapper_->IsOnMount(kTarget0File));
EXPECT_TRUE(fake_mapper_->IsOnMount(kTarget1File));
EXPECT_TRUE(fake_mapper_->IsOnMount(kTarget2File));
EXPECT_TRUE(fake_mapper_->IsOnMount(kTarget3File));
EXPECT_TRUE(fake_mapper_->IsOnMount(kTarget4File));
EXPECT_FALSE(fake_mapper_->IsOnMount(kTarget5File));
// Unmount
ASSERT_TRUE(fake_mapper_->Unmount(kTarget4));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget3));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget2));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget1));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget0));
}
TEST_F(FakeMountMapperTest, ListMountsBySourcePrefix_String) {
// Mount
ASSERT_TRUE(fake_mapper_->Mount(kSource1, kTarget0));
ASSERT_TRUE(fake_mapper_->Bind(kSource1, kTarget1));
ASSERT_TRUE(fake_mapper_->Bind(kSource2, kTarget2));
ASSERT_TRUE(fake_mapper_->Mount(kSource3, kTarget3));
std::multimap<const base::FilePath, const base::FilePath> result;
// Multiple sources, some of which multi-targeted
const std::string prefix_1("/home/.shadow/");
const std::multimap<const base::FilePath, const base::FilePath>
expected_mounts_1{
{kSource1, kTarget0},
{kSource1, kTarget1},
{kSource2, kTarget2},
{kSource3, kTarget3},
};
fake_mapper_->ListMountsBySourcePrefix(prefix_1, &result);
EXPECT_THAT(result, ::testing::UnorderedElementsAreArray(expected_mounts_1));
// Multiple sources, some of which multi-targeted, but on a partial path
const std::string prefix_2("/home/.shadow/00");
const std::multimap<const base::FilePath, const base::FilePath>
expected_mounts_2{
{kSource1, kTarget0},
{kSource1, kTarget1},
{kSource2, kTarget2},
};
fake_mapper_->ListMountsBySourcePrefix(prefix_2, &result);
EXPECT_THAT(result, ::testing::UnorderedElementsAreArray(expected_mounts_2));
// A prefix that doesn't match any sources
const std::string prefix_3("/home/.shadow/1");
const std::multimap<const base::FilePath, const base::FilePath>
expected_mounts_3;
fake_mapper_->ListMountsBySourcePrefix(prefix_3, &result);
EXPECT_THAT(result, ::testing::UnorderedElementsAreArray(expected_mounts_3));
// Unmount
ASSERT_TRUE(fake_mapper_->Unmount(kTarget3));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget2));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget1));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget0));
}
TEST_F(FakeMountMapperTest, ListMountsBySourcePrefix_Path) {
// Mount
ASSERT_TRUE(fake_mapper_->Mount(kSource1, kTarget0));
ASSERT_TRUE(fake_mapper_->Bind(kSource1, kTarget1));
ASSERT_TRUE(fake_mapper_->Bind(kSource2, kTarget2));
ASSERT_TRUE(fake_mapper_->Mount(kSource3, kTarget3));
ASSERT_TRUE(fake_mapper_->Mount(kTarget1, kTarget4));
std::multimap<const base::FilePath, const base::FilePath> result;
// Multiple sources, some of which multi-targeted
const base::FilePath prefix_1("/home/.shadow/");
const std::multimap<const base::FilePath, const base::FilePath>
expected_mounts_1{
{kSource1, kTarget0},
{kSource1, kTarget1},
{kSource2, kTarget2},
{kSource3, kTarget3},
};
fake_mapper_->ListMountsBySourcePrefix(prefix_1, &result);
EXPECT_THAT(result, ::testing::UnorderedElementsAreArray(expected_mounts_1));
// Prefix exactly matches the source
const base::FilePath prefix_2(kTarget1);
const std::multimap<const base::FilePath, const base::FilePath>
expected_mounts_2{
{kTarget1, kTarget4},
};
fake_mapper_->ListMountsBySourcePrefix(prefix_2, &result);
EXPECT_THAT(result, ::testing::UnorderedElementsAreArray(expected_mounts_2));
// Not a source for mount
const base::FilePath prefix_3("/var/log");
const std::multimap<const base::FilePath, const base::FilePath>
expected_mounts_3;
fake_mapper_->ListMountsBySourcePrefix(prefix_3, &result);
EXPECT_THAT(result, ::testing::UnorderedElementsAreArray(expected_mounts_3));
// Unmount
ASSERT_TRUE(fake_mapper_->Unmount(kTarget4));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget3));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget2));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget1));
ASSERT_TRUE(fake_mapper_->Unmount(kTarget0));
}
} // namespace
} // namespace cryptohome