diff options
| -rw-r--r-- | tests/test-webserver.cpp | 50 | 
1 files changed, 49 insertions, 1 deletions
| diff --git a/tests/test-webserver.cpp b/tests/test-webserver.cpp index 9321169..aa09a01 100644 --- a/tests/test-webserver.cpp +++ b/tests/test-webserver.cpp @@ -12,6 +12,7 @@  #include <boost/test/data/monomorphic.hpp>  #include <boost/test/data/test_case.hpp> +#include <boost/algorithm/string.hpp>  #include <boost/beast/core.hpp>  #include <boost/beast/http.hpp>  #ifdef BOOST_LATEST @@ -34,9 +35,10 @@  #include <string>  #include <thread> -#include <unistd.h> +#include <ext/stdio_filebuf.h>  #include <signal.h>  #include <sys/wait.h> +#include <unistd.h>  #include <libreichwein/file.h> @@ -118,16 +120,36 @@ public:    if (m_pid != 0)     throw std::runtime_error("Process already running, so it can't be started"); +  // connect stdout of new child process to stream of parent, via pipe +  int filedes[2]; +  if (pipe(filedes) == -1) +   throw std::runtime_error("Pipe error"); +    m_pid = fork();    if (m_pid < 0)     throw std::runtime_error("Fork unsuccessful.");    if (m_pid == 0) { // child process branch +                    // +   if (close(filedes[0]) == -1) +    throw std::runtime_error("Child can't close read end of pipe"); + +   // Replace stdout of child with pipe input (next 2 commands) +   if (close(1) == -1) +    throw std::runtime_error("Child can't close stdout"); +   if (dup(filedes[1]) == -1) +    throw std::runtime_error("Child replace stdout w/ pipe input"); +     char* argv[] = {(char*)"webserver", (char*)"-c", (char*)"./webserver.conf"};     webserver(sizeof(argv) / sizeof(char*), argv);     exit(0);    } +  if (close(filedes[1]) == -1) +   throw std::runtime_error("Parent can't close read end of pipe"); +  m_filebuf = std::make_shared<__gnu_cxx::stdio_filebuf<char>>(filedes[0], std::ios::in); +  m_is = std::make_shared<std::istream>(&(*m_filebuf)); +    // wait for server to start up    std::this_thread::sleep_for(std::chrono::milliseconds(100));   } @@ -144,6 +166,8 @@ public:     throw std::runtime_error("waitpid returned "s + std::to_string(result));    m_pid = 0; +  m_is = 0; +  m_filebuf = 0;   }   bool isRunning() @@ -168,8 +192,28 @@ public:    return state == "R" || state == "S";   } + std::string output() + { +  if (!isRunning()) +   throw std::runtime_error("No output/stdout available from webserver since it is not running"); + +  if (!m_is) +   throw std::runtime_error("Webserver stdout stream not initialized."); + +  std::stringstream result; +  std::string buffer(static_cast<std::string::size_type>(1024), '\0'); +  int size{}; +  while ((size = m_is->readsome(buffer.data(), buffer.size())) > 0) +   result << buffer.substr(0, size); +  return result.str(); + } +  private:   pid_t m_pid; + + // child stdout + std::shared_ptr<__gnu_cxx::stdio_filebuf<char>> m_filebuf; + std::shared_ptr<std::istream> m_is;  };  std::pair<std::string,std::string> HTTPGet(const std::string& target, bool ipv6 = true, bool HTTP11 = true) @@ -323,5 +367,9 @@ BOOST_DATA_TEST_CASE_F(Fixture, http_download, data::make({false, true}) * data:   BOOST_REQUIRE(serverProcess.isRunning());   auto response{(https ? HTTPSGet("/webserver.conf") : HTTPGet("/webserver.conf"))};   BOOST_REQUIRE(serverProcess.isRunning()); + BOOST_REQUIRE_EQUAL(response.first, "HTTP/1.1 200 OK\r\nServer: Reichwein.IT Webserver 1.17\r\nContent-Type: application/text\r\nContent-Length: 1021\r\n\r\n"); + BOOST_REQUIRE_EQUAL(response.second, File::getFile(serverProcess.testConfigFilename)); + auto output{serverProcess.output()}; + BOOST_REQUIRE_MESSAGE(boost::algorithm::contains(output, "Serving"), "Bad output: "s + output);  } | 
