Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: extensions/browser/mojo/stash_backend_unittest.cc

Issue 2410743002: Remove the mojo serial interfaces and related infrastructure. (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « extensions/browser/mojo/stash_backend.cc ('k') | extensions/common/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "extensions/browser/mojo/stash_backend.h"
6
7 #include <stdint.h>
8
9 #include <utility>
10
11 #include "base/bind.h"
12 #include "base/macros.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/run_loop.h"
15 #include "services/shell/public/interfaces/interface_provider.mojom.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 namespace extensions {
19 namespace {
20
21 // Create a data pipe, write some data to the producer handle and return the
22 // consumer handle.
23 mojo::ScopedHandle CreateReadableHandle() {
24 mojo::ScopedDataPipeConsumerHandle consumer_handle;
25 mojo::ScopedDataPipeProducerHandle producer_handle;
26 MojoCreateDataPipeOptions options = {
27 sizeof(options), MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, 1, 1,
28 };
29 MojoResult result =
30 mojo::CreateDataPipe(&options, &producer_handle, &consumer_handle);
31 EXPECT_EQ(MOJO_RESULT_OK, result);
32 uint32_t num_bytes = 1;
33 result = mojo::WriteDataRaw(producer_handle.get(), "a", &num_bytes,
34 MOJO_WRITE_DATA_FLAG_NONE);
35 EXPECT_EQ(MOJO_RESULT_OK, result);
36 EXPECT_EQ(1u, num_bytes);
37 return mojo::ScopedHandle::From(std::move(consumer_handle));
38 }
39
40 } // namespace
41
42 class StashServiceTest : public testing::Test {
43 public:
44 enum Event {
45 EVENT_NONE,
46 EVENT_STASH_RETRIEVED,
47 EVENT_HANDLE_READY,
48 };
49
50 StashServiceTest() {}
51
52 void SetUp() override {
53 expecting_error_ = false;
54 expected_event_ = EVENT_NONE;
55 stash_backend_.reset(new StashBackend(base::Bind(
56 &StashServiceTest::OnHandleReadyToRead, base::Unretained(this))));
57 stash_backend_->BindToRequest(mojo::GetProxy(&stash_service_));
58 stash_service_.set_connection_error_handler(base::Bind(&OnConnectionError));
59 handles_ready_ = 0;
60 }
61
62 static void OnConnectionError() { FAIL() << "Unexpected connection error"; }
63
64 mojo::Array<StashedObjectPtr> RetrieveStash() {
65 mojo::Array<StashedObjectPtr> stash;
66 stash_service_->RetrieveStash(base::Bind(
67 &StashServiceTest::StashRetrieved, base::Unretained(this), &stash));
68 WaitForEvent(EVENT_STASH_RETRIEVED);
69 return stash;
70 }
71
72 void StashRetrieved(mojo::Array<StashedObjectPtr>* output,
73 mojo::Array<StashedObjectPtr> stash) {
74 *output = std::move(stash);
75 EventReceived(EVENT_STASH_RETRIEVED);
76 }
77
78 void WaitForEvent(Event event) {
79 expected_event_ = event;
80 base::RunLoop run_loop;
81 stop_run_loop_ = run_loop.QuitClosure();
82 run_loop.Run();
83 }
84
85 void EventReceived(Event event) {
86 if (event == expected_event_ && !stop_run_loop_.is_null())
87 stop_run_loop_.Run();
88 }
89
90 void OnHandleReadyToRead() {
91 handles_ready_++;
92 EventReceived(EVENT_HANDLE_READY);
93 }
94
95 protected:
96 base::MessageLoop message_loop_;
97 base::Closure stop_run_loop_;
98 std::unique_ptr<StashBackend> stash_backend_;
99 Event expected_event_;
100 bool expecting_error_;
101 mojo::InterfacePtr<StashService> stash_service_;
102 int handles_ready_;
103
104 private:
105 DISALLOW_COPY_AND_ASSIGN(StashServiceTest);
106 };
107
108 // Test that adding stashed objects in multiple calls can all be retrieved by a
109 // Retrieve call.
110 TEST_F(StashServiceTest, AddTwiceAndRetrieve) {
111 mojo::Array<StashedObjectPtr> stashed_objects;
112 StashedObjectPtr stashed_object(StashedObject::New());
113 stashed_object->id = "test type";
114 stashed_object->data.push_back(1);
115 stashed_object->stashed_handles = mojo::Array<mojo::ScopedHandle>();
116 stashed_objects.push_back(std::move(stashed_object));
117 stash_service_->AddToStash(std::move(stashed_objects));
118 stashed_object = StashedObject::New();
119 stashed_object->id = "test type2";
120 stashed_object->data.push_back(2);
121 stashed_object->data.push_back(3);
122 stashed_object->stashed_handles = mojo::Array<mojo::ScopedHandle>();
123 stashed_objects.push_back(std::move(stashed_object));
124 stash_service_->AddToStash(std::move(stashed_objects));
125 stashed_objects = RetrieveStash();
126 ASSERT_EQ(2u, stashed_objects.size());
127 EXPECT_EQ("test type", stashed_objects[0]->id);
128 EXPECT_EQ(0u, stashed_objects[0]->stashed_handles.size());
129 EXPECT_EQ(1u, stashed_objects[0]->data.size());
130 EXPECT_EQ(1, stashed_objects[0]->data[0]);
131 EXPECT_EQ("test type2", stashed_objects[1]->id);
132 EXPECT_EQ(0u, stashed_objects[1]->stashed_handles.size());
133 EXPECT_EQ(2u, stashed_objects[1]->data.size());
134 EXPECT_EQ(2, stashed_objects[1]->data[0]);
135 EXPECT_EQ(3, stashed_objects[1]->data[1]);
136 }
137
138 // Test that handles survive a round-trip through the stash.
139 TEST_F(StashServiceTest, StashAndRetrieveHandles) {
140 mojo::Array<StashedObjectPtr> stashed_objects;
141 StashedObjectPtr stashed_object(StashedObject::New());
142 stashed_object->id = "test type";
143 stashed_object->data.push_back(1);
144
145 mojo::ScopedDataPipeConsumerHandle consumer;
146 mojo::ScopedDataPipeProducerHandle producer;
147 MojoCreateDataPipeOptions options = {
148 sizeof(options), MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, 1, 1,
149 };
150 mojo::CreateDataPipe(&options, &producer, &consumer);
151 uint32_t num_bytes = 1;
152 MojoResult result = mojo::WriteDataRaw(
153 producer.get(), "1", &num_bytes, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE);
154 ASSERT_EQ(MOJO_RESULT_OK, result);
155 ASSERT_EQ(1u, num_bytes);
156
157 stashed_object->stashed_handles.push_back(
158 mojo::ScopedHandle::From(std::move(producer)));
159 stashed_object->stashed_handles.push_back(
160 mojo::ScopedHandle::From(std::move(consumer)));
161 stashed_objects.push_back(std::move(stashed_object));
162 stash_service_->AddToStash(std::move(stashed_objects));
163 stashed_objects = RetrieveStash();
164 ASSERT_EQ(1u, stashed_objects.size());
165 EXPECT_EQ("test type", stashed_objects[0]->id);
166 ASSERT_EQ(2u, stashed_objects[0]->stashed_handles.size());
167
168 consumer = mojo::ScopedDataPipeConsumerHandle::From(
169 std::move(stashed_objects[0]->stashed_handles[1]));
170 result = mojo::Wait(
171 consumer.get(), MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE,
172 nullptr);
173 ASSERT_EQ(MOJO_RESULT_OK, result);
174 char data = '\0';
175 result = mojo::ReadDataRaw(
176 consumer.get(), &data, &num_bytes, MOJO_READ_DATA_FLAG_ALL_OR_NONE);
177 ASSERT_EQ(MOJO_RESULT_OK, result);
178 ASSERT_EQ(1u, num_bytes);
179 EXPECT_EQ('1', data);
180 }
181
182 TEST_F(StashServiceTest, RetrieveWithoutStashing) {
183 mojo::Array<StashedObjectPtr> stashed_objects = RetrieveStash();
184 ASSERT_TRUE(!stashed_objects.is_null());
185 EXPECT_EQ(0u, stashed_objects.size());
186 }
187
188 TEST_F(StashServiceTest, NotifyOnReadableHandle) {
189 mojo::Array<StashedObjectPtr> stash_entries;
190 StashedObjectPtr stashed_object(StashedObject::New());
191 stashed_object->id = "test type";
192 stashed_object->data.push_back(0);
193 stashed_object->monitor_handles = true;
194 shell::mojom::InterfaceProviderPtr interface_provider;
195
196 // Stash the ServiceProvider request. When we make a call on
197 // |interface_provider|, the stashed handle will become readable.
198 stashed_object->stashed_handles.push_back(mojo::ScopedHandle::From(
199 mojo::GetProxy(&interface_provider).PassMessagePipe()));
200
201 stash_entries.push_back(std::move(stashed_object));
202 stash_service_->AddToStash(std::move(stash_entries));
203
204 mojo::MessagePipe pipe;
205 interface_provider->GetInterface("", std::move(pipe.handle0));
206
207 WaitForEvent(EVENT_HANDLE_READY);
208 EXPECT_EQ(1, handles_ready_);
209 }
210
211 TEST_F(StashServiceTest, NotifyOnReadableDataPipeHandle) {
212 mojo::Array<StashedObjectPtr> stash_entries;
213 StashedObjectPtr stashed_object(StashedObject::New());
214 stashed_object->id = "test type";
215 stashed_object->monitor_handles = true;
216
217 MojoCreateDataPipeOptions options = {
218 sizeof(options), MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, 1, 1,
219 };
220 mojo::ScopedDataPipeConsumerHandle consumer_handle;
221 mojo::ScopedDataPipeProducerHandle producer_handle;
222 uint32_t num_bytes = 1;
223 MojoResult result =
224 mojo::CreateDataPipe(&options, &producer_handle, &consumer_handle);
225 ASSERT_EQ(MOJO_RESULT_OK, result);
226 result = mojo::WriteDataRaw(producer_handle.get(), "a", &num_bytes,
227 MOJO_WRITE_DATA_FLAG_NONE);
228 ASSERT_EQ(MOJO_RESULT_OK, result);
229 ASSERT_EQ(1u, num_bytes);
230 stashed_object->stashed_handles.push_back(
231 mojo::ScopedHandle::From(std::move(producer_handle)));
232 stashed_object->stashed_handles.push_back(
233 mojo::ScopedHandle::From(std::move(consumer_handle)));
234 stashed_object->data.push_back(1);
235
236 stash_entries.push_back(std::move(stashed_object));
237 stash_service_->AddToStash(std::move(stash_entries));
238 WaitForEvent(EVENT_HANDLE_READY);
239 EXPECT_EQ(1, handles_ready_);
240 }
241
242 TEST_F(StashServiceTest, NotifyOncePerStashOnReadableHandles) {
243 mojo::Array<StashedObjectPtr> stash_entries;
244 StashedObjectPtr stashed_object(StashedObject::New());
245 stashed_object->id = "test type";
246 stashed_object->data.push_back(1);
247 stashed_object->monitor_handles = true;
248 stashed_object->stashed_handles.push_back(CreateReadableHandle());
249 stashed_object->stashed_handles.push_back(CreateReadableHandle());
250 stash_entries.push_back(std::move(stashed_object));
251 stashed_object = StashedObject::New();
252 stashed_object->id = "another test type";
253 stashed_object->data.push_back(2);
254 stashed_object->monitor_handles = true;
255 stashed_object->stashed_handles.push_back(CreateReadableHandle());
256 stashed_object->stashed_handles.push_back(CreateReadableHandle());
257 stash_entries.push_back(std::move(stashed_object));
258 stash_service_->AddToStash(std::move(stash_entries));
259 WaitForEvent(EVENT_HANDLE_READY);
260 EXPECT_EQ(1, handles_ready_);
261
262 stashed_object = StashedObject::New();
263 stashed_object->id = "yet another test type";
264 stashed_object->data.push_back(3);
265 stashed_object->monitor_handles = true;
266 stashed_object->stashed_handles.push_back(CreateReadableHandle());
267 stashed_object->stashed_handles.push_back(CreateReadableHandle());
268 stash_entries.push_back(std::move(stashed_object));
269 stash_service_->AddToStash(std::move(stash_entries));
270
271 stash_service_->AddToStash(RetrieveStash());
272 WaitForEvent(EVENT_HANDLE_READY);
273 EXPECT_EQ(2, handles_ready_);
274 }
275
276 // Test that a stash service discards stashed objects when the backend no longer
277 // exists.
278 TEST_F(StashServiceTest, ServiceWithDeletedBackend) {
279 stash_backend_.reset();
280 stash_service_.set_connection_error_handler(base::Bind(&OnConnectionError));
281
282 mojo::Array<StashedObjectPtr> stashed_objects;
283 StashedObjectPtr stashed_object(StashedObject::New());
284 stashed_object->id = "test type";
285 stashed_object->data.push_back(1);
286 mojo::MessagePipe message_pipe;
287 stashed_object->stashed_handles.push_back(
288 mojo::ScopedHandle::From(std::move(message_pipe.handle0)));
289 stashed_objects.push_back(std::move(stashed_object));
290 stash_service_->AddToStash(std::move(stashed_objects));
291 stashed_objects = RetrieveStash();
292 ASSERT_EQ(0u, stashed_objects.size());
293 // Check that the stashed handle has been closed.
294 MojoResult result =
295 mojo::Wait(message_pipe.handle1.get(),
296 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_READABLE,
297 MOJO_DEADLINE_INDEFINITE, nullptr);
298 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
299 }
300
301 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/browser/mojo/stash_backend.cc ('k') | extensions/common/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698