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 in debug build. 6#ifndef NDEBUG 7 8#include "mojo/public/cpp/bindings/array.h" 9#include "mojo/public/cpp/bindings/lib/array_internal.h" 10#include "mojo/public/cpp/bindings/lib/array_serialization.h" 11#include "mojo/public/cpp/bindings/lib/fixed_buffer.h" 12#include "mojo/public/cpp/bindings/lib/validation_errors.h" 13#include "mojo/public/cpp/bindings/string.h" 14#include "mojo/public/cpp/environment/environment.h" 15#include "mojo/public/cpp/system/message_pipe.h" 16#include "mojo/public/interfaces/bindings/tests/serialization_test_structs.mojom.h" 17#include "testing/gtest/include/gtest/gtest.h" 18 19namespace mojo { 20namespace test { 21namespace { 22 23using mojo::internal::ArrayValidateParams; 24using mojo::internal::NoValidateParams; 25 26// Creates an array of arrays of handles (2 X 3) for testing. 27Array<Array<ScopedHandle> > CreateTestNestedHandleArray() { 28 Array<Array<ScopedHandle> > array(2); 29 for (size_t i = 0; i < array.size(); ++i) { 30 Array<ScopedHandle> nested_array(3); 31 for (size_t j = 0; j < nested_array.size(); ++j) { 32 MessagePipe pipe; 33 nested_array[j] = ScopedHandle::From(pipe.handle1.Pass()); 34 } 35 array[i] = nested_array.Pass(); 36 } 37 38 return array.Pass(); 39} 40 41class SerializationWarningTest : public testing::Test { 42 public: 43 virtual ~SerializationWarningTest() {} 44 45 protected: 46 template <typename T> 47 void TestWarning(T obj, mojo::internal::ValidationError expected_warning) { 48 warning_observer_.set_last_warning(mojo::internal::VALIDATION_ERROR_NONE); 49 50 mojo::internal::FixedBuffer buf(GetSerializedSize_(obj)); 51 typename T::Data_* data; 52 Serialize_(obj.Pass(), &buf, &data); 53 54 EXPECT_EQ(expected_warning, warning_observer_.last_warning()); 55 } 56 57 template <typename ValidateParams, typename T> 58 void TestArrayWarning(T obj, 59 mojo::internal::ValidationError expected_warning) { 60 warning_observer_.set_last_warning(mojo::internal::VALIDATION_ERROR_NONE); 61 62 mojo::internal::FixedBuffer buf(GetSerializedSize_(obj)); 63 typename T::Data_* data; 64 SerializeArray_<ValidateParams>(obj.Pass(), &buf, &data); 65 66 EXPECT_EQ(expected_warning, warning_observer_.last_warning()); 67 } 68 69 mojo::internal::SerializationWarningObserverForTesting warning_observer_; 70 Environment env_; 71}; 72 73TEST_F(SerializationWarningTest, HandleInStruct) { 74 Struct2Ptr test_struct(Struct2::New()); 75 EXPECT_FALSE(test_struct->hdl.is_valid()); 76 77 TestWarning(test_struct.Pass(), 78 mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE); 79 80 test_struct = Struct2::New(); 81 MessagePipe pipe; 82 test_struct->hdl = ScopedHandle::From(pipe.handle1.Pass()); 83 84 TestWarning(test_struct.Pass(), mojo::internal::VALIDATION_ERROR_NONE); 85} 86 87TEST_F(SerializationWarningTest, StructInStruct) { 88 Struct3Ptr test_struct(Struct3::New()); 89 EXPECT_TRUE(!test_struct->struct_1); 90 91 TestWarning(test_struct.Pass(), 92 mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER); 93 94 test_struct = Struct3::New(); 95 test_struct->struct_1 = Struct1::New(); 96 97 TestWarning(test_struct.Pass(), mojo::internal::VALIDATION_ERROR_NONE); 98} 99 100TEST_F(SerializationWarningTest, ArrayOfStructsInStruct) { 101 Struct4Ptr test_struct(Struct4::New()); 102 EXPECT_TRUE(!test_struct->array); 103 104 TestWarning(test_struct.Pass(), 105 mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER); 106 107 test_struct = Struct4::New(); 108 test_struct->array.resize(1); 109 110 TestWarning(test_struct.Pass(), 111 mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER); 112 113 test_struct = Struct4::New(); 114 test_struct->array.resize(0); 115 116 TestWarning(test_struct.Pass(), mojo::internal::VALIDATION_ERROR_NONE); 117 118 test_struct = Struct4::New(); 119 test_struct->array.resize(1); 120 test_struct->array[0] = Struct1::New(); 121 122 TestWarning(test_struct.Pass(), mojo::internal::VALIDATION_ERROR_NONE); 123} 124 125TEST_F(SerializationWarningTest, FixedArrayOfStructsInStruct) { 126 Struct5Ptr test_struct(Struct5::New()); 127 EXPECT_TRUE(!test_struct->pair); 128 129 TestWarning(test_struct.Pass(), 130 mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER); 131 132 test_struct = Struct5::New(); 133 test_struct->pair.resize(1); 134 test_struct->pair[0] = Struct1::New(); 135 136 TestWarning(test_struct.Pass(), 137 mojo::internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER); 138 139 test_struct = Struct5::New(); 140 test_struct->pair.resize(2); 141 test_struct->pair[0] = Struct1::New(); 142 test_struct->pair[1] = Struct1::New(); 143 144 TestWarning(test_struct.Pass(), mojo::internal::VALIDATION_ERROR_NONE); 145} 146 147TEST_F(SerializationWarningTest, StringInStruct) { 148 Struct6Ptr test_struct(Struct6::New()); 149 EXPECT_TRUE(!test_struct->str); 150 151 TestWarning(test_struct.Pass(), 152 mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER); 153 154 test_struct = Struct6::New(); 155 test_struct->str = "hello world"; 156 157 TestWarning(test_struct.Pass(), mojo::internal::VALIDATION_ERROR_NONE); 158} 159 160TEST_F(SerializationWarningTest, ArrayOfArraysOfHandles) { 161 Array<Array<ScopedHandle> > test_array = CreateTestNestedHandleArray(); 162 test_array[0] = Array<ScopedHandle>(); 163 test_array[1][0] = ScopedHandle(); 164 165 TestArrayWarning<ArrayValidateParams<0, true, 166 ArrayValidateParams<0, true, NoValidateParams> > >( 167 test_array.Pass(), mojo::internal::VALIDATION_ERROR_NONE); 168 169 test_array = CreateTestNestedHandleArray(); 170 test_array[0] = Array<ScopedHandle>(); 171 TestArrayWarning<ArrayValidateParams<0, false, 172 ArrayValidateParams<0, true, NoValidateParams> > >( 173 test_array.Pass(), 174 mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER); 175 176 test_array = CreateTestNestedHandleArray(); 177 test_array[1][0] = ScopedHandle(); 178 TestArrayWarning<ArrayValidateParams<0, true, 179 ArrayValidateParams<0, false, NoValidateParams> > >( 180 test_array.Pass(), 181 mojo::internal::VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE); 182} 183 184TEST_F(SerializationWarningTest, ArrayOfStrings) { 185 Array<String> test_array(3); 186 for (size_t i = 0; i < test_array.size(); ++i) 187 test_array[i] = "hello"; 188 189 TestArrayWarning<ArrayValidateParams<0, true, 190 ArrayValidateParams<0, false, NoValidateParams> > >( 191 test_array.Pass(), mojo::internal::VALIDATION_ERROR_NONE); 192 193 test_array = Array<String>(3); 194 TestArrayWarning<ArrayValidateParams<0, false, 195 ArrayValidateParams<0, false, NoValidateParams> > >( 196 test_array.Pass(), 197 mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER); 198 199 test_array = Array<String>(2); 200 TestArrayWarning<ArrayValidateParams<3, true, 201 ArrayValidateParams<0, false, NoValidateParams> > >( 202 test_array.Pass(), 203 mojo::internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER); 204} 205 206} // namespace 207} // namespace test 208} // namespace mojo 209 210#endif 211