Commit 4272303d authored by sevenuz's avatar sevenuz Committed by Julius Athenstaedt
Browse files

fuse integration test setup

parent f3b41042
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -143,6 +143,15 @@ if (GKFS_RENAME_SUPPORT)
    )
endif ()

if (GKFS_BUILD_FUSE)
    gkfs_add_python_test(
        NAME test_fuse_client
        PYTHON_VERSION 3.6
        WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests/integration
        SOURCE fuse/
    )
endif ()

if (GKFS_INSTALL_TESTS)
    install(DIRECTORY harness
        DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/gkfs/tests/integration
+16 −4
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ from pathlib import Path
from harness.logger import logger, initialize_logging, finalize_logging
from harness.cli import add_cli_options, set_default_log_formatter
from harness.workspace import Workspace, FileCreator
from harness.gkfs import Daemon, Client, ClientLibc, Proxy, ShellClient, ShellClientLibc, FwdDaemon, FwdClient, ShellFwdClient, FwdDaemonCreator, FwdClientCreator
from harness.gkfs import Daemon, Client, ClientLibc, Proxy, ShellClient, ShellClientLibc, FwdDaemon, FwdClient, ShellFwdClient, FwdDaemonCreator, FwdClientCreator, FuseClient
from harness.reporter import report_test_status, report_test_headline, report_assertion_pass

def pytest_configure(config):
@@ -225,3 +225,15 @@ def gkfwd_client_factory(test_workspace):
    """

    return FwdClientCreator(test_workspace)

@pytest.fixture
def fuse_client(test_workspace):
    """
    Sets up a gekkofs fuse client environment so that
    operations (system calls, library calls, ...) can
    be requested from a co-running daemon.
    """

    fuse_client = FuseClient(test_workspace)
    yield fuse_client.run()
    fuse_client.shutdown()
+49 −0
Original line number Diff line number Diff line
################################################################################
# Copyright 2018-2025, Barcelona Supercomputing Center (BSC), Spain            #
# Copyright 2015-2025, Johannes Gutenberg Universitaet Mainz, Germany          #
#                                                                              #
# This software was partially supported by the                                 #
# EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu).    #
#                                                                              #
# This software was partially supported by the                                 #
# ADA-FS project under the SPPEXA project funded by the DFG.                   #
#                                                                              #
# This file is part of GekkoFS.                                                #
#                                                                              #
# GekkoFS is free software: you can redistribute it and/or modify              #
# it under the terms of the GNU General Public License as published by         #
# the Free Software Foundation, either version 3 of the License, or            #
# (at your option) any later version.                                          #
#                                                                              #
# GekkoFS is distributed in the hope that it will be useful,                   #
# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                #
# GNU General Public License for more details.                                 #
#                                                                              #
# You should have received a copy of the GNU General Public License            #
# along with GekkoFS.  If not, see <https://www.gnu.org/licenses/>.            #
#                                                                              #
# SPDX-License-Identifier: GPL-3.0-or-later                                    #
################################################################################

import harness
from pathlib import Path
import errno
import stat
import os
import ctypes
import sh
import sys
import pytest
import time
from harness.logger import logger

nonexisting = "nonexisting"

def test_read(gkfs_daemon, fuse_client):

    file = gkfs_daemon.mountdir / "file"

    sh.bash("-c", "echo baum > " + str(file))
    assert sh.ls(fuse_client.mountdir) == "file\n"
    assert sh.cat(file) == "baum\n"
+89 −11
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ gkfwd_client_log_level = 'all'
gkfwd_client_log_syscall_filter = 'epoll_wait,epoll_create'
gkfwd_daemon_active_log_pattern = r'Startup successful. Daemon is ready.'

gkfs_fuse_client = 'fuse_client'

def get_ip_addr(iface):
    return netifaces.ifaddresses(iface)[netifaces.AF_INET][0]['addr']
@@ -1637,3 +1638,80 @@ class ShellFwdClient:
    @property
    def cwd(self):
        return self._workspace.twd

class FuseClient:
    def __init__(self, workspace):
        self._workspace = workspace
        #self._cmd = sh.Command("printenv", ["/usr/bin/"])#self._workspace.bindirs)
        self._cmd = sh.Command(gkfs_fuse_client, self._workspace.bindirs)
        self._env = os.environ.copy()
        self._metadir = self.rootdir

        libdirs = ':'.join(
                filter(None, [os.environ.get('LD_LIBRARY_PATH', '')] +
                             [str(p) for p in self._workspace.libdirs]))

        self._patched_env = {
            'LD_LIBRARY_PATH'      : libdirs,
            'GKFS_HOSTS_FILE'      : str(self.cwd / gkfs_hosts_file),
            'LIBGKFS_HOSTS_FILE'      : str(self.cwd / gkfs_hosts_file), # TODO wtf why? see gkfs::env::HOSTS_FILE
        }
        self._env.update(self._patched_env)

    def run(self):

        args = [ "-f", "-s", self._workspace.mountdir, "-o", "auto_unmount" ]

        print(f"spawning fuse client")
        print(f"cmdline: {self._cmd} " + " ".join(map(str, args)))
        print(f"patched env:\n{pformat(self._patched_env)}")

        self._proc = self._cmd(
                args,
                _env=self._env,
#                _out=sys.stdout,
#                _err=sys.stderr,
                _bg=True,
            )

        print(f"fuse client process spawned (PID={self._proc.pid})")
        time.sleep(2) # give fuse time to register mount

        return self

    def shutdown(self):
        print(f"terminating fuse client and unmounting")
        sh.fusermount("-u", self._workspace.mountdir)

        try:
            self._proc.terminate()
            err = self._proc.wait()
        except sh.SignalException_SIGTERM:
            pass
        except Exception:
            raise


    @property
    def cwd(self):
        return self._workspace.twd

    @property
    def rootdir(self):
        return self._workspace.rootdir

    @property
    def mountdir(self):
        return self._workspace.mountdir

    @property
    def bindirs(self):
        return self._workspace.bindirs

    @property
    def logdir(self):
        return self._workspace.logdir

    @property
    def env(self):
        return self._env