1 #!/usr/bin/env python 2 # Copyright (c) 2013 The Chromium Authors. All rights reserved. 3 # Use of this source code is governed by a BSD-style license that can be 4 # found in the LICENSE file. 5 6 import os 7 import sys 8 import unittest 9 10 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) 11 BUILD_TOOLS_DIR = os.path.dirname(SCRIPT_DIR) 12 CHROME_SRC = os.path.dirname(os.path.dirname(os.path.dirname(BUILD_TOOLS_DIR))) 13 MOCK_DIR = os.path.join(CHROME_SRC, "third_party", "pymock") 14 15 # For the mock library 16 sys.path.append(MOCK_DIR) 17 import mock 18 19 sys.path.append(BUILD_TOOLS_DIR) 20 import verify_ppapi 21 22 23 class TestPartition(unittest.TestCase): 24 def testBasic(self): 25 filenames = [ 26 os.path.join('ppapi', 'c', 'ppb_foo.h'), 27 os.path.join('ppapi', 'cpp', 'foo.h'), 28 os.path.join('ppapi', 'cpp', 'foo.cc'), 29 ] 30 result = verify_ppapi.PartitionFiles(filenames) 31 self.assertTrue(filenames[0] in result['ppapi']) 32 self.assertTrue(filenames[1] in result['ppapi_cpp']) 33 self.assertTrue(filenames[2] in result['ppapi_cpp']) 34 self.assertEqual(0, len(result['ppapi_cpp_private'])) 35 36 def testIgnoreDocumentation(self): 37 filenames = [ 38 os.path.join('ppapi', 'c', 'documentation', 'Doxyfile'), 39 os.path.join('ppapi', 'c', 'documentation', 'index.dox'), 40 os.path.join('ppapi', 'cpp', 'documentation', 'footer.html'), 41 ] 42 result = verify_ppapi.PartitionFiles(filenames) 43 self.assertEqual(0, len(result['ppapi'])) 44 self.assertEqual(0, len(result['ppapi_cpp'])) 45 self.assertEqual(0, len(result['ppapi_cpp_private'])) 46 47 def testIgnoreTrusted(self): 48 filenames = [ 49 os.path.join('ppapi', 'c', 'trusted', 'ppb_broker_trusted.h'), 50 os.path.join('ppapi', 'c', 'trusted', 'ppb_file_io_trusted.h'), 51 os.path.join('ppapi', 'cpp', 'trusted', 'file_chooser_trusted.cc'), 52 ] 53 result = verify_ppapi.PartitionFiles(filenames) 54 self.assertEqual(0, len(result['ppapi'])) 55 self.assertEqual(0, len(result['ppapi_cpp'])) 56 self.assertEqual(0, len(result['ppapi_cpp_private'])) 57 58 def testIgnoreIfNotSourceOrHeader(self): 59 filenames = [ 60 os.path.join('ppapi', 'c', 'DEPS'), 61 os.path.join('ppapi', 'c', 'blah', 'foo.xml'), 62 os.path.join('ppapi', 'cpp', 'DEPS'), 63 os.path.join('ppapi', 'cpp', 'foobar.py'), 64 ] 65 result = verify_ppapi.PartitionFiles(filenames) 66 self.assertEqual(0, len(result['ppapi'])) 67 self.assertEqual(0, len(result['ppapi_cpp'])) 68 self.assertEqual(0, len(result['ppapi_cpp_private'])) 69 70 def testIgnoreOtherDirectories(self): 71 ignored_directories = ['api', 'examples', 'generators', 'host', 'lib', 72 'native_client', 'proxy', 'shared_impl', 'tests', 'thunk'] 73 74 # Generate some random files in the ignored directories. 75 filenames = [] 76 for dirname in ignored_directories: 77 filenames = os.path.join('ppapi', dirname, 'foo.cc') 78 filenames = os.path.join('ppapi', dirname, 'subdir', 'foo.h') 79 filenames = os.path.join('ppapi', dirname, 'DEPS') 80 81 result = verify_ppapi.PartitionFiles(filenames) 82 self.assertEqual(0, len(result['ppapi'])) 83 self.assertEqual(0, len(result['ppapi_cpp'])) 84 self.assertEqual(0, len(result['ppapi_cpp_private'])) 85 86 87 class TestGetChangedAndRemoved(unittest.TestCase): 88 def testBasic(self): 89 modified_filenames = [ 90 os.path.join('ppapi', 'cpp', 'audio.cc'), 91 os.path.join('ppapi', 'cpp', 'graphics_2d.cc'), 92 os.path.join('ppapi', 'cpp', 'foobar.cc'), 93 os.path.join('ppapi', 'cpp', 'var.cc'), 94 ] 95 directory_list = [ 96 os.path.join('ppapi', 'cpp', 'audio.cc'), 97 os.path.join('ppapi', 'cpp', 'graphics_2d.cc'), 98 ] 99 changed, removed = verify_ppapi.GetChangedAndRemovedFilenames( 100 modified_filenames, directory_list) 101 self.assertTrue(modified_filenames[0] in changed) 102 self.assertTrue(modified_filenames[1] in changed) 103 self.assertTrue(modified_filenames[2] in removed) 104 self.assertTrue(modified_filenames[3] in removed) 105 106 107 class TestVerify(unittest.TestCase): 108 def testBasic(self): 109 dsc_filename = 'native_client_sdk/src/libraries/ppapi/library.dsc' 110 # The .dsc files typically uses basenames, not full paths. 111 dsc_sources_and_headers = [ 112 'ppb_audio.h', 113 'ppb_console.h', 114 'ppb_gamepad.h', 115 'ppb.h', 116 'ppp_zoom_dev.h', 117 ] 118 changed_filenames = [ 119 os.path.join('ppapi', 'c', 'ppb_audio.h'), 120 os.path.join('ppapi', 'c', 'ppb_console.h'), 121 ] 122 removed_filenames = [] 123 # Should not raise. 124 verify_ppapi.Verify(dsc_filename, dsc_sources_and_headers, 125 changed_filenames, removed_filenames) 126 127 # Raise, because we removed ppp_zoom_dev.h. 128 removed_filenames = [ 129 os.path.join('ppapi', 'c', 'ppb_console.h'), 130 ] 131 self.assertRaises(verify_ppapi.VerifyException, verify_ppapi.Verify, 132 dsc_filename, dsc_sources_and_headers, changed_filenames, 133 removed_filenames) 134 135 # Raise, because we added ppb_foo.h. 136 removed_filenames = [] 137 changed_filenames = [ 138 os.path.join('ppapi', 'c', 'ppb_audio.h'), 139 os.path.join('ppapi', 'c', 'ppb_console.h'), 140 os.path.join('ppapi', 'c', 'ppb_foo.h'), 141 ] 142 self.assertRaises(verify_ppapi.VerifyException, verify_ppapi.Verify, 143 dsc_filename, dsc_sources_and_headers, changed_filenames, 144 removed_filenames) 145 146 def testVerifyPrivate(self): 147 dsc_filename = \ 148 'native_client_sdk/src/libraries/ppapi_cpp_private/library.dsc' 149 # The .dsc files typically uses basenames, not full paths. 150 dsc_sources_and_headers = [ 151 'ext_crx_file_system_private.cc', 152 'file_io_private.cc', 153 'ppb_ext_crx_file_system_private.h', 154 'ppb_file_io_private.h', 155 'host_resolver_private.h', 156 'net_address_private.h', 157 ] 158 changed_filenames = [ 159 os.path.join('ppapi', 'c', 'private', 'ppb_foo_private.h'), 160 ] 161 removed_filenames = [] 162 163 with mock.patch('sys.stderr') as sys_stderr: 164 # When a new private file is added, just print to stderr, but don't fail. 165 result = verify_ppapi.VerifyOrPrintError( 166 dsc_filename, dsc_sources_and_headers, changed_filenames, 167 removed_filenames, is_private=True) 168 self.assertTrue(result) 169 self.assertTrue(sys_stderr.write.called) 170 171 # If is_private is False, then adding a new interface without updating the 172 # .dsc is an error. 173 sys_stderr.reset_mock() 174 result = verify_ppapi.VerifyOrPrintError( 175 dsc_filename, dsc_sources_and_headers, changed_filenames, 176 removed_filenames, is_private=False) 177 self.assertFalse(result) 178 self.assertTrue(sys_stderr.write.called) 179 180 # Removing a file without updating the .dsc is always an error. 181 sys_stderr.reset_mock() 182 changed_filenames = [] 183 removed_filenames = [ 184 os.path.join('ppapi', 'c', 'private', 'net_address_private.h'), 185 ] 186 result = verify_ppapi.VerifyOrPrintError( 187 dsc_filename, dsc_sources_and_headers, changed_filenames, 188 removed_filenames, is_private=True) 189 self.assertFalse(result) 190 self.assertTrue(sys_stderr.write.called) 191 192 193 if __name__ == '__main__': 194 unittest.main() 195