Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3afca7c1 authored by David Anderson's avatar David Anderson
Browse files

libfiemap: Remove brittle tests.

libfiemap functionality is extensively tested via libsnapshot, gsid, and
fiemap_writer_test. However those tests rely on the configuration of the
device, and libfiemap has fairly different behavior based on whether FBE
or metadata encryption is in use. (The former will use loop devices, the
latter uses dm-linear).

To expand coverage, we added tests with very complicated nesting,
creating fiemaps on a rw partition mounted off a device backed by a
fiemap. Unsurprisingly, this was brittle to begin with, and now
consistently fails due to the intermediate partition not having
sepolicy.

Given the preference toward metadata encryption, and the fact that the
FBE mode will still be properly tested via VTS, let's just remove these
tests.

Bug: 148874852
Test: fiemap_image_test
Change-Id: I7be7d44dea81508505c050ed995b3b78086ad35f
Merged-In: I7be7d44dea81508505c050ed995b3b78086ad35f
parent 64021d83
Loading
Loading
Loading
Loading
+0 −126
Original line number Diff line number Diff line
@@ -131,132 +131,6 @@ TEST_F(NativeTest, GetMappedImageDevice) {
    ASSERT_TRUE(manager_->UnmapImageDevice(base_name_));
}

// This fixture is for tests against a simulated device environment. Rather
// than use /data, we create an image and then layer a new filesystem within
// it. Each test then decides how to mount and create layered images. This
// allows us to test FBE vs FDE configurations.
class ImageTest : public ::testing::Test {
  public:
    ImageTest() : dm_(DeviceMapper::Instance()) {}

    void SetUp() override {
        manager_ = ImageManager::Open(kMetadataPath, gDataPath);
        ASSERT_NE(manager_, nullptr);

        manager_->set_partition_opener(std::make_unique<TestPartitionOpener>());

        submanager_ = ImageManager::Open(kMetadataPath + "/mnt"s, gDataPath + "/mnt"s);
        ASSERT_NE(submanager_, nullptr);

        submanager_->set_partition_opener(std::make_unique<TestPartitionOpener>());

        // Ensure that metadata is cleared in between runs.
        submanager_->RemoveAllImages();
        manager_->RemoveAllImages();

        const ::testing::TestInfo* tinfo = ::testing::UnitTest::GetInstance()->current_test_info();
        base_name_ = tinfo->name();
        test_image_name_ = base_name_ + "-base";
        wrapper_device_name_ = base_name_ + "-wrapper";

        ASSERT_TRUE(manager_->CreateBackingImage(base_name_, kTestImageSize * 16, false, nullptr));
        ASSERT_TRUE(manager_->MapImageDevice(base_name_, 5s, &base_device_));
    }

    void TearDown() override {
        submanager_->UnmapImageDevice(test_image_name_);
        umount(gDataMountPath.c_str());
        dm_.DeleteDeviceIfExists(wrapper_device_name_);
        manager_->UnmapImageDevice(base_name_);
        manager_->DeleteBackingImage(base_name_);
    }

  protected:
    bool DoFormat(const std::string& device) {
        // clang-format off
        std::vector<std::string> mkfs_args = {
            "/system/bin/mke2fs",
            "-F",
            "-b 4096",
            "-t ext4",
            "-m 0",
            "-O has_journal",
            device,
            ">/dev/null",
            "2>/dev/null",
            "</dev/null",
        };
        // clang-format on
        auto command = android::base::Join(mkfs_args, " ");
        return system(command.c_str()) == 0;
    }

    std::unique_ptr<ImageManager> manager_;
    std::unique_ptr<ImageManager> submanager_;

    DeviceMapper& dm_;
    std::string base_name_;
    std::string base_device_;
    std::string test_image_name_;
    std::string wrapper_device_name_;
};

TEST_F(ImageTest, DirectMount) {
    ASSERT_TRUE(DoFormat(base_device_));
    ASSERT_EQ(mount(base_device_.c_str(), gDataMountPath.c_str(), "ext4", 0, nullptr), 0);
    ASSERT_TRUE(submanager_->CreateBackingImage(test_image_name_, kTestImageSize, false, nullptr));

    std::string path;
    ASSERT_TRUE(submanager_->MapImageDevice(test_image_name_, 5s, &path));
    ASSERT_TRUE(android::base::StartsWith(path, "/dev/block/loop"));
}

TEST_F(ImageTest, IndirectMount) {
#ifdef SKIP_TEST_IN_PRESUBMIT
    GTEST_SKIP() << "WIP failure b/148874852";
#endif
    // Create a simple wrapper around the base device that we'll mount from
    // instead. This will simulate the code paths for dm-crypt/default-key/bow
    // and force us to use device-mapper rather than loop devices.
    uint64_t device_size = 0;
    {
        unique_fd fd(open(base_device_.c_str(), O_RDWR | O_CLOEXEC));
        ASSERT_GE(fd, 0);
        device_size = get_block_device_size(fd);
        ASSERT_EQ(device_size, kTestImageSize * 16);
    }
    uint64_t num_sectors = device_size / 512;

    auto& dm = DeviceMapper::Instance();

    DmTable table;
    table.Emplace<DmTargetLinear>(0, num_sectors, base_device_, 0);
    ASSERT_TRUE(dm.CreateDevice(wrapper_device_name_, table));

    // Format and mount.
    std::string wrapper_device;
    ASSERT_TRUE(dm.GetDmDevicePathByName(wrapper_device_name_, &wrapper_device));
    ASSERT_TRUE(WaitForFile(wrapper_device, 5s));
    ASSERT_TRUE(DoFormat(wrapper_device));
    ASSERT_EQ(mount(wrapper_device.c_str(), gDataMountPath.c_str(), "ext4", 0, nullptr), 0);

    ASSERT_TRUE(submanager_->CreateBackingImage(test_image_name_, kTestImageSize, false, nullptr));

    std::set<std::string> backing_devices;
    auto init = [&](std::set<std::string> devices) -> bool {
        backing_devices = std::move(devices);
        return true;
    };

    std::string path;
    ASSERT_TRUE(submanager_->MapImageDevice(test_image_name_, 5s, &path));
    ASSERT_TRUE(android::base::StartsWith(path, "/dev/block/dm-"));
    ASSERT_TRUE(submanager_->UnmapImageDevice(test_image_name_));
    ASSERT_TRUE(submanager_->MapAllImages(init));
    ASSERT_FALSE(backing_devices.empty());
    ASSERT_TRUE(submanager_->UnmapImageDevice(test_image_name_));
}

bool Mkdir(const std::string& path) {
    if (mkdir(path.c_str(), 0700) && errno != EEXIST) {
        std::cerr << "Could not mkdir " << path << ": " << strerror(errno) << std::endl;