• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 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 <string>
6 #include <utility>
7 
8 #include "base/bind.h"
9 #include "base/callback.h"
10 #include "base/logging.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/run_loop.h"
13 #include "mojo/public/cpp/bindings/binding_set.h"
14 #include "mojo/public/cpp/bindings/interface_request.h"
15 #include "mojo/public/cpp/bindings/tests/pickled_types_blink.h"
16 #include "mojo/public/cpp/bindings/tests/pickled_types_chromium.h"
17 #include "mojo/public/cpp/bindings/tests/variant_test_util.h"
18 #include "mojo/public/interfaces/bindings/tests/test_native_types.mojom-blink.h"
19 #include "mojo/public/interfaces/bindings/tests/test_native_types.mojom.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 
22 namespace mojo {
23 namespace test {
24 namespace {
25 
26 template <typename T>
DoExpectResult(int foo,int bar,const base::Closure & callback,const T & actual)27 void DoExpectResult(int foo,
28                     int bar,
29                     const base::Closure& callback,
30                     const T& actual) {
31   EXPECT_EQ(foo, actual.foo());
32   EXPECT_EQ(bar, actual.bar());
33   callback.Run();
34 }
35 
36 template <typename T>
ExpectResult(const T & t,const base::Closure & callback)37 base::Callback<void(const T&)> ExpectResult(const T& t,
38                                             const base::Closure& callback) {
39   return base::Bind(&DoExpectResult<T>, t.foo(), t.bar(), callback);
40 }
41 
42 template <typename T>
DoFail(const std::string & reason,const T &)43 void DoFail(const std::string& reason, const T&) {
44   EXPECT_TRUE(false) << reason;
45 }
46 
47 template <typename T>
Fail(const std::string & reason)48 base::Callback<void(const T&)> Fail(const std::string& reason) {
49   return base::Bind(&DoFail<T>, reason);
50 }
51 
52 template <typename T>
DoExpectEnumResult(T expected,const base::Closure & callback,T actual)53 void DoExpectEnumResult(T expected, const base::Closure& callback, T actual) {
54   EXPECT_EQ(expected, actual);
55   callback.Run();
56 }
57 
58 template <typename T>
ExpectEnumResult(T t,const base::Closure & callback)59 base::Callback<void(T)> ExpectEnumResult(T t, const base::Closure& callback) {
60   return base::Bind(&DoExpectEnumResult<T>, t, callback);
61 }
62 
63 template <typename T>
DoEnumFail(const std::string & reason,T)64 void DoEnumFail(const std::string& reason, T) {
65   EXPECT_TRUE(false) << reason;
66 }
67 
68 template <typename T>
EnumFail(const std::string & reason)69 base::Callback<void(T)> EnumFail(const std::string& reason) {
70   return base::Bind(&DoEnumFail<T>, reason);
71 }
72 
73 template <typename T>
ExpectError(InterfacePtr<T> * proxy,const base::Closure & callback)74 void ExpectError(InterfacePtr<T>* proxy, const base::Closure& callback) {
75   proxy->set_connection_error_handler(callback);
76 }
77 
78 template <typename Func, typename Arg>
RunSimpleLambda(Func func,Arg arg)79 void RunSimpleLambda(Func func, Arg arg) { func(std::move(arg)); }
80 
81 template <typename Arg, typename Func>
BindSimpleLambda(Func func)82 base::Callback<void(Arg)> BindSimpleLambda(Func func) {
83   return base::Bind(&RunSimpleLambda<Func, Arg>, func);
84 }
85 
86 // This implements the generated Chromium variant of PicklePasser.
87 class ChromiumPicklePasserImpl : public PicklePasser {
88  public:
ChromiumPicklePasserImpl()89   ChromiumPicklePasserImpl() {}
90 
91   // mojo::test::PicklePasser:
PassPickledStruct(const PickledStructChromium & pickle,const PassPickledStructCallback & callback)92   void PassPickledStruct(const PickledStructChromium& pickle,
93                          const PassPickledStructCallback& callback) override {
94     callback.Run(pickle);
95   }
96 
PassPickledEnum(PickledEnumChromium pickle,const PassPickledEnumCallback & callback)97   void PassPickledEnum(PickledEnumChromium pickle,
98                        const PassPickledEnumCallback& callback) override {
99     callback.Run(pickle);
100   }
101 
PassPickleContainer(PickleContainerPtr container,const PassPickleContainerCallback & callback)102   void PassPickleContainer(
103       PickleContainerPtr container,
104       const PassPickleContainerCallback& callback) override {
105     callback.Run(std::move(container));
106   }
107 
PassPickles(const std::vector<PickledStructChromium> & pickles,const PassPicklesCallback & callback)108   void PassPickles(const std::vector<PickledStructChromium>& pickles,
109                    const PassPicklesCallback& callback) override {
110     callback.Run(pickles);
111   }
112 
PassPickleArrays(const std::vector<std::vector<PickledStructChromium>> & pickle_arrays,const PassPickleArraysCallback & callback)113   void PassPickleArrays(
114       const std::vector<std::vector<PickledStructChromium>>& pickle_arrays,
115       const PassPickleArraysCallback& callback) override {
116     callback.Run(pickle_arrays);
117   }
118 };
119 
120 // This implements the generated Blink variant of PicklePasser.
121 class BlinkPicklePasserImpl : public blink::PicklePasser {
122  public:
BlinkPicklePasserImpl()123   BlinkPicklePasserImpl() {}
124 
125   // mojo::test::blink::PicklePasser:
PassPickledStruct(const PickledStructBlink & pickle,const PassPickledStructCallback & callback)126   void PassPickledStruct(const PickledStructBlink& pickle,
127                          const PassPickledStructCallback& callback) override {
128     callback.Run(pickle);
129   }
130 
PassPickledEnum(PickledEnumBlink pickle,const PassPickledEnumCallback & callback)131   void PassPickledEnum(PickledEnumBlink pickle,
132                        const PassPickledEnumCallback& callback) override {
133     callback.Run(pickle);
134   }
135 
PassPickleContainer(blink::PickleContainerPtr container,const PassPickleContainerCallback & callback)136   void PassPickleContainer(
137       blink::PickleContainerPtr container,
138       const PassPickleContainerCallback& callback) override {
139     callback.Run(std::move(container));
140   }
141 
PassPickles(const WTF::Vector<PickledStructBlink> & pickles,const PassPicklesCallback & callback)142   void PassPickles(const WTF::Vector<PickledStructBlink>& pickles,
143                    const PassPicklesCallback& callback) override {
144     callback.Run(pickles);
145   }
146 
PassPickleArrays(const WTF::Vector<WTF::Vector<PickledStructBlink>> & pickle_arrays,const PassPickleArraysCallback & callback)147   void PassPickleArrays(
148       const WTF::Vector<WTF::Vector<PickledStructBlink>>& pickle_arrays,
149       const PassPickleArraysCallback& callback) override {
150     callback.Run(pickle_arrays);
151   }
152 };
153 
154 // A test which runs both Chromium and Blink implementations of the
155 // PicklePasser service.
156 class PickleTest : public testing::Test {
157  public:
PickleTest()158   PickleTest() {}
159 
160   template <typename ProxyType = PicklePasser>
ConnectToChromiumService()161   InterfacePtr<ProxyType> ConnectToChromiumService() {
162     InterfacePtr<ProxyType> proxy;
163     InterfaceRequest<ProxyType> request = GetProxy(&proxy);
164     chromium_bindings_.AddBinding(
165         &chromium_service_,
166         ConvertInterfaceRequest<PicklePasser>(std::move(request)));
167     return proxy;
168   }
169 
170   template <typename ProxyType = blink::PicklePasser>
ConnectToBlinkService()171   InterfacePtr<ProxyType> ConnectToBlinkService() {
172     InterfacePtr<ProxyType> proxy;
173     InterfaceRequest<ProxyType> request = GetProxy(&proxy);
174     blink_bindings_.AddBinding(
175         &blink_service_,
176         ConvertInterfaceRequest<blink::PicklePasser>(std::move(request)));
177     return proxy;
178   }
179 
180  private:
181   base::MessageLoop loop_;
182   ChromiumPicklePasserImpl chromium_service_;
183   BindingSet<PicklePasser> chromium_bindings_;
184   BlinkPicklePasserImpl blink_service_;
185   BindingSet<blink::PicklePasser> blink_bindings_;
186 };
187 
188 }  // namespace
189 
TEST_F(PickleTest,ChromiumProxyToChromiumService)190 TEST_F(PickleTest, ChromiumProxyToChromiumService) {
191   auto chromium_proxy = ConnectToChromiumService();
192   {
193     base::RunLoop loop;
194     chromium_proxy->PassPickledStruct(
195         PickledStructChromium(1, 2),
196         ExpectResult(PickledStructChromium(1, 2), loop.QuitClosure()));
197     loop.Run();
198   }
199   {
200     base::RunLoop loop;
201     chromium_proxy->PassPickledStruct(
202         PickledStructChromium(4, 5),
203         ExpectResult(PickledStructChromium(4, 5), loop.QuitClosure()));
204     loop.Run();
205   }
206 
207   {
208     base::RunLoop loop;
209     chromium_proxy->PassPickledEnum(
210         PickledEnumChromium::VALUE_1,
211         ExpectEnumResult(PickledEnumChromium::VALUE_1, loop.QuitClosure()));
212     loop.Run();
213   }
214 }
215 
TEST_F(PickleTest,ChromiumProxyToBlinkService)216 TEST_F(PickleTest, ChromiumProxyToBlinkService) {
217   auto chromium_proxy = ConnectToBlinkService<PicklePasser>();
218   {
219     base::RunLoop loop;
220     chromium_proxy->PassPickledStruct(
221         PickledStructChromium(1, 2),
222         ExpectResult(PickledStructChromium(1, 2), loop.QuitClosure()));
223     loop.Run();
224   }
225   {
226     base::RunLoop loop;
227     chromium_proxy->PassPickledStruct(
228         PickledStructChromium(4, 5),
229         ExpectResult(PickledStructChromium(4, 5), loop.QuitClosure()));
230     loop.Run();
231   }
232   // The Blink service should drop our connection because the
233   // PickledStructBlink ParamTraits deserializer rejects negative values.
234   {
235     base::RunLoop loop;
236     chromium_proxy->PassPickledStruct(
237         PickledStructChromium(-1, -1),
238         Fail<PickledStructChromium>("Blink service should reject this."));
239     ExpectError(&chromium_proxy, loop.QuitClosure());
240     loop.Run();
241   }
242 
243   chromium_proxy = ConnectToBlinkService<PicklePasser>();
244   {
245     base::RunLoop loop;
246     chromium_proxy->PassPickledEnum(
247         PickledEnumChromium::VALUE_0,
248         ExpectEnumResult(PickledEnumChromium::VALUE_0, loop.QuitClosure()));
249     loop.Run();
250   }
251 
252   // The Blink service should drop our connection because the
253   // PickledEnumBlink ParamTraits deserializer rejects this value.
254   {
255     base::RunLoop loop;
256     chromium_proxy->PassPickledEnum(
257         PickledEnumChromium::VALUE_2,
258         EnumFail<PickledEnumChromium>("Blink service should reject this."));
259     ExpectError(&chromium_proxy, loop.QuitClosure());
260     loop.Run();
261   }
262 }
263 
TEST_F(PickleTest,BlinkProxyToBlinkService)264 TEST_F(PickleTest, BlinkProxyToBlinkService) {
265   auto blink_proxy = ConnectToBlinkService();
266   {
267     base::RunLoop loop;
268     blink_proxy->PassPickledStruct(
269         PickledStructBlink(1, 1),
270         ExpectResult(PickledStructBlink(1, 1), loop.QuitClosure()));
271     loop.Run();
272   }
273 
274   {
275     base::RunLoop loop;
276     blink_proxy->PassPickledEnum(
277         PickledEnumBlink::VALUE_0,
278         ExpectEnumResult(PickledEnumBlink::VALUE_0, loop.QuitClosure()));
279     loop.Run();
280   }
281 }
282 
TEST_F(PickleTest,BlinkProxyToChromiumService)283 TEST_F(PickleTest, BlinkProxyToChromiumService) {
284   auto blink_proxy = ConnectToChromiumService<blink::PicklePasser>();
285   {
286     base::RunLoop loop;
287     blink_proxy->PassPickledStruct(
288         PickledStructBlink(1, 1),
289         ExpectResult(PickledStructBlink(1, 1), loop.QuitClosure()));
290     loop.Run();
291   }
292 
293   {
294     base::RunLoop loop;
295     blink_proxy->PassPickledEnum(
296         PickledEnumBlink::VALUE_1,
297         ExpectEnumResult(PickledEnumBlink::VALUE_1, loop.QuitClosure()));
298     loop.Run();
299   }
300 }
301 
TEST_F(PickleTest,PickleArray)302 TEST_F(PickleTest, PickleArray) {
303   auto proxy = ConnectToChromiumService();
304   auto pickles = Array<PickledStructChromium>::New(2);
305   pickles[0].set_foo(1);
306   pickles[0].set_bar(2);
307   pickles[0].set_baz(100);
308   pickles[1].set_foo(3);
309   pickles[1].set_bar(4);
310   pickles[1].set_baz(100);
311   {
312     base::RunLoop run_loop;
313     // Verify that the array of pickled structs can be serialized and
314     // deserialized intact. This ensures that the ParamTraits are actually used
315     // rather than doing a byte-for-byte copy of the element data, beacuse the
316     // |baz| field should never be serialized.
317     proxy->PassPickles(
318         std::move(pickles),
319         BindSimpleLambda<const std::vector<PickledStructChromium>&>(
320             [&](const std::vector<PickledStructChromium>& passed) {
321               ASSERT_EQ(2u, passed.size());
322               EXPECT_EQ(1, passed[0].foo());
323               EXPECT_EQ(2, passed[0].bar());
324               EXPECT_EQ(0, passed[0].baz());
325               EXPECT_EQ(3, passed[1].foo());
326               EXPECT_EQ(4, passed[1].bar());
327               EXPECT_EQ(0, passed[1].baz());
328               run_loop.Quit();
329             }));
330     run_loop.Run();
331   }
332 }
333 
TEST_F(PickleTest,PickleArrayArray)334 TEST_F(PickleTest, PickleArrayArray) {
335   auto proxy = ConnectToChromiumService();
336   auto pickle_arrays = std::vector<std::vector<PickledStructChromium>>(2);
337   for (size_t i = 0; i < 2; ++i)
338     pickle_arrays[i] = std::vector<PickledStructChromium>(2);
339 
340   pickle_arrays[0][0].set_foo(1);
341   pickle_arrays[0][0].set_bar(2);
342   pickle_arrays[0][0].set_baz(100);
343   pickle_arrays[0][1].set_foo(3);
344   pickle_arrays[0][1].set_bar(4);
345   pickle_arrays[0][1].set_baz(100);
346   pickle_arrays[1][0].set_foo(5);
347   pickle_arrays[1][0].set_bar(6);
348   pickle_arrays[1][0].set_baz(100);
349   pickle_arrays[1][1].set_foo(7);
350   pickle_arrays[1][1].set_bar(8);
351   pickle_arrays[1][1].set_baz(100);
352   {
353     base::RunLoop run_loop;
354     // Verify that the array-of-arrays serializes and deserializes properly.
355     proxy->PassPickleArrays(
356         pickle_arrays,
357         BindSimpleLambda<
358             const std::vector<std::vector<PickledStructChromium>>&>(
359             [&](const std::vector<std::vector<PickledStructChromium>>& passed) {
360               ASSERT_EQ(2u, passed.size());
361               ASSERT_EQ(2u, passed[0].size());
362               ASSERT_EQ(2u, passed[1].size());
363               EXPECT_EQ(1, passed[0][0].foo());
364               EXPECT_EQ(2, passed[0][0].bar());
365               EXPECT_EQ(0, passed[0][0].baz());
366               EXPECT_EQ(3, passed[0][1].foo());
367               EXPECT_EQ(4, passed[0][1].bar());
368               EXPECT_EQ(0, passed[0][1].baz());
369               EXPECT_EQ(5, passed[1][0].foo());
370               EXPECT_EQ(6, passed[1][0].bar());
371               EXPECT_EQ(0, passed[1][0].baz());
372               EXPECT_EQ(7, passed[1][1].foo());
373               EXPECT_EQ(8, passed[1][1].bar());
374               EXPECT_EQ(0, passed[1][1].baz());
375               run_loop.Quit();
376             }));
377     run_loop.Run();
378   }
379 }
380 
TEST_F(PickleTest,PickleContainer)381 TEST_F(PickleTest, PickleContainer) {
382   auto proxy = ConnectToChromiumService();
383   PickleContainerPtr pickle_container = PickleContainer::New();
384   pickle_container->f_struct.set_foo(42);
385   pickle_container->f_struct.set_bar(43);
386   pickle_container->f_struct.set_baz(44);
387   pickle_container->f_enum = PickledEnumChromium::VALUE_1;
388   EXPECT_TRUE(pickle_container.Equals(pickle_container));
389   EXPECT_FALSE(pickle_container.Equals(PickleContainer::New()));
390   {
391     base::RunLoop run_loop;
392     proxy->PassPickleContainer(std::move(pickle_container),
393                                BindSimpleLambda<PickleContainerPtr>(
394                                    [&](PickleContainerPtr passed) {
395                                      ASSERT_FALSE(passed.is_null());
396                                      EXPECT_EQ(42, passed->f_struct.foo());
397                                      EXPECT_EQ(43, passed->f_struct.bar());
398                                      EXPECT_EQ(0, passed->f_struct.baz());
399                                      EXPECT_EQ(PickledEnumChromium::VALUE_1,
400                                                passed->f_enum);
401                                      run_loop.Quit();
402                                    }));
403     run_loop.Run();
404   }
405 }
406 
407 }  // namespace test
408 }  // namespace mojo
409