Home | History | Annotate | Download | only in tests
      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:
     19   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:
     30   explicit TestUnserializedStructImpl(
     31       test::TestUnserializedStructRequest request)
     32       : binding_(this, std::move(request)) {}
     33   ~TestUnserializedStructImpl() override {}
     34 
     35   // test::TestUnserializedStruct:
     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:
     50   ForceSerializeTesterImpl(test::ForceSerializeTesterRequest request)
     51       : binding_(this, std::move(request)) {}
     52   ~ForceSerializeTesterImpl() override = default;
     53 
     54   // test::ForceSerializeTester:
     55   void SendForceSerializedStruct(
     56       const test::StructForceSerializeImpl& s,
     57       const SendForceSerializedStructCallback& callback) override {
     58     callback.Run(s);
     59   }
     60 
     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 
     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 
    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 
    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