From fb7219b2f8553cebc9871427fed134ad4b162bac Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Wed, 4 Jan 2023 19:54:48 +0100 Subject: HTTP GET tests --- tests/test-webserver.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) (limited to 'tests') 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 #include +#include #include #include #ifdef BOOST_LATEST @@ -34,9 +35,10 @@ #include #include -#include +#include #include #include +#include #include @@ -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>(filedes[0], std::ios::in); + m_is = std::make_shared(&(*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(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> m_filebuf; + std::shared_ptr m_is; }; std::pair 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); } -- cgit v1.2.3