summaryrefslogtreecommitdiffstats
path: root/mojo
diff options
context:
space:
mode:
Diffstat (limited to 'mojo')
-rw-r--r--mojo/apps/js/test/js_to_cpp_unittest.cc3
-rw-r--r--mojo/mojo_public.gypi1
-rw-r--r--mojo/public/cpp/bindings/lib/message_header_validator.cc2
-rw-r--r--mojo/public/cpp/bindings/lib/router.cc10
-rw-r--r--mojo/public/cpp/bindings/lib/router.h15
-rw-r--r--mojo/public/cpp/bindings/lib/validation_errors.cc12
-rw-r--r--mojo/public/cpp/bindings/lib/validation_errors.h2
-rw-r--r--mojo/public/cpp/bindings/tests/validation_unittest.cc206
-rw-r--r--mojo/public/interfaces/bindings/tests/BUILD.gn1
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validate_header_good_simple.expected4
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/conformance_empty.data (renamed from mojo/public/interfaces/bindings/tests/data/validate_header_bad_empty.data)0
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/conformance_empty.expected (renamed from mojo/public/interfaces/bindings/tests/data/validate_header_bad_empty.expected)0
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/conformance_msghdr_incomplete_struct_header.data (renamed from mojo/public/interfaces/bindings/tests/data/validate_header_bad_too_small.data)0
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/conformance_msghdr_incomplete_struct_header.expected (renamed from mojo/public/interfaces/bindings/tests/data/validate_header_bad_too_small.expected)0
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/conformance_msghdr_num_bytes_less_than_struct_header.data (renamed from mojo/public/interfaces/bindings/tests/data/validate_header_bad_zeros.data)0
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/conformance_msghdr_num_bytes_less_than_struct_header.expected (renamed from mojo/public/interfaces/bindings/tests/data/validate_header_bad_zeros.expected)0
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd0_good.data (renamed from mojo/public/interfaces/bindings/tests/data/validate_header_good_simple.data)4
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd0_good.expected1
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/integration_intf1_mthd0_rqst_good.data17
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/integration_intf1_mthd0_rqst_good.expected1
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/integration_intf1_mthd0_rqst_unexpected_struct_header.data14
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/integration_intf1_mthd0_rqst_unexpected_struct_header.expected1
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/integration_intf2_mthd0_resp_good.data17
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/integration_intf2_mthd0_resp_good.expected1
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/integration_intf2_mthd0_resp_unexpected_array_header.data17
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/integration_intf2_mthd0_resp_unexpected_array_header.expected1
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/integration_msghdr_invalid_flags.data6
-rw-r--r--mojo/public/interfaces/bindings/tests/data/validation/integration_msghdr_invalid_flags.expected1
-rw-r--r--mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom25
29 files changed, 306 insertions, 56 deletions
diff --git a/mojo/apps/js/test/js_to_cpp_unittest.cc b/mojo/apps/js/test/js_to_cpp_unittest.cc
index fa34cc6..6d69bc2 100644
--- a/mojo/apps/js/test/js_to_cpp_unittest.cc
+++ b/mojo/apps/js/test/js_to_cpp_unittest.cc
@@ -394,8 +394,7 @@ class JsToCppTest : public testing::Test {
MakeProxy<js_to_cpp::JsSide>(pipe.handle0.Pass());
js_side.set_client(cpp_side);
- js_side.internal_state()->router()->
- set_enforce_errors_from_incoming_receiver(false);
+ js_side.internal_state()->router()->EnableTestingMode();
cpp_side->set_js_side(js_side.get());
diff --git a/mojo/mojo_public.gypi b/mojo/mojo_public.gypi
index 516f6f6..7badfda 100644
--- a/mojo/mojo_public.gypi
+++ b/mojo/mojo_public.gypi
@@ -304,6 +304,7 @@
'public/interfaces/bindings/tests/sample_interfaces.mojom',
'public/interfaces/bindings/tests/sample_service.mojom',
'public/interfaces/bindings/tests/test_structs.mojom',
+ 'public/interfaces/bindings/tests/validation_test_interfaces.mojom',
],
'includes': [ 'public/tools/bindings/mojom_bindings_generator.gypi' ],
'export_dependent_settings': [
diff --git a/mojo/public/cpp/bindings/lib/message_header_validator.cc b/mojo/public/cpp/bindings/lib/message_header_validator.cc
index d913598..a55917a 100644
--- a/mojo/public/cpp/bindings/lib/message_header_validator.cc
+++ b/mojo/public/cpp/bindings/lib/message_header_validator.cc
@@ -48,7 +48,7 @@ bool IsValidMessageHeader(const MessageHeader* header) {
if ((header->flags & kMessageExpectsResponse) &&
(header->flags & kMessageIsResponse)) {
ReportValidationError(
- VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAG_COMBINAION);
+ VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAG_COMBINATION);
return false;
}
diff --git a/mojo/public/cpp/bindings/lib/router.cc b/mojo/public/cpp/bindings/lib/router.cc
index 27510e7..a822220 100644
--- a/mojo/public/cpp/bindings/lib/router.cc
+++ b/mojo/public/cpp/bindings/lib/router.cc
@@ -57,7 +57,8 @@ Router::Router(ScopedMessagePipeHandle message_pipe,
connector_(message_pipe.Pass(), waiter),
weak_self_(this),
incoming_receiver_(NULL),
- next_request_id_(0) {
+ next_request_id_(0),
+ testing_mode_(false) {
filters_.SetSink(&thunk_);
connector_.set_incoming_receiver(filters_.GetHead());
}
@@ -94,6 +95,11 @@ bool Router::AcceptWithResponder(Message* message,
return true;
}
+void Router::EnableTestingMode() {
+ testing_mode_ = true;
+ connector_.set_enforce_errors_from_incoming_receiver(false);
+}
+
bool Router::HandleIncomingMessage(Message* message) {
if (message->has_flag(kMessageExpectsResponse)) {
if (incoming_receiver_) {
@@ -111,7 +117,7 @@ bool Router::HandleIncomingMessage(Message* message) {
uint64_t request_id = message->request_id();
ResponderMap::iterator it = responders_.find(request_id);
if (it == responders_.end()) {
- assert(false);
+ assert(testing_mode_);
return false;
}
MessageReceiver* responder = it->second;
diff --git a/mojo/public/cpp/bindings/lib/router.h b/mojo/public/cpp/bindings/lib/router.h
index e30b924..cd53270 100644
--- a/mojo/public/cpp/bindings/lib/router.h
+++ b/mojo/public/cpp/bindings/lib/router.h
@@ -33,13 +33,6 @@ class Router : public MessageReceiverWithResponder {
connector_.set_error_handler(error_handler);
}
- // Errors from incoming receivers will force the router's connector into an
- // error state, where no more messages will be processed. This method is used
- // during testing to prevent that from happening.
- void set_enforce_errors_from_incoming_receiver(bool enforce) {
- connector_.set_enforce_errors_from_incoming_receiver(enforce);
- }
-
// Returns true if an error was encountered while reading from the pipe or
// waiting to read from the pipe.
bool encountered_error() const { return connector_.encountered_error(); }
@@ -57,6 +50,13 @@ class Router : public MessageReceiverWithResponder {
virtual bool AcceptWithResponder(Message* message, MessageReceiver* responder)
MOJO_OVERRIDE;
+ // Sets this object to testing mode.
+ // In testing mode:
+ // - the object is more tolerant of unrecognized response messages;
+ // - the connector continues working after seeing errors from its incoming
+ // receiver.
+ void EnableTestingMode();
+
private:
typedef std::map<uint64_t, MessageReceiver*> ResponderMap;
@@ -81,6 +81,7 @@ class Router : public MessageReceiverWithResponder {
MessageReceiverWithResponder* incoming_receiver_;
ResponderMap responders_;
uint64_t next_request_id_;
+ bool testing_mode_;
};
} // namespace internal
diff --git a/mojo/public/cpp/bindings/lib/validation_errors.cc b/mojo/public/cpp/bindings/lib/validation_errors.cc
index 03201b9..ed5904d 100644
--- a/mojo/public/cpp/bindings/lib/validation_errors.cc
+++ b/mojo/public/cpp/bindings/lib/validation_errors.cc
@@ -31,8 +31,8 @@ const char* ValidationErrorToString(ValidationError error) {
return "VALIDATION_ERROR_ILLEGAL_HANDLE";
case VALIDATION_ERROR_ILLEGAL_POINTER:
return "VALIDATION_ERROR_ILLEGAL_POINTER";
- case VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAG_COMBINAION:
- return "VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAG_COMBINAION";
+ case VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAG_COMBINATION:
+ return "VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAG_COMBINATION";
case VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID:
return "VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID";
}
@@ -41,10 +41,12 @@ const char* ValidationErrorToString(ValidationError error) {
}
void ReportValidationError(ValidationError error) {
- // TODO(yzshen): Consider adding better logging support.
- fprintf(stderr, "Invalid message: %s\n", ValidationErrorToString(error));
- if (g_validation_error_observer)
+ if (g_validation_error_observer) {
g_validation_error_observer->set_last_error(error);
+ } else {
+ // TODO(yzshen): Consider adding better logging support.
+ fprintf(stderr, "Invalid message: %s\n", ValidationErrorToString(error));
+ }
}
ValidationErrorObserverForTesting::ValidationErrorObserverForTesting()
diff --git a/mojo/public/cpp/bindings/lib/validation_errors.h b/mojo/public/cpp/bindings/lib/validation_errors.h
index d0b7438..9b443c3 100644
--- a/mojo/public/cpp/bindings/lib/validation_errors.h
+++ b/mojo/public/cpp/bindings/lib/validation_errors.h
@@ -34,7 +34,7 @@ enum ValidationError {
// An encoded pointer is illegal.
VALIDATION_ERROR_ILLEGAL_POINTER,
// |flags| in the message header is an invalid flag combination.
- VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAG_COMBINAION,
+ VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAG_COMBINATION,
// |flags| in the message header indicates that a request ID is required but
// there isn't one.
VALIDATION_ERROR_MESSAGE_HEADER_MISSING_REQUEST_ID,
diff --git a/mojo/public/cpp/bindings/tests/validation_unittest.cc b/mojo/public/cpp/bindings/tests/validation_unittest.cc
index f111091..f1e1b0b 100644
--- a/mojo/public/cpp/bindings/tests/validation_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/validation_unittest.cc
@@ -5,14 +5,24 @@
#include <stdio.h>
#include <algorithm>
-#include <sstream>
#include <string>
#include <vector>
+#include "mojo/public/c/system/macros.h"
+#include "mojo/public/cpp/bindings/interface_impl.h"
+#include "mojo/public/cpp/bindings/interface_ptr.h"
+#include "mojo/public/cpp/bindings/lib/connector.h"
+#include "mojo/public/cpp/bindings/lib/filter_chain.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/environment/environment.h"
+#include "mojo/public/cpp/system/core.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"
#include "testing/gtest/include/gtest/gtest.h"
namespace mojo {
@@ -116,23 +126,51 @@ bool ReadResultFile(const std::string& path, std::string* result) {
}
std::string GetPath(const std::string& root, const std::string& suffix) {
- return "mojo/public/interfaces/bindings/tests/data/" + root + suffix;
+ return "mojo/public/interfaces/bindings/tests/data/validation/" +
+ root + suffix;
}
-void RunValidationTest(const std::string& root, std::string (*func)(Message*)) {
+// |message| should be a newly created object.
+bool ReadTestCase(const std::string& test,
+ Message* message,
+ std::string* expected) {
std::vector<uint8_t> data;
- ASSERT_TRUE(ReadAndParseDataFile(GetPath(root, ".data"), &data));
-
- std::string expected;
- ASSERT_TRUE(ReadResultFile(GetPath(root, ".expected"), &expected));
+ if (!ReadAndParseDataFile(GetPath(test, ".data"), &data) ||
+ !ReadResultFile(GetPath(test, ".expected"), expected)) {
+ return false;
+ }
- Message message;
- message.AllocUninitializedData(static_cast<uint32_t>(data.size()));
+ message->AllocUninitializedData(static_cast<uint32_t>(data.size()));
if (!data.empty())
- memcpy(message.mutable_data(), &data[0], data.size());
+ memcpy(message->mutable_data(), &data[0], data.size());
+
+ // TODO(yzshen): add support to specify the number of handles associated with
+ // the message.
+
+ return true;
+}
- std::string result = func(&message);
- EXPECT_EQ(expected, result) << "failed test: " << root;
+void RunValidationTests(const std::string& prefix,
+ MessageReceiver* test_message_receiver) {
+ std::vector<std::string> names =
+ EnumerateSourceRootRelativeDirectory(GetPath("", ""));
+ std::vector<std::string> tests = GetMatchingTests(names, prefix);
+
+ for (size_t i = 0; i < tests.size(); ++i) {
+ Message message;
+ std::string expected;
+ ASSERT_TRUE(ReadTestCase(tests[i], &message, &expected));
+
+ std::string result;
+ mojo::internal::ValidationErrorObserverForTesting observer;
+ bool unused MOJO_ALLOW_UNUSED = test_message_receiver->Accept(&message);
+ if (observer.last_error() == mojo::internal::VALIDATION_ERROR_NONE)
+ result = "PASS";
+ else
+ result = mojo::internal::ValidationErrorToString(observer.last_error());
+
+ EXPECT_EQ(expected, result) << "failed test: " << tests[i];
+ }
}
class DummyMessageReceiver : public MessageReceiver {
@@ -142,23 +180,93 @@ class DummyMessageReceiver : public MessageReceiver {
}
};
-std::string DumpMessageHeader(Message* message) {
- internal::ValidationErrorObserverForTesting observer;
- DummyMessageReceiver not_reached_receiver;
- internal::MessageHeaderValidator validator(&not_reached_receiver);
- bool rv = validator.Accept(message);
- if (!rv) {
- EXPECT_NE(internal::VALIDATION_ERROR_NONE, observer.last_error());
- return internal::ValidationErrorToString(observer.last_error());
+class ValidationIntegrationTest : public testing::Test {
+ public:
+ ValidationIntegrationTest() : test_message_receiver_(NULL) {
}
- std::ostringstream os;
- os << "num_bytes: " << message->header()->num_bytes << "\n"
- << "num_fields: " << message->header()->num_fields << "\n"
- << "name: " << message->header()->name << "\n"
- << "flags: " << message->header()->flags;
- return os.str();
-}
+ virtual ~ValidationIntegrationTest() {
+ }
+
+ virtual void SetUp() MOJO_OVERRIDE {
+ ScopedMessagePipeHandle tester_endpoint;
+ ASSERT_EQ(MOJO_RESULT_OK,
+ CreateMessagePipe(NULL, &tester_endpoint, &testee_endpoint_));
+ test_message_receiver_ =
+ new TestMessageReceiver(this, tester_endpoint.Pass());
+ }
+
+ virtual void TearDown() MOJO_OVERRIDE {
+ delete test_message_receiver_;
+ test_message_receiver_ = NULL;
+
+ // 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()) {
+ }
+ virtual ~TestMessageReceiver() {
+ }
+
+ virtual bool Accept(Message* message) MOJO_OVERRIDE {
+ bool rv = connector_.Accept(message);
+ owner_->PumpMessages();
+ return rv;
+ }
+
+ public:
+ ValidationIntegrationTest* owner_;
+ mojo::internal::Connector connector_;
+ };
+
+ void PumpMessages() {
+ loop_.RunUntilIdle();
+ }
+
+ Environment env_;
+ RunLoop loop_;
+ TestMessageReceiver* test_message_receiver_;
+ ScopedMessagePipeHandle testee_endpoint_;
+};
+
+class IntegrationTestInterface1Client : public IntegrationTestInterface1 {
+ public:
+ virtual ~IntegrationTestInterface1Client() {
+ }
+
+ virtual void Method0(BasicStructPtr param0) MOJO_OVERRIDE {
+ }
+};
+
+class IntegrationTestInterface1Impl
+ : public InterfaceImpl<IntegrationTestInterface1> {
+ public:
+ virtual ~IntegrationTestInterface1Impl() {
+ }
+
+ virtual void Method0(BasicStructPtr param0) MOJO_OVERRIDE {
+ }
+
+ virtual void OnConnectionError() MOJO_OVERRIDE {
+ delete this;
+ }
+};
TEST(ValidationTest, InputParser) {
{
@@ -254,15 +362,45 @@ TEST(ValidationTest, InputParser) {
}
}
-TEST(ValidationTest, TestAll) {
- std::vector<std::string> names =
- EnumerateSourceRootRelativeDirectory(GetPath("", ""));
+TEST(ValidationTest, Conformance) {
+ DummyMessageReceiver dummy_receiver;
+ mojo::internal::FilterChain validators(&dummy_receiver);
+ validators.Append<mojo::internal::MessageHeaderValidator>();
+ validators.Append<ConformanceTestInterface::RequestValidator_>();
+
+ // TODO(yzshen): add more conformance tests.
+ RunValidationTests("conformance_", validators.GetHead());
+}
+
+TEST_F(ValidationIntegrationTest, InterfacePtr) {
+ // Test that InterfacePtr<X> applies the correct validators and they don't
+ // conflict with each other:
+ // - MessageHeaderValidator
+ // - X::Client::RequestValidator_
+ // - X::ResponseValidator_
+
+ IntegrationTestInterface1Client interface1_client;
+ IntegrationTestInterface2Ptr interface2_ptr =
+ MakeProxy<IntegrationTestInterface2>(testee_endpoint().Pass());
+ interface2_ptr.set_client(&interface1_client);
+ interface2_ptr.internal_state()->router()->EnableTestingMode();
+
+ RunValidationTests("integration_", test_message_receiver());
+}
+
+TEST_F(ValidationIntegrationTest, InterfaceImpl) {
+ // Test that InterfaceImpl<X> applies the correct validators and they don't
+ // conflict with each other:
+ // - MessageHeaderValidator
+ // - X::RequestValidator_
+ // - X::Client::ResponseValidator_
- std::vector<std::string> header_tests =
- GetMatchingTests(names, "validate_header_");
+ // |interface1_impl| will delete itself when the pipe is closed.
+ IntegrationTestInterface1Impl* interface1_impl =
+ BindToPipe(new IntegrationTestInterface1Impl(), testee_endpoint().Pass());
+ interface1_impl->internal_state()->router()->EnableTestingMode();
- for (size_t i = 0; i < header_tests.size(); ++i)
- RunValidationTest(header_tests[i], &DumpMessageHeader);
+ RunValidationTests("integration_", test_message_receiver());
}
} // namespace
diff --git a/mojo/public/interfaces/bindings/tests/BUILD.gn b/mojo/public/interfaces/bindings/tests/BUILD.gn
index f394c8d..c747550 100644
--- a/mojo/public/interfaces/bindings/tests/BUILD.gn
+++ b/mojo/public/interfaces/bindings/tests/BUILD.gn
@@ -13,5 +13,6 @@ mojom("test_interfaces") {
"sample_interfaces.mojom",
"sample_service.mojom",
"test_structs.mojom",
+ "validation_test_interfaces.mojom",
]
}
diff --git a/mojo/public/interfaces/bindings/tests/data/validate_header_good_simple.expected b/mojo/public/interfaces/bindings/tests/data/validate_header_good_simple.expected
deleted file mode 100644
index c29d2ad..0000000
--- a/mojo/public/interfaces/bindings/tests/data/validate_header_good_simple.expected
+++ /dev/null
@@ -1,4 +0,0 @@
-num_bytes: 16
-num_fields: 2
-name: 0
-flags: 0
diff --git a/mojo/public/interfaces/bindings/tests/data/validate_header_bad_empty.data b/mojo/public/interfaces/bindings/tests/data/validation/conformance_empty.data
index e69de29..e69de29 100644
--- a/mojo/public/interfaces/bindings/tests/data/validate_header_bad_empty.data
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_empty.data
diff --git a/mojo/public/interfaces/bindings/tests/data/validate_header_bad_empty.expected b/mojo/public/interfaces/bindings/tests/data/validation/conformance_empty.expected
index 779df88..779df88 100644
--- a/mojo/public/interfaces/bindings/tests/data/validate_header_bad_empty.expected
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_empty.expected
diff --git a/mojo/public/interfaces/bindings/tests/data/validate_header_bad_too_small.data b/mojo/public/interfaces/bindings/tests/data/validation/conformance_msghdr_incomplete_struct_header.data
index 21e7fbc..21e7fbc 100644
--- a/mojo/public/interfaces/bindings/tests/data/validate_header_bad_too_small.data
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_msghdr_incomplete_struct_header.data
diff --git a/mojo/public/interfaces/bindings/tests/data/validate_header_bad_too_small.expected b/mojo/public/interfaces/bindings/tests/data/validation/conformance_msghdr_incomplete_struct_header.expected
index 779df88..779df88 100644
--- a/mojo/public/interfaces/bindings/tests/data/validate_header_bad_too_small.expected
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_msghdr_incomplete_struct_header.expected
diff --git a/mojo/public/interfaces/bindings/tests/data/validate_header_bad_zeros.data b/mojo/public/interfaces/bindings/tests/data/validation/conformance_msghdr_num_bytes_less_than_struct_header.data
index 169ea04..169ea04 100644
--- a/mojo/public/interfaces/bindings/tests/data/validate_header_bad_zeros.data
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_msghdr_num_bytes_less_than_struct_header.data
diff --git a/mojo/public/interfaces/bindings/tests/data/validate_header_bad_zeros.expected b/mojo/public/interfaces/bindings/tests/data/validation/conformance_msghdr_num_bytes_less_than_struct_header.expected
index 25aceee..25aceee 100644
--- a/mojo/public/interfaces/bindings/tests/data/validate_header_bad_zeros.expected
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_msghdr_num_bytes_less_than_struct_header.expected
diff --git a/mojo/public/interfaces/bindings/tests/data/validate_header_good_simple.data b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd0_good.data
index 43d3a37..cf2ac8d 100644
--- a/mojo/public/interfaces/bindings/tests/data/validate_header_good_simple.data
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd0_good.data
@@ -3,3 +3,7 @@
[u4]0 // name
[u4]0 // flags
[anchr]message_header
+
+[dist4]method0_params // num_bytes
+[u4]0 // num_fields
+[anchr]method0_params
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd0_good.expected b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd0_good.expected
new file mode 100644
index 0000000..7ef22e9
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd0_good.expected
@@ -0,0 +1 @@
+PASS
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/integration_intf1_mthd0_rqst_good.data b/mojo/public/interfaces/bindings/tests/data/validation/integration_intf1_mthd0_rqst_good.data
new file mode 100644
index 0000000..df7b7e8
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/integration_intf1_mthd0_rqst_good.data
@@ -0,0 +1,17 @@
+[dist4]message_header // num_bytes
+[u4]2 // num_fields
+[u4]0 // name
+[u4]0 // flags
+[anchr]message_header
+
+[dist4]method0_params // num_bytes
+[u4]1 // num_fields
+[dist8]param0_ptr // param0
+[anchr]method0_params
+
+[anchr]param0_ptr
+[dist4]basic_struct // num_bytes
+[u4]1 // num_fields
+[s4]-1 // a
+[u4]0 // padding
+[anchr]basic_struct
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/integration_intf1_mthd0_rqst_good.expected b/mojo/public/interfaces/bindings/tests/data/validation/integration_intf1_mthd0_rqst_good.expected
new file mode 100644
index 0000000..7ef22e9
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/integration_intf1_mthd0_rqst_good.expected
@@ -0,0 +1 @@
+PASS
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/integration_intf1_mthd0_rqst_unexpected_struct_header.data b/mojo/public/interfaces/bindings/tests/data/validation/integration_intf1_mthd0_rqst_unexpected_struct_header.data
new file mode 100644
index 0000000..3dcca9d
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/integration_intf1_mthd0_rqst_unexpected_struct_header.data
@@ -0,0 +1,14 @@
+[dist4]message_header // num_bytes
+[u4]2 // num_fields
+[u4]0 // name
+[u4]0 // flags
+[anchr]message_header
+
+[dist4]method0_params // num_bytes
+[u4]1 // num_fields
+[dist8]param0_ptr // param0
+[anchr]method0_params
+
+[anchr]param0_ptr
+[u4]0 // num_bytes: The struct size is too small.
+[u4]0 // num_fields
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/integration_intf1_mthd0_rqst_unexpected_struct_header.expected b/mojo/public/interfaces/bindings/tests/data/validation/integration_intf1_mthd0_rqst_unexpected_struct_header.expected
new file mode 100644
index 0000000..25aceee
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/integration_intf1_mthd0_rqst_unexpected_struct_header.expected
@@ -0,0 +1 @@
+VALIDATION_ERROR_UNEXPECTED_STRUCT_HEADER
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/integration_intf2_mthd0_resp_good.data b/mojo/public/interfaces/bindings/tests/data/validation/integration_intf2_mthd0_resp_good.data
new file mode 100644
index 0000000..f4b6c40
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/integration_intf2_mthd0_resp_good.data
@@ -0,0 +1,17 @@
+[dist4]message_header // num_bytes
+[u4]3 // num_fields
+[u4]0 // name
+[u4]2 // flags: Is response.
+[u8]1 // request_id
+[anchr]message_header
+
+[dist4]method0_params // num_bytes
+[u4]1 // num_fields
+[dist8]param0_ptr // param0
+[anchr]method0_params
+
+[anchr]param0_ptr
+[dist4]uint8_array // num_bytes
+[u4]1 // num_elements
+[u1]0
+[anchr]uint8_array
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/integration_intf2_mthd0_resp_good.expected b/mojo/public/interfaces/bindings/tests/data/validation/integration_intf2_mthd0_resp_good.expected
new file mode 100644
index 0000000..7ef22e9
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/integration_intf2_mthd0_resp_good.expected
@@ -0,0 +1 @@
+PASS
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/integration_intf2_mthd0_resp_unexpected_array_header.data b/mojo/public/interfaces/bindings/tests/data/validation/integration_intf2_mthd0_resp_unexpected_array_header.data
new file mode 100644
index 0000000..a357013
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/integration_intf2_mthd0_resp_unexpected_array_header.data
@@ -0,0 +1,17 @@
+[dist4]message_header // num_bytes
+[u4]3 // num_fields
+[u4]0 // name
+[u4]2 // flags: Is response.
+[u8]1 // request_id
+[anchr]message_header
+
+[dist4]method0_params // num_bytes
+[u4]1 // num_fields
+[dist8]param0_ptr // param0
+[anchr]method0_params
+
+[anchr]param0_ptr
+[dist4]uint8_array // num_bytes
+[u4]2 // num_elements: The size is too small to hold 2 elements.
+[u1]0
+[anchr]uint8_array
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/integration_intf2_mthd0_resp_unexpected_array_header.expected b/mojo/public/interfaces/bindings/tests/data/validation/integration_intf2_mthd0_resp_unexpected_array_header.expected
new file mode 100644
index 0000000..5a1ec4e
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/integration_intf2_mthd0_resp_unexpected_array_header.expected
@@ -0,0 +1 @@
+VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/integration_msghdr_invalid_flags.data b/mojo/public/interfaces/bindings/tests/data/validation/integration_msghdr_invalid_flags.data
new file mode 100644
index 0000000..6d2cb4e
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/integration_msghdr_invalid_flags.data
@@ -0,0 +1,6 @@
+[dist4]message_header // num_bytes
+[u4]3 // num_fields
+[u4]0xffffffff // name
+[u4]3 // flags: This combination is illegal.
+[u8]1 // request_id
+[anchr]message_header
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/integration_msghdr_invalid_flags.expected b/mojo/public/interfaces/bindings/tests/data/validation/integration_msghdr_invalid_flags.expected
new file mode 100644
index 0000000..696c78d
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/data/validation/integration_msghdr_invalid_flags.expected
@@ -0,0 +1 @@
+VALIDATION_ERROR_MESSAGE_HEADER_INVALID_FLAG_COMBINATION
diff --git a/mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom b/mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom
new file mode 100644
index 0000000..52ae995
--- /dev/null
+++ b/mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom
@@ -0,0 +1,25 @@
+// 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.
+
+module mojo.test {
+
+struct BasicStruct {
+ int32 a;
+};
+
+interface ConformanceTestInterface {
+ Method0();
+};
+
+[Client=IntegrationTestInterface2]
+interface IntegrationTestInterface1 {
+ Method0(BasicStruct param0);
+};
+
+[Client=IntegrationTestInterface1]
+interface IntegrationTestInterface2 {
+ Method0() => (uint8[] param0);
+};
+
+}