| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // Serialization warnings are only recorded in debug build. |
| #ifndef NDEBUG |
| |
| #include "gtest/gtest.h" |
| #include "mojo/public/cpp/bindings/array.h" |
| #include "mojo/public/cpp/bindings/lib/array_internal.h" |
| #include "mojo/public/cpp/bindings/lib/array_serialization.h" |
| #include "mojo/public/cpp/bindings/lib/fixed_buffer.h" |
| #include "mojo/public/cpp/bindings/lib/validation_errors.h" |
| #include "mojo/public/cpp/bindings/string.h" |
| #include "mojo/public/cpp/system/message_pipe.h" |
| #include "mojo/public/interfaces/bindings/tests/serialization_test_structs.mojom.h" |
| |
| namespace mojo { |
| namespace test { |
| namespace { |
| |
| using mojo::internal::ArrayValidateParams; |
| |
| // Creates an array of arrays of handles (2 X 3) for testing. |
| Array<Array<ScopedHandle>> CreateTestNestedHandleArray() { |
| auto array = Array<Array<ScopedHandle>>::New(2); |
| for (size_t i = 0; i < array.size(); ++i) { |
| auto nested_array = Array<ScopedHandle>::New(3); |
| for (size_t j = 0; j < nested_array.size(); ++j) { |
| MessagePipe pipe; |
| nested_array[j] = ScopedHandle::From(pipe.handle1.Pass()); |
| } |
| array[i] = nested_array.Pass(); |
| } |
| |
| return array; |
| } |
| |
| class SerializationWarningTest : public testing::Test { |
| public: |
| ~SerializationWarningTest() override {} |
| |
| protected: |
| template <typename T> |
| void TestWarning(StructPtr<T> obj, |
| mojo::internal::ValidationError expected_warning) { |
| TestStructWarningImpl<T>(obj.Pass(), expected_warning); |
| } |
| |
| template <typename T> |
| void TestWarning(InlinedStructPtr<T> obj, |
| mojo::internal::ValidationError expected_warning) { |
| TestStructWarningImpl<T>(obj.Pass(), expected_warning); |
| } |
| |
| template <typename T, typename TPtr> |
| void TestStructWarningImpl(TPtr obj, |
| mojo::internal::ValidationError expected_warning) { |
| mojo::internal::FixedBufferForTesting buf(GetSerializedSize_(*obj)); |
| typename T::Data_* data; |
| EXPECT_EQ(expected_warning, Serialize_(obj.get(), &buf, &data)); |
| } |
| |
| template <typename T> |
| void TestArrayWarning(T obj, |
| mojo::internal::ValidationError expected_warning, |
| const ArrayValidateParams* validate_params) { |
| mojo::internal::FixedBufferForTesting buf(GetSerializedSize_(obj)); |
| typename T::Data_* data; |
| EXPECT_EQ(expected_warning, |
| SerializeArray_(&obj, &buf, &data, validate_params)); |
| } |
| }; |
| |
| TEST_F(SerializationWarningTest, HandleInStruct) { |
| Struct2Ptr test_struct(Struct2::New()); |
| EXPECT_FALSE(test_struct->hdl.is_valid()); |
| |
| TestWarning(test_struct.Pass(), |
| mojo::internal::ValidationError::UNEXPECTED_INVALID_HANDLE); |
| |
| test_struct = Struct2::New(); |
| MessagePipe pipe; |
| test_struct->hdl = ScopedHandle::From(pipe.handle1.Pass()); |
| |
| TestWarning(test_struct.Pass(), mojo::internal::ValidationError::NONE); |
| } |
| |
| TEST_F(SerializationWarningTest, StructInStruct) { |
| Struct3Ptr test_struct(Struct3::New()); |
| EXPECT_TRUE(!test_struct->struct_1); |
| |
| TestWarning(test_struct.Pass(), |
| mojo::internal::ValidationError::UNEXPECTED_NULL_POINTER); |
| |
| test_struct = Struct3::New(); |
| test_struct->struct_1 = Struct1::New(); |
| |
| TestWarning(test_struct.Pass(), mojo::internal::ValidationError::NONE); |
| } |
| |
| TEST_F(SerializationWarningTest, ArrayOfStructsInStruct) { |
| Struct4Ptr test_struct(Struct4::New()); |
| EXPECT_TRUE(!test_struct->data); |
| |
| TestWarning(test_struct.Pass(), |
| mojo::internal::ValidationError::UNEXPECTED_NULL_POINTER); |
| |
| test_struct = Struct4::New(); |
| test_struct->data.resize(1); |
| |
| TestWarning(test_struct.Pass(), |
| mojo::internal::ValidationError::UNEXPECTED_NULL_POINTER); |
| |
| test_struct = Struct4::New(); |
| test_struct->data.resize(0); |
| |
| TestWarning(test_struct.Pass(), mojo::internal::ValidationError::NONE); |
| |
| test_struct = Struct4::New(); |
| test_struct->data.resize(1); |
| test_struct->data[0] = Struct1::New(); |
| |
| TestWarning(test_struct.Pass(), mojo::internal::ValidationError::NONE); |
| } |
| |
| TEST_F(SerializationWarningTest, FixedArrayOfStructsInStruct) { |
| Struct5Ptr test_struct(Struct5::New()); |
| EXPECT_TRUE(!test_struct->pair); |
| |
| TestWarning(test_struct.Pass(), |
| mojo::internal::ValidationError::UNEXPECTED_NULL_POINTER); |
| |
| test_struct = Struct5::New(); |
| test_struct->pair.resize(1); |
| test_struct->pair[0] = Struct1::New(); |
| |
| TestWarning(test_struct.Pass(), |
| mojo::internal::ValidationError::UNEXPECTED_ARRAY_HEADER); |
| |
| test_struct = Struct5::New(); |
| test_struct->pair.resize(2); |
| test_struct->pair[0] = Struct1::New(); |
| test_struct->pair[1] = Struct1::New(); |
| |
| TestWarning(test_struct.Pass(), mojo::internal::ValidationError::NONE); |
| } |
| |
| TEST_F(SerializationWarningTest, StringInStruct) { |
| Struct6Ptr test_struct(Struct6::New()); |
| EXPECT_TRUE(!test_struct->str); |
| |
| TestWarning(test_struct.Pass(), |
| mojo::internal::ValidationError::UNEXPECTED_NULL_POINTER); |
| |
| test_struct = Struct6::New(); |
| test_struct->str = "hello world"; |
| |
| TestWarning(test_struct.Pass(), mojo::internal::ValidationError::NONE); |
| } |
| |
| TEST_F(SerializationWarningTest, ArrayOfArraysOfHandles) { |
| Array<Array<ScopedHandle>> test_array = CreateTestNestedHandleArray(); |
| test_array[0] = Array<ScopedHandle>(); |
| test_array[1][0] = ScopedHandle(); |
| |
| ArrayValidateParams validate_params_0( |
| 0, true, new ArrayValidateParams(0, true, nullptr)); |
| TestArrayWarning(test_array.Pass(), mojo::internal::ValidationError::NONE, |
| &validate_params_0); |
| |
| test_array = CreateTestNestedHandleArray(); |
| test_array[0] = Array<ScopedHandle>(); |
| ArrayValidateParams validate_params_1( |
| 0, false, new ArrayValidateParams(0, true, nullptr)); |
| TestArrayWarning(test_array.Pass(), |
| mojo::internal::ValidationError::UNEXPECTED_NULL_POINTER, |
| &validate_params_1); |
| |
| test_array = CreateTestNestedHandleArray(); |
| test_array[1][0] = ScopedHandle(); |
| ArrayValidateParams validate_params_2( |
| 0, true, new ArrayValidateParams(0, false, nullptr)); |
| TestArrayWarning(test_array.Pass(), |
| mojo::internal::ValidationError::UNEXPECTED_INVALID_HANDLE, |
| &validate_params_2); |
| } |
| |
| TEST_F(SerializationWarningTest, ArrayOfStrings) { |
| auto test_array = Array<String>::New(3); |
| for (size_t i = 0; i < test_array.size(); ++i) |
| test_array[i] = "hello"; |
| |
| ArrayValidateParams validate_params_0( |
| 0, true, new ArrayValidateParams(0, false, nullptr)); |
| TestArrayWarning(test_array.Pass(), mojo::internal::ValidationError::NONE, |
| &validate_params_0); |
| |
| test_array = Array<String>::New(3); |
| ArrayValidateParams validate_params_1( |
| 0, false, new ArrayValidateParams(0, false, nullptr)); |
| TestArrayWarning(test_array.Pass(), |
| mojo::internal::ValidationError::UNEXPECTED_NULL_POINTER, |
| &validate_params_1); |
| |
| test_array = Array<String>::New(2); |
| ArrayValidateParams validate_params_2( |
| 3, true, new ArrayValidateParams(0, false, nullptr)); |
| TestArrayWarning(test_array.Pass(), |
| mojo::internal::ValidationError::UNEXPECTED_ARRAY_HEADER, |
| &validate_params_2); |
| } |
| |
| } // namespace |
| } // namespace test |
| } // namespace mojo |
| |
| #endif |