~aleteoryx/muditaos

215e4d96b7ec0e6da77ce7c12fc72abdbd0a4b08 — Lefucjusz 3 years ago afd7e7b
[MOS-783] Fixed Pure unit tests

Fixed (most of the) hardcoded
paths in Pure's unit tests.
M board/linux/libiosyscalls/src/iosyscalls.cpp => board/linux/libiosyscalls/src/iosyscalls.cpp +0 -1
@@ 3,7 3,6 @@

#include "iosyscalls-internal.hpp"

#include <debug.hpp>
#include <parallel_hashmap/phmap.h>

#include <dirent.h>

M module-gui/test/mock/InitializedFontManager.cpp => module-gui/test/mock/InitializedFontManager.cpp +3 -2
@@ 1,8 1,9 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "InitializedFontManager.hpp"
#include <mutex>
#include <purefs/filesystem_paths.hpp>

namespace mockup
{


@@ 13,7 14,7 @@ namespace mockup
        std::lock_guard<std::mutex> scoped(guard);
        auto &fontmanager = gui::FontManager::getInstance();
        if (!fontmanager.isInitialized()) {
            fontmanager.init("assets");
            fontmanager.init(purefs::dir::getAssetsDirPath());
        }
        return fontmanager;
    }

M module-gui/test/test-catch/test-gui.cpp => module-gui/test/test-catch/test-gui.cpp +4 -13
@@ 7,24 7,15 @@

#include <memory>
#include <functional>
#include <iostream>
#include <string>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <catch2/catch.hpp>

#include <log/log.hpp>
#include <utf8/UTF8.hpp>

#include <module-gui/gui/core/ImageManager.hpp>
#include <module-gui/gui/core/BoundingBox.hpp>
#include <module-gui/gui/widgets/text/Label.hpp>
#include <module-gui/gui/widgets/BoxLayout.hpp>
#include <module-gui/gui/widgets/Image.hpp>

#include <purefs/filesystem_paths.hpp>

#include <mock/TestWindow.hpp>

using namespace std;


@@ 53,8 44,8 @@ TEST_CASE("Are fonts loaded")
    // check getInstance - getting even default font will result in nullptr
    // this is because no fonts are loaded
    REQUIRE(fontmanager.getFont() == nullptr);
    // now initialize, from where is it taken? nobody knows from this foo
    fontmanager.init("sys/current/assets");
    // now initialize
    fontmanager.init(purefs::dir::getAssetsDirPath());
    // check if there is at least default font
    REQUIRE(fontmanager.getFont() != nullptr);
}

M module-gui/test/test-google/test-gui-dom-dump.cpp => module-gui/test/test-google/test-gui-dom-dump.cpp +4 -5
@@ 1,17 1,16 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "gtest/gtest.h"
#include <sstream>

#include "gui/dom/Item2JsonSerializer.hpp"

#include "Item.hpp"
#include "Rect.hpp"
#include "Label.hpp"
#include "Text.hpp"
#include "FontManager.hpp"
#include <iostream>

#include <purefs/filesystem_paths.hpp>

