Commit ba5ba056 authored by Ramon Nou's avatar Ramon Nou
Browse files

Added path_resolution test

parent 12f25c51
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@ gkfs_add_python_test(
    NAME test_directories
    PYTHON_VERSION 3.6
    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests/integration
    SOURCE directories/test_directories.py
    SOURCE directories/
)

if (GLIBC_HAS_STATX)
+114 −0
Original line number Diff line number Diff line
################################################################################
#  Copyright 2018-2020, Barcelona Supercomputing Center (BSC), Spain           #
#  Copyright 2015-2020, 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.                  #
#                                                                              #
#  SPDX-License-Identifier: MIT                                                #
################################################################################

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

nonexisting = "nonexisting"


#@pytest.mark.xfail(reason="invalid errno returned on success")
def test_pathresolution(gkfs_daemon, gkfs_client):
    """Testing different path resolution capabilities"""

    mountdir = gkfs_daemon.mountdir
    extdir = "/tmp/ext.tmp"
    ext_linkdir = "/tmp/link.tmp"
    nodir = "/tmp/notexistent"
    intdir = mountdir / "int"

    # Just clean if it exists, due to a failed test
    
    ret = gkfs_client.rmdir(extdir)
    try:
        os.unlink(ext_linkdir) # it is external
    except Exception as e:
        pass

    ret = gkfs_client.mkdir(
            extdir, 
            stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)

    assert ret.retval == 0

    ret = gkfs_client.mkdir(
            intdir, 
            stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)

    assert ret.retval == 0
    

    # test stat on existing dir
    ret = gkfs_client.stat(nodir)

    assert ret.retval == -1
    assert ret.errno == errno.ENOENT
   
    ret = gkfs_client.chdir(nodir)
    assert ret.retval == -1
    assert ret.errno == errno.ENOENT


    # Chdir to external dir
  
    ret = gkfs_client.chdir(extdir)
    assert ret.retval == 0
    
    ret = gkfs_client.getcwd_validate(str(intdir)+"../../../../../../../../../../../../../../../../../../.."+str(intdir))
    assert ret.path == str(intdir)
    assert ret.retval == 0

    # test path resolution: from inside to outside
    ret = gkfs_client.getcwd_validate("../../../../../../../../../../../.." + str(extdir))
    assert ret.path == str(extdir)
    assert ret.retval == 0

    # test complex path resolution
    ret = gkfs_client.getcwd_validate("../../../../../../../../../../../.." + str(extdir) + "/../../../../../../../../../../../.." + str(intdir))
    assert ret.path == str(intdir)
    assert ret.retval == 0

    #Test external symlink

    ret = gkfs_client.symlink(extdir, ext_linkdir)
    assert ret.retval == 0

    ret = gkfs_client.getcwd_validate(str(extdir) + "/../link.tmp")
    assert ret.path == str(extdir)
    assert ret.retval == 0

    ret = gkfs_client.getcwd_validate(str(intdir) + "/../../../../../../../../../../../../../../../../../../../.."+str(extdir) + "/../link.tmp/../link.tmp/../../../../../../../../../../../../../../../../../../../../.."  + str(intdir))
    assert ret.path == str(intdir)
    assert ret.retval == 0

    # Teardown

    # Clean external link
    os.unlink(ext_linkdir)

    ret = gkfs_client.rmdir(extdir)
    assert ret.retval == 0
   
   #  Clean internal dir
    ret = gkfs_client.rmdir(intdir)
    assert ret.retval == 0    

    return
+3 −0
Original line number Diff line number Diff line
@@ -30,6 +30,9 @@ add_executable(gkfs.io
    gkfs.io/write_random.cpp
    gkfs.io/truncate.cpp
    gkfs.io/util/file_compare.cpp
    gkfs.io/chdir.cpp
    gkfs.io/getcwd_validate.cpp
    gkfs.io/symlink.cpp
)

include(FetchContent)
+98 −0
Original line number Diff line number Diff line
/*
  Copyright 2018-2020, Barcelona Supercomputing Center (BSC), Spain
  Copyright 2015-2020, 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.

  SPDX-License-Identifier: MIT
*/

/* C++ includes */
#include <CLI/CLI.hpp>
#include <nlohmann/json.hpp>
#include <memory>
#include <fmt/format.h>
#include <commands.hpp>
#include <reflection.hpp>
#include <serialize.hpp>

/* C includes */
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

using json = nlohmann::json;

struct chdir_options {
    bool verbose;
    std::string pathname;

    REFL_DECL_STRUCT(chdir_options,
        REFL_DECL_MEMBER(bool, verbose),
        REFL_DECL_MEMBER(std::string, pathname)
    );
};

struct chdir_output {
    int retval;
    int errnum;

    REFL_DECL_STRUCT(chdir_output,
        REFL_DECL_MEMBER(int, retval),
        REFL_DECL_MEMBER(int, errnum)
    );
};

void
to_json(json& record, 
        const chdir_output& out) {
    record = serialize(out);
}

void 
chdir_exec(const chdir_options& opts) {

    int rv = ::chdir(opts.pathname.c_str());

    if(opts.verbose) {
        fmt::print("chdir(pathname=\"{}\") = {}, errno: {} [{}]\n", 
                   opts.pathname, rv, errno, ::strerror(errno));
        return;
    }

    json out = chdir_output{rv, errno};
    fmt::print("{}\n", out.dump(2));
}

void
chdir_init(CLI::App& app) {

    // Create the option and subcommand objects
    auto opts = std::make_shared<chdir_options>();
    auto* cmd = app.add_subcommand(
            "chdir", 
            "Execute the chdir() system call");

    // Add options to cmd, binding them to opts
    cmd->add_flag(
            "-v,--verbose",
            opts->verbose,
            "Produce human readable output"
        );

    cmd->add_option(
            "pathname", 
            opts->pathname,
            "Directory name"
        )
        ->required()
        ->type_name("");

    cmd->callback([opts]() { 
        chdir_exec(*opts); 
    });
}
+8 −0
Original line number Diff line number Diff line
@@ -79,5 +79,13 @@ truncate_init(CLI::App& app);
// UTIL
void
file_compare_init(CLI::App& app);
void
chdir_init(CLI::App& app);

void
getcwd_validate_init(CLI::App& app);

void
symlink_init(CLI::App& app);

#endif // IO_COMMANDS_HPP
Loading