Index: mojo/public/cpp/bindings/tests/validation_unittest.cc |
diff --git a/mojo/public/cpp/bindings/tests/validation_unittest.cc b/mojo/public/cpp/bindings/tests/validation_unittest.cc |
deleted file mode 100644 |
index cfb93d1f13bd54f8b170f79de0eb6d537ff90f34..0000000000000000000000000000000000000000 |
--- a/mojo/public/cpp/bindings/tests/validation_unittest.cc |
+++ /dev/null |
@@ -1,454 +0,0 @@ |
-// 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. |
- |
-#include <stdio.h> |
- |
-#include <algorithm> |
-#include <string> |
-#include <utility> |
-#include <vector> |
- |
-#include "gtest/gtest.h" |
-#include "mojo/public/cpp/bindings/binding.h" |
-#include "mojo/public/cpp/bindings/interface_ptr.h" |
-#include "mojo/public/cpp/bindings/lib/connector.h" |
-#include "mojo/public/cpp/bindings/lib/message_header_validator.h" |
-#include "mojo/public/cpp/bindings/lib/router.h" |
-#include "mojo/public/cpp/bindings/lib/validation_errors.h" |
-#include "mojo/public/cpp/bindings/message.h" |
-#include "mojo/public/cpp/bindings/tests/validation_test_input_parser.h" |
-#include "mojo/public/cpp/bindings/tests/validation_util.h" |
-#include "mojo/public/cpp/system/macros.h" |
-#include "mojo/public/cpp/system/message_pipe.h" |
-#include "mojo/public/cpp/test_support/test_support.h" |
-#include "mojo/public/cpp/utility/run_loop.h" |
-#include "mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom.h" |
- |
-namespace mojo { |
- |
-using internal::MessageValidator; |
-using internal::MessageValidatorList; |
-using internal::ValidationError; |
-using internal::ValidationErrorToString; |
- |
-namespace test { |
-namespace { |
- |
-template <typename T> |
-void Append(std::vector<uint8_t>* data_vector, T data) { |
- size_t pos = data_vector->size(); |
- data_vector->resize(pos + sizeof(T)); |
- memcpy(&(*data_vector)[pos], &data, sizeof(T)); |
-} |
- |
-bool TestInputParser(const std::string& input, |
- bool expected_result, |
- const std::vector<uint8_t>& expected_data, |
- size_t expected_num_handles) { |
- std::vector<uint8_t> data; |
- size_t num_handles; |
- std::string error_message; |
- |
- bool result = |
- ParseValidationTestInput(input, &data, &num_handles, &error_message); |
- if (expected_result) { |
- if (result && error_message.empty() && expected_data == data && |
- expected_num_handles == num_handles) { |
- return true; |
- } |
- |
- // Compare with an empty string instead of checking |error_message.empty()|, |
- // so that the message will be printed out if the two are not equal. |
- EXPECT_EQ(std::string(), error_message); |
- EXPECT_EQ(expected_data, data); |
- EXPECT_EQ(expected_num_handles, num_handles); |
- return false; |
- } |
- |
- EXPECT_FALSE(error_message.empty()); |
- return !result && !error_message.empty(); |
-} |
- |
-void RunValidationTests(const std::string& prefix, |
- const MessageValidatorList& validators, |
- MessageReceiver* test_message_receiver) { |
- std::vector<std::string> tests = validation_util::GetMatchingTests(prefix); |
- |
- for (size_t i = 0; i < tests.size(); ++i) { |
- std::string expected; |
- std::vector<uint8_t> data; |
- size_t num_handles; |
- ASSERT_TRUE(validation_util::ReadTestCase(tests[i], &data, &num_handles, |
- &expected)); |
- |
- Message message; |
- message.AllocUninitializedData(data.size()); |
- if (!data.empty()) |
- memcpy(message.mutable_data(), &data[0], data.size()); |
- message.mutable_handles()->resize(num_handles); |
- |
- std::string actual; |
- auto result = RunValidatorsOnMessage(validators, &message, nullptr); |
- if (result == ValidationError::NONE) { |
- ignore_result(test_message_receiver->Accept(&message)); |
- actual = "PASS"; |
- } else { |
- actual = ValidationErrorToString(result); |
- } |
- |
- EXPECT_EQ(expected, actual) << "failed test: " << tests[i]; |
- } |
-} |
- |
-class DummyMessageReceiver : public MessageReceiver { |
- public: |
- bool Accept(Message* message) override { |
- return true; // Any message is OK. |
- } |
-}; |
- |
-class ValidationIntegrationTest : public testing::Test { |
- public: |
- ValidationIntegrationTest() : test_message_receiver_(nullptr) {} |
- |
- ~ValidationIntegrationTest() override {} |
- |
- void SetUp() override { |
- ScopedMessagePipeHandle tester_endpoint; |
- ASSERT_EQ(MOJO_RESULT_OK, |
- CreateMessagePipe(nullptr, &tester_endpoint, &testee_endpoint_)); |
- test_message_receiver_ = |
- new TestMessageReceiver(this, tester_endpoint.Pass()); |
- } |
- |
- void TearDown() override { |
- delete test_message_receiver_; |
- test_message_receiver_ = nullptr; |
- |
- // Make sure that the other end receives the OnConnectionError() |
- // notification. |
- PumpMessages(); |
- } |
- |
- MessageReceiver* test_message_receiver() { return test_message_receiver_; } |
- |
- ScopedMessagePipeHandle testee_endpoint() { return testee_endpoint_.Pass(); } |
- |
- private: |
- class TestMessageReceiver : public MessageReceiver { |
- public: |
- TestMessageReceiver(ValidationIntegrationTest* owner, |
- ScopedMessagePipeHandle handle) |
- : owner_(owner), connector_(handle.Pass()) { |
- connector_.set_enforce_errors_from_incoming_receiver(false); |
- } |
- ~TestMessageReceiver() override {} |
- |
- bool Accept(Message* message) override { |
- bool rv = connector_.Accept(message); |
- owner_->PumpMessages(); |
- return rv; |
- } |
- |
- public: |
- ValidationIntegrationTest* owner_; |
- mojo::internal::Connector connector_; |
- }; |
- |
- void PumpMessages() { loop_.RunUntilIdle(); } |
- |
- RunLoop loop_; |
- TestMessageReceiver* test_message_receiver_; |
- ScopedMessagePipeHandle testee_endpoint_; |
-}; |
- |
-class IntegrationTestInterfaceImpl : public IntegrationTestInterface { |
- public: |
- ~IntegrationTestInterfaceImpl() override {} |
- |
- void Method0(BasicStructPtr param0, |
- const Method0Callback& callback) override { |
- callback.Run(Array<uint8_t>::New(0u)); |
- } |
-}; |
- |
-class FailingValidator : public mojo::internal::MessageValidator { |
- public: |
- explicit FailingValidator(ValidationError err) : err_(err) {} |
- ValidationError Validate(const Message* message, std::string* err) override { |
- return err_; |
- } |
- |
- private: |
- ValidationError err_; |
-}; |
- |
-TEST(ValidationTest, InputParser) { |
- { |
- // The parser, as well as Append() defined above, assumes that this code is |
- // running on a little-endian platform. Test whether that is true. |
- uint16_t x = 1; |
- ASSERT_EQ(1, *(reinterpret_cast<char*>(&x))); |
- } |
- { |
- // Test empty input. |
- std::string input; |
- std::vector<uint8_t> expected; |
- |
- EXPECT_TRUE(TestInputParser(input, true, expected, 0)); |
- } |
- { |
- // Test input that only consists of comments and whitespaces. |
- std::string input = " \t // hello world \n\r \t// the answer is 42 "; |
- std::vector<uint8_t> expected; |
- |
- EXPECT_TRUE(TestInputParser(input, true, expected, 0)); |
- } |
- { |
- std::string input = |
- "[u1]0x10// hello world !! \n\r \t [u2]65535 \n" |
- "[u4]65536 [u8]0xFFFFFFFFFFFFFFFF 0 0Xff"; |
- std::vector<uint8_t> expected; |
- Append(&expected, static_cast<uint8_t>(0x10)); |
- Append(&expected, static_cast<uint16_t>(65535)); |
- Append(&expected, static_cast<uint32_t>(65536)); |
- Append(&expected, static_cast<uint64_t>(0xffffffffffffffff)); |
- Append(&expected, static_cast<uint8_t>(0)); |
- Append(&expected, static_cast<uint8_t>(0xff)); |
- |
- EXPECT_TRUE(TestInputParser(input, true, expected, 0)); |
- } |
- { |
- std::string input = "[s8]-0x800 [s1]-128\t[s2]+0 [s4]-40"; |
- std::vector<uint8_t> expected; |
- Append(&expected, -static_cast<int64_t>(0x800)); |
- Append(&expected, static_cast<int8_t>(-128)); |
- Append(&expected, static_cast<int16_t>(0)); |
- Append(&expected, static_cast<int32_t>(-40)); |
- |
- EXPECT_TRUE(TestInputParser(input, true, expected, 0)); |
- } |
- { |
- std::string input = "[b]00001011 [b]10000000 // hello world\r [b]00000000"; |
- std::vector<uint8_t> expected; |
- Append(&expected, static_cast<uint8_t>(11)); |
- Append(&expected, static_cast<uint8_t>(128)); |
- Append(&expected, static_cast<uint8_t>(0)); |
- |
- EXPECT_TRUE(TestInputParser(input, true, expected, 0)); |
- } |
- { |
- std::string input = "[f]+.3e9 [d]-10.03"; |
- std::vector<uint8_t> expected; |
- Append(&expected, +.3e9f); |
- Append(&expected, -10.03); |
- |
- EXPECT_TRUE(TestInputParser(input, true, expected, 0)); |
- } |
- { |
- std::string input = "[dist4]foo 0 [dist8]bar 0 [anchr]foo [anchr]bar"; |
- std::vector<uint8_t> expected; |
- Append(&expected, static_cast<uint32_t>(14)); |
- Append(&expected, static_cast<uint8_t>(0)); |
- Append(&expected, static_cast<uint64_t>(9)); |
- Append(&expected, static_cast<uint8_t>(0)); |
- |
- EXPECT_TRUE(TestInputParser(input, true, expected, 0)); |
- } |
- { |
- std::string input = "// This message has handles! \n[handles]50 [u8]2"; |
- std::vector<uint8_t> expected; |
- Append(&expected, static_cast<uint64_t>(2)); |
- |
- EXPECT_TRUE(TestInputParser(input, true, expected, 50)); |
- } |
- |
- // Test some failure cases. |
- { |
- const char* error_inputs[] = {"/ hello world", |
- "[u1]x", |
- "[u2]-1000", |
- "[u1]0x100", |
- "[s2]-0x8001", |
- "[b]1", |
- "[b]1111111k", |
- "[dist4]unmatched", |
- "[anchr]hello [dist8]hello", |
- "[dist4]a [dist4]a [anchr]a", |
- "[dist4]a [anchr]a [dist4]a [anchr]a", |
- "0 [handles]50", |
- nullptr}; |
- |
- for (size_t i = 0; error_inputs[i]; ++i) { |
- std::vector<uint8_t> expected; |
- if (!TestInputParser(error_inputs[i], false, expected, 0)) |
- ADD_FAILURE() << "Unexpected test result for: " << error_inputs[i]; |
- } |
- } |
-} |
- |
-TEST(ValidationTest, Conformance) { |
- DummyMessageReceiver dummy_receiver; |
- MessageValidatorList validators; |
- validators.push_back(std::unique_ptr<MessageValidator>( |
- new mojo::internal::MessageHeaderValidator)); |
- validators.push_back(std::unique_ptr<MessageValidator>( |
- new ConformanceTestInterface::RequestValidator_)); |
- |
- RunValidationTests("conformance_", validators, &dummy_receiver); |
-} |
- |
-// This test is similar to Conformance test but its goal is specifically |
-// do bounds-check testing of message validation. For example we test the |
-// detection of off-by-one errors in method ordinals. |
-TEST(ValidationTest, BoundsCheck) { |
- DummyMessageReceiver dummy_receiver; |
- MessageValidatorList validators; |
- validators.push_back(std::unique_ptr<MessageValidator>( |
- new mojo::internal::MessageHeaderValidator)); |
- validators.push_back(std::unique_ptr<MessageValidator>( |
- new BoundsCheckTestInterface::RequestValidator_)); |
- |
- RunValidationTests("boundscheck_", validators, &dummy_receiver); |
-} |
- |
-// This test is similar to the Conformance test but for responses. |
-TEST(ValidationTest, ResponseConformance) { |
- DummyMessageReceiver dummy_receiver; |
- MessageValidatorList validators; |
- validators.push_back(std::unique_ptr<MessageValidator>( |
- new mojo::internal::MessageHeaderValidator)); |
- validators.push_back(std::unique_ptr<MessageValidator>( |
- new ConformanceTestInterface::ResponseValidator_)); |
- |
- RunValidationTests("resp_conformance_", validators, &dummy_receiver); |
-} |
- |
-// This test is similar to the BoundsCheck test but for responses. |
-TEST(ValidationTest, ResponseBoundsCheck) { |
- DummyMessageReceiver dummy_receiver; |
- MessageValidatorList validators; |
- validators.push_back(std::unique_ptr<MessageValidator>( |
- new mojo::internal::MessageHeaderValidator)); |
- validators.push_back(std::unique_ptr<MessageValidator>( |
- new BoundsCheckTestInterface::ResponseValidator_)); |
- |
- RunValidationTests("resp_boundscheck_", validators, &dummy_receiver); |
-} |
- |
-// Test that InterfacePtr<X> applies the correct validators and they don't |
-// conflict with each other: |
-// - MessageHeaderValidator |
-// - X::ResponseValidator_ |
-TEST_F(ValidationIntegrationTest, InterfacePtr) { |
- IntegrationTestInterfacePtr interface_ptr = |
- IntegrationTestInterfacePtr::Create( |
- InterfaceHandle<IntegrationTestInterface>(testee_endpoint(), 0u)); |
- interface_ptr.internal_state()->router_for_testing()->EnableTestingMode(); |
- |
- mojo::internal::MessageValidatorList validators; |
- validators.push_back(std::unique_ptr<MessageValidator>( |
- new mojo::internal::MessageHeaderValidator)); |
- validators.push_back(std::unique_ptr<MessageValidator>( |
- new typename IntegrationTestInterface::ResponseValidator_)); |
- |
- RunValidationTests("integration_intf_resp", validators, |
- test_message_receiver()); |
- RunValidationTests("integration_msghdr", validators, test_message_receiver()); |
-} |
- |
-// Test that Binding<X> applies the correct validators and they don't |
-// conflict with each other: |
-// - MessageHeaderValidator |
-// - X::RequestValidator_ |
-TEST_F(ValidationIntegrationTest, Binding) { |
- IntegrationTestInterfaceImpl interface_impl; |
- Binding<IntegrationTestInterface> binding( |
- &interface_impl, |
- InterfaceRequest<IntegrationTestInterface>(testee_endpoint().Pass())); |
- binding.internal_router()->EnableTestingMode(); |
- |
- mojo::internal::MessageValidatorList validators; |
- validators.push_back(std::unique_ptr<MessageValidator>( |
- new mojo::internal::MessageHeaderValidator)); |
- validators.push_back(std::unique_ptr<MessageValidator>( |
- new typename IntegrationTestInterface::RequestValidator_)); |
- |
- RunValidationTests("integration_intf_rqst", validators, |
- test_message_receiver()); |
- RunValidationTests("integration_msghdr", validators, test_message_receiver()); |
-} |
- |
-// Test pointer validation (specifically, that the encoded offset is 32-bit) |
-TEST(ValidationTest, ValidateEncodedPointer) { |
- uint64_t offset; |
- |
- offset = 0ULL; |
- EXPECT_TRUE(mojo::internal::ValidateEncodedPointer(&offset)); |
- |
- offset = 1ULL; |
- EXPECT_TRUE(mojo::internal::ValidateEncodedPointer(&offset)); |
- |
- // offset must be <= 32-bit. |
- offset = std::numeric_limits<uint32_t>::max() + 1ULL; |
- EXPECT_FALSE(mojo::internal::ValidateEncodedPointer(&offset)); |
-} |
- |
-TEST(ValidationTest, RunValidatorsOnMessageTest) { |
- Message msg; |
- mojo::internal::MessageValidatorList validators; |
- |
- validators.push_back(std::unique_ptr<MessageValidator>( |
- new mojo::internal::PassThroughValidator)); |
- EXPECT_EQ(ValidationError::NONE, |
- RunValidatorsOnMessage(validators, &msg, nullptr)); |
- |
- validators.push_back(std::unique_ptr<MessageValidator>( |
- new FailingValidator(ValidationError::MESSAGE_HEADER_INVALID_FLAGS))); |
- EXPECT_EQ(ValidationError::MESSAGE_HEADER_INVALID_FLAGS, |
- RunValidatorsOnMessage(validators, &msg, nullptr)); |
- |
- validators.insert(validators.begin(), |
- std::unique_ptr<MessageValidator>( |
- new FailingValidator(ValidationError::ILLEGAL_HANDLE))); |
- EXPECT_EQ(ValidationError::ILLEGAL_HANDLE, |
- RunValidatorsOnMessage(validators, &msg, nullptr)); |
-} |
- |
-// Tests the IsValidValue() function generated for BasicEnum. |
-TEST(EnumValueValidationTest, BasicEnum) { |
- // BasicEnum can have -3,0,1,10 as possible integral values. |
- EXPECT_FALSE(BasicEnum_IsValidValue(static_cast<BasicEnum>(-4))); |
- EXPECT_TRUE(BasicEnum_IsValidValue(static_cast<BasicEnum>(-3))); |
- EXPECT_FALSE(BasicEnum_IsValidValue(static_cast<BasicEnum>(-2))); |
- EXPECT_FALSE(BasicEnum_IsValidValue(static_cast<BasicEnum>(-1))); |
- EXPECT_TRUE(BasicEnum_IsValidValue(static_cast<BasicEnum>(0))); |
- EXPECT_TRUE(BasicEnum_IsValidValue(static_cast<BasicEnum>(1))); |
- EXPECT_FALSE(BasicEnum_IsValidValue(static_cast<BasicEnum>(2))); |
- EXPECT_FALSE(BasicEnum_IsValidValue(static_cast<BasicEnum>(9))); |
- // In the mojom, we represent this value as hex (0xa). |
- EXPECT_TRUE(BasicEnum_IsValidValue(static_cast<BasicEnum>(10))); |
- EXPECT_FALSE(BasicEnum_IsValidValue(static_cast<BasicEnum>(11))); |
-} |
- |
-// Tests the IsValidValue() method generated for StructWithEnum. |
-TEST(EnumValueValidationTest, EnumWithin) { |
- // StructWithEnum::EnumWithin can have [0,4] as possible integral values. |
- EXPECT_FALSE(StructWithEnum::EnumWithin_IsValidValue( |
- static_cast<StructWithEnum::EnumWithin>(-1))); |
- EXPECT_TRUE(StructWithEnum::EnumWithin_IsValidValue( |
- static_cast<StructWithEnum::EnumWithin>(0))); |
- EXPECT_TRUE(StructWithEnum::EnumWithin_IsValidValue( |
- static_cast<StructWithEnum::EnumWithin>(1))); |
- EXPECT_TRUE(StructWithEnum::EnumWithin_IsValidValue( |
- static_cast<StructWithEnum::EnumWithin>(2))); |
- EXPECT_TRUE(StructWithEnum::EnumWithin_IsValidValue( |
- static_cast<StructWithEnum::EnumWithin>(3))); |
- EXPECT_FALSE(StructWithEnum::EnumWithin_IsValidValue( |
- static_cast<StructWithEnum::EnumWithin>(4))); |
-} |
- |
-} // namespace |
-} // namespace test |
-} // namespace mojo |