class Item2JsonSerializerTester : public ::testing::Test
{


@@ 21,7 20,7 @@ class Item2JsonSerializerTester : public ::testing::Test
    Item2JsonSerializerTester()
    {
        auto &fm = gui::FontManager::getInstance();
        fm.init("sys/current/assets");
        fm.init(purefs::dir::getAssetsDirPath());

        auto text = new gui::Text(nullptr, 0, 0, 0, 0);
        text->setText(testTextValue1);

M module-platform/linux/tests/genlfstestimg.sh => module-platform/linux/tests/genlfstestimg.sh +12 -7
@@ 1,5 1,5 @@
#!/bin/bash -e
#Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
#Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
#For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

usage() {


@@ 15,23 15,28 @@ Usage: $(basename $0) [image_size] [image_file] [sysroot] [files]...
if [ $# -lt 2 ]; then
	echo "Error! Invalid argument count"
	usage
	exit -1
	exit 1
fi
IMAGE_SIZE="$1"
IMAGE_FILE="$2"
SYSROOT="$3"
shift 3

if [ ! -d "${SYSROOT}/sys" ]; then
	echo "Invalid sysroot: ${SYSROOT}"
	exit -1
# Validate image source folder
if [ ! -d "${SYSROOT}/system_a" ]; then
	echo "Fatal! Image folder 'system_a' missing in build. Check build system."
	exit 1
fi
if [ ! -d "${SYSROOT}/user" ]; then
	echo "Fatal! Image folder 'user' missing in build. Check build system."
	exit 1
fi

_REQ_CMDS="sfdisk truncate"
for cmd in $_REQ_CMDS; do
	if [ ! $(command -v $cmd) ]; then
		echo "Error! $cmd is not installed, please use 'sudo apt install' for install required tool"
		exit -1
		exit 1
	fi
done
truncate -s $IMAGE_SIZE $IMAGE_FILE


@@ 46,4 51,4 @@ unit: sectors
/dev/sdz1 : start=$SECTOR_START, size=$SECTOR_END, type=9e
==sfdisk
pwd
./genlittlefs --image $IMAGE_FILE --block_size=32768  --overwrite  --partition_num 1 -- ${SYSROOT}/sys/.boot.json ${SYSROOT}/sys/current/assets/* module-platform/test_dir/*
./genlittlefs --image $IMAGE_FILE --block_size=32768  --overwrite  --partition_num 1 -- ${SYSROOT}/user/boot.json ${SYSROOT}/system_a/assets/* module-platform/test_dir/*

M module-platform/linux/tests/unittest_filesystem_core.cpp => module-platform/linux/tests/unittest_filesystem_core.cpp +76 -67
@@ 7,8 7,7 @@

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

#include <purefs/fs/thread_local_cwd.hpp>



@@ 30,27 29,27 @@ TEST_CASE("Corefs: Registering and unregistering block device")
    REQUIRE(dm->register_device(disk, "emmc0") == 0);
    purefs::fs::filesystem fscore(dm);
    /* Requested filesystem is not registered */
    REQUIRE(fscore.mount("emmc0", "/sys", "vfat") == -ENODEV);
    const auto vfs_vfat = std::make_shared<fs::drivers::filesystem_vfat>();
    REQUIRE(vfs_vfat->mount_count() == 0);
    auto ret = fscore.register_filesystem("vfat", vfs_vfat);
    REQUIRE(fscore.mount("emmc0", "/sys", "ext4") == -ENODEV);
    const auto vfs_ext4 = std::make_shared<fs::drivers::filesystem_ext4>();
    REQUIRE(vfs_ext4->mount_count() == 0);
    auto ret = fscore.register_filesystem("ext4", vfs_ext4);
    REQUIRE(ret == 0);
    ret = fscore.mount("emmc0part0", "/sys", "vfat");
    ret = fscore.mount("emmc0part0", "/sys", "ext4");
    REQUIRE(ret == 0);
    REQUIRE(vfs_vfat->mount_count() == 1);
    REQUIRE(vfs_ext4->mount_count() == 1);
    REQUIRE(fscore.umount("/ala") == -ENOENT);
    ret = fscore.mount("emmc0part0", "/sys", "vfat");
    ret = fscore.mount("emmc0part0", "/sys", "ext4");
    REQUIRE(ret == -EBUSY);
    ret = fscore.mount("emmc0part0", "/path", "vfat");
    ret = fscore.mount("emmc0part0", "/path", "ext4");
    REQUIRE(ret == -EBUSY);
    ret = fscore.mount("emmc0part2", "/path", "nonexisting_fs");
    REQUIRE(ret == -ENODEV);
    ret = fscore.umount("/sys");
    REQUIRE(ret == 0);
    REQUIRE(vfs_vfat->mount_count() == 0);
    ret = fscore.mount("emmc0part0", "/path", "vfat");
    REQUIRE(vfs_ext4->mount_count() == 0);
    ret = fscore.mount("emmc0part0", "/path", "ext4");
    REQUIRE(ret == 0);
    REQUIRE(vfs_vfat->mount_count() == 1);
    REQUIRE(vfs_ext4->mount_count() == 1);
    ret = fscore.umount("/path");
    REQUIRE(ret == 0);
}


@@ 63,29 62,31 @@ TEST_CASE("Corefs: Basic API test")
    REQUIRE(disk);
    REQUIRE(dm->register_device(disk, "emmc0") == 0);
    purefs::fs::filesystem fscore(dm);
    const auto vfs_vfat = std::make_shared<fs::drivers::filesystem_vfat>();
    REQUIRE(vfs_vfat->mount_count() == 0);
    auto ret = fscore.register_filesystem("vfat", vfs_vfat);
    const auto vfs_ext4 = std::make_shared<fs::drivers::filesystem_ext4>();
    REQUIRE(vfs_ext4->mount_count() == 0);
    auto ret = fscore.register_filesystem("ext4", vfs_ext4);
    REQUIRE(ret == 0);
    // List partitions
    for (const auto &part : dm->partitions("emmc0")) {
        std::cout << part.name << " " << part.bootable << std::endl;
    }
    ret = fscore.mount("emmc0part0", "/sys", "vfat");
    ret = fscore.mount("emmc0part0", "/sys", "ext4");
    REQUIRE(ret == 0);
    {
        struct statvfs ssv;
        ret = fscore.stat_vfs("/sys/", ssv);
        struct statvfs sv
        {};
        ret = fscore.stat_vfs("/sys/", sv);
        REQUIRE(ret == 0);
    }
    {
        ret = fscore.open("/sys/ala/ma/kota/", 0, 0);
        REQUIRE(ret == -ENOENT);
        // Simple file test
        int hwnd = fscore.open("/sys/.boot.json", 0, 0);
        int hwnd = fscore.open("/sys/assets/fonts/fontmap.json", 0, 0);
        REQUIRE(hwnd >= 3);
        std::cout << "File open handle " << hwnd << std::endl;
        struct stat st;
        struct stat st
        {};
        ret = fscore.fstat(hwnd, st);
        REQUIRE(ret == 0);
        std::cout << "File size " << st.st_size << std::endl;


@@ 122,18 123,20 @@ TEST_CASE("Corefs: Create new file, write, read from it")
    REQUIRE(disk);
    REQUIRE(dm->register_device(disk, "emmc0") == 0);
    purefs::fs::filesystem fscore(dm);
    const auto vfs_vfat = std::make_shared<fs::drivers::filesystem_vfat>();
    REQUIRE(vfs_vfat->mount_count() == 0);
    auto ret = fscore.register_filesystem("vfat", vfs_vfat);
    const auto vfs_ext4 = std::make_shared<fs::drivers::filesystem_ext4>();
    REQUIRE(vfs_ext4->mount_count() == 0);
    auto ret = fscore.register_filesystem("ext4", vfs_ext4);
    REQUIRE(ret == 0);
    REQUIRE(fscore.mount("emmc0part0", "/sys", "vfat") == 0);
    REQUIRE(fscore.mount("emmc0part0", "/sys", "ext4") == 0);

    int hwnd = fscore.open("/sys/test.txt", O_RDWR | O_CREAT, 0660);
    REQUIRE(hwnd >= 3);
    const std::string text = "test";
    fscore.write(hwnd, text.c_str(), text.size());

    REQUIRE(fscore.close(hwnd) == 0);
    {
        int hwnd = fscore.open("/sys/test.txt", O_RDWR | O_CREAT, 0660);
        REQUIRE(hwnd >= 3);
        fscore.write(hwnd, text.c_str(), text.size());
        REQUIRE(fscore.close(hwnd) == 0);
    }

    {
        int hwnd = fscore.open("/sys/test.txt", O_RDONLY, 0);


@@ 182,9 185,9 @@ TEST_CASE("Corefs: Mount empty strings")
    REQUIRE(disk);
    REQUIRE(dm->register_device(disk, "emmc0") == 0);
    purefs::fs::filesystem fscore(dm);
    const auto vfs_vfat = std::make_shared<fs::drivers::filesystem_vfat>();
    REQUIRE(vfs_vfat->mount_count() == 0);
    auto ret = fscore.register_filesystem("vfat", vfs_vfat);
    const auto vfs_ext4 = std::make_shared<fs::drivers::filesystem_ext4>();
    REQUIRE(vfs_ext4->mount_count() == 0);
    auto ret = fscore.register_filesystem("vfat", vfs_ext4);
    REQUIRE(ret == 0);
    REQUIRE(fscore.mount("", "", "") == -EINVAL);
    REQUIRE(fscore.umount("") == -ENOENT);


@@ 198,16 201,16 @@ TEST_CASE("Corefs: Write to not valid file descriptor")
    REQUIRE(disk);
    REQUIRE(dm->register_device(disk, "emmc0") == 0);
    purefs::fs::filesystem fscore(dm);
    const auto vfs_vfat = std::make_shared<fs::drivers::filesystem_vfat>();
    REQUIRE(vfs_vfat->mount_count() == 0);
    auto ret = fscore.register_filesystem("vfat", vfs_vfat);
    const auto vfs_ext4 = std::make_shared<fs::drivers::filesystem_ext4>();
    REQUIRE(vfs_ext4->mount_count() == 0);
    auto ret = fscore.register_filesystem("ext4", vfs_ext4);
    REQUIRE(ret == 0);
    REQUIRE(fscore.mount("emmc0part0", "/sys", "vfat") == 0);
    REQUIRE(fscore.mount("emmc0part0", "/sys", "ext4") == 0);

    const auto fd = fscore.open("/sys/.boot.json", 0, 0);
    const auto fd = fscore.open("/sys/assets/fonts/fontmap.json", 0, 0);
    REQUIRE(fd >= 3);
    const auto text = "test";
    REQUIRE(fscore.write(0, text, sizeof(text)) == -EBADF);
    REQUIRE(fscore.write(0, text, strlen(text)) == -EBADF);
    REQUIRE(fscore.close(fd) == 0);
    REQUIRE(fscore.umount("/sys") == 0);
}


@@ 220,19 223,20 @@ TEST_CASE("Corefs: Directory operations")
    REQUIRE(disk);
    REQUIRE(dm->register_device(disk, "emmc0") == 0);
    purefs::fs::filesystem fscore(dm);
    const auto vfs_vfat = std::make_shared<fs::drivers::filesystem_vfat>();
    REQUIRE(vfs_vfat->mount_count() == 0);
    auto ret = fscore.register_filesystem("vfat", vfs_vfat);
    const auto vfs_ext4 = std::make_shared<fs::drivers::filesystem_ext4>();
    REQUIRE(vfs_ext4->mount_count() == 0);
    auto ret = fscore.register_filesystem("ext4", vfs_ext4);
    REQUIRE(ret == 0);
    REQUIRE(fscore.mount("emmc0part0", "/sys", "vfat") == 0);
    REQUIRE(fscore.mount("emmc0part0", "/sys", "ext4") == 0);

    const auto dirhandle = fscore.diropen("/sys/current");
    const auto dirhandle = fscore.diropen("/sys/assets");
    REQUIRE(dirhandle);
    REQUIRE(dirhandle->error() == 0);

    SECTION("Null pointer handle dirnext")
    {
        struct stat st;
        struct stat st
        {};
        std::string fnm;
        REQUIRE(fscore.dirnext(nullptr, fnm, st) == -ENXIO);
        REQUIRE(fscore.dirclose(dirhandle) == 0);


@@ 248,7 252,8 @@ TEST_CASE("Corefs: Directory operations")

    SECTION("Directory reset")
    {
        struct stat st;
        struct stat st
        {};
        std::vector<std::tuple<std::string, struct stat>> vec;
        for (std::string fnm;;) {
            if (fscore.dirnext(dirhandle, fnm, st) != 0) {


@@ 286,11 291,11 @@ TEST_CASE("Corefs: Read only filesystem")
    REQUIRE(disk);
    REQUIRE(dm->register_device(disk, "emmc0") == 0);
    purefs::fs::filesystem fscore(dm);
    const auto vfs_vfat = std::make_shared<fs::drivers::filesystem_vfat>();
    REQUIRE(vfs_vfat->mount_count() == 0);
    auto ret = fscore.register_filesystem("vfat", vfs_vfat);
    const auto vfs_ext4 = std::make_shared<fs::drivers::filesystem_ext4>();
    REQUIRE(vfs_ext4->mount_count() == 0);
    auto ret = fscore.register_filesystem("ext4", vfs_ext4);
    REQUIRE(ret == 0);
    REQUIRE(fscore.mount("emmc0part0", "/sys", "vfat", fs::mount_flags::read_only) == 0);
    REQUIRE(fscore.mount("emmc0part0", "/sys", "ext4", fs::mount_flags::read_only) == 0);
    SECTION("Open file in O_RDWR")
    {
        int hwnd = fscore.open("/sys/rotest.txt", O_RDWR | O_CREAT, 0660);


@@ 300,14 305,16 @@ TEST_CASE("Corefs: Read only filesystem")
    }
    SECTION("Check function which not modify fs")
    {
        struct statvfs ssv;
        ret = fscore.stat_vfs("/sys/", ssv);
        struct statvfs sv
        {};
        ret = fscore.stat_vfs("/sys/", sv);
        REQUIRE(ret == 0);
    }
    SECTION("Check stat to not set S_IW...")
    {
        struct stat st;
        ret = fscore.stat("/sys/current", st);
        struct stat st
        {};
        ret = fscore.stat("/sys/assets", st);
        REQUIRE(ret == 0);
        REQUIRE(st.st_mode & S_IFDIR);
        REQUIRE((st.st_mode & (S_IWGRP | S_IWUSR | S_IWOTH)) == 0);


@@ 323,11 330,11 @@ TEST_CASE("Corefs: Remount filesystem from RO to RW and to RO")
    REQUIRE(disk);
    REQUIRE(dm->register_device(disk, "emmc0") == 0);
    auto fscore         = std::make_shared<purefs::fs::filesystem>(dm);
    const auto vfs_vfat = std::make_shared<fs::drivers::filesystem_vfat>();
    REQUIRE(vfs_vfat->mount_count() == 0);
    auto ret = fscore->register_filesystem("vfat", vfs_vfat);
    const auto vfs_ext4 = std::make_shared<fs::drivers::filesystem_ext4>();
    REQUIRE(vfs_ext4->mount_count() == 0);
    auto ret = fscore->register_filesystem("ext4", vfs_ext4);
    REQUIRE(ret == 0);
    REQUIRE(fscore->mount("emmc0part0", "/sys", "vfat", fs::mount_flags::read_only) == 0);
    REQUIRE(fscore->mount("emmc0part0", "/sys", "ext4", fs::mount_flags::read_only) == 0);

    {
        const int hwnd = fscore->open("/sys/remount_test.txt", O_RDWR | O_CREAT, 0660);


@@ 342,8 349,9 @@ TEST_CASE("Corefs: Remount filesystem from RO to RW and to RO")
        REQUIRE(fscore->close(hwnd) == 0);
    }
    {
        struct stat st;
        ret = fscore->stat("/sys/current", st);
        struct stat st
        {};
        ret = fscore->stat("/sys/assets", st);
        REQUIRE(ret == 0);
        REQUIRE(st.st_mode & S_IFDIR);
        REQUIRE(st.st_mode & (S_IWGRP | S_IWUSR | S_IWOTH));


@@ 359,9 367,9 @@ TEST_CASE("Corefs: Autodetect filesystems")
    REQUIRE(disk);
    REQUIRE(dm->register_device(disk, "emmc0") == 0);
    auto fscore         = std::make_shared<purefs::fs::filesystem>(dm);
    const auto vfs_vfat = std::make_shared<fs::drivers::filesystem_vfat>();
    REQUIRE(vfs_vfat->mount_count() == 0);
    auto ret = fscore->register_filesystem("vfat", vfs_vfat);
    const auto vfs_ext4 = std::make_shared<fs::drivers::filesystem_ext4>();
    REQUIRE(vfs_ext4->mount_count() == 0);
    auto ret = fscore->register_filesystem("ext4", vfs_ext4);
    REQUIRE(ret == 0);
    REQUIRE(fscore->mount("emmc0part0", "/sys", "auto") == 0);
    REQUIRE(fscore->umount("/sys") == 0);


@@ 375,14 383,15 @@ TEST_CASE("Corefs: stat extended")
    REQUIRE(disk);
    REQUIRE(dm->register_device(disk, "emmc0") == 0);
    purefs::fs::filesystem fs_core(dm);
    const auto vfs_vfat = std::make_shared<fs::drivers::filesystem_vfat>();
    REQUIRE(vfs_vfat->mount_count() == 0);
    auto ret = fs_core.register_filesystem("vfat", vfs_vfat);
    const auto vfs_ext4 = std::make_shared<fs::drivers::filesystem_ext4>();
    REQUIRE(vfs_ext4->mount_count() == 0);
    auto ret = fs_core.register_filesystem("ext4", vfs_ext4);
    REQUIRE(ret == 0);
    REQUIRE(fs_core.mount("emmc0part0", "/sys", "vfat") == 0);
    REQUIRE(fs_core.mount("emmc0part0", "/sys", "ext4") == 0);

    // Check if it is a directory
    struct stat st;
    struct stat st
    {};
    REQUIRE(fs_core.stat("/sys", st) == 0);
    REQUIRE(S_ISDIR(st.st_mode));
    REQUIRE(fs_core.stat("/sys/", st) == 0);

M module-platform/linux/tests/unittest_filesystem_dualmount.cpp => module-platform/linux/tests/unittest_filesystem_dualmount.cpp +34 -33
@@ 7,14 7,13 @@

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

#include "test-setup.hpp"

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

namespace


@@ 38,10 37,10 @@ namespace
        }

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

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


@@ 57,49 56,51 @@ 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 ext4_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(ext4_disk);
    REQUIRE(lfs_disk);
    REQUIRE(dm->register_device(vfat_disk, "vfat0") == 0);
    REQUIRE(dm->register_device(ext4_disk, "ext40") == 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_ext4 = std::make_shared<fs::drivers::filesystem_ext4>();
    const auto vfs_lfs  = std::make_shared<fs::drivers::filesystem_littlefs>();
    REQUIRE(vfs_vfat->mount_count() == 0);
    REQUIRE(vfs_ext4->mount_count() == 0);
    REQUIRE(vfs_lfs->mount_count() == 0);
    REQUIRE(fs_core.register_filesystem("vfat", vfs_vfat) == 0);
    REQUIRE(fs_core.register_filesystem("ext4", vfs_ext4) == 0);
    REQUIRE(fs_core.register_filesystem("littlefs", vfs_lfs) == 0);

    REQUIRE(fs_core.mount("vfat0part0", "/vfat", "vfat") == 0);
    REQUIRE(fs_core.mount("ext40part0", "/ext4", "ext4") == 0);
    REQUIRE(fs_core.mount("lfs0part0", "/lfs", "littlefs") == 0);
    REQUIRE(vfs_vfat->mount_count() == 1);
    REQUIRE(vfs_ext4->mount_count() == 1);
    REQUIRE(vfs_lfs->mount_count() == 1);
    REQUIRE(fs_core.umount("/vfat") == 0);
    REQUIRE(fs_core.umount("/ext4") == 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);
    auto [fs_core, dm] = prepare_filesystem("ext40", "lfs0");
    REQUIRE(fs_core->mount("ext40part0", "/ext4", "ext4") == 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 ext4_fd = fs_core->open("/ext4/assets/fonts/fontmap.json", O_RDONLY, 0);
        REQUIRE(ext4_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);
        struct stat ext4_file_stat
        {};
        struct stat lfs_file_stat
        {};
        REQUIRE(fs_core->fstat(ext4_fd, ext4_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(ext4_file_stat.st_dev != lfs_file_stat.st_dev);

        REQUIRE(fs_core->close(vfat_fd) == 0);
        REQUIRE(fs_core->close(ext4_fd) == 0);
        REQUIRE(fs_core->close(lfs_fd) == 0);
    }
    SECTION("Create, read & write files")


@@ 107,9 108,9 @@ TEST_CASE("dualmount: API tests")
        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);
        static constexpr auto ext4_filename = "/ext4/test_write_tmp_1.txt";
        auto ext4_fd                        = fs_core->open(ext4_filename, O_CREAT | O_RDWR, 0);
        REQUIRE(ext4_fd >= 3);

        const std::string expected = "01234567";



@@ 117,23 118,23 @@ TEST_CASE("dualmount: API tests")
            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);
            REQUIRE(fs_core->write(ext4_fd, buf, expected.size()) == static_cast<ssize_t>(expected.size()));
            REQUIRE(fs_core->close(ext4_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()));
            ext4_fd = fs_core->open(ext4_filename, O_RDWR, 0);
            REQUIRE(ext4_fd >= 3);
            REQUIRE(fs_core->read(ext4_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(ext4_fd) == 0);
        }

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

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

M module-platform/linux/tests/unittest_iosys.cpp => module-platform/linux/tests/unittest_iosys.cpp +3 -2
@@ 13,11 13,12 @@ TEST_CASE("VFS linux support")

    REQUIRE_NOTHROW(platform.init());

    static constexpr auto filenm = "assets/lang/English.json";
    static constexpr auto filenm = "/system/data/lang/English.json";

    SECTION("std::filesystem")
    {
        REQUIRE(std::filesystem::file_size(filenm) > 0);
        const auto file_size = std::filesystem::file_size(filenm);
        REQUIRE(file_size > 0);
    }

    SECTION("iterators")

M module-utils/i18n/tests/test_i18n.cpp => module-utils/i18n/tests/test_i18n.cpp +10 -8
@@ 6,11 6,13 @@
#include <i18n/i18n.hpp>
#include <string>

#include <purefs/filesystem_paths.hpp>

using namespace std;

TEST_CASE("Test set display language - empty display language string")
{
    utils::resetAssetsPath("sys/current/assets");
    utils::resetAssetsPath(purefs::dir::getDataDirPath());
    utils::resetDisplayLanguages();
    REQUIRE(utils::getDisplayLanguage().empty());



@@ 21,7 23,7 @@ TEST_CASE("Test set display language - empty display language string")

TEST_CASE("Test set display language - invalid display language string")
{
    utils::resetAssetsPath("sys/current/assets");
    utils::resetAssetsPath(purefs::dir::getDataDirPath());
    utils::resetDisplayLanguages();
    REQUIRE(utils::getDisplayLanguage().empty());



@@ 32,7 34,7 @@ TEST_CASE("Test set display language - invalid display language string")

TEST_CASE("Test set display language - double invalid display language string")
{
    utils::resetAssetsPath("sys/current/assets");
    utils::resetAssetsPath(purefs::dir::getDataDirPath());
    utils::resetDisplayLanguages();
    REQUIRE(utils::getDisplayLanguage().empty());



@@ 49,7 51,7 @@ TEST_CASE("Test set display language - set display language with valid string")
{
    static constexpr auto languageToChange = "Polski";

    utils::resetAssetsPath("sys/current/assets");
    utils::resetAssetsPath(purefs::dir::getDataDirPath());
    utils::resetDisplayLanguages();
    REQUIRE(utils::getDisplayLanguage().empty());



@@ 62,7 64,7 @@ TEST_CASE("Test set display language - set display language with valid string an
{
    static constexpr auto languageToChange = "Polski";

    utils::resetAssetsPath("sys/current/assets");
    utils::resetAssetsPath(purefs::dir::getDataDirPath());
    utils::resetDisplayLanguages();
    REQUIRE(utils::getDisplayLanguage().empty());



@@ 77,7 79,7 @@ TEST_CASE("Test set display language - set display language with valid string an

TEST_CASE("Test get string method - no display language set")
{
    utils::resetAssetsPath("sys/current/assets");
    utils::resetAssetsPath(purefs::dir::getDataDirPath());
    utils::resetDisplayLanguages();
    REQUIRE(utils::getDisplayLanguage().empty());



@@ 87,7 89,7 @@ TEST_CASE("Test get string method - no display language set")

TEST_CASE("Test get string method - invalid display language set")
{
    utils::resetAssetsPath("sys/current/assets");
    utils::resetAssetsPath(purefs::dir::getDataDirPath());
    utils::resetDisplayLanguages();
    REQUIRE(utils::getDisplayLanguage().empty());



@@ 103,7 105,7 @@ TEST_CASE("Test get string method - valid display language set")
{
    static constexpr auto languageToChange = "Polski";

    utils::resetAssetsPath("sys/current/assets");
    utils::resetAssetsPath(purefs::dir::getDataDirPath());
    utils::resetDisplayLanguages();
    REQUIRE(utils::getDisplayLanguage().empty());


M module-vfs/src/purefs/vfs_subsystem.cpp => module-vfs/src/purefs/vfs_subsystem.cpp +1 -3
@@ 8,13 8,10 @@
#include <purefs/blkdev/disk_manager.hpp>
#include <purefs/vfs_subsystem.hpp>
#include <purefs/vfs_subsystem_internal.hpp>
#include <hal/boot_reason.h>
#include <hal/boot_control.h>
#include <purefs/fs/thread_local_cwd.hpp>
#include <log/log.hpp>
#include <purefs/filesystem_paths.hpp>
#include <json11.hpp>
#include <sys/stat.h>
#include <fcntl.h>

namespace purefs::subsystem


@@ 178,6 175,7 @@ namespace purefs::subsystem
            if (err)
                break;
        }
        boot_control_deinit();
        return err;
    }


M test/CMakeLists.txt => test/CMakeLists.txt +9 -5
@@ 23,14 23,17 @@ target_compile_options(gtest PRIVATE -Wno-error=maybe-uninitialized)
add_custom_target(unittests)

set(ROOT_TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE)
set(TEST_ASSETS_DEST_DIR ${CMAKE_BINARY_DIR}/test-sysroot/sys)
set(TEST_ASSETS_DEST_DIR ${TEST_ASSETS_DEST_DIR} PARENT_SCOPE)
set(SYSROOT ${CMAKE_BINARY_DIR}/test-sysroot)
set(SYSTEM_DEST_DIR ${SYSROOT}/system_a)
set(SYSTEM_DEST_DIR ${SYSTEM_DEST_DIR} PARENT_SCOPE)
set(USER_DEST_DIR ${SYSROOT}/user)
set(USER_DEST_DIR ${USER_DEST_DIR} PARENT_SCOPE)

include(DownloadAsset)

download_asset_release_json(json-test-community-target
                            ${CMAKE_CURRENT_SOURCE_DIR}/assets/assets_community.json
                            ${TEST_ASSETS_DEST_DIR}/current/
                            ${SYSTEM_DEST_DIR}
                            MuditaOSPublicAssets
                            0.0.7
                            ${MUDITA_CACHE_DIR}


@@ 38,7 41,7 @@ download_asset_release_json(json-test-community-target

download_asset_json(json-test-proprietary-target
                    ${CMAKE_CURRENT_SOURCE_DIR}/assets/assets_proprietary.json
                    ${TEST_ASSETS_DEST_DIR}/current/
                    ${SYSTEM_DEST_DIR}
                    MuditaOSAssets
                    ${MUDITA_CACHE_DIR}
    )


@@ 56,7 59,8 @@ endif()
add_assets_target(
    TARGET test-assets
    SOURCE_DIR ${ASSETS_SOURCE_DIR}
    DEST_DIR ${TEST_ASSETS_DEST_DIR}
    SYSTEM_DEST_DIR ${SYSTEM_DEST_DIR}
    USER_DEST_DIR ${USER_DEST_DIR}
    DEVEL ON
    DEPENDS
        ${ASSETS_DEPENDENCIES}