Merge lp:~alan-griffiths/miral/first-cut-at-test-server into lp:miral

Proposed by Alan Griffiths
Status: Merged
Approved by: Gerry Boland
Approved revision: 271
Merged at revision: 272
Proposed branch: lp:~alan-griffiths/miral/first-cut-at-test-server
Merge into: lp:miral
Diff against target: 245 lines (+225/-0)
3 files modified
test/CMakeLists.txt (+1/-0)
test/test_server.cpp (+154/-0)
test/test_server.h (+70/-0)
To merge this branch: bzr merge lp:~alan-griffiths/miral/first-cut-at-test-server
Reviewer Review Type Date Requested Status
Gerry Boland (community) Approve
Review via email: mp+302677@code.launchpad.net

Commit message

Add a TestServer fixture for writing miral tests

Description of the change

Add a TestServer fixture for writing miral tests

Prerequisite for writing further tests of miral

To post a comment you must log in.
271. By Alan Griffiths

Don't report startup until after init

Revision history for this message
Gerry Boland (gerboland) wrote :

The mir test framework has a bunch of test servers, why is this needed? Isn't the HeadlessTestServer enough?

review: Needs Information
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> The mir test framework has a bunch of test servers, why is this needed? Isn't
> the HeadlessTestServer enough?

The objective is to enable tests of the MirAL infrastructure.

A lot of the logic is similar to HeadlessTestServer, but it uses the MirAL infrastructure (MirRunner et alia) to start the server. Once we start to consolidate the MirAL work with Mir there will be opportunities to simplify.

Revision history for this message
Gerry Boland (gerboland) wrote :

