~thomas-voss/location-service/fix-1347887

« back to all changes in this revision

Viewing changes to tests/web_server.h

This MP consolidates multiple related changes together, with the goal of:

(1.) Make the service instance accessible via a cli. Useful for testing scenarios.
(2.) To cut down time-to-first-fix (ttff) by:
  (2.1) Leveraging SUPL and other supplementary data downloaded over ordinary data connections.
  (2.2) Enabling network-based positioning providers to acquire fast position estimates.

In more detail:

* Added tests for daemon and cli.
* Unified daemon and cli header and implementation files.
* Add a command-line interface to the service.
* Split up provider selection policy to rely on an interface ProviderEnumerator to ease in testing.
* Trimmed down on types.
* Removed connectivity API draft to prepare for simpler approach.
* Refactored includes.
* Added a configuration option to handle cell and wifi ID reporting.
* Add a mock for a connectivity API exposed to providers and reporters.
* Add units for connectivity api.
* Refactor cell class into namespace radio. Fixes: 1226204, 1248973, 1281817

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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.
 
5
 *
 
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.
 
10
 *
 
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/>.
 
13
 *
 
14
 * Authored by: Thomas Voß <thomas.voss@canonical.com>
 
15
 */
 
16
#ifndef TESTING_WEB_SERVER_H_
 
17
#define TESTING_WEB_SERVER_H_
 
18
 
 
19
#include <core/posix/exit.h>
 
20
#include <core/posix/signal.h>
 
21
 
 
22
#include <core/testing/cross_process_sync.h>
 
23
#include <gtest/gtest.h>
 
24
 
 
25
#include <cstdint>
 
26
 
 
27
#include <functional>
 
28
#include <thread>
 
29
 
 
30
#include "mongoose.h"
 
31
 
 
32
namespace testing
 
33
{
 
34
namespace web
 
35
{
 
36
namespace server
 
37
{
 
38
// Configuration options for creating a testing web server.
 
39
struct Configuration
 
40
{
 
41
    // The port to expose the web-server on.
 
42
    std::uint16_t port;
 
43
    // Function that is invoked for individual client requests.
 
44
    std::function<int(mg_connection*)> request_handler;
 
45
};
 
46
}
 
47
}
 
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)
 
50
{
 
51
    return [configuration](core::testing::CrossProcessSync& cps)
 
52
    {
 
53
        bool terminated = false;
 
54
 
 
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)
 
60
        {
 
61
            trap->stop();
 
62
            terminated = true;
 
63
        });
 
64
 
 
65
        struct Context
 
66
        {
 
67
            static int on_request(mg_connection* conn, mg_event ev)
 
68
            {
 
69
                auto thiz = static_cast<Context*>(conn->server_param);
 
70
 
 
71
                switch (ev)
 
72
                {
 
73
                case MG_REQUEST:
 
74
                    return thiz->handle_request(conn);
 
75
                case MG_AUTH:
 
76
                    return MG_TRUE;
 
77
                default:
 
78
                    return MG_FALSE;
 
79
                }
 
80
 
 
81
                return MG_FALSE;
 
82
            }
 
83
 
 
84
            int handle_request(mg_connection* conn)
 
85
            {
 
86
                return configuration.request_handler(conn);
 
87
            }
 
88
 
 
89
            const testing::web::server::Configuration& configuration;
 
90
        } context{configuration};
 
91
 
 
92
        std::thread trap_worker
 
93
        {
 
94
            [trap]()
 
95
            {
 
96
                trap->run();
 
97
            }
 
98
        };
 
99
 
 
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
 
106
        for (;;)
 
107
        {
 
108
            mg_poll_server(server, 200);
 
109
 
 
110
            if (terminated)
 
111
                break;
 
112
        }
 
113
 
 
114
        // Cleanup, and free server instance
 
115
        mg_destroy_server(&server);
 
116
 
 
117
        if (trap_worker.joinable())
 
118
            trap_worker.join();
 
119
 
 
120
        return ::testing::Test::HasFailure() ? core::posix::exit::Status::failure : core::posix::exit::Status::success;
 
121
    };
 
122
}
 
123
}
 
124
 
 
125
#endif // TESTING_WEB_SERVER_H_