1 #include "test_utils.h"
16 #include <boost/asio/io_service.hpp>
17 #include <boost/filesystem.hpp>
18 #include <boost/process.hpp>
20 #include "logging/logging.h"
22 in_port_t TestUtils::getFreePortAsInt() {
23 int s = socket(AF_INET, SOCK_STREAM, 0);
25 std::cout <<
"socket() failed: " << errno;
26 throw std::runtime_error(
"Could not open socket");
28 struct sockaddr_in soc_addr;
29 memset(&soc_addr, 0,
sizeof(
struct sockaddr_in));
30 soc_addr.sin_family = AF_INET;
31 soc_addr.sin_addr.s_addr = INADDR_ANY;
32 soc_addr.sin_port = htons(INADDR_ANY);
34 if (bind(s, (
struct sockaddr *)&soc_addr,
sizeof(soc_addr)) == -1) {
35 std::cout <<
"bind() failed: " << errno;
36 throw std::runtime_error(
"Could not bind socket");
39 struct sockaddr_in sa;
40 unsigned int sa_len =
sizeof(sa);
41 if (getsockname(s, (
struct sockaddr *)&sa, &sa_len) == -1) {
42 throw std::runtime_error(
"getsockname failed");
48 std::string TestUtils::getFreePort() {
return std::to_string(ntohs(getFreePortAsInt())); }
50 void TestUtils::writePathToConfig(
const boost::filesystem::path &toml_in,
const boost::filesystem::path &toml_out,
51 const boost::filesystem::path &storage_path) {
54 boost::filesystem::copy_file(toml_in, toml_out);
55 std::string conf_path_str = toml_out.string();
56 std::ofstream cs(conf_path_str.c_str(), std::ofstream::app);
57 cs <<
"\n[storage]\npath = " << storage_path.string() <<
"\n";
60 void TestUtils::waitForServer(
const std::string &address) {
63 curlEasySetoptWrapper(curl.get(), CURLOPT_URL, address.c_str());
64 curlEasySetoptWrapper(curl.get(), CURLOPT_CONNECTTIMEOUT, 3L);
65 curlEasySetoptWrapper(curl.get(), CURLOPT_NOBODY, 1L);
66 curlEasySetoptWrapper(curl.get(), CURLOPT_VERBOSE, 1L);
67 curlEasySetoptWrapper(curl.get(), CURLOPT_SSL_VERIFYPEER, 0L);
70 for (
size_t counter = 1; counter <= 100; counter++) {
71 result = curl_easy_perform(curl.get());
76 if (counter % 5 == 0) {
77 std::cout <<
"Unable to connect to " << address <<
" after " << counter <<
" tries.\n";
79 std::this_thread::sleep_for(std::chrono::milliseconds(200));
83 throw std::runtime_error(
"Wait for server timed out");
87 Process::Result Process::spawn(
const std::string &executable_to_run,
const std::vector<std::string> &executable_args) {
88 std::future<std::string> output;
89 std::future<std::string> err_output;
90 std::future<int> child_process_exit_code;
91 boost::asio::io_service io_service;
94 std::string executable_path;
95 if (boost::filesystem::exists(executable_to_run)) {
96 executable_path = executable_to_run;
98 executable_path = boost::process::search_path(executable_to_run).string();
100 boost::process::child child_process(boost::process::exe = executable_path, boost::process::args = executable_args,
101 boost::process::std_out > output, boost::process::std_err > err_output,
102 boost::process::on_exit = child_process_exit_code, io_service);
106 bool wait_successfull = child_process.wait_for(std::chrono::seconds(60));
107 if (!wait_successfull) {
108 throw std::runtime_error(
"Timeout occured while waiting for a child process completion");
115 }
catch (
const std::exception &exc) {
116 throw std::runtime_error(
"Failed to spawn process " + executable_to_run +
" exited with an error: " + exc.what());
119 return std::make_tuple(child_process_exit_code.get(), output.get(), err_output.get());
122 Process::Result Process::run(
const std::vector<std::string> &args) {
124 last_stdout_.clear();
125 last_stderr_.clear();
127 auto cred_gen_result = Process::spawn(exe_path_, args);
128 std::tie(last_exit_code_, last_stdout_, last_stderr_) = cred_gen_result;
129 if (last_exit_code_ != 0) {
130 LOG_WARNING << last_stderr_;
133 return cred_gen_result;