summaryrefslogtreecommitdiff
path: root/native_client_sdk
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2013-07-18 11:57:30 +0100
committerBen Murdoch <benm@google.com>2013-07-18 11:57:30 +0100
commit9ab5563a3196760eb381d102cbb2bc0f7abc6a50 (patch)
tree1c690f8b0c998ba536a0c7aeff34764383c7dff6 /native_client_sdk
parent106cdaa9e420b49e5b1ef6941f08dd990128a374 (diff)
downloadchromium_org-9ab5563a3196760eb381d102cbb2bc0f7abc6a50.tar.gz
Merge from Chromium at DEPS revision r212225
This commit was generated by merge_to_master.py. Change-Id: I9b658b6bade7aff6166611a04fb26f4bcf0ca77c
Diffstat (limited to 'native_client_sdk')
-rwxr-xr-xnative_client_sdk/src/build_tools/tests/verify_ppapi_test.py194
-rwxr-xr-xnative_client_sdk/src/build_tools/verify_ppapi.py186
-rw-r--r--native_client_sdk/src/libraries/nacl_io/mount_html5fs.cc7
-rwxr-xr-xnative_client_sdk/src/test_all.py1
4 files changed, 382 insertions, 6 deletions
diff --git a/native_client_sdk/src/build_tools/tests/verify_ppapi_test.py b/native_client_sdk/src/build_tools/tests/verify_ppapi_test.py
new file mode 100755
index 0000000000..d770182bc2
--- /dev/null
+++ b/native_client_sdk/src/build_tools/tests/verify_ppapi_test.py
@@ -0,0 +1,194 @@
+#!/usr/bin/env python
+# Copyright (c) 2013 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.
+
+import os
+import sys
+import unittest
+
+SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
+BUILD_TOOLS_DIR = os.path.dirname(SCRIPT_DIR)
+CHROME_SRC = os.path.dirname(os.path.dirname(os.path.dirname(BUILD_TOOLS_DIR)))
+MOCK_DIR = os.path.join(CHROME_SRC, "third_party", "pymock")
+
+# For the mock library
+sys.path.append(MOCK_DIR)
+import mock
+
+sys.path.append(BUILD_TOOLS_DIR)
+import verify_ppapi
+
+
+class TestPartition(unittest.TestCase):
+ def testBasic(self):
+ filenames = [
+ os.path.join('ppapi', 'c', 'ppb_foo.h'),
+ os.path.join('ppapi', 'cpp', 'foo.h'),
+ os.path.join('ppapi', 'cpp', 'foo.cc'),
+ ]
+ result = verify_ppapi.PartitionFiles(filenames)
+ self.assertTrue(filenames[0] in result['ppapi'])
+ self.assertTrue(filenames[1] in result['ppapi_cpp'])
+ self.assertTrue(filenames[2] in result['ppapi_cpp'])
+ self.assertEqual(0, len(result['ppapi_cpp_private']))
+
+ def testIgnoreDocumentation(self):
+ filenames = [
+ os.path.join('ppapi', 'c', 'documentation', 'Doxyfile'),
+ os.path.join('ppapi', 'c', 'documentation', 'index.dox'),
+ os.path.join('ppapi', 'cpp', 'documentation', 'footer.html'),
+ ]
+ result = verify_ppapi.PartitionFiles(filenames)
+ self.assertEqual(0, len(result['ppapi']))
+ self.assertEqual(0, len(result['ppapi_cpp']))
+ self.assertEqual(0, len(result['ppapi_cpp_private']))
+
+ def testIgnoreTrusted(self):
+ filenames = [
+ os.path.join('ppapi', 'c', 'trusted', 'ppb_broker_trusted.h'),
+ os.path.join('ppapi', 'c', 'trusted', 'ppb_file_io_trusted.h'),
+ os.path.join('ppapi', 'cpp', 'trusted', 'file_chooser_trusted.cc'),
+ ]
+ result = verify_ppapi.PartitionFiles(filenames)
+ self.assertEqual(0, len(result['ppapi']))
+ self.assertEqual(0, len(result['ppapi_cpp']))
+ self.assertEqual(0, len(result['ppapi_cpp_private']))
+
+ def testIgnoreIfNotSourceOrHeader(self):
+ filenames = [
+ os.path.join('ppapi', 'c', 'DEPS'),
+ os.path.join('ppapi', 'c', 'blah', 'foo.xml'),
+ os.path.join('ppapi', 'cpp', 'DEPS'),
+ os.path.join('ppapi', 'cpp', 'foobar.py'),
+ ]
+ result = verify_ppapi.PartitionFiles(filenames)
+ self.assertEqual(0, len(result['ppapi']))
+ self.assertEqual(0, len(result['ppapi_cpp']))
+ self.assertEqual(0, len(result['ppapi_cpp_private']))
+
+ def testIgnoreOtherDirectories(self):
+ ignored_directories = ['api', 'examples', 'generators', 'host', 'lib',
+ 'native_client', 'proxy', 'shared_impl', 'tests', 'thunk']
+
+ # Generate some random files in the ignored directories.
+ filenames = []
+ for dirname in ignored_directories:
+ filenames = os.path.join('ppapi', dirname, 'foo.cc')
+ filenames = os.path.join('ppapi', dirname, 'subdir', 'foo.h')
+ filenames = os.path.join('ppapi', dirname, 'DEPS')
+
+ result = verify_ppapi.PartitionFiles(filenames)
+ self.assertEqual(0, len(result['ppapi']))
+ self.assertEqual(0, len(result['ppapi_cpp']))
+ self.assertEqual(0, len(result['ppapi_cpp_private']))
+
+
+class TestGetChangedAndRemoved(unittest.TestCase):
+ def testBasic(self):
+ modified_filenames = [
+ os.path.join('ppapi', 'cpp', 'audio.cc'),
+ os.path.join('ppapi', 'cpp', 'graphics_2d.cc'),
+ os.path.join('ppapi', 'cpp', 'foobar.cc'),
+ os.path.join('ppapi', 'cpp', 'var.cc'),
+ ]
+ directory_list = [
+ os.path.join('ppapi', 'cpp', 'audio.cc'),
+ os.path.join('ppapi', 'cpp', 'graphics_2d.cc'),
+ ]
+ changed, removed = verify_ppapi.GetChangedAndRemovedFilenames(
+ modified_filenames, directory_list)
+ self.assertTrue(modified_filenames[0] in changed)
+ self.assertTrue(modified_filenames[1] in changed)
+ self.assertTrue(modified_filenames[2] in removed)
+ self.assertTrue(modified_filenames[3] in removed)
+
+
+class TestVerify(unittest.TestCase):
+ def testBasic(self):
+ dsc_filename = 'native_client_sdk/src/libraries/ppapi/library.dsc'
+ # The .dsc files typically uses basenames, not full paths.
+ dsc_sources_and_headers = [
+ 'ppb_audio.h',
+ 'ppb_console.h',
+ 'ppb_gamepad.h',
+ 'ppb.h',
+ 'ppp_zoom_dev.h',
+ ]
+ changed_filenames = [
+ os.path.join('ppapi', 'c', 'ppb_audio.h'),
+ os.path.join('ppapi', 'c', 'ppb_console.h'),
+ ]
+ removed_filenames = []
+ # Should not raise.
+ verify_ppapi.Verify(dsc_filename, dsc_sources_and_headers,
+ changed_filenames, removed_filenames)
+
+ # Raise, because we removed ppp_zoom_dev.h.
+ removed_filenames = [
+ os.path.join('ppapi', 'c', 'ppb_console.h'),
+ ]
+ self.assertRaises(verify_ppapi.VerifyException, verify_ppapi.Verify,
+ dsc_filename, dsc_sources_and_headers, changed_filenames,
+ removed_filenames)
+
+ # Raise, because we added ppb_foo.h.
+ removed_filenames = []
+ changed_filenames = [
+ os.path.join('ppapi', 'c', 'ppb_audio.h'),
+ os.path.join('ppapi', 'c', 'ppb_console.h'),
+ os.path.join('ppapi', 'c', 'ppb_foo.h'),
+ ]
+ self.assertRaises(verify_ppapi.VerifyException, verify_ppapi.Verify,
+ dsc_filename, dsc_sources_and_headers, changed_filenames,
+ removed_filenames)
+
+ def testVerifyPrivate(self):
+ dsc_filename = \
+ 'native_client_sdk/src/libraries/ppapi_cpp_private/library.dsc'
+ # The .dsc files typically uses basenames, not full paths.
+ dsc_sources_and_headers = [
+ 'ext_crx_file_system_private.cc',
+ 'file_io_private.cc',
+ 'ppb_ext_crx_file_system_private.h',
+ 'ppb_file_io_private.h',
+ 'host_resolver_private.h',
+ 'net_address_private.h',
+ ]
+ changed_filenames = [
+ os.path.join('ppapi', 'c', 'private', 'ppb_foo_private.h'),
+ ]
+ removed_filenames = []
+
+ with mock.patch('sys.stderr') as sys_stderr:
+ # When a new private file is added, just print to stderr, but don't fail.
+ result = verify_ppapi.VerifyOrPrintError(
+ dsc_filename, dsc_sources_and_headers, changed_filenames,
+ removed_filenames, is_private=True)
+ self.assertTrue(result)
+ self.assertTrue(sys_stderr.write.called)
+
+ # If is_private is False, then adding a new interface without updating the
+ # .dsc is an error.
+ sys_stderr.reset_mock()
+ result = verify_ppapi.VerifyOrPrintError(
+ dsc_filename, dsc_sources_and_headers, changed_filenames,
+ removed_filenames, is_private=False)
+ self.assertFalse(result)
+ self.assertTrue(sys_stderr.write.called)
+
+ # Removing a file without updating the .dsc is always an error.
+ sys_stderr.reset_mock()
+ changed_filenames = []
+ removed_filenames = [
+ os.path.join('ppapi', 'c', 'private', 'net_address_private.h'),
+ ]
+ result = verify_ppapi.VerifyOrPrintError(
+ dsc_filename, dsc_sources_and_headers, changed_filenames,
+ removed_filenames, is_private=True)
+ self.assertFalse(result)
+ self.assertTrue(sys_stderr.write.called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/native_client_sdk/src/build_tools/verify_ppapi.py b/native_client_sdk/src/build_tools/verify_ppapi.py
new file mode 100755
index 0000000000..8a51e3c288
--- /dev/null
+++ b/native_client_sdk/src/build_tools/verify_ppapi.py
@@ -0,0 +1,186 @@
+#!/usr/bin/env python
+# Copyright (c) 2013 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.
+
+"""Helper script for PPAPI's PRESUBMIT.py to detect if additions or removals of
+PPAPI interfaces have been propagated to the Native Client libraries (.dsc
+files).
+
+For example, if a user adds "ppapi/c/foo.h", we check that the interface has
+been added to "native_client_sdk/src/libraries/ppapi/library.dsc".
+"""
+
+import optparse
+import os
+import sys
+
+from build_paths import PPAPI_DIR, SRC_DIR, SDK_LIBRARY_DIR
+import parse_dsc
+
+
+class VerifyException(Exception):
+ def __init__(self, lib_path, expected, unexpected):
+ self.expected = expected
+ self.unexpected = unexpected
+
+ msg = 'In %s:\n' % lib_path
+ if expected:
+ msg += ' these files are missing and should be added:\n'
+ for filename in sorted(expected):
+ msg += ' %s\n' % filename
+ if unexpected:
+ msg += ' these files no longer exist and should be removed:\n'
+ for filename in sorted(unexpected):
+ msg += ' %s\n' % filename
+
+ Exception.__init__(self, msg)
+
+
+def PartitionFiles(filenames):
+ c_filenames = set()
+ cpp_filenames = set()
+ private_filenames = set()
+
+ for filename in filenames:
+ if os.path.splitext(filename)[1] not in ('.cc', '.h'):
+ continue
+
+ parts = filename.split(os.sep)
+ if 'private' in filename:
+ if 'flash' in filename:
+ continue
+ private_filenames.add(filename)
+ elif parts[0:2] == ['ppapi', 'c']:
+ if len(parts) >= 2 and parts[2] in ('documentation', 'trusted'):
+ continue
+ c_filenames.add(filename)
+ elif (parts[0:2] == ['ppapi', 'cpp'] or
+ parts[0:2] == ['ppapi', 'utility']):
+ if len(parts) >= 2 and parts[2] in ('documentation', 'trusted'):
+ continue
+ cpp_filenames.add(filename)
+ else:
+ continue
+
+ return {
+ 'ppapi': c_filenames,
+ 'ppapi_cpp': cpp_filenames,
+ 'ppapi_cpp_private': private_filenames
+ }
+
+
+def GetDirectoryList(directory_path, relative_to):
+ result = []
+ for root, _, files in os.walk(directory_path):
+ rel_root = os.path.relpath(root, relative_to)
+ if rel_root == '.':
+ rel_root = ''
+ for base_name in files:
+ result.append(os.path.join(rel_root, base_name))
+ return result
+
+
+def GetDscSourcesAndHeaders(dsc):
+ result = []
+ for headers_info in dsc.get('HEADERS', []):
+ result.extend(headers_info['FILES'])
+ for targets_info in dsc.get('TARGETS', []):
+ result.extend(targets_info['SOURCES'])
+ return result
+
+
+def GetChangedAndRemovedFilenames(modified_filenames, directory_list):
+ changed = set()
+ removed = set()
+ directory_list_set = set(directory_list)
+ for filename in modified_filenames:
+ if filename in directory_list_set:
+ # We can't know if a file was added (that would require knowing the
+ # previous state of the working directory). Instead, we assume that a
+ # changed file may have been added, and check it accordingly.
+ changed.add(filename)
+ else:
+ removed.add(filename)
+ return changed, removed
+
+
+def GetDscFilenameFromLibraryName(lib_name):
+ return os.path.join(SDK_LIBRARY_DIR, lib_name, 'library.dsc')
+
+
+def Verify(dsc_filename, dsc_sources_and_headers, changed_filenames,
+ removed_filenames):
+ expected_filenames = set()
+ unexpected_filenames = set()
+
+ for filename in changed_filenames:
+ basename = os.path.basename(filename)
+ if basename not in dsc_sources_and_headers:
+ expected_filenames.add(filename)
+
+ for filename in removed_filenames:
+ basename = os.path.basename(filename)
+ if basename in dsc_sources_and_headers:
+ unexpected_filenames.add(filename)
+
+ if expected_filenames or unexpected_filenames:
+ raise VerifyException(dsc_filename, expected_filenames,
+ unexpected_filenames)
+
+
+def VerifyOrPrintError(dsc_filename, dsc_sources_and_headers, changed_filenames,
+ removed_filenames, is_private=False):
+ try:
+ Verify(dsc_filename, dsc_sources_and_headers, changed_filenames,
+ removed_filenames)
+ except VerifyException as e:
+ should_fail = True
+ if is_private and e.expected:
+ # For ppapi_cpp_private, we don't fail if there are expected filenames...
+ # we may not want to include them. We still want to fail if there are
+ # unexpected filenames, though.
+ sys.stderr.write('>>> WARNING: private interface files changed. '
+ 'Should they be added to the Native Client SDK? <<<\n')
+ if not e.unexpected:
+ should_fail = False
+ sys.stderr.write(str(e) + '\n')
+ if should_fail:
+ return False
+ return True
+
+
+def main(args):
+ usage = '%prog <file>...'
+ description = __doc__
+ parser = optparse.OptionParser(usage=usage, description=description)
+ args = parser.parse_args(args)[1]
+ if not args:
+ parser.error('Expected a PPAPI header or source file.')
+
+ retval = 0
+ lib_files = PartitionFiles(args)
+ directory_list = GetDirectoryList(PPAPI_DIR, relative_to=SRC_DIR)
+ for lib_name, filenames in lib_files.iteritems():
+ if not filenames:
+ continue
+
+ changed_filenames, removed_filenames = \
+ GetChangedAndRemovedFilenames(filenames, directory_list)
+
+ dsc_filename = GetDscFilenameFromLibraryName(lib_name)
+ dsc = parse_dsc.LoadProject(dsc_filename)
+ dsc_sources_and_headers = GetDscSourcesAndHeaders(dsc)
+
+ # Use the relative path to the .dsc to make the error messages shorter.
+ rel_dsc_filename = os.path.relpath(dsc_filename, SRC_DIR)
+ is_private = lib_name == 'ppapi_cpp_private'
+ if not VerifyOrPrintError(rel_dsc_filename, dsc_sources_and_headers,
+ changed_filenames, removed_filenames,
+ is_private=is_private):
+ retval = 1
+ return retval
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_html5fs.cc b/native_client_sdk/src/libraries/nacl_io/mount_html5fs.cc
index e883501da4..3507ae9f74 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_html5fs.cc
+++ b/native_client_sdk/src/libraries/nacl_io/mount_html5fs.cc
@@ -28,12 +28,7 @@ int64_t strtoull(const char* nptr, char** endptr, int base) {
Error MountHtml5Fs::Access(const Path& path, int a_mode) {
// a_mode is unused, since all files are readable, writable and executable.
ScopedMountNode node;
- Error error = Open(path, O_RDONLY, &node);
- if (error)
- return error;
-
- node->Release();
- return 0;
+ return Open(path, O_RDONLY, &node);
}
Error MountHtml5Fs::Open(const Path& path,
diff --git a/native_client_sdk/src/test_all.py b/native_client_sdk/src/test_all.py
index 5e9be95a0d..a13bf80f2d 100755
--- a/native_client_sdk/src/test_all.py
+++ b/native_client_sdk/src/test_all.py
@@ -28,6 +28,7 @@ TEST_MODULES = [
'sel_ldr_test',
'update_nacl_manifest_test',
'verify_filelist_test',
+ 'verify_ppapi_test',
]
def main():