Mir

Merge lp:~raof/mir/a-little-more-error-checkin into lp:mir

Proposed by Chris Halse Rogers
Status: Merged
Approved by: Alberto Aguirre
Approved revision: no longer in the source branch.
Merged at revision: 2039
Proposed branch: lp:~raof/mir/a-little-more-error-checkin
Merge into: lp:mir
Diff against target: 1196 lines (+659/-157)
18 files modified
src/client/mir_connection.cpp (+8/-0)
src/client/mir_connection_api.cpp (+12/-4)
src/client/mir_connection_api.h (+5/-1)
src/client/mir_surface.cpp (+45/-12)
src/client/mir_surface.h (+2/-0)
src/client/mir_surface_api.cpp (+7/-3)
tests/acceptance-tests/CMakeLists.txt (+1/-0)
tests/acceptance-tests/test_client_library.cpp (+0/-38)
tests/acceptance-tests/test_client_library_errors.cpp (+338/-0)
tests/acceptance-tests/test_server_disconnect.cpp (+4/-1)
tests/include/mir_test/stub_server_tool.h (+8/-1)
tests/include/mir_test/validity_matchers.h (+64/-0)
tests/include/mir_test_framework/using_stub_client_platform.h (+61/-17)
tests/integration-tests/client/test_client_render.cpp (+7/-1)
tests/integration-tests/test_error_reporting.cpp (+49/-34)
tests/mir_test/CMakeLists.txt (+1/-0)
tests/mir_test/validity_matchers.cpp (+32/-0)
tests/mir_test_framework/using_stub_client_platform.cpp (+15/-45)
To merge this branch: bzr merge lp:~raof/mir/a-little-more-error-checkin
Reviewer Review Type Date Requested Status
Alberto Aguirre (community) Approve
Alan Griffiths Approve
PS Jenkins bot (community) continuous-integration Approve
Robert Carr (community) Needs Information
Review via email: mp+232508@code.launchpad.net

Commit message

Improve error checking and reporting for the client library.

Description of the change

Some more miscellaneous error checking niceties that would have been great to have while developing privatise-all-the-things.

This starts fleshing out the error handling policy I think we settled on in London - *create calls always return a non-null object, but passing error objects to any method other than *_is_valid or *_release is fatal.

Oh, and it also fixes UsingStubClientPlatform so that it does something :).

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Robert Carr (robertcarr) wrote :

661, 672. Maybe use the new validity matchers here?

review: Needs Information
Revision history for this message
Chris Halse Rogers (raof) wrote :

Move to WIP - I can do this better with a real stub platform.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

538 +TEST_F(ClientLibraryErrors, CreateSurfaceReturnsErrorObjectOnFailureInReplyProcessing)

this_is_how_we_name_test_cases_around_here

review: Needs Fixing
Revision history for this message
Chris Halse Rogers (raof) wrote :

Man, I hope gtest never does anything would break test_names_with_underscores_in_them, which the documentation explicitly tells you not to use.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Chris Halse Rogers (raof) wrote :

I am confused as to why “make test” doesn't catch these failures locally. Anyway, let's try this again.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

