Advertisement
Jakowlew

Untitled

Apr 16th, 2024
580
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.04 KB | None | 0 0
  1. #include <doctest/doctest.h>
  2.  
  3. #include <chrono>
  4. #include <filesystem>
  5.  
  6. #include <unistd.h> // getpid
  7.  
  8. #include <boost/algorithm/string/trim.hpp>
  9.  
  10. #include <v2/boost_runner.hpp>
  11.  
  12. namespace loudplay::service::v2
  13. {
  14.     namespace fs = std::filesystem;
  15.     namespace chrono = std::chrono;
  16.     namespace ba = boost::algorithm;
  17.  
  18.     using namespace std::chrono_literals;
  19.  
  20.     constexpr auto WAIT_TIME = 2s;
  21.  
  22.     std::string output_of(std::string const & cmd)
  23.     {
  24.         bp::ipstream pipe;
  25.         bp::system(cmd, bp::std_out > pipe);
  26.        
  27.         auto output = readPipe(pipe);
  28.         ba::trim(output);
  29.         return output;
  30.     }
  31.  
  32.     std::string working_dir(pid_t pid)
  33.     {
  34.         return output_of(fmt::format("readlink -e /proc/{}/cwd", pid));
  35.     }
  36.  
  37.     std::string environment(pid_t pid)
  38.     {
  39.         return output_of(fmt::format("bash -c \"cat /proc/{}/environ | tr '\\0' '\\n'\"", pid));
  40.     }
  41.  
  42.     TEST_CASE("BoostRunner") {
  43.         BoostRunner r;
  44.  
  45.         REQUIRE_FALSE(r.running());
  46.         REQUIRE_FALSE(r.wait().has_value());
  47.         REQUIRE(r.kill());
  48.         REQUIRE(r.pid() == r.invalid_pid);
  49.  
  50.         const auto this_pid = getpid();
  51.  
  52.         const auto cwd = fs::current_path();
  53.         const auto child_cwd = fs::path{"/usr"};
  54.  
  55.         REQUIRE(child_cwd != cwd);
  56.  
  57.         StartupParams sp{
  58.             .command = fmt::format("sleep {}", WAIT_TIME.count()),
  59.             .working_dir = child_cwd,
  60.             .env = withEnvCopy([&](auto & env){
  61.                 env["TEST_ENVVAR"] = "test";
  62.             })
  63.         };
  64.         REQUIRE(r.run(sp));
  65.         CHECK(r.running());
  66.  
  67.         SUBCASE("Check cwd and env invariants") {
  68.             const auto pid = r.pid();
  69.             CHECK(pid != r.invalid_pid);
  70.            
  71.             // cwd of current process must be unchanged
  72.             CHECK(cwd == fs::current_path());
  73.             // cwd of child process must match cwd from startup params
  74.             CHECK(child_cwd == working_dir(pid));
  75.  
  76.             const auto expected_env = environment(this_pid) + "\nTEST_ENVVAR=test";
  77.             CHECK(expected_env == environment(pid));
  78.         }
  79.  
  80.         SUBCASE("Check wait") {
  81.             const auto start = chrono::steady_clock::now();
  82.             CHECK(r.wait().has_value());
  83.             const auto end = chrono::steady_clock::now();
  84.            
  85.             const auto elapsed = end - start;
  86.             CHECK(elapsed >= WAIT_TIME);
  87.  
  88.             CHECK_FALSE(r.wait().has_value()); // already finished
  89.             CHECK_FALSE(r.running());
  90.             CHECK(r.pid() == r.invalid_pid);
  91.         }
  92.  
  93.         SUBCASE("Check kill") {
  94.             const auto start = chrono::steady_clock::now();
  95.             CHECK(r.kill());
  96.             const auto end = chrono::steady_clock::now();
  97.  
  98.             const auto elapsed = end - start;
  99.             CHECK(elapsed <= 100ms); // shouldn't kill way too long
  100.  
  101.             CHECK_FALSE(r.running());
  102.             CHECK(r.kill()); // already killed
  103.             CHECK(r.pid() == r.invalid_pid);
  104.         }
  105.     }
  106. }
  107.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement