This paves the way for implementing daggys and other utilities. Squashed commit of the following: commit 1f77239ab3c9e44d190eef94531a39501c8c4dfe Author: Ian Roddis <gitlab@ie2r.com> Date: Mon Oct 18 16:25:02 2021 -0300 Adding README, stdout support for daggyd logging commit c2c237224e84a3be68aaa597ce98af1365e74a13 Author: Ian Roddis <gitlab@ie2r.com> Date: Mon Oct 18 16:10:29 2021 -0300 removing old daggyd commit cfea2baf61ca10c535801c5a391d2d525a1a2d04 Author: Ian Roddis <gitlab@ie2r.com> Date: Mon Oct 18 16:10:09 2021 -0300 Moving tests into their sub-project folders commit e41ca42069bea1db16dd76b6684a3f692fef6b15 Author: Ian Roddis <gitlab@ie2r.com> Date: Mon Oct 18 15:57:40 2021 -0300 Splitting out daggyd from libdaggy commit be97b146c1d2446f5c03cb78707e921f18c60bd8 Author: Ian Roddis <gitlab@ie2r.com> Date: Mon Oct 18 15:56:55 2021 -0300 Splitting out daggyd from libdaggy commit cb61e140e9d6d8832d61fb7037fd4c0ff6edad00 Author: Ian Roddis <gitlab@ie2r.com> Date: Mon Oct 18 15:49:47 2021 -0300 moving daggy to libdaggy
182 lines
5.9 KiB
C++
182 lines
5.9 KiB
C++
#include <catch2/catch.hpp>
|
|
#include <filesystem>
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <thread>
|
|
|
|
#include "daggy/Serialization.hpp"
|
|
#include "daggy/Utilities.hpp"
|
|
#include "daggy/executors/task/ForkingTaskExecutor.hpp"
|
|
|
|
namespace fs = std::filesystem;
|
|
|
|
TEST_CASE("forking_executor", "[forking_executor]")
|
|
{
|
|
daggy::executors::task::ForkingTaskExecutor ex(10);
|
|
|
|
SECTION("Simple Run")
|
|
{
|
|
daggy::Task task{
|
|
.job{{"command", daggy::executors::task::ForkingTaskExecutor::Command{
|
|
"/usr/bin/echo", "abc", "123"}}}};
|
|
|
|
REQUIRE(ex.validateTaskParameters(task.job));
|
|
|
|
auto recFuture = ex.execute(0, "command", task);
|
|
auto rec = recFuture.get();
|
|
|
|
REQUIRE(rec.rc == 0);
|
|
REQUIRE(rec.outputLog.size() >= 6);
|
|
REQUIRE(rec.errorLog.empty());
|
|
}
|
|
|
|
SECTION("Simple Run using commandString")
|
|
{
|
|
daggy::Task task{.job{{"commandString", R"(/usr/bin/echo "abc 123")"}}};
|
|
|
|
REQUIRE(ex.validateTaskParameters(task.job));
|
|
|
|
auto recFuture = ex.execute(0, "command", task);
|
|
auto rec = recFuture.get();
|
|
|
|
REQUIRE(rec.rc == 0);
|
|
REQUIRE(rec.outputLog.size() >= 6);
|
|
REQUIRE(rec.errorLog.empty());
|
|
}
|
|
|
|
SECTION("Simple run with environment")
|
|
{
|
|
// Create the shell script
|
|
auto scriptFile = fs::current_path() / "fork_simple.sh";
|
|
|
|
if (fs::exists(scriptFile))
|
|
fs::remove_all(scriptFile);
|
|
|
|
std::ofstream ofh(scriptFile);
|
|
ofh << "#!/bin/bash\necho \"${DAGGY_TEST_VAR}\"\necho "
|
|
"\"${DAGGY_TEST_VAR2}\"\n";
|
|
ofh.close();
|
|
fs::permissions(scriptFile, fs::perms::owner_all,
|
|
fs::perm_options::replace);
|
|
|
|
std::string valOne = "funky_times";
|
|
std::string valTwo = "bleep_bloop";
|
|
daggy::Task task{.job{{"command",
|
|
daggy::executors::task::ForkingTaskExecutor::Command{
|
|
scriptFile.string()}},
|
|
{"environment", std::vector<std::string>{
|
|
"DAGGY_TEST_VAR=" + valOne,
|
|
"DAGGY_TEST_VAR2=" + valTwo}}}};
|
|
|
|
REQUIRE(ex.validateTaskParameters(task.job));
|
|
|
|
auto recFuture = ex.execute(0, "command", task);
|
|
auto rec = recFuture.get();
|
|
|
|
REQUIRE(rec.rc == 0);
|
|
REQUIRE(rec.outputLog.size() >= 6);
|
|
REQUIRE(rec.outputLog.find(valOne) != std::string::npos);
|
|
REQUIRE(rec.outputLog.find(valTwo) != std::string::npos);
|
|
REQUIRE(rec.errorLog.empty());
|
|
|
|
// if (fs::exists(scriptFile)) fs::remove_all(scriptFile);
|
|
}
|
|
|
|
SECTION("Error Run")
|
|
{
|
|
daggy::Task task{
|
|
.job{{"command", daggy::executors::task::ForkingTaskExecutor::Command{
|
|
"/usr/bin/expr", "1", "+", "+"}}}};
|
|
|
|
auto recFuture = ex.execute(0, "command", task);
|
|
auto rec = recFuture.get();
|
|
|
|
REQUIRE(rec.rc == 2);
|
|
REQUIRE(rec.errorLog.size() >= 20);
|
|
REQUIRE(rec.outputLog.empty());
|
|
}
|
|
|
|
SECTION("Killing a long task")
|
|
{
|
|
daggy::Task task{
|
|
.job{{"command", daggy::executors::task::ForkingTaskExecutor::Command{
|
|
"/usr/bin/sleep", "30"}}}};
|
|
|
|
auto start = daggy::Clock::now();
|
|
auto recFuture = ex.execute(0, "command", task);
|
|
std::this_thread::sleep_for(1s);
|
|
ex.stop(0, "command");
|
|
auto rec = recFuture.get();
|
|
auto stop = daggy::Clock::now();
|
|
|
|
REQUIRE(rec.rc == 9);
|
|
REQUIRE(rec.errorLog.empty());
|
|
REQUIRE(rec.outputLog.empty());
|
|
REQUIRE(rec.executorLog == "Killed");
|
|
REQUIRE(
|
|
std::chrono::duration_cast<std::chrono::seconds>(stop - start).count() <
|
|
20);
|
|
}
|
|
|
|
SECTION("Large Output")
|
|
{
|
|
const std::vector<std::string> BIG_FILES{"/usr/share/dict/linux.words",
|
|
"/usr/share/dict/cracklib-small",
|
|
"/etc/ssh/moduli"};
|
|
|
|
for (const auto &bigFile : BIG_FILES) {
|
|
if (!std::filesystem::exists(bigFile))
|
|
continue;
|
|
|
|
daggy::Task task{
|
|
.job{{"command", daggy::executors::task::ForkingTaskExecutor::Command{
|
|
"/usr/bin/cat", bigFile}}}};
|
|
|
|
auto recFuture = ex.execute(0, "command", task);
|
|
auto rec = recFuture.get();
|
|
|
|
REQUIRE(rec.rc == 0);
|
|
REQUIRE(rec.outputLog.size() == std::filesystem::file_size(bigFile));
|
|
REQUIRE(rec.errorLog.empty());
|
|
}
|
|
}
|
|
|
|
SECTION("Parameter Expansion")
|
|
{
|
|
std::string testParams{R"({"DATE": ["2021-05-06", "2021-05-07" ]})"};
|
|
auto params = daggy::configFromJSON(testParams);
|
|
|
|
std::string taskJSON =
|
|
R"({"B": {"job": {"command": ["/usr/bin/echo", "{{DATE}}"]}, "children": ["C"]}})";
|
|
auto tasks = daggy::tasksFromJSON(taskJSON);
|
|
|
|
auto result = daggy::expandTaskSet(tasks, ex, params);
|
|
REQUIRE(result.size() == 2);
|
|
}
|
|
|
|
SECTION("Build with expansion")
|
|
{
|
|
std::string testParams{
|
|
R"({"DATE": ["2021-05-06", "2021-05-07" ], "SOURCE": "name"})"};
|
|
auto params = daggy::configFromJSON(testParams);
|
|
std::string testTasks =
|
|
R"({"A": {"job": {"command": ["/bin/echo", "A"]}, "children": ["B"]}, "B": {"job": {"command": ["/bin/echo", "B", "{{SOURCE}}", "{{DATE}}"]}, "children": ["C"]}, "C": {"job": {"command": ["/bin/echo", "C"]}}})";
|
|
auto tasks =
|
|
daggy::expandTaskSet(daggy::tasksFromJSON(testTasks), ex, params);
|
|
REQUIRE(tasks.size() == 4);
|
|
}
|
|
|
|
SECTION("Build with expansion using parents instead of children")
|
|
{
|
|
std::string testParams{
|
|
R"({"DATE": ["2021-05-06", "2021-05-07" ], "SOURCE": "name"})"};
|
|
auto params = daggy::configFromJSON(testParams);
|
|
std::string testTasks =
|
|
R"({"A": {"job": {"command": ["/bin/echo", "A"]}}, "B": {"job": {"command": ["/bin/echo", "B", "{{SOURCE}}", "{{DATE}}"]}, "parents": ["A"]}, "C": {"job": {"command": ["/bin/echo", "C"]}, "parents": ["A"]}})";
|
|
auto tasks =
|
|
daggy::expandTaskSet(daggy::tasksFromJSON(testTasks), ex, params);
|
|
|
|
REQUIRE(tasks.size() == 4);
|
|
}
|
|
}
|