From 577b29ee4f96b770e486a3b1e54c510e08bd7956 Mon Sep 17 00:00:00 2001 From: alokp Date: Thu, 4 May 2017 16:10:09 -0700 Subject: [PATCH] Moving mojo/validation test into LayoutTests BUG=647036 TBR=yzshen,dpranke,jbroman Review-Url: https://codereview.chromium.org/2853293003 Cr-Commit-Position: refs/heads/master@{#469506} --- BUILD.gn | 2 +- mojo/edk/js/tests/run_js_unittests.cc | 4 - .../public/interfaces/bindings/tests/BUILD.gn | 38 ++ mojo/public/js/BUILD.gn | 3 - mojo/public/js/tests/validation_unittest.js | 343 ------------------ .../tools/bindings/gen_data_files_list.py | 36 ++ .../validation_test_input_parser.js | 3 +- .../WebKit/LayoutTests/mojo/validation.html | 298 +++++++++++++++ 8 files changed, 375 insertions(+), 352 deletions(-) delete mode 100644 mojo/public/js/tests/validation_unittest.js create mode 100644 mojo/public/tools/bindings/gen_data_files_list.py rename {mojo/public/js/tests => third_party/WebKit/LayoutTests/mojo/resources}/validation_test_input_parser.js (99%) create mode 100644 third_party/WebKit/LayoutTests/mojo/validation.html diff --git a/BUILD.gn b/BUILD.gn index 1120495be3a0b2..cd3feb81a14d7e 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -872,8 +872,8 @@ if (!is_ios) { data_deps = [ ":layout_test_data_mojo_bindings", "//content/shell:content_shell", + "//mojo/public/interfaces/bindings/tests", "//mojo/public/interfaces/bindings/tests:test_associated_interfaces", - "//mojo/public/interfaces/bindings/tests:test_interfaces", "//third_party/WebKit/public:blink_devtools_frontend_resources_files", "//third_party/mesa:osmesa", "//tools/imagediff", diff --git a/mojo/edk/js/tests/run_js_unittests.cc b/mojo/edk/js/tests/run_js_unittests.cc index 13e796ba62ba54..26d3b67e47fc13 100644 --- a/mojo/edk/js/tests/run_js_unittests.cc +++ b/mojo/edk/js/tests/run_js_unittests.cc @@ -51,10 +51,6 @@ TEST(JSTest, Core) { RunTest("core_unittest.js", true); } -TEST(JSTest, Validation) { - RunTest("validation_unittest.js", true); -} - } // namespace } // namespace js } // namespace edk diff --git a/mojo/public/interfaces/bindings/tests/BUILD.gn b/mojo/public/interfaces/bindings/tests/BUILD.gn index e496eb656c0f16..7fa34eb17f9d31 100644 --- a/mojo/public/interfaces/bindings/tests/BUILD.gn +++ b/mojo/public/interfaces/bindings/tests/BUILD.gn @@ -4,6 +4,44 @@ import("../../../tools/bindings/mojom.gni") +group("tests") { + testonly = true + deps = [ + ":test_interfaces", + ] + data_deps = [ + ":test_data", + ":test_data_list", + ] +} + +copy("test_data") { + testonly = true + sources = [ + "data/validation", + ] + outputs = [ + "$root_gen_dir/layout_test_data/{{source_root_relative_dir}}/{{source_file_part}}", + ] +} + +action_foreach("test_data_list") { + testonly = true + script = "//mojo/public/tools/bindings/gen_data_files_list.py" + sources = [ + "data/validation", + ] + outputs = [ + "$root_gen_dir/layout_test_data/{{source_root_relative_dir}}/{{source_file_part}}_index.txt", + ] + args = [ + "-d", + rebase_path(sources[0], root_build_dir), + "-o", + rebase_path(outputs[0], root_build_dir), + ] +} + mojom("test_interfaces") { testonly = true sources = [ diff --git a/mojo/public/js/BUILD.gn b/mojo/public/js/BUILD.gn index 3861163f6a4f1a..4447ac31cea7ae 100644 --- a/mojo/public/js/BUILD.gn +++ b/mojo/public/js/BUILD.gn @@ -82,10 +82,7 @@ group("tests") { testonly = true data = [ - "//mojo/public/interfaces/bindings/tests/data/validation/", "tests/core_unittest.js", - "tests/validation_test_input_parser.js", - "tests/validation_unittest.js", ] public_deps = [ diff --git a/mojo/public/js/tests/validation_unittest.js b/mojo/public/js/tests/validation_unittest.js deleted file mode 100644 index abefe8e878c61b..00000000000000 --- a/mojo/public/js/tests/validation_unittest.js +++ /dev/null @@ -1,343 +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. - -define([ - "console", - "file", - "gin/test/expect", - "mojo/public/interfaces/bindings/tests/validation_test_associated_interfaces.mojom", - "mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom", - "mojo/public/js/bindings", - "mojo/public/js/buffer", - "mojo/public/js/codec", - "mojo/public/js/core", - "mojo/public/js/tests/validation_test_input_parser", - "mojo/public/js/validator", -], function(console, - file, - expect, - testAssociatedInterface, - testInterface, - bindings, - buffer, - codec, - core, - parser, - validator) { - - var noError = validator.validationError.NONE; - - function checkTestMessageParser() { - function TestMessageParserFailure(message, input) { - this.message = message; - this.input = input; - } - - TestMessageParserFailure.prototype.toString = function() { - return 'Error: ' + this.message + ' for "' + this.input + '"'; - }; - - function checkData(data, expectedData, input) { - if (data.byteLength != expectedData.byteLength) { - var s = "message length (" + data.byteLength + ") doesn't match " + - "expected length: " + expectedData.byteLength; - throw new TestMessageParserFailure(s, input); - } - - for (var i = 0; i < data.byteLength; i++) { - if (data.getUint8(i) != expectedData.getUint8(i)) { - var s = 'message data mismatch at byte offset ' + i; - throw new TestMessageParserFailure(s, input); - } - } - } - - function testFloatItems() { - var input = '[f]+.3e9 [d]-10.03'; - var msg = parser.parseTestMessage(input); - var expectedData = new buffer.Buffer(12); - expectedData.setFloat32(0, +.3e9); - expectedData.setFloat64(4, -10.03); - checkData(msg.buffer, expectedData, input); - } - - function testUnsignedIntegerItems() { - var input = '[u1]0x10// hello world !! \n\r \t [u2]65535 \n' + - '[u4]65536 [u8]0xFFFFFFFFFFFFF 0 0Xff'; - var msg = parser.parseTestMessage(input); - var expectedData = new buffer.Buffer(17); - expectedData.setUint8(0, 0x10); - expectedData.setUint16(1, 65535); - expectedData.setUint32(3, 65536); - expectedData.setUint64(7, 0xFFFFFFFFFFFFF); - expectedData.setUint8(15, 0); - expectedData.setUint8(16, 0xff); - checkData(msg.buffer, expectedData, input); - } - - function testSignedIntegerItems() { - var input = '[s8]-0x800 [s1]-128\t[s2]+0 [s4]-40'; - var msg = parser.parseTestMessage(input); - var expectedData = new buffer.Buffer(15); - expectedData.setInt64(0, -0x800); - expectedData.setInt8(8, -128); - expectedData.setInt16(9, 0); - expectedData.setInt32(11, -40); - checkData(msg.buffer, expectedData, input); - } - - function testByteItems() { - var input = '[b]00001011 [b]10000000 // hello world\n [b]00000000'; - var msg = parser.parseTestMessage(input); - var expectedData = new buffer.Buffer(3); - expectedData.setUint8(0, 11); - expectedData.setUint8(1, 128); - expectedData.setUint8(2, 0); - checkData(msg.buffer, expectedData, input); - } - - function testAnchors() { - var input = '[dist4]foo 0 [dist8]bar 0 [anchr]foo [anchr]bar'; - var msg = parser.parseTestMessage(input); - var expectedData = new buffer.Buffer(14); - expectedData.setUint32(0, 14); - expectedData.setUint8(4, 0); - expectedData.setUint64(5, 9); - expectedData.setUint8(13, 0); - checkData(msg.buffer, expectedData, input); - } - - function testHandles() { - var input = '// This message has handles! \n[handles]50 [u8]2'; - var msg = parser.parseTestMessage(input); - var expectedData = new buffer.Buffer(8); - expectedData.setUint64(0, 2); - - if (msg.handleCount != 50) { - var s = 'wrong handle count (' + msg.handleCount + ')'; - throw new TestMessageParserFailure(s, input); - } - checkData(msg.buffer, expectedData, input); - } - - function testEmptyInput() { - var msg = parser.parseTestMessage(''); - if (msg.buffer.byteLength != 0) - throw new TestMessageParserFailure('expected empty message', ''); - } - - function testBlankInput() { - var input = ' \t // hello world \n\r \t// the answer is 42 '; - var msg = parser.parseTestMessage(input); - if (msg.buffer.byteLength != 0) - throw new TestMessageParserFailure('expected empty message', input); - } - - function testInvalidInput() { - function parserShouldFail(input) { - try { - parser.parseTestMessage(input); - } catch (e) { - if (e instanceof parser.InputError) - return; - throw new TestMessageParserFailure( - 'unexpected exception ' + e.toString(), input); - } - throw new TestMessageParserFailure("didn't detect invalid input", file); - } - - ['/ 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' - ].forEach(parserShouldFail); - } - - try { - testFloatItems(); - testUnsignedIntegerItems(); - testSignedIntegerItems(); - testByteItems(); - testInvalidInput(); - testEmptyInput(); - testBlankInput(); - testHandles(); - testAnchors(); - } catch (e) { - return e.toString(); - } - return null; - } - - function getMessageTestFiles(prefix) { - var sourceRoot = file.getSourceRootDirectory(); - expect(sourceRoot).not.toBeNull(); - - var testDir = sourceRoot + - "/mojo/public/interfaces/bindings/tests/data/validation/"; - var testFiles = file.getFilesInDirectory(testDir); - expect(testFiles).not.toBeNull(); - expect(testFiles.length).toBeGreaterThan(0); - - // The matching ".data" pathnames with the extension removed. - return testFiles.filter(function(s) { - return s.substr(-5) == ".data" && s.indexOf(prefix) == 0; - }).map(function(s) { - return testDir + s.slice(0, -5); - }); - } - - function readTestMessage(filename) { - var contents = file.readFileToString(filename + ".data"); - expect(contents).not.toBeNull(); - return parser.parseTestMessage(contents); - } - - function readTestExpected(filename) { - var contents = file.readFileToString(filename + ".expected"); - expect(contents).not.toBeNull(); - return contents.trim(); - } - - function checkValidationResult(testFile, err) { - var actualResult = (err === noError) ? "PASS" : err; - var expectedResult = readTestExpected(testFile); - if (actualResult != expectedResult) - console.log("[Test message validation failed: " + testFile + " ]"); - expect(actualResult).toEqual(expectedResult); - } - - function testMessageValidation(prefix, filters) { - var testFiles = getMessageTestFiles(prefix); - expect(testFiles.length).toBeGreaterThan(0); - - for (var i = 0; i < testFiles.length; i++) { - // TODO(hansmuller) Temporarily skipping array pointer overflow tests - // because JS numbers are limited to 53 bits. - // TODO(rudominer): Temporarily skipping 'no-such-method', - // 'invalid_request_flags', and 'invalid_response_flags' until additional - // logic in *RequestValidator and *ResponseValidator is ported from - // cpp to js. - // TODO(crbug/640298): Implement max recursion depth for JS. - // TODO(crbug/628104): Support struct map keys for JS. - if (testFiles[i].indexOf("overflow") != -1 || - testFiles[i].indexOf("conformance_mthd19") != -1 || - testFiles[i].indexOf("conformance_mthd20") != -1 || - testFiles[i].indexOf("no_such_method") != -1 || - testFiles[i].indexOf("invalid_request_flags") != -1 || - testFiles[i].indexOf("invalid_response_flags") != -1) { - console.log("[Skipping " + testFiles[i] + "]"); - continue; - } - - var testMessage = readTestMessage(testFiles[i]); - var handles = new Array(testMessage.handleCount); - var message = new codec.Message(testMessage.buffer, handles); - var messageValidator = new validator.Validator(message); - - var err = messageValidator.validateMessageHeader(); - for (var j = 0; err === noError && j < filters.length; ++j) - err = filters[j](messageValidator); - - checkValidationResult(testFiles[i], err); - } - } - - function testConformanceMessageValidation() { - testMessageValidation("conformance_", [ - testInterface.ConformanceTestInterface.validateRequest]); - } - - function testBoundsCheckMessageValidation() { - testMessageValidation("boundscheck_", [ - testInterface.BoundsCheckTestInterface.validateRequest]); - } - - function testResponseConformanceMessageValidation() { - testMessageValidation("resp_conformance_", [ - testInterface.ConformanceTestInterface.validateResponse]); - } - - function testResponseBoundsCheckMessageValidation() { - testMessageValidation("resp_boundscheck_", [ - testInterface.BoundsCheckTestInterface.validateResponse]); - } - - function testAssociatedConformanceMessageValidation() { - testMessageValidation("associated_conformance_", [ - testAssociatedInterface.AssociatedConformanceTestInterface - .validateRequest]); - } - - function testIntegratedMessageValidation(testFilesPattern, endpoint) { - var testFiles = getMessageTestFiles(testFilesPattern); - expect(testFiles.length).toBeGreaterThan(0); - - var testMessagePipe = core.createMessagePipe(); - expect(testMessagePipe.result).toBe(core.RESULT_OK); - - endpoint.bind(testMessagePipe.handle1); - var observer = validator.ValidationErrorObserverForTesting.getInstance(); - - for (var i = 0; i < testFiles.length; i++) { - var testMessage = readTestMessage(testFiles[i]); - var handles = new Array(testMessage.handleCount); - - var writeMessageValue = core.writeMessage( - testMessagePipe.handle0, - new Uint8Array(testMessage.buffer.arrayBuffer), - new Array(testMessage.handleCount), - core.WRITE_MESSAGE_FLAG_NONE); - expect(writeMessageValue).toBe(core.RESULT_OK); - - endpoint.waitForNextMessageForTesting(); - checkValidationResult(testFiles[i], observer.lastError); - observer.reset(); - } - - expect(core.close(testMessagePipe.handle0)).toBe(core.RESULT_OK); - } - - function testIntegratedMessageHeaderValidation() { - testIntegratedMessageValidation( - "integration_msghdr", - new bindings.Binding(testInterface.IntegrationTestInterface, {})); - testIntegratedMessageValidation( - "integration_msghdr", - new testInterface.IntegrationTestInterfacePtr().ptr); - } - - function testIntegratedRequestMessageValidation() { - testIntegratedMessageValidation( - "integration_intf_rqst", - new bindings.Binding(testInterface.IntegrationTestInterface, {})); - } - - function testIntegratedResponseMessageValidation() { - testIntegratedMessageValidation( - "integration_intf_resp", - new testInterface.IntegrationTestInterfacePtr().ptr); - } - - expect(checkTestMessageParser()).toBeNull(); - testAssociatedConformanceMessageValidation(); - testConformanceMessageValidation(); - testBoundsCheckMessageValidation(); - testResponseConformanceMessageValidation(); - testResponseBoundsCheckMessageValidation(); - testIntegratedMessageHeaderValidation(); - testIntegratedResponseMessageValidation(); - testIntegratedRequestMessageValidation(); - validator.clearTestingMode(); - - this.result = "PASS"; -}); diff --git a/mojo/public/tools/bindings/gen_data_files_list.py b/mojo/public/tools/bindings/gen_data_files_list.py new file mode 100644 index 00000000000000..47fcbe3651c2db --- /dev/null +++ b/mojo/public/tools/bindings/gen_data_files_list.py @@ -0,0 +1,36 @@ +# Copyright 2017 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. +"""Generates a list of all files in a directory. + +This script takes in a directory and an output file name as input. +It then reads the directory and creates a list of all file names +in that directory. The list is written to the output file. +There is also an option to pass in '-p' or '--pattern' +which will check each file name against a regular expression +pattern that is passed in. Only files which match the regex +will be written to the list. +""" + +from optparse import OptionParser +import os +import re +import sys + +def main(): + parser = OptionParser() + parser.add_option('-d', '--directory', help='Read files from DIRECTORY') + parser.add_option('-o', '--output', help='Write list to FILE') + parser.add_option('-p', + '--pattern', + help='Only reads files that name matches PATTERN', + default=".") + (options, _) = parser.parse_args() + pattern = re.compile(options.pattern) + files = [f for f in os.listdir(options.directory) if pattern.match(f)] + with file(options.output, 'w') as out: + for f in files: + print >> out, f + +if __name__ == '__main__': + sys.exit(main()) diff --git a/mojo/public/js/tests/validation_test_input_parser.js b/third_party/WebKit/LayoutTests/mojo/resources/validation_test_input_parser.js similarity index 99% rename from mojo/public/js/tests/validation_test_input_parser.js rename to third_party/WebKit/LayoutTests/mojo/resources/validation_test_input_parser.js index f5a57f91722688..c1403fd4d079db 100644 --- a/mojo/public/js/tests/validation_test_input_parser.js +++ b/third_party/WebKit/LayoutTests/mojo/resources/validation_test_input_parser.js @@ -6,7 +6,7 @@ // or ".data" files. The input format is described here: // mojo/public/cpp/bindings/tests/validation_test_input_parser.h -define([ +define("mojo/resources/validation_test_input_parser", [ "mojo/public/js/buffer" ], function(buffer) { @@ -14,6 +14,7 @@ define([ // or ".data" file. function InputError(message, line) { + this.name = "InputError"; this.message = message; this.line = line; } diff --git a/third_party/WebKit/LayoutTests/mojo/validation.html b/third_party/WebKit/LayoutTests/mojo/validation.html new file mode 100644 index 00000000000000..1faec5d57ac3a2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/mojo/validation.html @@ -0,0 +1,298 @@ + + + + + +