~aleteoryx/muditaos

ref: 2a53becd2524fc0dba7260632d3ec409eb3a61fd muditaos/module-platform/linux/tests/unittest_filesystem_dualmount.cpp -rw-r--r-- 5.0 KiB
2a53becd — Maciej Janicki [BH-1136] Fix bootloop after low power 4 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>

#include <platform/linux/DiskImage.hpp>

#include <purefs/fs/filesystem.hpp>
#include <purefs/blkdev/disk_manager.hpp>
#include <purefs/fs/drivers/filesystem_vfat.hpp>
#include <purefs/fs/drivers/filesystem_littlefs.hpp>

#include "test-setup.hpp"

#include <sys/statvfs.h>
#include <sys/stat.h>
#include <fcntl.h>

namespace
{
    constexpr auto lfs_disk_image = "lfstest.img";

    auto prepare_filesystem(std::string_view vfat_dev_name, std::string_view lfs_dev_name)
        -> std::pair<std::unique_ptr<purefs::fs::filesystem>, std::shared_ptr<purefs::blkdev::disk_manager>>
    {
        using namespace purefs;

        auto dm        = std::make_shared<blkdev::disk_manager>();
        auto vfat_disk = std::make_shared<blkdev::disk_image>(::testing::vfs::disk_image);
        auto lfs_disk  = std::make_shared<blkdev::disk_image>(lfs_disk_image);

        if (dm->register_device(vfat_disk, vfat_dev_name) != 0) {
            return {};
        }
        if (dm->register_device(lfs_disk, lfs_dev_name) != 0) {
            return {};
        }

        auto fs_core        = std::make_unique<fs::filesystem>(dm);
        const auto vfs_vfat = std::make_shared<fs::drivers::filesystem_vfat>();
        const auto vfs_lfs  = std::make_shared<fs::drivers::filesystem_littlefs>();

        if (fs_core->register_filesystem("vfat", vfs_vfat) != 0) {
            return {};
        }
        if (fs_core->register_filesystem("littlefs", vfs_lfs) != 0) {
            return {};
        }

        return std::make_pair(std::move(fs_core), std::move(dm));
    }
} // namespace

TEST_CASE("dualmount: Basic mount")
{
    using namespace purefs;

    auto dm        = std::make_shared<blkdev::disk_manager>();
    auto vfat_disk = std::make_shared<blkdev::disk_image>(::testing::vfs::disk_image);
    auto lfs_disk  = std::make_shared<blkdev::disk_image>(lfs_disk_image);
    REQUIRE(vfat_disk);
    REQUIRE(lfs_disk);
    REQUIRE(dm->register_device(vfat_disk, "vfat0") == 0);
    REQUIRE(dm->register_device(lfs_disk, "lfs0") == 0);

    fs::filesystem fs_core(dm);
    const auto vfs_vfat = std::make_shared<fs::drivers::filesystem_vfat>();
    const auto vfs_lfs  = std::make_shared<fs::drivers::filesystem_littlefs>();
    REQUIRE(vfs_vfat->mount_count() == 0);
    REQUIRE(vfs_lfs->mount_count() == 0);
    REQUIRE(fs_core.register_filesystem("vfat", vfs_vfat) == 0);
    REQUIRE(fs_core.register_filesystem("littlefs", vfs_lfs) == 0);

    REQUIRE(fs_core.mount("vfat0part0", "/vfat", "vfat") == 0);
    REQUIRE(fs_core.mount("lfs0part0", "/lfs", "littlefs") == 0);
    REQUIRE(vfs_vfat->mount_count() == 1);
    REQUIRE(vfs_lfs->mount_count() == 1);
    REQUIRE(fs_core.umount("/vfat") == 0);
    REQUIRE(fs_core.umount("/lfs") == 0);
}

TEST_CASE("dualmount: API tests")
{
    auto [fs_core, dm] = prepare_filesystem("vfat0", "lfs0");
    REQUIRE(fs_core->mount("vfat0part0", "/vfat", "vfat") == 0);
    REQUIRE(fs_core->mount("lfs0part0", "/lfs", "littlefs") == 0);

    SECTION("Files stat")
    {
        const auto vfat_fd = fs_core->open("/vfat/.boot.json", O_RDONLY, 0);
        REQUIRE(vfat_fd >= 3);
        const auto lfs_fd = fs_core->open("/lfs/test_read_1.txt", O_RDONLY, 0);
        REQUIRE(lfs_fd >= 3);

        struct stat vfat_file_stat;
        struct stat lfs_file_stat;
        REQUIRE(fs_core->fstat(vfat_fd, vfat_file_stat) == 0);
        REQUIRE(fs_core->fstat(lfs_fd, lfs_file_stat) == 0);
        REQUIRE(vfat_file_stat.st_dev != lfs_file_stat.st_dev);

        REQUIRE(fs_core->close(vfat_fd) == 0);
        REQUIRE(fs_core->close(lfs_fd) == 0);
    }
    SECTION("Create, read & write files")
    {
        const auto lfs_fd = fs_core->open("/lfs/test_read_1.txt", O_RDONLY, 0);
        REQUIRE(lfs_fd >= 3);

        static constexpr auto vfat_filename = "/vfat/test_write_tmp_1.txt";
        auto vfat_fd                        = fs_core->open(vfat_filename, O_CREAT | O_RDWR, 0);
        REQUIRE(vfat_fd >= 3);

        const std::string expected = "01234567";

        {
            char buf[64];
            REQUIRE(fs_core->read(lfs_fd, buf, expected.size()) == static_cast<ssize_t>(expected.size()));
            REQUIRE(memcmp(buf, expected.c_str(), expected.size()) == 0);
            REQUIRE(fs_core->write(vfat_fd, buf, expected.size()) == static_cast<ssize_t>(expected.size()));
            REQUIRE(fs_core->close(vfat_fd) == 0);
        }

        {
            char buf[64];
            vfat_fd = fs_core->open(vfat_filename, O_RDWR, 0);
            REQUIRE(vfat_fd >= 3);
            REQUIRE(fs_core->read(vfat_fd, buf, expected.size()) == static_cast<ssize_t>(expected.size()));
            REQUIRE(memcmp(buf, expected.c_str(), expected.size()) == 0);
            REQUIRE(fs_core->close(vfat_fd) == 0);
        }

        REQUIRE(fs_core->close(lfs_fd) == 0);
        fs_core->unlink(vfat_filename);
    }

    REQUIRE(fs_core->umount("/vfat") == 0);
    REQUIRE(fs_core->umount("/lfs") == 0);
}