ok, looks reasonable

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'test/CMakeLists.txt'
--- test/CMakeLists.txt 2016-08-02 09:05:46 +0000
+++ test/CMakeLists.txt 2016-08-11 15:06:12 +0000
@@ -9,6 +9,7 @@
9add_executable(miral-test9add_executable(miral-test
10 mru_window_list.cpp10 mru_window_list.cpp
11 active_outputs.cpp11 active_outputs.cpp
12 test_server.cpp test_server.h
12)13)
1314
14target_link_libraries(miral-test15target_link_libraries(miral-test
1516
=== added file 'test/test_server.cpp'
--- test/test_server.cpp 1970-01-01 00:00:00 +0000
+++ test/test_server.cpp 2016-08-11 15:06:12 +0000
@@ -0,0 +1,154 @@
1/*
2 * Copyright © 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Alan Griffiths <alan@octopull.co.uk>
17 */
18
19#include "test_server.h"
20
21#include <miral/canonical_window_manager.h>
22#include <miral/set_window_managment_policy.h>
23
24#include <mir_test_framework/executable_path.h>
25#include "mir_test_framework/stub_server_platform_factory.h"
26
27#include <mir/fd.h>
28#include <mir/main_loop.h>
29#include <mir/server.h>
30#include <mir/version.h>
31
32#include <boost/throw_exception.hpp>
33
34
35using namespace miral;
36using namespace testing;
37namespace mtf = mir_test_framework;
38
39namespace
40{
41std::chrono::seconds const timeout{20};
42char const* dummy_args[2] = { "TestServer", nullptr };
43}
44
45miral::TestServer::TestServer() :
46 runner{1, dummy_args}
47{
48 add_to_environment("MIR_SERVER_PLATFORM_GRAPHICS_LIB", mtf::server_platform("graphics-dummy.so").c_str());
49 add_to_environment("MIR_SERVER_PLATFORM_INPUT_LIB", mtf::server_platform("input-stub.so").c_str());
50}
51
52void miral::TestServer::SetUp()
53{
54#if MIR_SERVER_VERSION < MIR_VERSION_NUMBER(0, 25, 0)
55 mtf::set_next_preset_display({}); // Workaround for lp:1611337
56#endif
57
58 mir::test::AutoJoinThread t([this]
59 {
60 auto init = [this](mir::Server& server)
61 {
62 server.add_init_callback([&]
63 {
64 auto const main_loop = server.the_main_loop();
65 // By enqueuing the notification code in the main loop, we are
66 // ensuring that the server has really and fully started before
67 // leaving start_mir_server().
68 main_loop->enqueue(this, [&]
69 {
70 std::lock_guard<std::mutex> lock(mutex);
71 server_running = &server;
72 started.notify_one();
73 });
74 });
75 };
76
77 try
78 {
79 runner.run_with({init, set_window_managment_policy<TestWindowManagerPolicy>(*this)});
80 }
81 catch (std::exception const& e)
82 {
83 FAIL() << e.what();
84 }
85
86 std::lock_guard<std::mutex> lock(mutex);
87 server_running = nullptr;
88 started.notify_one();
89 });
90
91 std::unique_lock<std::mutex> lock(mutex);
92 started.wait_for(lock, timeout, [&] { return server_running; });
93
94 if (!server_running)
95 BOOST_THROW_EXCEPTION(std::runtime_error{"Failed to start server thread"});
96
97 server_thread = std::move(t);
98}
99
100void miral::TestServer::TearDown()
101{
102 std::unique_lock<std::mutex> lock(mutex);
103
104 if (server_running)
105 server_running->stop();
106
107 started.wait_for(lock, timeout, [&] { return !server_running; });
108
109 if (server_running)
110 BOOST_THROW_EXCEPTION(std::logic_error{"Failed to stop server"});
111
112 server_thread.stop();
113}
114
115auto miral::TestServer::connect_client(std::string name) -> toolkit::Connection
116{
117 std::lock_guard<std::mutex> lock(mutex);
118
119 if (!server_running)
120 BOOST_THROW_EXCEPTION(std::runtime_error{"Server not running"});
121
122 char connect_string[64] = {0};
123 sprintf(connect_string, "fd://%d", dup(server_running->open_client_socket()));
124
125 return toolkit::Connection{mir_connect_sync(connect_string, name.c_str())};
126}
127
128void miral::TestRuntimeEnvironment::add_to_environment(char const* key, char const* value)
129{
130 env.emplace_back(key, value);
131}
132
133struct miral::TestServer::TestWindowManagerPolicy : CanonicalWindowManagerPolicy
134{
135 TestWindowManagerPolicy(WindowManagerTools const& tools, TestServer& test_fixture) :
136 CanonicalWindowManagerPolicy{tools}
137 {
138 test_fixture.tools = tools;
139 }
140
141 bool handle_keyboard_event(MirKeyboardEvent const*) override { return false; }
142 bool handle_pointer_event(MirPointerEvent const*) override { return false; }
143 bool handle_touch_event(MirTouchEvent const*) override { return false; }
144};
145
146using miral::TestServer;
147
148// Minimal test to ensure the server runs and exits
149TEST_F(TestServer, connect_client_works)
150{
151 auto const connection = connect_client(__PRETTY_FUNCTION__);
152
153 EXPECT_TRUE(mir_connection_is_valid(connection));
154}
0155
=== added file 'test/test_server.h'
--- test/test_server.h 1970-01-01 00:00:00 +0000
+++ test/test_server.h 2016-08-11 15:06:12 +0000
@@ -0,0 +1,70 @@
1/*
2 * Copyright © 2016 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Alan Griffiths <alan@octopull.co.uk>
17 */
18
19#ifndef MIRAL_TEST_SERVER_H
20#define MIRAL_TEST_SERVER_H
21
22#include <miral/toolkit/connection.h>
23
24#include <miral/runner.h>
25#include <miral/window_manager_tools.h>
26
27#include <mir/test/auto_unblock_thread.h>
28#include <mir_test_framework/temporary_environment_value.h>
29
30#include <gtest/gtest.h>
31
32#include <condition_variable>
33#include <list>
34#include <mutex>
35
36namespace miral
37{
38class TestRuntimeEnvironment
39{
40public:
41 void add_to_environment(char const* key, char const* value);
42
43private:
44 std::list<mir_test_framework::TemporaryEnvironmentValue> env;
45};
46
47struct TestServer : testing::Test, private TestRuntimeEnvironment
48{
49 TestServer();
50
51 void SetUp() override;
52 void TearDown() override;
53
54 auto connect_client(std::string name) -> toolkit::Connection;
55
56 using TestRuntimeEnvironment::add_to_environment;
57 WindowManagerTools tools{nullptr};
58
59private:
60 struct TestWindowManagerPolicy;
61
62 MirRunner runner;
63 mir::test::AutoJoinThread server_thread;
64 std::mutex mutex;
65 std::condition_variable started;
66 mir::Server* server_running{nullptr};
67};
68}
69
70#endif //MIRAL_TEST_SERVER_H

Subscribers

People subscribed via source and target branches