• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 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 "base/macros.h"
6 #include "base/run_loop.h"
7 #include "base/test/bind_test_util.h"
8 #include "base/test/scoped_task_environment.h"
9 #include "mojo/public/cpp/bindings/binding.h"
10 #include "mojo/public/cpp/bindings/tests/bindings_test_base.h"
11 #include "mojo/public/interfaces/bindings/tests/struct_with_traits.mojom.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 
14 namespace mojo {
15 namespace {
16 
17 class LazySerializationTest : public testing::Test {
18  public:
LazySerializationTest()19   LazySerializationTest() {}
~LazySerializationTest()20   ~LazySerializationTest() override {}
21 
22  private:
23   base::test::ScopedTaskEnvironment task_environment_;
24 
25   DISALLOW_COPY_AND_ASSIGN(LazySerializationTest);
26 };
27 
28 class TestUnserializedStructImpl : public test::TestUnserializedStruct {
29  public:
TestUnserializedStructImpl(test::TestUnserializedStructRequest request)30   explicit TestUnserializedStructImpl(
31       test::TestUnserializedStructRequest request)
32       : binding_(this, std::move(request)) {}
~TestUnserializedStructImpl()33   ~TestUnserializedStructImpl() override {}
34 
35   // test::TestUnserializedStruct:
PassUnserializedStruct(const test::StructWithUnreachableTraitsImpl & s,const PassUnserializedStructCallback & callback)36   void PassUnserializedStruct(
37       const test::StructWithUnreachableTraitsImpl& s,
38       const PassUnserializedStructCallback& callback) override {
39     callback.Run(s);
40   }
41 
42  private:
43   mojo::Binding<test::TestUnserializedStruct> binding_;
44 
45   DISALLOW_COPY_AND_ASSIGN(TestUnserializedStructImpl);
46 };
47 
48 class ForceSerializeTesterImpl : public test::ForceSerializeTester {
49  public:
ForceSerializeTesterImpl(test::ForceSerializeTesterRequest request)50   ForceSerializeTesterImpl(test::ForceSerializeTesterRequest request)
51       : binding_(this, std::move(request)) {}
52   ~ForceSerializeTesterImpl() override = default;
53 
54   // test::ForceSerializeTester:
SendForceSerializedStruct(const test::StructForceSerializeImpl & s,const SendForceSerializedStructCallback & callback)55   void SendForceSerializedStruct(
56       const test::StructForceSerializeImpl& s,
57       const SendForceSerializedStructCallback& callback) override {
58     callback.Run(s);
59   }
60 
SendNestedForceSerializedStruct(const test::StructNestedForceSerializeImpl & s,const SendNestedForceSerializedStructCallback & callback)61   void SendNestedForceSerializedStruct(
62       const test::StructNestedForceSerializeImpl& s,
63       const SendNestedForceSerializedStructCallback& callback) override {
64     callback.Run(s);
65   }
66 
67  private:
68   Binding<test::ForceSerializeTester> binding_;
69 
70   DISALLOW_COPY_AND_ASSIGN(ForceSerializeTesterImpl);
71 };
72 
TEST_F(LazySerializationTest,NeverSerialize)73 TEST_F(LazySerializationTest, NeverSerialize) {
74   // Basic sanity check to ensure that no messages are serialized by default in
75   // environments where lazy serialization is supported, on an interface which
76   // supports lazy serialization, and where both ends of the interface are in
77   // the same process.
78 
79   test::TestUnserializedStructPtr ptr;
80   TestUnserializedStructImpl impl(MakeRequest(&ptr));
81 
82   const int32_t kTestMagicNumber = 42;
83 
84   test::StructWithUnreachableTraitsImpl data;
85   EXPECT_EQ(0, data.magic_number);
86   data.magic_number = kTestMagicNumber;
87 
88   // Send our data over the pipe and wait for it to come back. The value should
89   // be preserved. We know the data was never serialized because the
90   // StructTraits for this type will DCHECK if executed in any capacity.
91   int received_number = 0;
92   base::RunLoop loop;
93   ptr->PassUnserializedStruct(
94       data, base::Bind(
95                 [](base::RunLoop* loop, int* received_number,
96                    const test::StructWithUnreachableTraitsImpl& passed) {
97                   *received_number = passed.magic_number;
98                   loop->Quit();
99                 },
100                 &loop, &received_number));
101   loop.Run();
102   EXPECT_EQ(kTestMagicNumber, received_number);
103 }
104 
TEST_F(LazySerializationTest,ForceSerialize)105 TEST_F(LazySerializationTest, ForceSerialize) {
106   // Verifies that the [force_serialize] attribute works as intended: i.e., even
107   // with lazy serialization enabled, messages which carry a force-serialized
108   // type will always serialize at call time.
109 
110   test::ForceSerializeTesterPtr tester;
111   ForceSerializeTesterImpl impl(mojo::MakeRequest(&tester));
112 
113   constexpr int32_t kTestValue = 42;
114 
115   base::RunLoop loop;
116   test::StructForceSerializeImpl in;
117   in.set_value(kTestValue);
118   EXPECT_FALSE(in.was_serialized());
119   EXPECT_FALSE(in.was_deserialized());
120   tester->SendForceSerializedStruct(
121       in, base::BindLambdaForTesting(
122               [&](const test::StructForceSerializeImpl& passed) {
123                 EXPECT_EQ(kTestValue, passed.value());
124                 EXPECT_TRUE(passed.was_deserialized());
125                 EXPECT_FALSE(passed.was_serialized());
126                 loop.Quit();
127               }));
128   EXPECT_TRUE(in.was_serialized());
129   EXPECT_FALSE(in.was_deserialized());
130   loop.Run();
131   EXPECT_TRUE(in.was_serialized());
132   EXPECT_FALSE(in.was_deserialized());
133 }
134 
TEST_F(LazySerializationTest,ForceSerializeNested)135 TEST_F(LazySerializationTest, ForceSerializeNested) {
136   // Verifies that the [force_serialize] attribute works as intended in a nested
137   // context, i.e. when a force-serialized type is contained within a
138   // non-force-serialized type,
139 
140   test::ForceSerializeTesterPtr tester;
141   ForceSerializeTesterImpl impl(mojo::MakeRequest(&tester));
142 
143   constexpr int32_t kTestValue = 42;
144 
145   base::RunLoop loop;
146   test::StructNestedForceSerializeImpl in;
147   in.force().set_value(kTestValue);
148   EXPECT_FALSE(in.was_serialized());
149   EXPECT_FALSE(in.was_deserialized());
150   tester->SendNestedForceSerializedStruct(
151       in, base::BindLambdaForTesting(
152               [&](const test::StructNestedForceSerializeImpl& passed) {
153                 EXPECT_EQ(kTestValue, passed.force().value());
154                 EXPECT_TRUE(passed.was_deserialized());
155                 EXPECT_FALSE(passed.was_serialized());
156                 loop.Quit();
157               }));
158   EXPECT_TRUE(in.was_serialized());
159   EXPECT_FALSE(in.was_deserialized());
160   loop.Run();
161   EXPECT_TRUE(in.was_serialized());
162   EXPECT_FALSE(in.was_deserialized());
163 }
164 
165 }  // namespace
166 }  // namespace mojo
167