Commit 86e4783b authored by Alberto Miranda's avatar Alberto Miranda ♨️
Browse files

Add basic test for remote copies

The test infrastructure now supports creating a secondary "remote"
daemon that binds to a different port in the localhost interface. With
this, we can simulate remote transfers between different urd instances.
parent af5c3aa8
Loading
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ api_SOURCES = \
	api-namespace-register.cpp \
	api-namespace-unregister.cpp \
	api-copy-local-data.cpp \
	api-copy-remote-data.cpp \
	api-remove-local-data.cpp \
	api-job-register.cpp \
	api-job-update.cpp \
+1524 −0

File added.

Preview size limit exceeded, changes collapsed.

+18 −13
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@
#include "nornsctl.h"
#include "fake-daemon.hpp"

norns::config::settings test_cfg(
norns::config::settings default_cfg(
    "test_urd", /* progname */
    false, /* daemonize */
    false, /* use syslog */
@@ -71,25 +71,30 @@ void fake_daemon::configure(const bfs::path& config_file,

    m_config.load_from_file(config_file);

    m_config.progname() = test_cfg.progname();
    m_config.daemonize() = test_cfg.daemonize();
    m_config.use_syslog() = test_cfg.use_syslog();
    m_config.progname() = default_cfg.progname();
    m_config.daemonize() = default_cfg.daemonize();
    m_config.use_syslog() = default_cfg.use_syslog();
    m_config.use_console() = default_cfg.use_console();
    m_config.dry_run() = override_cfg.m_dry_run;
    m_config.dry_run_duration() = override_cfg.m_dry_run_duration;
    m_config.remote_port() = test_cfg.remote_port();
    m_config.workers_in_pool() = test_cfg.workers_in_pool();
    m_config.remote_port() = default_cfg.remote_port();
    m_config.workers_in_pool() = default_cfg.workers_in_pool();
    m_config.config_file() = config_file;
    m_config.default_namespaces().clear();
}

void fake_daemon::configure(const bfs::path& config_file) {
void fake_daemon::configure(const bfs::path& config_file,
                            const std::string& alias) {

    m_config.load_from_file(config_file);
    m_config.progname() = test_cfg.progname();
    m_config.daemonize() = test_cfg.daemonize();
    m_config.use_syslog() = test_cfg.use_syslog();
    m_config.dry_run() = test_cfg.dry_run();
    m_config.remote_port() = test_cfg.remote_port();
    m_config.workers_in_pool() = test_cfg.workers_in_pool();

    m_config.progname() = default_cfg.progname() + alias;
    m_config.daemonize() = default_cfg.daemonize();
    m_config.use_syslog() = default_cfg.use_syslog();
    m_config.use_console() = default_cfg.use_console();
    m_config.dry_run() = default_cfg.dry_run();
    m_config.dry_run_duration() = default_cfg.dry_run_duration();
    m_config.workers_in_pool() = default_cfg.workers_in_pool();
    m_config.config_file() = config_file;
    m_config.default_namespaces().clear();
}
+1 −1
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ struct fake_daemon {
    fake_daemon();
    ~fake_daemon();
    void configure(const bfs::path& config_file, const fake_daemon_cfg& override_cfg);
    void configure(const bfs::path& config_file);
    void configure(const bfs::path& config_file, const std::string& alias = "");
    void run();
    int stop();

+60 −23
Original line number Diff line number Diff line
@@ -40,7 +40,6 @@
#include "config-template.hpp"

//#define __DEBUG_OUTPUT__

namespace bfs = boost::filesystem;

namespace {
@@ -50,40 +49,58 @@ std::string generate_testid() {
    return std::string("test_") + seed.substr(0, 8);
}



#ifndef USE_REAL_DAEMON
bfs::path create_config_file(const bfs::path& basedir) {

    const bfs::path cfgdir = basedir / "config";
using replacement_list = 
    std::vector<
        std::pair<std::string, std::string>>;

bfs::path 
create_config_file(const bfs::path& basedir, 
                   const std::string& alias, 
                   const replacement_list& reps = replacement_list()) {

    const bfs::path cfgdir = basedir / ("config" + alias);

    if(!bfs::exists(cfgdir)) {
        bool res = bfs::create_directory(cfgdir);
        REQUIRE(res == true);
    }

    const bfs::path config_file = cfgdir / "test.conf";
    bfs::ofstream outf(config_file);
    outf << boost::regex_replace(config_file::cftemplate,
    const std::string name = "test.conf" + alias;

    const bfs::path config_file = cfgdir / name;

    auto outstr = boost::regex_replace(config_file::cftemplate,
                                             boost::regex("@localstatedir@"),
                                             cfgdir.string());

    for(const auto& r : reps) {
        outstr = boost::regex_replace(outstr, boost::regex(r.first), r.second);
    }

    bfs::ofstream outf(config_file);
    outf << outstr;
    outf.close();

    return config_file;
}

bfs::path patch_libraries(const bfs::path& basedir) {

    const auto config_file = create_config_file(basedir);
void
patch_libraries(const bfs::path& config_file) {

    int rv = ::setenv("NORNS_CONFIG_FILE", config_file.c_str(), 1);
    REQUIRE(rv != -1);

    libnorns_reload_config_file();
    libnornsctl_reload_config_file();

    return config_file;
}
#endif

}

test_env::test_env() :
test_env::test_env(bool requires_remote_peer) :
    m_test_succeeded(false),
    m_uid(generate_testid()),
    m_base_dir(bfs::absolute(bfs::current_path() / m_uid)) {
@@ -97,9 +114,28 @@ test_env::test_env() :
    }

#ifndef USE_REAL_DAEMON
    const auto config_file = patch_libraries(m_base_dir);
    m_td.configure(config_file);
    m_td.run();
    const std::string alias(".local");
    const auto local_config = ::create_config_file(m_base_dir, alias);
    ::patch_libraries(local_config);
    m_ltd.configure(local_config, alias);
    m_ltd.run();

    // if the test requires a remote peer, we need to spawn another daemon
    if(requires_remote_peer) {
        const std::string alias(".remote");
        const auto remote_config = 
            ::create_config_file(m_base_dir, alias,
                { {"(remote_port:)\\s*?42000\\s*?,$",    "\\1 50000,"} });

        // temporarily patch the libraries so that we can 
        // ping the "remote" daemon
        ::patch_libraries(remote_config);
        m_rtd.configure(remote_config, alias);
        m_rtd.run();

        // restore the libraries for the client
        ::patch_libraries(local_config);
    }
#endif

}
@@ -118,9 +154,10 @@ test_env::test_env(const fake_daemon_cfg& cfg) :
    }

#ifndef USE_REAL_DAEMON
    const auto config_file = patch_libraries(m_base_dir);
    m_td.configure(config_file, cfg);
    m_td.run();
    const auto config_file = ::create_config_file(m_base_dir, "");
    ::patch_libraries(config_file);
    m_ltd.configure(config_file, cfg);
    m_ltd.run();
#else
    (void) cfg;
#endif
@@ -166,7 +203,7 @@ test_env::~test_env() {
    }

#ifndef USE_REAL_DAEMON
    int ret = m_td.stop();
    int ret = m_ltd.stop();
    //REQUIRE(ret == 0);
#endif

Loading