67 + return mir_connection_api_impl->connect(mir_connection_api_impl->configuration_factory(),

Looks horrible. But I don't have a better suggestion in mind.

review: Approve
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/client/mir_connection.cpp'
--- src/client/mir_connection.cpp 2014-11-03 19:06:48 +0000
+++ src/client/mir_connection.cpp 2014-11-05 22:26:46 +0000
@@ -34,6 +34,8 @@
34#include <unistd.h>34#include <unistd.h>
35#include <signal.h>35#include <signal.h>
3636
37#include <boost/exception/diagnostic_information.hpp>
38
37namespace mcl = mir::client;39namespace mcl = mir::client;
38namespace mircv = mir::input::receiver;40namespace mircv = mir::input::receiver;
39namespace gp = google::protobuf;41namespace gp = google::protobuf;
@@ -219,6 +221,7 @@
219void MirConnection::connected(mir_connected_callback callback, void * context)221void MirConnection::connected(mir_connected_callback callback, void * context)
220{222{
221 bool safe_to_callback = true;223 bool safe_to_callback = true;
224 try
222 {225 {
223 std::lock_guard<decltype(mutex)> lock(mutex);226 std::lock_guard<decltype(mutex)> lock(mutex);
224227
@@ -262,6 +265,11 @@
262 display_configuration->set_configuration(connect_result.display_configuration());265 display_configuration->set_configuration(connect_result.display_configuration());
263 lifecycle_control->set_lifecycle_event_handler(default_lifecycle_event_handler);266 lifecycle_control->set_lifecycle_event_handler(default_lifecycle_event_handler);
264 }267 }
268 catch (std::exception const& e)
269 {
270 connect_result.set_error(std::string{"Failed to process connect response: "} +
271 boost::diagnostic_information(e));
272 }
265273
266 if (safe_to_callback) callback(this, context);274 if (safe_to_callback) callback(this, context);
267 connect_wait_handle.result_received();275 connect_wait_handle.result_received();
268276
=== modified file 'src/client/mir_connection_api.cpp'
--- src/client/mir_connection_api.cpp 2014-10-01 06:25:56 +0000
+++ src/client/mir_connection_api.cpp 2014-11-05 22:26:46 +0000
@@ -53,6 +53,7 @@
53{53{
54public:54public:
55 MirWaitHandle* connect(55 MirWaitHandle* connect(
56 mcl::ConfigurationFactory configuration,
56 char const* socket_file,57 char const* socket_file,
57 char const* name,58 char const* name,
58 mir_connected_callback callback,59 mir_connected_callback callback,
@@ -112,10 +113,13 @@
112 delete connection;113 delete connection;
113 }114 }
114115
115 std::unique_ptr<mcl::ConnectionConfiguration> configuration(std::string const& socket) override116 mcl::ConfigurationFactory configuration_factory() override
116 {117 {
117 return std::unique_ptr<mcl::ConnectionConfiguration>{118 return [](std::string const& socket) {
118 new mcl::DefaultConnectionConfiguration{socket}};119 return std::unique_ptr<mcl::ConnectionConfiguration>{
120 new mcl::DefaultConnectionConfiguration{socket}
121 };
122 };
119 }123 }
120};124};
121125
@@ -132,7 +136,11 @@
132{136{
133 try137 try
134 {138 {
135 return mir_connection_api_impl->connect(socket_file, name, callback, context);139 return mir_connection_api_impl->connect(mir_connection_api_impl->configuration_factory(),
140 socket_file,
141 name,
142 callback,
143 context);
136 }144 }
137 catch (std::exception const&)145 catch (std::exception const&)
138 {146 {
139147
=== modified file 'src/client/mir_connection_api.h'
--- src/client/mir_connection_api.h 2014-10-01 06:25:56 +0000
+++ src/client/mir_connection_api.h 2014-11-05 22:26:46 +0000
@@ -23,6 +23,7 @@
2323
24#include <string>24#include <string>
25#include <memory>25#include <memory>
26#include <functional>
2627
27namespace mir28namespace mir
28{29{
@@ -30,12 +31,15 @@
30{31{
31class ConnectionConfiguration;32class ConnectionConfiguration;
3233
34using ConfigurationFactory = std::function<std::unique_ptr<ConnectionConfiguration>(std::string const&)>;
35
33class MirConnectionAPI36class MirConnectionAPI
34{37{
35public:38public:
36 virtual ~MirConnectionAPI() = default;39 virtual ~MirConnectionAPI() = default;
3740
38 virtual MirWaitHandle* connect(41 virtual MirWaitHandle* connect(
42 ConfigurationFactory configuration,
39 char const* socket_file,43 char const* socket_file,
40 char const* name,44 char const* name,
41 mir_connected_callback callback,45 mir_connected_callback callback,
@@ -43,7 +47,7 @@
4347
44 virtual void release(MirConnection* connection) = 0;48 virtual void release(MirConnection* connection) = 0;
4549
46 virtual std::unique_ptr<ConnectionConfiguration> configuration(std::string const& socket) = 0;50 virtual ConfigurationFactory configuration_factory() = 0;
4751
48protected:52protected:
49 MirConnectionAPI() = default;53 MirConnectionAPI() = default;
5054
=== modified file 'src/client/mir_surface.cpp'
--- src/client/mir_surface.cpp 2014-10-28 22:48:39 +0000
+++ src/client/mir_surface.cpp 2014-11-05 22:26:46 +0000
@@ -30,6 +30,8 @@
30#include <cassert>30#include <cassert>
31#include <unistd.h>31#include <unistd.h>
3232
33#include <boost/exception/diagnostic_information.hpp>
34
33namespace geom = mir::geometry;35namespace geom = mir::geometry;
34namespace mcl = mir::client;36namespace mcl = mir::client;
35namespace mircv = mir::input::receiver;37namespace mircv = mir::input::receiver;
@@ -39,11 +41,22 @@
39namespace41namespace
40{42{
41void null_callback(MirSurface*, void*) {}43void null_callback(MirSurface*, void*) {}
44mp::DisplayServer::Stub null_server{nullptr};
4245
43std::mutex handle_mutex;46std::mutex handle_mutex;
44std::unordered_set<MirSurface*> valid_surfaces;47std::unordered_set<MirSurface*> valid_surfaces;
45}48}
4649
50MirSurface::MirSurface(std::string const& error)
51 : server{null_server},
52 connection{nullptr}
53{
54 surface.set_error(error);
55
56 std::lock_guard<decltype(handle_mutex)> lock(handle_mutex);
57 valid_surfaces.insert(this);
58}
59
47MirSurface::MirSurface(60MirSurface::MirSurface(
48 MirConnection *allocating_connection,61 MirConnection *allocating_connection,
49 mp::DisplayServer::Stub & server,62 mp::DisplayServer::Stub & server,
@@ -258,20 +271,29 @@
258{271{
259 auto platform = connection->get_client_platform();272 auto platform = connection->get_client_platform();
260273
274 try
261 {275 {
262 std::lock_guard<decltype(mutex)> lock(mutex);
263
264 process_incoming_buffer();
265 accelerated_window = platform->create_egl_native_window(this);
266
267 for(int i = 0; i < surface.attributes_size(); i++)
268 {276 {
269 auto const& attrib = surface.attributes(i);277 std::lock_guard<decltype(mutex)> lock(mutex);
270 attrib_cache[attrib.attrib()] = attrib.ivalue();278
279 process_incoming_buffer();
280 accelerated_window = platform->create_egl_native_window(this);
281
282 for(int i = 0; i < surface.attributes_size(); i++)
283 {
284 auto const& attrib = surface.attributes(i);
285 attrib_cache[attrib.attrib()] = attrib.ivalue();
286 }
271 }287 }
272 }288
273289 connection->on_surface_created(id(), this);
274 connection->on_surface_created(id(), this);290 }
291 catch (std::exception const& error)
292 {
293 surface.set_error(std::string{"Error processing Surface creating response:"} +
294 boost::diagnostic_information(error));
295 }
296
275 callback(this, context);297 callback(this, context);
276 create_wait_handle.result_received();298 create_wait_handle.result_received();
277}299}
@@ -296,7 +318,18 @@
296 valid_surfaces.erase(this);318 valid_surfaces.erase(this);
297 }319 }
298320
299 return connection->release_surface(this, callback, context);321 MirWaitHandle* wait_handle{nullptr};
322 if (connection)
323 {
324 wait_handle = connection->release_surface(this, callback, context);
325 }
326 else
327 {
328 callback(this, context);
329 delete this;
330 }
331
332 return wait_handle;
300}333}
301334
302MirNativeBuffer* MirSurface::get_current_buffer_package()335MirNativeBuffer* MirSurface::get_current_buffer_package()
303336
=== modified file 'src/client/mir_surface.h'
--- src/client/mir_surface.h 2014-10-27 22:31:16 +0000
+++ src/client/mir_surface.h 2014-11-05 22:26:46 +0000
@@ -59,6 +59,8 @@
59 MirSurface(MirSurface const &) = delete;59 MirSurface(MirSurface const &) = delete;
60 MirSurface& operator=(MirSurface const &) = delete;60 MirSurface& operator=(MirSurface const &) = delete;
6161
62 MirSurface(std::string const& error);
63
62 MirSurface(64 MirSurface(
63 MirConnection *allocating_connection,65 MirConnection *allocating_connection,
64 mir::protobuf::DisplayServer::Stub & server,66 mir::protobuf::DisplayServer::Stub & server,
6567
=== modified file 'src/client/mir_surface_api.cpp'
--- src/client/mir_surface_api.cpp 2014-10-27 22:31:16 +0000
+++ src/client/mir_surface_api.cpp 2014-11-05 22:26:46 +0000
@@ -23,6 +23,8 @@
23#include "mir_surface.h"23#include "mir_surface.h"
24#include "error_connections.h"24#include "error_connections.h"
2525
26#include <boost/exception/diagnostic_information.hpp>
27
26namespace mcl = mir::client;28namespace mcl = mir::client;
2729
28namespace30namespace
@@ -43,15 +45,17 @@
43 mir_surface_callback callback,45 mir_surface_callback callback,
44 void* context)46 void* context)
45{47{
46 if (mcl::ErrorConnections::instance().contains(connection)) return 0;48 if (!mir_connection_is_valid(connection)) abort();
4749
48 try50 try
49 {51 {
50 return connection->create_surface(*params, callback, context);52 return connection->create_surface(*params, callback, context);
51 }53 }
52 catch (std::exception const&)54 catch (std::exception const& error)
53 {55 {
54 // TODO callback with an error surface56 auto error_surf = new MirSurface{std::string{"Failed to create surface: "} +
57 boost::diagnostic_information(error)};
58 (*callback)(error_surf, context);
55 return nullptr;59 return nullptr;
56 }60 }
57}61}
5862
=== modified file 'tests/acceptance-tests/CMakeLists.txt'
--- tests/acceptance-tests/CMakeLists.txt 2014-11-03 19:06:48 +0000
+++ tests/acceptance-tests/CMakeLists.txt 2014-11-05 22:26:46 +0000
@@ -17,6 +17,7 @@
17 server_signal_handling.cpp17 server_signal_handling.cpp
18 clients.cpp18 clients.cpp
19 test_client_library.cpp19 test_client_library.cpp
20 test_client_library_errors.cpp
20 test_client_library_old.cpp21 test_client_library_old.cpp
21 test_client_surface_events.cpp22 test_client_surface_events.cpp
22 test_client_surface_swap_buffers.cpp23 test_client_surface_swap_buffers.cpp
2324
=== modified file 'tests/acceptance-tests/test_client_library.cpp'
--- tests/acceptance-tests/test_client_library.cpp 2014-10-29 10:11:50 +0000
+++ tests/acceptance-tests/test_client_library.cpp 2014-11-05 22:26:46 +0000
@@ -53,8 +53,6 @@
53{53{
54struct ClientLibrary : mtf::HeadlessInProcessServer54struct ClientLibrary : mtf::HeadlessInProcessServer
55{55{
56 mtf::UsingStubClientPlatform using_stub_client_platform;
57
58 std::set<MirSurface*> surfaces;56 std::set<MirSurface*> surfaces;
59 MirConnection* connection = nullptr;57 MirConnection* connection = nullptr;
60 MirSurface* surface = nullptr;58 MirSurface* surface = nullptr;
@@ -597,42 +595,6 @@
597 mir_connection_release(connection);595 mir_connection_release(connection);
598}596}
599597
600TEST_F(ClientLibrary, connect_errors_handled)
601{
602 mir_wait_for(mir_connect("garbage", __PRETTY_FUNCTION__, connection_callback, this));
603 ASSERT_THAT(connection, NotNull());
604
605 char const* error = mir_connection_get_error_message(connection);
606
607 if (std::strcmp("connect: No such file or directory", error) &&
608 std::strcmp("Can't find MIR server", error) &&
609 !std::strstr(error, "Failed to connect to server socket"))
610 {
611 FAIL() << error;
612 }
613}
614
615TEST_F(ClientLibrary, connect_errors_dont_blow_up)
616{
617 mir_wait_for(mir_connect("garbage", __PRETTY_FUNCTION__, connection_callback, this));
618
619 MirSurfaceParameters const request_params =
620 {
621 __PRETTY_FUNCTION__,
622 640, 480,
623 mir_pixel_format_abgr_8888,
624 mir_buffer_usage_hardware,
625 mir_display_output_id_invalid
626 };
627
628 mir_wait_for(mir_connection_create_surface(connection, &request_params, create_surface_callback, this));
629// TODO surface_create needs to fail safe too. After that is done we should add the following:
630// TODO mir_wait_for(mir_surface_swap_buffers(surface, next_buffer_callback, this));
631// TODO mir_wait_for(mir_surface_release( surface, release_surface_callback, this));
632
633 mir_connection_release(connection);
634}
635
636TEST_F(ClientLibrary, MultiSurfaceClientTracksBufferFdsCorrectly)598TEST_F(ClientLibrary, MultiSurfaceClientTracksBufferFdsCorrectly)
637{599{
638 mir_wait_for(mir_connect(new_connection().c_str(), __PRETTY_FUNCTION__, connection_callback, this));600 mir_wait_for(mir_connect(new_connection().c_str(), __PRETTY_FUNCTION__, connection_callback, this));
639601
=== added file 'tests/acceptance-tests/test_client_library_errors.cpp'
--- tests/acceptance-tests/test_client_library_errors.cpp 1970-01-01 00:00:00 +0000
+++ tests/acceptance-tests/test_client_library_errors.cpp 2014-11-05 22:26:46 +0000
@@ -0,0 +1,338 @@
1/*
2 * Copyright © 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * 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: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
17 */
18
19#include "mir_toolkit/mir_client_library.h"
20#include "mir_toolkit/debug/surface.h"
21
22#include "src/client/client_platform_factory.h"
23#include "src/client/client_platform.h"
24#include "src/client/client_buffer_factory.h"
25
26#include "mir_test/validity_matchers.h"
27
28#include "mir_test_framework/in_process_server.h"
29#include "mir_test_framework/stubbed_server_configuration.h"
30#include "mir_test_framework/using_stub_client_platform.h"
31#include "mir_test_framework/stub_client_connection_configuration.h"
32
33#include <gtest/gtest.h>
34#include <gmock/gmock.h>
35
36#include <stdexcept>
37#include <boost/throw_exception.hpp>
38#include <cstring>
39
40namespace mcl = mir::client;
41namespace mtf = mir_test_framework;
42
43namespace
44{
45enum Method : uint64_t
46{
47 none = 0,
48 the_client_platform_factory = 1<<0,
49 create_client_platform = 1<<1,
50 create_egl_native_window = 1<<2,
51 create_buffer_factory = 1<<3
52};
53
54std::string const exception_text{"Ducks!"};
55
56template<Method name, Method failure_set>
57bool should_fail()
58{
59 return (name & failure_set);
60}
61
62class StubClientBufferFactory : public mir::client::ClientBufferFactory
63{
64 std::shared_ptr<mir::client::ClientBuffer> create_buffer(const std::shared_ptr<MirBufferPackage>&,
65 mir::geometry::Size,
66 MirPixelFormat)
67 {
68 return std::shared_ptr<mir::client::ClientBuffer>{};
69 }
70};
71
72template<Method failure_set>
73class ConfigurableFailurePlatform : public mir::client::ClientPlatform
74{
75 std::shared_ptr<EGLNativeWindowType> create_egl_native_window(mir::client::ClientSurface *)
76 {
77 if (should_fail<Method::create_egl_native_window, failure_set>())
78 {
79 BOOST_THROW_EXCEPTION(std::runtime_error{exception_text});
80 }
81 return std::shared_ptr<EGLNativeWindowType>{};
82 }
83 MirPlatformType platform_type() const
84 {
85 BOOST_THROW_EXCEPTION(std::runtime_error{exception_text});
86 return MirPlatformType::mir_platform_type_gbm;
87 }
88 std::shared_ptr<mir::client::ClientBufferFactory> create_buffer_factory()
89 {
90 if (should_fail<Method::create_buffer_factory, failure_set>())
91 {
92 BOOST_THROW_EXCEPTION(std::runtime_error{exception_text});
93 }
94 return std::make_shared<StubClientBufferFactory>();
95 }
96 std::shared_ptr<EGLNativeDisplayType> create_egl_native_display()
97 {
98 return std::shared_ptr<EGLNativeDisplayType>{};
99 }
100 MirNativeBuffer *convert_native_buffer(mir::graphics::NativeBuffer*) const
101 {
102 BOOST_THROW_EXCEPTION(std::runtime_error{exception_text});
103 return nullptr;
104 }
105};
106
107template<Method failure_set>
108class ConfigurableFailureFactory: public mir::client::ClientPlatformFactory
109{
110 std::shared_ptr<mir::client::ClientPlatform>
111 create_client_platform(mir::client::ClientContext* /*context*/) override
112 {
113 if (should_fail<Method::create_client_platform, failure_set>())
114 {
115 BOOST_THROW_EXCEPTION(std::runtime_error{exception_text});
116 }
117 return std::make_shared<ConfigurableFailurePlatform<failure_set>>();
118 }
119};
120
121template<Method failure_set>
122class ConfigurableFailureConfiguration : public mtf::StubConnectionConfiguration
123{
124 using mtf::StubConnectionConfiguration::StubConnectionConfiguration;
125
126 std::shared_ptr<mir::client::ClientPlatformFactory> the_client_platform_factory() override
127 {
128 if (should_fail<Method::the_client_platform_factory, failure_set>())
129 {
130 BOOST_THROW_EXCEPTION(std::runtime_error{exception_text});
131 }
132 return std::make_shared<ConfigurableFailureFactory<failure_set>>();
133 }
134};
135
136class ClientLibraryErrors : public mtf::InProcessServer
137{
138private:
139 mtf::StubbedServerConfiguration config;
140
141 mir::DefaultServerConfiguration &server_config() override
142 {
143 return config;
144 }
145};
146}
147
148TEST_F(ClientLibraryErrors, exception_in_client_configuration_constructor_generates_error)
149{
150 mtf::UsingClientPlatform<ConfigurableFailureConfiguration<Method::the_client_platform_factory>> stubby;
151
152 auto connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
153
154 EXPECT_FALSE(mir_connection_is_valid(connection));
155 EXPECT_THAT(mir_connection_get_error_message(connection), testing::HasSubstr(exception_text));
156 mir_connection_release(connection);
157}
158
159TEST_F(ClientLibraryErrors, exception_in_platform_construction_generates_error)
160{
161 mtf::UsingClientPlatform<ConfigurableFailureConfiguration<Method::create_client_platform>> stubby;
162
163 auto connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
164
165 EXPECT_FALSE(mir_connection_is_valid(connection));
166 EXPECT_THAT(mir_connection_get_error_message(connection), testing::HasSubstr(exception_text));
167 mir_connection_release(connection);
168}
169
170TEST_F(ClientLibraryErrors, connecting_to_garbage_socket_returns_appropriate_error)
171{
172 using namespace testing;
173 mtf::UsingStubClientPlatform stubby;
174
175 auto connection = mir_connect_sync("garbage", __PRETTY_FUNCTION__);
176 ASSERT_THAT(connection, NotNull());
177
178 char const* error = mir_connection_get_error_message(connection);
179
180 if (std::strcmp("connect: No such file or directory", error) &&
181 std::strcmp("Can't find MIR server", error) &&
182 !std::strstr(error, "Failed to connect to server socket"))
183 {
184 FAIL() << error;
185 }
186 mir_connection_release(connection);
187}
188
189TEST_F(ClientLibraryErrors, create_surface_returns_error_object_on_failure)
190{
191 mtf::UsingClientPlatform<ConfigurableFailureConfiguration<Method::create_buffer_factory>> stubby;
192
193 auto connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
194
195 ASSERT_THAT(connection, IsValid());
196
197 MirSurfaceParameters const request_params =
198 {
199 __PRETTY_FUNCTION__,
200 640, 480,
201 mir_pixel_format_abgr_8888,
202 mir_buffer_usage_hardware,
203 mir_display_output_id_invalid
204 };
205
206 auto surface = mir_connection_create_surface_sync(connection, &request_params);
207 ASSERT_NE(surface, nullptr);
208 EXPECT_FALSE(mir_surface_is_valid(surface));
209 EXPECT_THAT(mir_surface_get_error_message(surface), testing::HasSubstr(exception_text));
210
211 mir_surface_release_sync(surface);
212 mir_connection_release(connection);
213}
214
215namespace
216{
217void recording_surface_callback(MirSurface*, void* ctx)
218{
219 auto called = static_cast<bool*>(ctx);
220 *called = true;
221}
222}
223
224TEST_F(ClientLibraryErrors, surface_release_on_error_object_still_calls_callback)
225{
226 mtf::UsingClientPlatform<ConfigurableFailureConfiguration<Method::create_buffer_factory>> stubby;
227
228 auto connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
229
230 ASSERT_THAT(connection, IsValid());
231
232 MirSurfaceParameters const request_params =
233 {
234 __PRETTY_FUNCTION__,
235 640, 480,
236 mir_pixel_format_abgr_8888,
237 mir_buffer_usage_hardware,
238 mir_display_output_id_invalid
239 };
240
241 auto surface = mir_connection_create_surface_sync(connection, &request_params);
242 ASSERT_NE(surface, nullptr);
243 EXPECT_FALSE(mir_surface_is_valid(surface));
244 EXPECT_THAT(mir_surface_get_error_message(surface), testing::HasSubstr(exception_text));
245
246 bool callback_called{false};
247 mir_surface_release(surface, &recording_surface_callback, &callback_called);
248 EXPECT_TRUE(callback_called);
249 mir_connection_release(connection);
250}
251
252
253TEST_F(ClientLibraryErrors, create_surface_returns_error_object_on_failure_in_reply_processing)
254{
255 mtf::UsingClientPlatform<ConfigurableFailureConfiguration<Method::create_egl_native_window>> stubby;
256
257 auto connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
258
259 ASSERT_THAT(connection, IsValid());
260
261 MirSurfaceParameters const request_params =
262 {
263 __PRETTY_FUNCTION__,
264 640, 480,
265 mir_pixel_format_abgr_8888,
266 mir_buffer_usage_hardware,
267 mir_display_output_id_invalid
268 };
269
270 auto surface = mir_connection_create_surface_sync(connection, &request_params);
271 ASSERT_NE(surface, nullptr);
272 EXPECT_FALSE(mir_surface_is_valid(surface));
273 EXPECT_THAT(mir_surface_get_error_message(surface), testing::HasSubstr(exception_text));
274
275 mir_surface_release_sync(surface);
276 mir_connection_release(connection);
277}
278
279using ClientLibraryErrorsDeathTest = ClientLibraryErrors;
280
281
282TEST_F(ClientLibraryErrorsDeathTest, createing_surface_on_garbage_connection_is_fatal)
283{
284 mtf::UsingStubClientPlatform stubby;
285
286 auto connection = mir_connect_sync("garbage", __PRETTY_FUNCTION__);
287
288 MirSurfaceParameters const request_params =
289 {
290 __PRETTY_FUNCTION__,
291 640, 480,
292 mir_pixel_format_abgr_8888,
293 mir_buffer_usage_hardware,
294 mir_display_output_id_invalid
295 };
296
297 ASSERT_FALSE(mir_connection_is_valid(connection));
298 EXPECT_DEATH(mir_connection_create_surface_sync(connection, &request_params), "");
299}
300
301
302TEST_F(ClientLibraryErrorsDeathTest, creating_surface_synchronosly_on_malconstructed_connection_is_fatal)
303{
304 MirSurfaceParameters const request_params =
305 {
306 __PRETTY_FUNCTION__,
307 640, 480,
308 mir_pixel_format_abgr_8888,
309 mir_buffer_usage_hardware,
310 mir_display_output_id_invalid
311 };
312
313 mtf::UsingClientPlatform<ConfigurableFailureConfiguration<Method::the_client_platform_factory>> stubby;
314
315 auto connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
316
317 ASSERT_FALSE(mir_connection_is_valid(connection));
318 EXPECT_DEATH(mir_connection_create_surface_sync(connection, &request_params), "");
319}
320
321TEST_F(ClientLibraryErrorsDeathTest, creating_surface_synchronosly_on_invalid_connection_is_fatal)
322{
323 MirSurfaceParameters const request_params =
324 {
325 __PRETTY_FUNCTION__,
326 640, 480,
327 mir_pixel_format_abgr_8888,
328 mir_buffer_usage_hardware,
329 mir_display_output_id_invalid
330 };
331
332 mtf::UsingClientPlatform<ConfigurableFailureConfiguration<Method::create_client_platform>> stubby;
333
334 auto connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
335
336 ASSERT_FALSE(mir_connection_is_valid(connection));
337 EXPECT_DEATH(mir_connection_create_surface_sync(connection, &request_params), "");
338}
0339
=== modified file 'tests/acceptance-tests/test_server_disconnect.cpp'
--- tests/acceptance-tests/test_server_disconnect.cpp 2014-10-01 06:25:56 +0000
+++ tests/acceptance-tests/test_server_disconnect.cpp 2014-11-05 22:26:46 +0000
@@ -107,7 +107,7 @@
107 mir_buffer_usage_hardware,107 mir_buffer_usage_hardware,
108 mir_display_output_id_invalid108 mir_display_output_id_invalid
109 };109 };
110 mir_connection_create_surface_sync(connection, &parameters);110 surf = mir_connection_create_surface_sync(connection, &parameters);
111 });111 });
112112
113 configure_display.exec([&] {113 configure_display.exec([&] {
@@ -117,6 +117,7 @@
117 });117 });
118118
119 disconnect.exec([&] {119 disconnect.exec([&] {
120 mir_surface_release_sync(surf);
120 mir_connection_release(connection);121 mir_connection_release(connection);
121 });122 });
122 }123 }
@@ -129,6 +130,8 @@
129 mt::CrossProcessAction create_surface;130 mt::CrossProcessAction create_surface;
130 mt::CrossProcessAction configure_display;131 mt::CrossProcessAction configure_display;
131 mt::CrossProcessAction disconnect;132 mt::CrossProcessAction disconnect;
133private:
134 MirSurface* surf;
132};135};
133136
134/*137/*
135138
=== modified file 'tests/include/mir_test/stub_server_tool.h'
--- tests/include/mir_test/stub_server_tool.h 2014-10-01 06:25:56 +0000
+++ tests/include/mir_test/stub_server_tool.h 2014-11-05 22:26:46 +0000
@@ -86,7 +86,14 @@
86 ::google::protobuf::Closure* done) override86 ::google::protobuf::Closure* done) override
87 {87 {
88 app_name = request->application_name();88 app_name = request->application_name();
89 connect_msg->set_error("");89 // If you check out MirConnection::connected either the platform and display_configuration
90 // have to be set or the error has to be set, otherwise we die and fail to callback.
91 //
92 // Since setting the error to "" means that mir_connection_is_valid will return false
93 // with a confusing non-error-message, instead clear the error and set the platform et al.
94 connect_msg->clear_error();
95 connect_msg->set_allocated_platform(new mir::protobuf::Platform{});
96 connect_msg->set_allocated_display_configuration(new mir::protobuf::DisplayConfiguration{});
90 done->Run();97 done->Run();
91 }98 }
9299
93100
=== added file 'tests/include/mir_test/validity_matchers.h'
--- tests/include/mir_test/validity_matchers.h 1970-01-01 00:00:00 +0000
+++ tests/include/mir_test/validity_matchers.h 2014-11-05 22:26:46 +0000
@@ -0,0 +1,64 @@
1/*
2 * Copyright © 2014 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: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
17 */
18
19#ifndef MIR_TEST_VALIDITY_MATCHERS_H_
20#define MIR_TEST_VALIDITY_MATCHERS_H_
21
22#include <gmock/gmock.h>
23
24#include "mir_toolkit/mir_client_library.h"
25
26using ::testing::MakePolymorphicMatcher;
27using ::testing::MatchResultListener;
28using ::testing::NotNull;
29using ::testing::PolymorphicMatcher;
30
31class IsValidMatcher {
32public:
33 // To implement a polymorphic matcher, first define a COPYABLE class
34 // that has three members MatchAndExplain(), DescribeTo(), and
35 // DescribeNegationTo(), like the following.
36
37 // In this example, we want to use NotNull() with any pointer, so
38 // MatchAndExplain() accepts a pointer of any type as its first argument.
39 // In general, you can define MatchAndExplain() as an ordinary method or
40 // a method template, or even overload it.
41 template <typename T>
42 bool MatchAndExplain(T* p, MatchResultListener* listener) const;
43
44 // Describes the property of a value matching this matcher.
45 void DescribeTo(::std::ostream* os) const { *os << "is valid"; }
46
47 // Describes the property of a value NOT matching this matcher.
48 void DescribeNegationTo(::std::ostream* os) const { *os << "is not valid"; }
49};
50
51template<>
52bool IsValidMatcher::MatchAndExplain(MirConnection* connection, MatchResultListener* listener) const;
53
54template<>
55bool IsValidMatcher::MatchAndExplain(MirSurface* surface, MatchResultListener* listener) const;
56
57// To construct a polymorphic matcher, pass an instance of the class
58// to MakePolymorphicMatcher(). Note the return type.
59inline PolymorphicMatcher<IsValidMatcher> IsValid()
60{
61 return MakePolymorphicMatcher(IsValidMatcher{});
62}
63
64#endif // MIR_TEST_VALIDITY_MATCHERS_H_
065
=== modified file 'tests/include/mir_test_framework/using_stub_client_platform.h'
--- tests/include/mir_test_framework/using_stub_client_platform.h 2014-10-01 06:25:56 +0000
+++ tests/include/mir_test_framework/using_stub_client_platform.h 2014-11-05 22:26:46 +0000
@@ -20,32 +20,76 @@
20#define MIR_TEST_FRAMEWORK_USING_STUB_CLIENT_PLATFORM_H_20#define MIR_TEST_FRAMEWORK_USING_STUB_CLIENT_PLATFORM_H_
2121
22#include <memory>22#include <memory>
2323#include <functional>
24namespace mir24
25{25#include "mir_test_framework/stub_client_connection_configuration.h"
26namespace client26#include "src/client/mir_connection_api.h"
27{27
28class MirConnectionAPI;28namespace mcl = mir::client;
29}
30}
3129
32namespace mir_test_framework30namespace mir_test_framework
33{31{
3432
35class UsingStubClientPlatform33class StubMirConnectionAPI : public mcl::MirConnectionAPI
36{34{
37public:35public:
38 UsingStubClientPlatform();36 StubMirConnectionAPI(mcl::MirConnectionAPI* prev_api,
39 ~UsingStubClientPlatform();37 mcl::ConfigurationFactory factory)
4038 : prev_api{prev_api},
41private:39 factory{factory}
42 UsingStubClientPlatform(UsingStubClientPlatform const&) = delete;40 {
43 UsingStubClientPlatform operator=(UsingStubClientPlatform const&) = delete;41 }
42
43 MirWaitHandle* connect(
44 mcl::ConfigurationFactory configuration,
45 char const* socket_file,
46 char const* name,
47 mir_connected_callback callback,
48 void* context) override;
49
50 void release(MirConnection* connection) override;
51
52 mcl::ConfigurationFactory configuration_factory() override;
53
54private:
55 mcl::MirConnectionAPI* const prev_api;
56 mcl::ConfigurationFactory factory;
57};
58
59template<class ClientConfig>
60class UsingClientPlatform
61{
62public:
63 UsingClientPlatform()
64 : prev_api{mir_connection_api_impl},
65 stub_api{new StubMirConnectionAPI{prev_api, make_configuration_factory()}}
66 {
67 mir_connection_api_impl = stub_api.get();
68 }
69
70 ~UsingClientPlatform()
71 {
72 mir_connection_api_impl = prev_api;
73 }
74
75private:
76 UsingClientPlatform(UsingClientPlatform const&) = delete;
77 UsingClientPlatform operator=(UsingClientPlatform const&) = delete;
4478
45 mir::client::MirConnectionAPI* prev_api;79 mir::client::MirConnectionAPI* prev_api;
46 std::unique_ptr<mir::client::MirConnectionAPI> stub_api;80 std::unique_ptr<mir::client::MirConnectionAPI> stub_api;
81
82 mcl::ConfigurationFactory make_configuration_factory()
83 {
84 return [](std::string const& socket) {
85 return std::unique_ptr<mir::client::ConnectionConfiguration>{
86 new ClientConfig{socket}
87 };
88 };
89 }
47};90};
4891
92using UsingStubClientPlatform = UsingClientPlatform<StubConnectionConfiguration>;
49}93}
5094
51#endif /* MIR_TEST_FRAMEWORK_USING_STUB_CLIENT_PLATFORM_H_ */95#endif /* MIR_TEST_FRAMEWORK_USING_STUB_CLIENT_PLATFORM_H_ */
5296
=== modified file 'tests/integration-tests/client/test_client_render.cpp'
--- tests/integration-tests/client/test_client_render.cpp 2014-10-30 18:37:11 +0000
+++ tests/integration-tests/client/test_client_render.cpp 2014-11-05 22:26:46 +0000
@@ -28,6 +28,7 @@
28#include "examples/testdraw/patterns.h"28#include "examples/testdraw/patterns.h"
29#include "mir_test/stub_server_tool.h"29#include "mir_test/stub_server_tool.h"
30#include "mir_test/test_protobuf_server.h"30#include "mir_test/test_protobuf_server.h"
31#include "mir_test/validity_matchers.h"
3132
32#include "mir/frontend/connector.h"33#include "mir/frontend/connector.h"
3334
@@ -92,7 +93,9 @@
92 mir_buffer_usage_software, mir_display_output_id_invalid93 mir_buffer_usage_software, mir_display_output_id_invalid
93 };94 };
94 auto connection = mir_connect_sync(socket_file, "test_renderer");95 auto connection = mir_connect_sync(socket_file, "test_renderer");
96 EXPECT_THAT(connection, IsValid());
95 auto surface = mir_connection_create_surface_sync(connection, &surface_parameters);97 auto surface = mir_connection_create_surface_sync(connection, &surface_parameters);
98 EXPECT_THAT(surface, IsValid());
96 MirGraphicsRegion graphics_region;99 MirGraphicsRegion graphics_region;
97 for(int i=0u; i < num_frames; i++)100 for(int i=0u; i < num_frames; i++)
98 {101 {
@@ -119,6 +122,7 @@
119 process_sync.wait_for_signal_ready_for();122 process_sync.wait_for_signal_ready_for();
120123
121 auto connection = mir_connect_sync(socket_file, "test_renderer");124 auto connection = mir_connect_sync(socket_file, "test_renderer");
125 EXPECT_THAT(connection, IsValid());
122126
123 /* set up egl context */127 /* set up egl context */
124 int major, minor, n;128 int major, minor, n;
@@ -137,7 +141,9 @@
137 eglInitialize(egl_display, &major, &minor);141 eglInitialize(egl_display, &major, &minor);
138 eglChooseConfig(egl_display, attribs, &egl_config, 1, &n);142 eglChooseConfig(egl_display, attribs, &egl_config, 1, &n);
139143
140 auto mir_surface = create_mir_surface(connection, egl_display, egl_config);144 auto mir_surface = create_mir_surface(connection, egl_display, egl_config);
145 EXPECT_THAT(mir_surface, IsValid());
146
141 auto native_window = static_cast<EGLNativeWindowType>(147 auto native_window = static_cast<EGLNativeWindowType>(
142 mir_surface_get_egl_native_window(mir_surface));148 mir_surface_get_egl_native_window(mir_surface));
143149
144150
=== modified file 'tests/integration-tests/test_error_reporting.cpp'
--- tests/integration-tests/test_error_reporting.cpp 2014-10-01 06:25:56 +0000
+++ tests/integration-tests/test_error_reporting.cpp 2014-11-05 22:26:46 +0000
@@ -24,6 +24,7 @@
24#include "mir/frontend/connector.h"24#include "mir/frontend/connector.h"
2525
26#include "src/server/frontend/display_server.h"26#include "src/server/frontend/display_server.h"
27#include "src/server/scene/surface_allocator.h"
2728
28#include "mir_test_framework/display_server_test_fixture.h"29#include "mir_test_framework/display_server_test_fixture.h"
29#include "mir_test_doubles/stub_ipc_factory.h"30#include "mir_test_doubles/stub_ipc_factory.h"
@@ -34,6 +35,7 @@
34#include <gmock/gmock.h>35#include <gmock/gmock.h>
35#include <gtest/gtest.h>36#include <gtest/gtest.h>
36#include "mir_test/gmock_fixes.h"37#include "mir_test/gmock_fixes.h"
38#include "mir_test/validity_matchers.h"
3739
38namespace mc = mir::compositor;40namespace mc = mir::compositor;
39namespace mf = mir::frontend;41namespace mf = mir::frontend;
@@ -45,32 +47,13 @@
45namespace47namespace
46{48{
47char const* const mir_test_socket = mtf::test_socket_file().c_str();49char const* const mir_test_socket = mtf::test_socket_file().c_str();
4850std::string const test_exception_text{"test exception text"};
49struct ErrorServer : mf::detail::DisplayServer51
52
53struct ConnectionErrorServer : mf::detail::DisplayServer
50{54{
51 void client_pid(int /*pid*/) override {}55 void client_pid(int /*pid*/) override {}
5256
53 static std::string const test_exception_text;
54
55 void create_surface(
56 google::protobuf::RpcController*,
57 const mir::protobuf::SurfaceParameters*,
58 mir::protobuf::Surface*,
59 google::protobuf::Closure*)
60 {
61 throw std::runtime_error(test_exception_text);
62 }
63
64 void release_surface(
65 google::protobuf::RpcController*,
66 const mir::protobuf::SurfaceId*,
67 mir::protobuf::Void*,
68 google::protobuf::Closure*)
69 {
70 throw std::runtime_error(test_exception_text);
71 }
72
73
74 void connect(57 void connect(
75 ::google::protobuf::RpcController*,58 ::google::protobuf::RpcController*,
76 const ::mir::protobuf::ConnectParameters*,59 const ::mir::protobuf::ConnectParameters*,
@@ -90,8 +73,6 @@
90 }73 }
91};74};
9275
93std::string const ErrorServer::test_exception_text{"test exception text"};
94
95struct SurfaceSync76struct SurfaceSync
96{77{
97 SurfaceSync() :78 SurfaceSync() :
@@ -193,7 +174,7 @@
193174
194using ErrorReporting = BespokeDisplayServerTestFixture;175using ErrorReporting = BespokeDisplayServerTestFixture;
195176
196TEST_F(ErrorReporting, c_api_returns_error)177TEST_F(ErrorReporting, c_api_returns_connection_error)
197{178{
198179
199 struct ServerConfig : TestingServerConfiguration180 struct ServerConfig : TestingServerConfiguration
@@ -201,7 +182,7 @@
201 std::shared_ptr<mf::ProtobufIpcFactory> new_ipc_factory(182 std::shared_ptr<mf::ProtobufIpcFactory> new_ipc_factory(
202 std::shared_ptr<mf::SessionAuthorizer> const&) override183 std::shared_ptr<mf::SessionAuthorizer> const&) override
203 {184 {
204 static auto error_server = std::make_shared<ErrorServer>();185 static auto error_server = std::make_shared<ConnectionErrorServer>();
205 return std::make_shared<mtd::StubIpcFactory>(*error_server);186 return std::make_shared<mtd::StubIpcFactory>(*error_server);
206 }187 }
207 } server_config;188 } server_config;
@@ -218,7 +199,46 @@
218199
219 ASSERT_TRUE(connection != NULL);200 ASSERT_TRUE(connection != NULL);
220 EXPECT_FALSE(mir_connection_is_valid(connection));201 EXPECT_FALSE(mir_connection_is_valid(connection));
221 EXPECT_TRUE(std::strstr(mir_connection_get_error_message(connection), ErrorServer::test_exception_text.c_str()));202 EXPECT_TRUE(std::strstr(mir_connection_get_error_message(connection), test_exception_text.c_str()));
203
204 mir_connection_release(connection);
205 }
206 } client_config;
207
208 launch_client_process(client_config);
209}
210
211TEST_F(ErrorReporting, c_api_returns_surface_creation_error)
212{
213
214 struct ServerConfig : TestingServerConfiguration
215 {
216 class BoobytrappedSurfaceFactory : public mir::scene::SurfaceFactory
217 {
218 std::shared_ptr<mir::scene::Surface>
219 create_surface(mir::scene::SurfaceCreationParameters const&) override
220 {
221 throw std::runtime_error{test_exception_text};
222 }
223 };
224
225 std::shared_ptr<mir::scene::SurfaceFactory> the_surface_factory() override
226 {
227 return std::make_shared<BoobytrappedSurfaceFactory>();
228 }
229 } server_config;
230
231 launch_server_process(server_config);
232
233 struct ClientConfig : ClientConfigCommon
234 {
235 void exec()
236 {
237 mir_connect(mir_test_socket, __PRETTY_FUNCTION__, connection_callback, this);
238
239 wait_for_connect();
240
241 ASSERT_THAT(connection, IsValid());
222242
223 MirSurfaceParameters const request_params =243 MirSurfaceParameters const request_params =
224 {244 {
@@ -235,12 +255,7 @@
235255
236 ASSERT_TRUE(ssync->surface != NULL);256 ASSERT_TRUE(ssync->surface != NULL);
237 EXPECT_FALSE(mir_surface_is_valid(ssync->surface));257 EXPECT_FALSE(mir_surface_is_valid(ssync->surface));
238 EXPECT_TRUE(std::strstr(mir_surface_get_error_message(ssync->surface), ErrorServer::test_exception_text.c_str()));258 EXPECT_TRUE(std::strstr(mir_surface_get_error_message(ssync->surface), test_exception_text.c_str()));
239
240 EXPECT_NO_THROW({
241 MirSurfaceParameters response_params;
242 mir_surface_get_parameters(ssync->surface, &response_params);
243 });
244259
245 mir_surface_release(ssync->surface, release_surface_callback, ssync);260 mir_surface_release(ssync->surface, release_surface_callback, ssync);
246261
247262
=== modified file 'tests/mir_test/CMakeLists.txt'
--- tests/mir_test/CMakeLists.txt 2014-11-03 04:01:25 +0000
+++ tests/mir_test/CMakeLists.txt 2014-11-05 22:26:46 +0000
@@ -10,6 +10,7 @@
10 popen.cpp10 popen.cpp
11 wait_object.cpp11 wait_object.cpp
12 current_thread_name.cpp12 current_thread_name.cpp
13 validity_matchers.cpp
13)14)
1415
15target_link_libraries(mir-test mirprotobuf)16target_link_libraries(mir-test mirprotobuf)
1617
=== added file 'tests/mir_test/validity_matchers.cpp'
--- tests/mir_test/validity_matchers.cpp 1970-01-01 00:00:00 +0000
+++ tests/mir_test/validity_matchers.cpp 2014-11-05 22:26:46 +0000
@@ -0,0 +1,32 @@
1#include "mir_test/validity_matchers.h"
2#include "mir_toolkit/mir_client_library.h"
3
4template<>
5bool IsValidMatcher::MatchAndExplain(MirConnection* connection, MatchResultListener* listener) const
6{
7 if (connection == nullptr)
8 {
9 return false;
10 }
11 if (!mir_connection_is_valid(connection))
12 {
13 *listener << "error is: " << mir_connection_get_error_message(connection);
14 return false;
15 }
16 return true;
17}
18
19template<>
20bool IsValidMatcher::MatchAndExplain(MirSurface* surface, MatchResultListener* listener) const
21{
22 if (surface == nullptr)
23 {
24 return false;
25 }
26 if (!mir_surface_is_valid(surface))
27 {
28 *listener << "error is: " << mir_surface_get_error_message(surface);
29 return false;
30 }
31 return true;
32}
033
=== modified file 'tests/mir_test_framework/using_stub_client_platform.cpp'
--- tests/mir_test_framework/using_stub_client_platform.cpp 2014-10-27 15:22:31 +0000
+++ tests/mir_test_framework/using_stub_client_platform.cpp 2014-11-05 22:26:46 +0000
@@ -17,57 +17,27 @@
17 */17 */
1818
19#include "mir_test_framework/using_stub_client_platform.h"19#include "mir_test_framework/using_stub_client_platform.h"
20#include "mir_test_framework/stub_client_connection_configuration.h"
21#include "mir_toolkit/mir_client_library.h"20#include "mir_toolkit/mir_client_library.h"
22#include "src/client/mir_connection_api.h"
2321
24namespace mtf = mir_test_framework;22namespace mtf = mir_test_framework;
25namespace mcl = mir::client;23namespace mcl = mir::client;
2624
27namespace25MirWaitHandle* mtf::StubMirConnectionAPI::connect(
28{26 mcl::ConfigurationFactory /*configuration*/,
29class StubMirConnectionAPI : public mcl::MirConnectionAPI
30{
31public:
32 StubMirConnectionAPI(mcl::MirConnectionAPI* prev_api)
33 : prev_api{prev_api}
34 {
35 }
36
37 MirWaitHandle* connect(
38 char const* socket_file,27 char const* socket_file,
39 char const* name,28 char const* name,
40 mir_connected_callback callback,29 mir_connected_callback callback,
41 void* context) override30 void* context)
42 {31{
43 return prev_api->connect(socket_file, name, callback, context);32 return prev_api->connect(configuration_factory(), socket_file, name, callback, context);
44 }33}
4534
46 void release(MirConnection* connection) override35void mtf::StubMirConnectionAPI::release(MirConnection* connection)
47 {36{
48 return prev_api->release(connection);37 return prev_api->release(connection);
49 }38}
5039
51 std::unique_ptr<mcl::ConnectionConfiguration> configuration(std::string const& socket) override40mcl::ConfigurationFactory mtf::StubMirConnectionAPI::configuration_factory()
52 {41{
53 return std::unique_ptr<mcl::ConnectionConfiguration>{42 return factory;
54 new mtf::StubConnectionConfiguration{socket}};
55 }
56
57private:
58 mcl::MirConnectionAPI* const prev_api;
59};
60
61}
62
63mtf::UsingStubClientPlatform::UsingStubClientPlatform()
64 : prev_api{mir_connection_api_impl},
65 stub_api{new StubMirConnectionAPI{prev_api}}
66{
67 mir_connection_api_impl = stub_api.get();
68}
69
70mtf::UsingStubClientPlatform::~UsingStubClientPlatform()
71{
72 mir_connection_api_impl = prev_api;
73}43}

Subscribers

People subscribed via source and target branches