2
* This program is free software: you can redistribute it and/or modify it
3
* under the terms of the GNU Lesser General Public License version 3,
4
* as published by the Free Software Foundation.
6
* This program is distributed in the hope that it will be useful,
7
* but WITHOUT ANY WARRANTY; without even the implied warranty of
8
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9
* GNU Lesser General Public License for more details.
11
* You should have received a copy of the GNU Lesser General Public License
12
* along with this program. If not, see <http://www.gnu.org/licenses/>.
14
* Authored by: Thomas Voß <thomas.voss@canonical.com>
16
#ifndef TESTING_WEB_SERVER_H_
17
#define TESTING_WEB_SERVER_H_
19
#include <core/posix/exit.h>
20
#include <core/posix/signal.h>
22
#include <core/testing/cross_process_sync.h>
23
#include <gtest/gtest.h>
38
// Configuration options for creating a testing web server.
41
// The port to expose the web-server on.
43
// Function that is invoked for individual client requests.
44
std::function<int(mg_connection*)> request_handler;
48
// Returns an executable web-server for the given configuration.
49
inline std::function<core::posix::exit::Status(core::testing::CrossProcessSync& cps)> a_web_server(const web::server::Configuration& configuration)
51
return [configuration](core::testing::CrossProcessSync& cps)
53
bool terminated = false;
55
// Register for SIG_TERM
56
auto trap = core::posix::trap_signals_for_all_subsequent_threads({core::posix::Signal::sig_term});
57
// On SIG_TERM, we set terminated to false and request a clean shutdown
58
// of the polling loop.
59
trap->signal_raised().connect([trap, &terminated](core::posix::Signal)
67
static int on_request(mg_connection* conn, mg_event ev)
69
auto thiz = static_cast<Context*>(conn->server_param);
74
return thiz->handle_request(conn);
84
int handle_request(mg_connection* conn)
86
return configuration.request_handler(conn);
89
const testing::web::server::Configuration& configuration;
90
} context{configuration};
92
std::thread trap_worker
100
auto server = mg_create_server(&context, Context::on_request);
101
// Setup the port on which the server should be exposed.
102
mg_set_option(server, "listening_port", std::to_string(configuration.port).c_str());
103
// Notify framework that we are good to go
104
cps.try_signal_ready_for(std::chrono::milliseconds{500});
105
// Start the polling loop
108
mg_poll_server(server, 200);
114
// Cleanup, and free server instance
115
mg_destroy_server(&server);
117
if (trap_worker.joinable())
120
return ::testing::Test::HasFailure() ? core::posix::exit::Status::failure : core::posix::exit::Status::success;
125
#endif // TESTING_WEB_SERVER_H_