Home | History | Annotate | Download | only in tests
      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 // Serialization warnings are only recorded when DLOG is enabled.
      6 #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
      7 
      8 #include <stddef.h>
      9 #include <utility>
     10 
     11 #include "mojo/public/cpp/bindings/lib/array_internal.h"
     12 #include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
     13 #include "mojo/public/cpp/bindings/lib/serialization.h"
     14 #include "mojo/public/cpp/bindings/lib/validation_errors.h"
     15 #include "mojo/public/cpp/system/message_pipe.h"
     16 #include "mojo/public/interfaces/bindings/tests/serialization_test_structs.mojom.h"
     17 #include "mojo/public/interfaces/bindings/tests/test_unions.mojom.h"
     18 #include "testing/gtest/include/gtest/gtest.h"
     19 
     20 namespace mojo {
     21 namespace test {
     22 namespace {
     23 
     24 using mojo::internal::ContainerValidateParams;
     25 
     26 // Creates an array of arrays of handles (2 X 3) for testing.
     27 std::vector<base::Optional<std::vector<ScopedHandle>>>
     28 CreateTestNestedHandleArray() {
     29   std::vector<base::Optional<std::vector<ScopedHandle>>> array(2);
     30   for (size_t i = 0; i < array.size(); ++i) {
     31     std::vector<ScopedHandle> nested_array(3);
     32     for (size_t j = 0; j < nested_array.size(); ++j) {
     33       MessagePipe pipe;
     34       nested_array[j] = ScopedHandle::From(std::move(pipe.handle1));
     35     }
     36     array[i].emplace(std::move(nested_array));
     37   }
     38 
     39   return array;
     40 }
     41 
     42 class SerializationWarningTest : public testing::Test {
     43  public:
     44   ~SerializationWarningTest() override {}
     45 
     46  protected:
     47   template <typename T>
     48   void TestWarning(T obj, mojo::internal::ValidationError expected_warning) {
     49     using MojomType = typename T::Struct::DataView;
     50 
     51     warning_observer_.set_last_warning(mojo::internal::VALIDATION_ERROR_NONE);
     52 
     53     mojo::internal::SerializationContext context;
     54     mojo::Message message(0, 0, 0, 0, nullptr);
     55     typename mojo::internal::MojomTypeTraits<MojomType>::Data::BufferWriter
     56         writer;
     57     mojo::internal::Serialize<MojomType>(obj, message.payload_buffer(), &writer,
     58                                          &context);
     59     EXPECT_EQ(expected_warning, warning_observer_.last_warning());
     60   }
     61 
     62   template <typename MojomType, typename T>
     63   void TestArrayWarning(T obj,
     64                         mojo::internal::ValidationError expected_warning,
     65                         const ContainerValidateParams* validate_params) {
     66     warning_observer_.set_last_warning(mojo::internal::VALIDATION_ERROR_NONE);
     67 
     68     mojo::internal::SerializationContext context;
     69     mojo::Message message(0, 0, 0, 0, nullptr);
     70     typename mojo::internal::MojomTypeTraits<MojomType>::Data::BufferWriter
     71         writer;
     72     mojo::internal::Serialize<MojomType>(obj, message.payload_buffer(), &writer,
     73                                          validate_params, &context);
     74     EXPECT_EQ(expected_warning, warning_observer_.last_warning());
     75   }
     76 
     77   template <typename T>
     78   void TestUnionWarning(T obj,
     79                         mojo::internal::ValidationError expected_warning) {
     80     using MojomType = typename T::Struct::DataView;
     81 
     82     warning_observer_.set_last_warning(mojo::internal::VALIDATION_ERROR_NONE);
     83 
     84     mojo::internal::SerializationContext context;
     85     mojo::Message message(0, 0, 0, 0, nullptr);
     86     typename mojo::internal::MojomTypeTraits<MojomType>::Data::BufferWriter
     87         writer;
     88     mojo::internal::Serialize<MojomType>(obj, message.payload_buffer(), &writer,
     89                                          false, &context);
     90 
     91     EXPECT_EQ(expected_warning, warning_observer_.last_warning());
     92   }
     93 
     94   mojo::internal::SerializationWarningObserverForTesting warning_observer_;
     95 };
     96 
     97 TEST_F(SerializationWarningTest, HandleInStruct) {
     98   Struct2Ptr test_struct(Struct2::New());
     99   EXPECT_FALSE(test_struct->hdl.is_valid());
    100 
    101   TestWarning(std::move(test_struct),
    102               mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE);
    103 
    104   test_struct = Struct2::New();
    105   MessagePipe pipe;
    106   test_struct->hdl = ScopedHandle::From(std::move(pipe.handle1));
    107 
    108   TestWarning(std::move(test_struct), mojo::internal::VALIDATION_ERROR_NONE);
    109 }
    110 
    111 TEST_F(SerializationWarningTest, StructInStruct) {
    112   Struct3Ptr test_struct(Struct3::New());
    113   EXPECT_TRUE(!test_struct->struct_1);
    114 
    115   TestWarning(std::move(test_struct),
    116               mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER);
    117 
    118   test_struct = Struct3::New();
    119   test_struct->struct_1 = Struct1::New();
    120 
    121   TestWarning(std::move(test_struct), mojo::internal::VALIDATION_ERROR_NONE);
    122 }
    123 
    124 TEST_F(SerializationWarningTest, ArrayOfStructsInStruct) {
    125   Struct4Ptr test_struct(Struct4::New());
    126   test_struct->data.resize(1);
    127 
    128   TestWarning(std::move(test_struct),
    129               mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER);
    130 
    131   test_struct = Struct4::New();
    132   test_struct->data.resize(0);
    133 
    134   TestWarning(std::move(test_struct), mojo::internal::VALIDATION_ERROR_NONE);
    135 
    136   test_struct = Struct4::New();
    137   test_struct->data.resize(1);
    138   test_struct->data[0] = Struct1::New();
    139 
    140   TestWarning(std::move(test_struct), mojo::internal::VALIDATION_ERROR_NONE);
    141 }
    142 
    143 TEST_F(SerializationWarningTest, FixedArrayOfStructsInStruct) {
    144   Struct5Ptr test_struct(Struct5::New());
    145   test_struct->pair.resize(1);
    146   test_struct->pair[0] = Struct1::New();
    147 
    148   TestWarning(std::move(test_struct),
    149               mojo::internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER);
    150 
    151   test_struct = Struct5::New();
    152   test_struct->pair.resize(2);
    153   test_struct->pair[0] = Struct1::New();
    154   test_struct->pair[1] = Struct1::New();
    155 
    156   TestWarning(std::move(test_struct), mojo::internal::VALIDATION_ERROR_NONE);
    157 }
    158 
    159 TEST_F(SerializationWarningTest, ArrayOfArraysOfHandles) {
    160   using MojomType = ArrayDataView<ArrayDataView<ScopedHandle>>;
    161   auto test_array = CreateTestNestedHandleArray();
    162   test_array[0] = base::nullopt;
    163   (*test_array[1])[0] = ScopedHandle();
    164 
    165   ContainerValidateParams validate_params_0(
    166       0, true, new ContainerValidateParams(0, true, nullptr));
    167   TestArrayWarning<MojomType>(std::move(test_array),
    168                               mojo::internal::VALIDATION_ERROR_NONE,
    169                               &validate_params_0);
    170 
    171   test_array = CreateTestNestedHandleArray();
    172   test_array[0] = base::nullopt;
    173   ContainerValidateParams validate_params_1(
    174       0, false, new ContainerValidateParams(0, true, nullptr));
    175   TestArrayWarning<MojomType>(
    176       std::move(test_array),
    177       mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
    178       &validate_params_1);
    179 
    180   test_array = CreateTestNestedHandleArray();
    181   (*test_array[1])[0] = ScopedHandle();
    182   ContainerValidateParams validate_params_2(
    183       0, true, new ContainerValidateParams(0, false, nullptr));
    184   TestArrayWarning<MojomType>(
    185       std::move(test_array),
    186       mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
    187       &validate_params_2);
    188 }
    189 
    190 TEST_F(SerializationWarningTest, ArrayOfStrings) {
    191   using MojomType = ArrayDataView<StringDataView>;
    192 
    193   std::vector<std::string> test_array(3);
    194   for (size_t i = 0; i < test_array.size(); ++i)
    195     test_array[i] = "hello";
    196 
    197   ContainerValidateParams validate_params_0(
    198       0, true, new ContainerValidateParams(0, false, nullptr));
    199   TestArrayWarning<MojomType>(std::move(test_array),
    200                               mojo::internal::VALIDATION_ERROR_NONE,
    201                               &validate_params_0);
    202 
    203   std::vector<base::Optional<std::string>> optional_test_array(3);
    204   ContainerValidateParams validate_params_1(
    205       0, false, new ContainerValidateParams(0, false, nullptr));
    206   TestArrayWarning<MojomType>(
    207       std::move(optional_test_array),
    208       mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
    209       &validate_params_1);
    210 
    211   test_array = std::vector<std::string>(2);
    212   ContainerValidateParams validate_params_2(
    213       3, true, new ContainerValidateParams(0, false, nullptr));
    214   TestArrayWarning<MojomType>(
    215       std::move(test_array),
    216       mojo::internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER,
    217       &validate_params_2);
    218 }
    219 
    220 TEST_F(SerializationWarningTest, StructInUnion) {
    221   DummyStructPtr dummy(nullptr);
    222   ObjectUnionPtr obj(ObjectUnion::New());
    223   obj->set_f_dummy(std::move(dummy));
    224 
    225   TestUnionWarning(std::move(obj),
    226                    mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER);
    227 }
    228 
    229 TEST_F(SerializationWarningTest, UnionInUnion) {
    230   PodUnionPtr pod(nullptr);
    231   ObjectUnionPtr obj(ObjectUnion::New());
    232   obj->set_f_pod_union(std::move(pod));
    233 
    234   TestUnionWarning(std::move(obj),
    235                    mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER);
    236 }
    237 
    238 TEST_F(SerializationWarningTest, HandleInUnion) {
    239   ScopedMessagePipeHandle pipe;
    240   HandleUnionPtr handle(HandleUnion::New());
    241   handle->set_f_message_pipe(std::move(pipe));
    242 
    243   TestUnionWarning(std::move(handle),
    244                    mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE);
    245 }
    246 
    247 }  // namespace
    248 }  // namespace test
    249 }  // namespace mojo
    250 
    251 #endif
    252