Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <doctest/doctest.h>
- #include <chrono>
- #include <filesystem>
- #include <unistd.h> // getpid
- #include <boost/algorithm/string/trim.hpp>
- #include <v2/boost_runner.hpp>
- namespace loudplay::service::v2
- {
- namespace fs = std::filesystem;
- namespace chrono = std::chrono;
- namespace ba = boost::algorithm;
- using namespace std::chrono_literals;
- constexpr auto WAIT_TIME = 2s;
- std::string output_of(std::string const & cmd)
- {
- bp::ipstream pipe;
- bp::system(cmd, bp::std_out > pipe);
- auto output = readPipe(pipe);
- ba::trim(output);
- return output;
- }
- std::string working_dir(pid_t pid)
- {
- return output_of(fmt::format("readlink -e /proc/{}/cwd", pid));
- }
- std::string environment(pid_t pid)
- {
- return output_of(fmt::format("bash -c \"cat /proc/{}/environ | tr '\\0' '\\n'\"", pid));
- }
- TEST_CASE("BoostRunner") {
- BoostRunner r;
- REQUIRE_FALSE(r.running());
- REQUIRE_FALSE(r.wait().has_value());
- REQUIRE(r.kill());
- REQUIRE(r.pid() == r.invalid_pid);
- const auto this_pid = getpid();
- const auto cwd = fs::current_path();
- const auto child_cwd = fs::path{"/usr"};
- REQUIRE(child_cwd != cwd);
- StartupParams sp{
- .command = fmt::format("sleep {}", WAIT_TIME.count()),
- .working_dir = child_cwd,
- .env = withEnvCopy([&](auto & env){
- env["TEST_ENVVAR"] = "test";
- })
- };
- REQUIRE(r.run(sp));
- CHECK(r.running());
- SUBCASE("Check cwd and env invariants") {
- const auto pid = r.pid();
- CHECK(pid != r.invalid_pid);
- // cwd of current process must be unchanged
- CHECK(cwd == fs::current_path());
- // cwd of child process must match cwd from startup params
- CHECK(child_cwd == working_dir(pid));
- const auto expected_env = environment(this_pid) + "\nTEST_ENVVAR=test";
- CHECK(expected_env == environment(pid));
- }
- SUBCASE("Check wait") {
- const auto start = chrono::steady_clock::now();
- CHECK(r.wait().has_value());
- const auto end = chrono::steady_clock::now();
- const auto elapsed = end - start;
- CHECK(elapsed >= WAIT_TIME);
- CHECK_FALSE(r.wait().has_value()); // already finished
- CHECK_FALSE(r.running());
- CHECK(r.pid() == r.invalid_pid);
- }
- SUBCASE("Check kill") {
- const auto start = chrono::steady_clock::now();
- CHECK(r.kill());
- const auto end = chrono::steady_clock::now();
- const auto elapsed = end - start;
- CHECK(elapsed <= 100ms); // shouldn't kill way too long
- CHECK_FALSE(r.running());
- CHECK(r.kill()); // already killed
- CHECK(r.pid() == r.invalid_pid);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement