 Chromium Code Reviews
 Chromium Code Reviews Issue 1398883004:
  [NaCl SDK] Fix create_nmf to include arm/glibc ELF loader  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 1398883004:
  [NaCl SDK] Fix create_nmf to include arm/glibc ELF loader  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| OLD | NEW | 
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python | 
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be | 
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. | 
| 5 import json | 5 import json | 
| 6 import os | 6 import os | 
| 7 import posixpath | 7 import posixpath | 
| 8 import shutil | 8 import shutil | 
| 9 import subprocess | 9 import subprocess | 
| 10 import sys | 10 import sys | 
| (...skipping 11 matching lines...) Expand all Loading... | |
| 22 sys.path.append(MOCK_DIR) | 22 sys.path.append(MOCK_DIR) | 
| 23 sys.path.append(TOOLS_DIR) | 23 sys.path.append(TOOLS_DIR) | 
| 24 sys.path.append(BUILD_TOOLS_DIR) | 24 sys.path.append(BUILD_TOOLS_DIR) | 
| 25 | 25 | 
| 26 import build_paths | 26 import build_paths | 
| 27 import create_nmf | 27 import create_nmf | 
| 28 import getos | 28 import getos | 
| 29 from mock import patch, Mock | 29 from mock import patch, Mock | 
| 30 | 30 | 
| 31 TOOLCHAIN_OUT = os.path.join(build_paths.OUT_DIR, 'sdk_tests', 'toolchain') | 31 TOOLCHAIN_OUT = os.path.join(build_paths.OUT_DIR, 'sdk_tests', 'toolchain') | 
| 32 NACL_X86_GLIBC_TOOLCHAIN = os.path.join(TOOLCHAIN_OUT, | 32 X86_GLIBC_TOOLCHAIN = os.path.join(TOOLCHAIN_OUT, | 
| 33 '%s_x86' % getos.GetPlatform(), | 33 '%s_x86' % getos.GetPlatform(), | 
| 34 'nacl_x86_glibc') | 34 'nacl_x86_glibc') | 
| 35 ARM_GLIBC_TOOLCHAIN = os.path.join(TOOLCHAIN_OUT, | |
| 36 '%s_x86' % getos.GetPlatform(), | |
| 37 'nacl_arm_glibc') | |
| 35 | 38 | 
| 36 PosixRelPath = create_nmf.PosixRelPath | 39 PosixRelPath = create_nmf.PosixRelPath | 
| 37 | 40 | 
| 38 | 41 | 
| 39 def StripSo(name): | 42 def StripSo(name): | 
| 40 """Strip trailing hexidecimal characters from the name of a shared object. | 43 """Strip trailing hexidecimal characters from the name of a shared object. | 
| 41 | 44 | 
| 42 It strips everything after the last '.' in the name, and checks that the new | 45 It strips everything after the last '.' in the name, and checks that the new | 
| 43 name ends with .so. | 46 name ends with .so. | 
| 44 | 47 | 
| 45 e.g. | 48 e.g. | 
| 46 | 49 | 
| 47 libc.so.ad6acbfa => libc.so | 50 libc.so.ad6acbfa => libc.so | 
| 48 foo.bar.baz => foo.bar.baz | 51 foo.bar.baz => foo.bar.baz | 
| 49 """ | 52 """ | 
| 50 stripped_name = '.'.join(name.split('.')[:-1]) | 53 if '.' in name: | 
| 51 if stripped_name.endswith('.so'): | 54 stripped_name, ext = name.rsplit('.', 1) | 
| 52 return stripped_name | 55 if stripped_name.endswith('.so') and len(ext) > 1: | 
| 56 return stripped_name | |
| 53 return name | 57 return name | 
| 54 | 58 | 
| 55 | 59 | 
| 56 class TestPosixRelPath(unittest.TestCase): | 60 class TestPosixRelPath(unittest.TestCase): | 
| 57 def testBasic(self): | 61 def testBasic(self): | 
| 58 # Note that PosixRelPath only converts from native path format to posix | 62 # Note that PosixRelPath only converts from native path format to posix | 
| 59 # path format, that's why we have to use os.path.join here. | 63 # path format, that's why we have to use os.path.join here. | 
| 60 path = os.path.join(os.path.sep, 'foo', 'bar', 'baz.blah') | 64 path = os.path.join(os.path.sep, 'foo', 'bar', 'baz.blah') | 
| 61 start = os.path.sep + 'foo' | 65 start = os.path.sep + 'foo' | 
| 62 self.assertEqual(PosixRelPath(path, start), 'bar/baz.blah') | 66 self.assertEqual(PosixRelPath(path, start), 'bar/baz.blah') | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 96 paths = create_nmf.GetDefaultLibPath('Debug') | 100 paths = create_nmf.GetDefaultLibPath('Debug') | 
| 97 self.assertTrue(any(os.path.join('ports', 'lib') in p for p in paths), | 101 self.assertTrue(any(os.path.join('ports', 'lib') in p for p in paths), | 
| 98 'naclports libpath missing: %s' % str(paths)) | 102 'naclports libpath missing: %s' % str(paths)) | 
| 99 | 103 | 
| 100 | 104 | 
| 101 class TestNmfUtils(unittest.TestCase): | 105 class TestNmfUtils(unittest.TestCase): | 
| 102 """Tests for the main NmfUtils class in create_nmf.""" | 106 """Tests for the main NmfUtils class in create_nmf.""" | 
| 103 | 107 | 
| 104 def setUp(self): | 108 def setUp(self): | 
| 105 self.tempdir = None | 109 self.tempdir = None | 
| 106 self.toolchain = NACL_X86_GLIBC_TOOLCHAIN | 110 self.objdump = os.path.join(X86_GLIBC_TOOLCHAIN, 'bin', 'i686-nacl-objdump') | 
| 107 self.objdump = os.path.join(self.toolchain, 'bin', 'i686-nacl-objdump') | |
| 108 if os.name == 'nt': | 111 if os.name == 'nt': | 
| 109 self.objdump += '.exe' | 112 self.objdump += '.exe' | 
| 110 self._Mktemp() | 113 self._Mktemp() | 
| 111 | 114 | 
| 115 # Create dummy elf_loader_arm.nexe by duplicating an existing so. | |
| 116 # This nexe is normally build during SDK build but we want these tests | |
| 117 # to run standalone, and the contents of the ELF are not important for | |
| 118 # these tests. | |
| 119 arm_libdir = os.path.join(ARM_GLIBC_TOOLCHAIN, 'arm-nacl', 'lib') | |
| 120 shutil.copy(os.path.join(arm_libdir, 'ld-nacl-arm.so.1'), | |
| 121 os.path.join(arm_libdir, 'elf_loader_arm.nexe')) | |
| 122 | |
| 123 | |
| 112 def _CreateTestNexe(self, name, arch): | 124 def _CreateTestNexe(self, name, arch): | 
| 113 """Create an empty test .nexe file for use in create_nmf tests. | 125 """Create an empty test .nexe file for use in create_nmf tests. | 
| 114 | 126 | 
| 115 This is used rather than checking in test binaries since the | 127 This is used rather than checking in test binaries since the | 
| 116 checked in binaries depend on .so files that only exist in the | 128 checked in binaries depend on .so files that only exist in the | 
| 117 certain SDK that build them. | 129 certain SDK that build them. | 
| 118 """ | 130 """ | 
| 119 compiler = os.path.join(self.toolchain, 'bin', '%s-nacl-g++' % arch) | 131 if arch == 'arm': | 
| 132 toolchain = ARM_GLIBC_TOOLCHAIN | |
| 133 else: | |
| 134 toolchain = X86_GLIBC_TOOLCHAIN | |
| 135 | |
| 136 compiler = os.path.join(toolchain, 'bin', '%s-nacl-g++' % arch) | |
| 120 if os.name == 'nt': | 137 if os.name == 'nt': | 
| 121 compiler += '.exe' | 138 compiler += '.exe' | 
| 122 os.environ['CYGWIN'] = 'nodosfilewarning' | 139 os.environ['CYGWIN'] = 'nodosfilewarning' | 
| 123 program = 'int main() { return 0; }' | 140 program = 'int main() { return 0; }' | 
| 124 name = os.path.join(self.tempdir, name) | 141 name = os.path.join(self.tempdir, name) | 
| 125 dst_dir = os.path.dirname(name) | 142 dst_dir = os.path.dirname(name) | 
| 126 if not os.path.exists(dst_dir): | 143 if not os.path.exists(dst_dir): | 
| 127 os.makedirs(dst_dir) | 144 os.makedirs(dst_dir) | 
| 128 self.assertTrue(os.path.exists(compiler), 'compiler missing: %s' % compiler) | 145 self.assertTrue(os.path.exists(compiler), 'compiler missing: %s' % compiler) | 
| 129 cmd = [compiler, '-pthread', '-x' , 'c', '-o', name, '-'] | 146 cmd = [compiler, '-pthread', '-x' , 'c', '-o', name, '-'] | 
| 130 p = subprocess.Popen(cmd, stdin=subprocess.PIPE) | 147 p = subprocess.Popen(cmd, stdin=subprocess.PIPE) | 
| 131 p.communicate(input=program) | 148 p.communicate(input=program) | 
| 132 self.assertEqual(p.returncode, 0) | 149 self.assertEqual(p.returncode, 0) | 
| 133 return name | 150 return name | 
| 134 | 151 | 
| 135 def tearDown(self): | 152 def tearDown(self): | 
| 136 if self.tempdir: | 153 if self.tempdir: | 
| 137 shutil.rmtree(self.tempdir) | 154 shutil.rmtree(self.tempdir) | 
| 138 | 155 | 
| 139 def _Mktemp(self): | 156 def _Mktemp(self): | 
| 140 self.tempdir = tempfile.mkdtemp() | 157 self.tempdir = tempfile.mkdtemp() | 
| 141 | 158 | 
| 142 def _CreateNmfUtils(self, nexes, **kwargs): | 159 def _CreateNmfUtils(self, nexes, **kwargs): | 
| 143 if not kwargs.get('lib_path'): | 160 if not kwargs.get('lib_path'): | 
| 144 # Use lib instead of lib64 (lib64 is a symlink to lib). | |
| 145 kwargs['lib_path'] = [ | 161 kwargs['lib_path'] = [ | 
| 146 os.path.join(self.toolchain, 'x86_64-nacl', 'lib'), | 162 # Use lib instead of lib64 (lib64 is a symlink to lib). | 
| 147 os.path.join(self.toolchain, 'x86_64-nacl', 'lib32')] | 163 os.path.join(X86_GLIBC_TOOLCHAIN, 'x86_64-nacl', 'lib'), | 
| 164 os.path.join(X86_GLIBC_TOOLCHAIN, 'x86_64-nacl', 'lib32'), | |
| 165 os.path.join(ARM_GLIBC_TOOLCHAIN, 'arm-nacl', 'lib')] | |
| 148 return create_nmf.NmfUtils(nexes, | 166 return create_nmf.NmfUtils(nexes, | 
| 149 objdump=self.objdump, | 167 objdump=self.objdump, | 
| 150 **kwargs) | 168 **kwargs) | 
| 151 | 169 | 
| 152 def _CreateStatic(self, arch_path=None, **kwargs): | 170 def _CreateStatic(self, arch_path=None, **kwargs): | 
| 153 """Copy all static .nexe files from the DATA_DIR to a temporary directory. | 171 """Copy all static .nexe files from the DATA_DIR to a temporary directory. | 
| 154 | 172 | 
| 155 Args: | 173 Args: | 
| 156 arch_path: A dictionary mapping architecture to the directory to generate | 174 arch_path: A dictionary mapping architecture to the directory to generate | 
| 157 the .nexe for the architecture in. | 175 the .nexe for the architecture in. | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 190 kwargs: Keyword arguments to pass through to create_nmf.NmfUtils | 208 kwargs: Keyword arguments to pass through to create_nmf.NmfUtils | 
| 191 constructor. | 209 constructor. | 
| 192 | 210 | 
| 193 Returns: | 211 Returns: | 
| 194 A tuple with 2 elements: | 212 A tuple with 2 elements: | 
| 195 * The generated NMF as a dictionary (i.e. parsed by json.loads) | 213 * The generated NMF as a dictionary (i.e. parsed by json.loads) | 
| 196 * A list of the generated .nexe paths | 214 * A list of the generated .nexe paths | 
| 197 """ | 215 """ | 
| 198 arch_path = arch_path or {} | 216 arch_path = arch_path or {} | 
| 199 nexes = [] | 217 nexes = [] | 
| 200 for arch in ('x86_64', 'x86_32'): | 218 for arch in ('x86_64', 'x86_32', 'arm'): | 
| 201 nexe_name = 'test_dynamic_%s.nexe' % arch | 219 nexe_name = 'test_dynamic_%s.nexe' % arch | 
| 202 rel_nexe = os.path.join(arch_path.get(arch, ''), nexe_name) | 220 rel_nexe = os.path.join(arch_path.get(arch, ''), nexe_name) | 
| 203 arch_alt = 'i686' if arch == 'x86_32' else arch | 221 arch_alt = 'i686' if arch == 'x86_32' else arch | 
| 204 nexe = self._CreateTestNexe(rel_nexe, arch_alt) | 222 nexe = self._CreateTestNexe(rel_nexe, arch_alt) | 
| 205 nexes.append(nexe) | 223 nexes.append(nexe) | 
| 206 | 224 | 
| 207 nexes.sort() | 225 nexes.sort() | 
| 208 nmf_utils = self._CreateNmfUtils(nexes, **kwargs) | 226 nmf_utils = self._CreateNmfUtils(nexes, **kwargs) | 
| 209 nmf = json.loads(nmf_utils.GetJson()) | 227 nmf = json.loads(nmf_utils.GetJson()) | 
| 210 nmf_utils.StageDependencies(self.tempdir) | 228 nmf_utils.StageDependencies(self.tempdir) | 
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 278 new_v = v[:] | 296 new_v = v[:] | 
| 279 elif type(v) is dict: | 297 elif type(v) is dict: | 
| 280 new_v = StripSoCopyDict(v) | 298 new_v = StripSoCopyDict(v) | 
| 281 else: | 299 else: | 
| 282 # Assume that anything else can be copied directly. | 300 # Assume that anything else can be copied directly. | 
| 283 new_v = v | 301 new_v = v | 
| 284 | 302 | 
| 285 new_d[new_k] = new_v | 303 new_d[new_k] = new_v | 
| 286 return new_d | 304 return new_d | 
| 287 | 305 | 
| 288 self.assertEqual(StripSoCopyDict(manifest), expected) | 306 strip_manifest = StripSoCopyDict(manifest) | 
| 307 self.assertEqual(strip_manifest['program'], expected['program']) | |
| 
binji
2015/10/15 17:06:07
why separate this out?
 
Sam Clegg
2015/10/15 17:27:23
It makes debugging the failures a lot easier.  The
 | |
| 308 if 'files' in strip_manifest: | |
| 309 for key in strip_manifest['files']: | |
| 310 self.assertEqual(strip_manifest['files'][key], expected['files'][key]) | |
| 311 | |
| 312 self.assertEqual(strip_manifest, expected) | |
| 289 | 313 | 
| 290 def assertStagingEquals(self, expected): | 314 def assertStagingEquals(self, expected): | 
| 291 """Compare the contents of the temporary directory, to an expected | 315 """Compare the contents of the temporary directory, to an expected | 
| 292 directory layout. | 316 directory layout. | 
| 293 | 317 | 
| 294 Args: | 318 Args: | 
| 295 expected: The expected directory layout. | 319 expected: The expected directory layout. | 
| 296 """ | 320 """ | 
| 297 all_files = [] | 321 all_files = [] | 
| 298 for root, _, files in os.walk(self.tempdir): | 322 for root, _, files in os.walk(self.tempdir): | 
| 299 rel_root_posix = PosixRelPath(root, self.tempdir) | 323 rel_root_posix = PosixRelPath(root, self.tempdir) | 
| 300 for f in files: | 324 for f in files: | 
| 301 path = posixpath.join(rel_root_posix, StripSo(f)) | 325 path = posixpath.join(rel_root_posix, StripSo(f)) | 
| 302 if path.startswith('./'): | 326 if path.startswith('./'): | 
| 303 path = path[2:] | 327 path = path[2:] | 
| 304 all_files.append(path) | 328 all_files.append(path) | 
| 305 self.assertEqual(set(expected), set(all_files)) | 329 self.assertEqual(set(expected), set(all_files)) | 
| 306 | 330 | 
| 331 arch_dir = {'x86_32': 'x86_32', 'x86_64': 'x86_64', 'arm': 'arm'} | |
| 307 | 332 | 
| 308 def testStatic(self): | 333 def testStatic(self): | 
| 309 nmf, _ = self._CreateStatic() | 334 nmf, _ = self._CreateStatic() | 
| 310 expected_manifest = { | 335 expected_manifest = { | 
| 311 'files': {}, | 336 'files': {}, | 
| 312 'program': { | 337 'program': { | 
| 313 'x86-64': {'url': 'test_static_x86_64.nexe'}, | 338 'x86-64': {'url': 'test_static_x86_64.nexe'}, | 
| 314 'x86-32': {'url': 'test_static_x86_32.nexe'}, | 339 'x86-32': {'url': 'test_static_x86_32.nexe'}, | 
| 315 'arm': {'url': 'test_static_arm.nexe'}, | 340 'arm': {'url': 'test_static_arm.nexe'}, | 
| 316 } | 341 } | 
| 317 } | 342 } | 
| 318 self.assertManifestEquals(nmf, expected_manifest) | 343 self.assertManifestEquals(nmf, expected_manifest) | 
| 319 | 344 | 
| 320 def testStaticWithPath(self): | 345 def testStaticWithPath(self): | 
| 321 arch_dir = {'x86_32': 'x86_32', 'x86_64': 'x86_64', 'arm': 'arm'} | 346 nmf, _ = self._CreateStatic(self.arch_dir, nmf_root=self.tempdir) | 
| 322 nmf, _ = self._CreateStatic(arch_dir, nmf_root=self.tempdir) | |
| 323 expected_manifest = { | 347 expected_manifest = { | 
| 324 'files': {}, | 348 'files': {}, | 
| 325 'program': { | 349 'program': { | 
| 326 'x86-32': {'url': 'x86_32/test_static_x86_32.nexe'}, | 350 'x86-32': {'url': 'x86_32/test_static_x86_32.nexe'}, | 
| 327 'x86-64': {'url': 'x86_64/test_static_x86_64.nexe'}, | 351 'x86-64': {'url': 'x86_64/test_static_x86_64.nexe'}, | 
| 328 'arm': {'url': 'arm/test_static_arm.nexe'}, | 352 'arm': {'url': 'arm/test_static_arm.nexe'}, | 
| 329 } | 353 } | 
| 330 } | 354 } | 
| 331 self.assertManifestEquals(nmf, expected_manifest) | 355 self.assertManifestEquals(nmf, expected_manifest) | 
| 332 | 356 | 
| 333 def testStaticWithPathNoNmfRoot(self): | 357 def testStaticWithPathNoNmfRoot(self): | 
| 334 # This case is not particularly useful, but it is similar to how create_nmf | 358 # This case is not particularly useful, but it is similar to how create_nmf | 
| 335 # used to work. If there is no nmf_root given, all paths are relative to | 359 # used to work. If there is no nmf_root given, all paths are relative to | 
| 336 # the first nexe passed on the commandline. I believe the assumption | 360 # the first nexe passed on the commandline. I believe the assumption | 
| 337 # previously was that all .nexes would be in the same directory. | 361 # previously was that all .nexes would be in the same directory. | 
| 338 arch_dir = {'x86_32': 'x86_32', 'x86_64': 'x86_64', 'arm': 'arm'} | 362 nmf, _ = self._CreateStatic(self.arch_dir) | 
| 339 nmf, _ = self._CreateStatic(arch_dir) | |
| 340 expected_manifest = { | 363 expected_manifest = { | 
| 341 'files': {}, | 364 'files': {}, | 
| 342 'program': { | 365 'program': { | 
| 343 'x86-32': {'url': '../x86_32/test_static_x86_32.nexe'}, | 366 'x86-32': {'url': '../x86_32/test_static_x86_32.nexe'}, | 
| 344 'x86-64': {'url': '../x86_64/test_static_x86_64.nexe'}, | 367 'x86-64': {'url': '../x86_64/test_static_x86_64.nexe'}, | 
| 345 'arm': {'url': 'test_static_arm.nexe'}, | 368 'arm': {'url': 'test_static_arm.nexe'}, | 
| 346 } | 369 } | 
| 347 } | 370 } | 
| 348 self.assertManifestEquals(nmf, expected_manifest) | 371 self.assertManifestEquals(nmf, expected_manifest) | 
| 349 | 372 | 
| 350 def testStaticWithNexePrefix(self): | 373 def testStaticWithNexePrefix(self): | 
| 351 nmf, _ = self._CreateStatic(nexe_prefix='foo') | 374 nmf, _ = self._CreateStatic(nexe_prefix='foo') | 
| 352 expected_manifest = { | 375 expected_manifest = { | 
| 353 'files': {}, | 376 'files': {}, | 
| 354 'program': { | 377 'program': { | 
| 355 'x86-64': {'url': 'foo/test_static_x86_64.nexe'}, | 378 'x86-64': {'url': 'foo/test_static_x86_64.nexe'}, | 
| 356 'x86-32': {'url': 'foo/test_static_x86_32.nexe'}, | 379 'x86-32': {'url': 'foo/test_static_x86_32.nexe'}, | 
| 357 'arm': {'url': 'foo/test_static_arm.nexe'}, | 380 'arm': {'url': 'foo/test_static_arm.nexe'}, | 
| 358 } | 381 } | 
| 359 } | 382 } | 
| 360 self.assertManifestEquals(nmf, expected_manifest) | 383 self.assertManifestEquals(nmf, expected_manifest) | 
| 361 | 384 | 
| 362 def testDynamic(self): | 385 def testDynamic(self): | 
| 363 nmf, nexes = self._CreateDynamicAndStageDeps() | 386 nmf, nexes = self._CreateDynamicAndStageDeps() | 
| 364 expected_manifest = { | 387 expected_manifest = { | 
| 365 'files': { | 388 'files': { | 
| 366 'main.nexe': { | 389 'main.nexe': { | 
| 367 'x86-32': {'url': 'test_dynamic_x86_32.nexe'}, | 390 'x86-32': {'url': 'test_dynamic_x86_32.nexe'}, | 
| 368 'x86-64': {'url': 'test_dynamic_x86_64.nexe'}, | 391 'x86-64': {'url': 'test_dynamic_x86_64.nexe'}, | 
| 392 'arm': {'url': 'test_dynamic_arm.nexe'}, | |
| 393 }, | |
| 394 'ld-nacl-arm.so.1': { | |
| 395 'arm': {'url': 'libarm/ld-nacl-arm.so.1'}, | |
| 396 }, | |
| 397 'libc.so.0.1': { | |
| 398 'arm': {'url': 'libarm/libc.so.0.1'} | |
| 369 }, | 399 }, | 
| 370 'libc.so': { | 400 'libc.so': { | 
| 371 'x86-32': {'url': 'lib32/libc.so'}, | 401 'x86-32': {'url': 'lib32/libc.so'}, | 
| 372 'x86-64': {'url': 'lib64/libc.so'}, | 402 'x86-64': {'url': 'lib64/libc.so'}, | 
| 373 }, | 403 }, | 
| 374 'libgcc_s.so': { | 404 'libgcc_s.so.1': { | 
| 375 'x86-32': {'url': 'lib32/libgcc_s.so'}, | 405 'arm': {'url': 'libarm/libgcc_s.so.1'}, | 
| 376 'x86-64': {'url': 'lib64/libgcc_s.so'}, | 406 'x86-32': {'url': 'lib32/libgcc_s.so.1'}, | 
| 407 'x86-64': {'url': 'lib64/libgcc_s.so.1'}, | |
| 408 }, | |
| 409 'libpthread.so.0': { | |
| 410 'arm': { 'url': 'libarm/libpthread.so.0'} | |
| 377 }, | 411 }, | 
| 378 'libpthread.so': { | 412 'libpthread.so': { | 
| 379 'x86-32': {'url': 'lib32/libpthread.so'}, | 413 'x86-32': {'url': 'lib32/libpthread.so'}, | 
| 380 'x86-64': {'url': 'lib64/libpthread.so'}, | 414 'x86-64': {'url': 'lib64/libpthread.so'}, | 
| 381 }, | 415 }, | 
| 382 }, | 416 }, | 
| 383 'program': { | 417 'program': { | 
| 418 'arm': {'url': 'libarm/elf_loader_arm.nexe'}, | |
| 384 'x86-32': {'url': 'lib32/runnable-ld.so'}, | 419 'x86-32': {'url': 'lib32/runnable-ld.so'}, | 
| 385 'x86-64': {'url': 'lib64/runnable-ld.so'}, | 420 'x86-64': {'url': 'lib64/runnable-ld.so'}, | 
| 386 } | 421 } | 
| 387 } | 422 } | 
| 388 | 423 | 
| 389 expected_staging = [os.path.basename(f) for f in nexes] | 424 expected_staging = [os.path.basename(f) for f in nexes] | 
| 390 expected_staging.extend([ | 425 expected_staging.extend([ | 
| 391 'lib32/libc.so', | 426 'lib32/libc.so', | 
| 392 'lib32/libgcc_s.so', | 427 'lib32/libgcc_s.so.1', | 
| 393 'lib32/libpthread.so', | 428 'lib32/libpthread.so', | 
| 394 'lib32/runnable-ld.so', | 429 'lib32/runnable-ld.so', | 
| 395 'lib64/libc.so', | 430 'lib64/libc.so', | 
| 396 'lib64/libgcc_s.so', | 431 'lib64/libgcc_s.so.1', | 
| 397 'lib64/libpthread.so', | 432 'lib64/libpthread.so', | 
| 398 'lib64/runnable-ld.so']) | 433 'lib64/runnable-ld.so', | 
| 434 'libarm/elf_loader_arm.nexe', | |
| 435 'libarm/libpthread.so.0', | |
| 436 'libarm/ld-nacl-arm.so.1', | |
| 437 'libarm/libgcc_s.so.1', | |
| 438 'libarm/libc.so.0.1' | |
| 439 ]) | |
| 399 | 440 | 
| 400 self.assertManifestEquals(nmf, expected_manifest) | 441 self.assertManifestEquals(nmf, expected_manifest) | 
| 401 self.assertStagingEquals(expected_staging) | 442 self.assertStagingEquals(expected_staging) | 
| 402 | 443 | 
| 403 def testDynamicWithPath(self): | 444 def testDynamicWithPath(self): | 
| 404 arch_dir = {'x86_64': 'x86_64', 'x86_32': 'x86_32'} | 445 nmf, nexes = self._CreateDynamicAndStageDeps(self.arch_dir, | 
| 405 nmf, nexes = self._CreateDynamicAndStageDeps(arch_dir, | |
| 406 nmf_root=self.tempdir) | 446 nmf_root=self.tempdir) | 
| 407 expected_manifest = { | 447 expected_manifest = { | 
| 408 'files': { | 448 'files': { | 
| 409 'main.nexe': { | 449 'main.nexe': { | 
| 450 'arm': {'url': 'arm/test_dynamic_arm.nexe'}, | |
| 410 'x86-32': {'url': 'x86_32/test_dynamic_x86_32.nexe'}, | 451 'x86-32': {'url': 'x86_32/test_dynamic_x86_32.nexe'}, | 
| 411 'x86-64': {'url': 'x86_64/test_dynamic_x86_64.nexe'}, | 452 'x86-64': {'url': 'x86_64/test_dynamic_x86_64.nexe'}, | 
| 412 }, | 453 }, | 
| 454 'libc.so.0.1': { | |
| 455 'arm': {'url': 'arm/libarm/libc.so.0.1'} | |
| 456 }, | |
| 457 'ld-nacl-arm.so.1': { | |
| 458 'arm': {'url': 'arm/libarm/ld-nacl-arm.so.1'}, | |
| 459 }, | |
| 413 'libc.so': { | 460 'libc.so': { | 
| 414 'x86-32': {'url': 'x86_32/lib32/libc.so'}, | 461 'x86-32': {'url': 'x86_32/lib32/libc.so'}, | 
| 415 'x86-64': {'url': 'x86_64/lib64/libc.so'}, | 462 'x86-64': {'url': 'x86_64/lib64/libc.so'}, | 
| 416 }, | 463 }, | 
| 417 'libgcc_s.so': { | 464 'libgcc_s.so.1': { | 
| 418 'x86-32': {'url': 'x86_32/lib32/libgcc_s.so'}, | 465 'arm': {'url': 'arm/libarm/libgcc_s.so.1'}, | 
| 419 'x86-64': {'url': 'x86_64/lib64/libgcc_s.so'}, | 466 'x86-32': {'url': 'x86_32/lib32/libgcc_s.so.1'}, | 
| 467 'x86-64': {'url': 'x86_64/lib64/libgcc_s.so.1'}, | |
| 468 }, | |
| 469 'libpthread.so.0': { | |
| 470 'arm': { 'url': 'arm/libarm/libpthread.so.0'} | |
| 420 }, | 471 }, | 
| 421 'libpthread.so': { | 472 'libpthread.so': { | 
| 422 'x86-32': {'url': 'x86_32/lib32/libpthread.so'}, | 473 'x86-32': {'url': 'x86_32/lib32/libpthread.so'}, | 
| 423 'x86-64': {'url': 'x86_64/lib64/libpthread.so'}, | 474 'x86-64': {'url': 'x86_64/lib64/libpthread.so'}, | 
| 424 }, | 475 }, | 
| 425 }, | 476 }, | 
| 426 'program': { | 477 'program': { | 
| 478 'arm': {'url': 'arm/libarm/elf_loader_arm.nexe'}, | |
| 427 'x86-32': {'url': 'x86_32/lib32/runnable-ld.so'}, | 479 'x86-32': {'url': 'x86_32/lib32/runnable-ld.so'}, | 
| 428 'x86-64': {'url': 'x86_64/lib64/runnable-ld.so'}, | 480 'x86-64': {'url': 'x86_64/lib64/runnable-ld.so'}, | 
| 429 } | 481 } | 
| 430 } | 482 } | 
| 431 | 483 | 
| 432 expected_staging = [PosixRelPath(f, self.tempdir) for f in nexes] | 484 expected_staging = [PosixRelPath(f, self.tempdir) for f in nexes] | 
| 433 expected_staging.extend([ | 485 expected_staging.extend([ | 
| 434 'x86_32/lib32/libc.so', | 486 'x86_32/lib32/libc.so', | 
| 435 'x86_32/lib32/libgcc_s.so', | 487 'x86_32/lib32/libgcc_s.so.1', | 
| 436 'x86_32/lib32/libpthread.so', | 488 'x86_32/lib32/libpthread.so', | 
| 437 'x86_32/lib32/runnable-ld.so', | 489 'x86_32/lib32/runnable-ld.so', | 
| 438 'x86_64/lib64/libc.so', | 490 'x86_64/lib64/libc.so', | 
| 439 'x86_64/lib64/libgcc_s.so', | 491 'x86_64/lib64/libgcc_s.so.1', | 
| 440 'x86_64/lib64/libpthread.so', | 492 'x86_64/lib64/libpthread.so', | 
| 441 'x86_64/lib64/runnable-ld.so']) | 493 'x86_64/lib64/runnable-ld.so', | 
| 494 'arm/libarm/elf_loader_arm.nexe', | |
| 495 'arm/libarm/libpthread.so.0', | |
| 496 'arm/libarm/ld-nacl-arm.so.1', | |
| 497 'arm/libarm/libgcc_s.so.1', | |
| 498 'arm/libarm/libc.so.0.1' | |
| 499 ]) | |
| 442 | 500 | 
| 443 self.assertManifestEquals(nmf, expected_manifest) | 501 self.assertManifestEquals(nmf, expected_manifest) | 
| 444 self.assertStagingEquals(expected_staging) | 502 self.assertStagingEquals(expected_staging) | 
| 445 | 503 | 
| 446 def testDynamicWithRelPath(self): | 504 def testDynamicWithRelPath(self): | 
| 447 """Test that when the nmf root is a relative path that things work.""" | 505 """Test that when the nmf root is a relative path that things work.""" | 
| 448 arch_dir = {'x86_64': 'x86_64', 'x86_32': 'x86_32'} | |
| 449 old_path = os.getcwd() | 506 old_path = os.getcwd() | 
| 450 try: | 507 try: | 
| 451 os.chdir(self.tempdir) | 508 os.chdir(self.tempdir) | 
| 452 nmf, nexes = self._CreateDynamicAndStageDeps(arch_dir, nmf_root='') | 509 nmf, nexes = self._CreateDynamicAndStageDeps(self.arch_dir, nmf_root='') | 
| 453 expected_manifest = { | 510 expected_manifest = { | 
| 454 'files': { | 511 'files': { | 
| 455 'main.nexe': { | 512 'main.nexe': { | 
| 513 'arm': {'url': 'arm/test_dynamic_arm.nexe'}, | |
| 456 'x86-32': {'url': 'x86_32/test_dynamic_x86_32.nexe'}, | 514 'x86-32': {'url': 'x86_32/test_dynamic_x86_32.nexe'}, | 
| 457 'x86-64': {'url': 'x86_64/test_dynamic_x86_64.nexe'}, | 515 'x86-64': {'url': 'x86_64/test_dynamic_x86_64.nexe'}, | 
| 458 }, | 516 }, | 
| 517 'ld-nacl-arm.so.1': { | |
| 518 'arm': {'url': 'arm/libarm/ld-nacl-arm.so.1'}, | |
| 519 }, | |
| 520 'libc.so.0.1': { | |
| 521 'arm': {'url': 'arm/libarm/libc.so.0.1'} | |
| 522 }, | |
| 459 'libc.so': { | 523 'libc.so': { | 
| 460 'x86-32': {'url': 'x86_32/lib32/libc.so'}, | 524 'x86-32': {'url': 'x86_32/lib32/libc.so'}, | 
| 461 'x86-64': {'url': 'x86_64/lib64/libc.so'}, | 525 'x86-64': {'url': 'x86_64/lib64/libc.so'}, | 
| 462 }, | 526 }, | 
| 463 'libgcc_s.so': { | 527 'libgcc_s.so.1': { | 
| 464 'x86-32': {'url': 'x86_32/lib32/libgcc_s.so'}, | 528 'arm': {'url': 'arm/libarm/libgcc_s.so.1'}, | 
| 465 'x86-64': {'url': 'x86_64/lib64/libgcc_s.so'}, | 529 'x86-32': {'url': 'x86_32/lib32/libgcc_s.so.1'}, | 
| 530 'x86-64': {'url': 'x86_64/lib64/libgcc_s.so.1'}, | |
| 531 }, | |
| 532 'libpthread.so.0': { | |
| 533 'arm': { 'url': 'arm/libarm/libpthread.so.0'} | |
| 466 }, | 534 }, | 
| 467 'libpthread.so': { | 535 'libpthread.so': { | 
| 468 'x86-32': {'url': 'x86_32/lib32/libpthread.so'}, | 536 'x86-32': {'url': 'x86_32/lib32/libpthread.so'}, | 
| 469 'x86-64': {'url': 'x86_64/lib64/libpthread.so'}, | 537 'x86-64': {'url': 'x86_64/lib64/libpthread.so'}, | 
| 470 }, | 538 }, | 
| 471 }, | 539 }, | 
| 472 'program': { | 540 'program': { | 
| 541 'arm': {'url': 'arm/libarm/elf_loader_arm.nexe'}, | |
| 473 'x86-32': {'url': 'x86_32/lib32/runnable-ld.so'}, | 542 'x86-32': {'url': 'x86_32/lib32/runnable-ld.so'}, | 
| 474 'x86-64': {'url': 'x86_64/lib64/runnable-ld.so'}, | 543 'x86-64': {'url': 'x86_64/lib64/runnable-ld.so'}, | 
| 475 } | 544 } | 
| 476 } | 545 } | 
| 477 | 546 | 
| 478 expected_staging = [PosixRelPath(f, self.tempdir) for f in nexes] | 547 expected_staging = [PosixRelPath(f, self.tempdir) for f in nexes] | 
| 479 expected_staging.extend([ | 548 expected_staging.extend([ | 
| 480 'x86_32/lib32/libc.so', | 549 'x86_32/lib32/libc.so', | 
| 481 'x86_32/lib32/libgcc_s.so', | 550 'x86_32/lib32/libgcc_s.so.1', | 
| 482 'x86_32/lib32/libpthread.so', | 551 'x86_32/lib32/libpthread.so', | 
| 483 'x86_32/lib32/runnable-ld.so', | 552 'x86_32/lib32/runnable-ld.so', | 
| 484 'x86_64/lib64/libc.so', | 553 'x86_64/lib64/libc.so', | 
| 485 'x86_64/lib64/libgcc_s.so', | 554 'x86_64/lib64/libgcc_s.so.1', | 
| 486 'x86_64/lib64/libpthread.so', | 555 'x86_64/lib64/libpthread.so', | 
| 487 'x86_64/lib64/runnable-ld.so']) | 556 'x86_64/lib64/runnable-ld.so', | 
| 557 'arm/libarm/elf_loader_arm.nexe', | |
| 558 'arm/libarm/libpthread.so.0', | |
| 559 'arm/libarm/ld-nacl-arm.so.1', | |
| 560 'arm/libarm/libgcc_s.so.1', | |
| 561 'arm/libarm/libc.so.0.1' | |
| 562 ]) | |
| 488 | 563 | 
| 489 self.assertManifestEquals(nmf, expected_manifest) | 564 self.assertManifestEquals(nmf, expected_manifest) | 
| 490 self.assertStagingEquals(expected_staging) | 565 self.assertStagingEquals(expected_staging) | 
| 491 finally: | 566 finally: | 
| 492 os.chdir(old_path) | 567 os.chdir(old_path) | 
| 493 | 568 | 
| 494 def testDynamicWithPathNoArchPrefix(self): | 569 def testDynamicWithPathNoArchPrefix(self): | 
| 495 arch_dir = {'x86_64': 'x86_64', 'x86_32': 'x86_32'} | 570 nmf, nexes = self._CreateDynamicAndStageDeps(self.arch_dir, | 
| 496 nmf, nexes = self._CreateDynamicAndStageDeps(arch_dir, | |
| 497 nmf_root=self.tempdir, | 571 nmf_root=self.tempdir, | 
| 498 no_arch_prefix=True) | 572 no_arch_prefix=True) | 
| 499 expected_manifest = { | 573 expected_manifest = { | 
| 500 'files': { | 574 'files': { | 
| 501 'main.nexe': { | 575 'main.nexe': { | 
| 576 'arm': {'url': 'arm/test_dynamic_arm.nexe'}, | |
| 502 'x86-32': {'url': 'x86_32/test_dynamic_x86_32.nexe'}, | 577 'x86-32': {'url': 'x86_32/test_dynamic_x86_32.nexe'}, | 
| 503 'x86-64': {'url': 'x86_64/test_dynamic_x86_64.nexe'}, | 578 'x86-64': {'url': 'x86_64/test_dynamic_x86_64.nexe'}, | 
| 504 }, | 579 }, | 
| 580 'ld-nacl-arm.so.1': { | |
| 581 'arm': {'url': 'arm/ld-nacl-arm.so.1'}, | |
| 582 }, | |
| 583 'libc.so.0.1': { | |
| 584 'arm': {'url': 'arm/libc.so.0.1'} | |
| 585 }, | |
| 505 'libc.so': { | 586 'libc.so': { | 
| 506 'x86-32': {'url': 'x86_32/libc.so'}, | 587 'x86-32': {'url': 'x86_32/libc.so'}, | 
| 507 'x86-64': {'url': 'x86_64/libc.so'}, | 588 'x86-64': {'url': 'x86_64/libc.so'}, | 
| 508 }, | 589 }, | 
| 509 'libgcc_s.so': { | 590 'libgcc_s.so.1': { | 
| 510 'x86-32': {'url': 'x86_32/libgcc_s.so'}, | 591 'arm': {'url': 'arm/libgcc_s.so.1'}, | 
| 511 'x86-64': {'url': 'x86_64/libgcc_s.so'}, | 592 'x86-32': {'url': 'x86_32/libgcc_s.so.1'}, | 
| 593 'x86-64': {'url': 'x86_64/libgcc_s.so.1'}, | |
| 594 }, | |
| 595 'libpthread.so.0': { | |
| 596 'arm': { 'url': 'arm/libpthread.so.0'} | |
| 512 }, | 597 }, | 
| 513 'libpthread.so': { | 598 'libpthread.so': { | 
| 514 'x86-32': {'url': 'x86_32/libpthread.so'}, | 599 'x86-32': {'url': 'x86_32/libpthread.so'}, | 
| 515 'x86-64': {'url': 'x86_64/libpthread.so'}, | 600 'x86-64': {'url': 'x86_64/libpthread.so'}, | 
| 516 }, | 601 }, | 
| 517 }, | 602 }, | 
| 518 'program': { | 603 'program': { | 
| 604 'arm': {'url': 'arm/elf_loader_arm.nexe'}, | |
| 519 'x86-32': {'url': 'x86_32/runnable-ld.so'}, | 605 'x86-32': {'url': 'x86_32/runnable-ld.so'}, | 
| 520 'x86-64': {'url': 'x86_64/runnable-ld.so'}, | 606 'x86-64': {'url': 'x86_64/runnable-ld.so'}, | 
| 521 } | 607 } | 
| 522 } | 608 } | 
| 523 | 609 | 
| 524 expected_staging = [PosixRelPath(f, self.tempdir) for f in nexes] | 610 expected_staging = [PosixRelPath(f, self.tempdir) for f in nexes] | 
| 525 expected_staging.extend([ | 611 expected_staging.extend([ | 
| 526 'x86_32/libc.so', | 612 'x86_32/libc.so', | 
| 527 'x86_32/libgcc_s.so', | 613 'x86_32/libgcc_s.so.1', | 
| 528 'x86_32/libpthread.so', | 614 'x86_32/libpthread.so', | 
| 529 'x86_32/runnable-ld.so', | 615 'x86_32/runnable-ld.so', | 
| 530 'x86_64/libc.so', | 616 'x86_64/libc.so', | 
| 531 'x86_64/libgcc_s.so', | 617 'x86_64/libgcc_s.so.1', | 
| 532 'x86_64/libpthread.so', | 618 'x86_64/libpthread.so', | 
| 533 'x86_64/runnable-ld.so']) | 619 'x86_64/runnable-ld.so', | 
| 620 'arm/elf_loader_arm.nexe', | |
| 621 'arm/libpthread.so.0', | |
| 622 'arm/ld-nacl-arm.so.1', | |
| 623 'arm/libgcc_s.so.1', | |
| 624 'arm/libc.so.0.1' | |
| 625 ]) | |
| 534 | 626 | 
| 535 self.assertManifestEquals(nmf, expected_manifest) | 627 self.assertManifestEquals(nmf, expected_manifest) | 
| 536 self.assertStagingEquals(expected_staging) | 628 self.assertStagingEquals(expected_staging) | 
| 537 | 629 | 
| 538 def testDynamicWithLibPrefix(self): | 630 def testDynamicWithLibPrefix(self): | 
| 539 nmf, nexes = self._CreateDynamicAndStageDeps(lib_prefix='foo') | 631 nmf, nexes = self._CreateDynamicAndStageDeps(lib_prefix='foo') | 
| 540 expected_manifest = { | 632 expected_manifest = { | 
| 541 'files': { | 633 'files': { | 
| 542 'main.nexe': { | 634 'main.nexe': { | 
| 635 'arm': {'url': 'test_dynamic_arm.nexe'}, | |
| 543 'x86-32': {'url': 'test_dynamic_x86_32.nexe'}, | 636 'x86-32': {'url': 'test_dynamic_x86_32.nexe'}, | 
| 544 'x86-64': {'url': 'test_dynamic_x86_64.nexe'}, | 637 'x86-64': {'url': 'test_dynamic_x86_64.nexe'}, | 
| 545 }, | 638 }, | 
| 639 'ld-nacl-arm.so.1': { | |
| 640 'arm': {'url': 'foo/libarm/ld-nacl-arm.so.1'}, | |
| 641 }, | |
| 642 'libc.so.0.1': { | |
| 643 'arm': {'url': 'foo/libarm/libc.so.0.1'} | |
| 644 }, | |
| 546 'libc.so': { | 645 'libc.so': { | 
| 547 'x86-32': {'url': 'foo/lib32/libc.so'}, | 646 'x86-32': {'url': 'foo/lib32/libc.so'}, | 
| 548 'x86-64': {'url': 'foo/lib64/libc.so'}, | 647 'x86-64': {'url': 'foo/lib64/libc.so'}, | 
| 549 }, | 648 }, | 
| 550 'libgcc_s.so': { | 649 'libgcc_s.so.1': { | 
| 551 'x86-32': {'url': 'foo/lib32/libgcc_s.so'}, | 650 'arm': {'url': 'foo/libarm/libgcc_s.so.1'}, | 
| 552 'x86-64': {'url': 'foo/lib64/libgcc_s.so'}, | 651 'x86-32': {'url': 'foo/lib32/libgcc_s.so.1'}, | 
| 652 'x86-64': {'url': 'foo/lib64/libgcc_s.so.1'}, | |
| 653 }, | |
| 654 'libpthread.so.0': { | |
| 655 'arm': { 'url': 'foo/libarm/libpthread.so.0'} | |
| 553 }, | 656 }, | 
| 554 'libpthread.so': { | 657 'libpthread.so': { | 
| 555 'x86-32': {'url': 'foo/lib32/libpthread.so'}, | 658 'x86-32': {'url': 'foo/lib32/libpthread.so'}, | 
| 556 'x86-64': {'url': 'foo/lib64/libpthread.so'}, | 659 'x86-64': {'url': 'foo/lib64/libpthread.so'}, | 
| 557 }, | 660 }, | 
| 558 }, | 661 }, | 
| 559 'program': { | 662 'program': { | 
| 663 'arm': {'url': 'foo/libarm/elf_loader_arm.nexe'}, | |
| 560 'x86-32': {'url': 'foo/lib32/runnable-ld.so'}, | 664 'x86-32': {'url': 'foo/lib32/runnable-ld.so'}, | 
| 561 'x86-64': {'url': 'foo/lib64/runnable-ld.so'}, | 665 'x86-64': {'url': 'foo/lib64/runnable-ld.so'}, | 
| 562 } | 666 } | 
| 563 } | 667 } | 
| 564 | 668 | 
| 565 expected_staging = [PosixRelPath(f, self.tempdir) for f in nexes] | 669 expected_staging = [PosixRelPath(f, self.tempdir) for f in nexes] | 
| 566 expected_staging.extend([ | 670 expected_staging.extend([ | 
| 567 'foo/lib32/libc.so', | 671 'foo/lib32/libc.so', | 
| 568 'foo/lib32/libgcc_s.so', | 672 'foo/lib32/libgcc_s.so.1', | 
| 569 'foo/lib32/libpthread.so', | 673 'foo/lib32/libpthread.so', | 
| 570 'foo/lib32/runnable-ld.so', | 674 'foo/lib32/runnable-ld.so', | 
| 571 'foo/lib64/libc.so', | 675 'foo/lib64/libc.so', | 
| 572 'foo/lib64/libgcc_s.so', | 676 'foo/lib64/libgcc_s.so.1', | 
| 573 'foo/lib64/libpthread.so', | 677 'foo/lib64/libpthread.so', | 
| 574 'foo/lib64/runnable-ld.so']) | 678 'foo/lib64/runnable-ld.so', | 
| 679 'foo/libarm/elf_loader_arm.nexe', | |
| 680 'foo/libarm/libpthread.so.0', | |
| 681 'foo/libarm/ld-nacl-arm.so.1', | |
| 682 'foo/libarm/libgcc_s.so.1', | |
| 683 'foo/libarm/libc.so.0.1' | |
| 684 ]) | |
| 575 | 685 | 
| 576 self.assertManifestEquals(nmf, expected_manifest) | 686 self.assertManifestEquals(nmf, expected_manifest) | 
| 577 self.assertStagingEquals(expected_staging) | 687 self.assertStagingEquals(expected_staging) | 
| 578 | 688 | 
| 579 def testPexe(self): | 689 def testPexe(self): | 
| 580 nmf, _ = self._CreatePexe() | 690 nmf, _ = self._CreatePexe() | 
| 581 expected_manifest = { | 691 expected_manifest = { | 
| 582 'program': { | 692 'program': { | 
| 583 'portable': { | 693 'portable': { | 
| 584 'pnacl-translate': { | 694 'pnacl-translate': { | 
| (...skipping 28 matching lines...) Expand all Loading... | |
| 613 'optlevel': 0, | 723 'optlevel': 0, | 
| 614 } | 724 } | 
| 615 } | 725 } | 
| 616 } | 726 } | 
| 617 } | 727 } | 
| 618 self.assertManifestEquals(nmf, expected_manifest) | 728 self.assertManifestEquals(nmf, expected_manifest) | 
| 619 | 729 | 
| 620 | 730 | 
| 621 if __name__ == '__main__': | 731 if __name__ == '__main__': | 
| 622 unittest.main() | 732 unittest.main() | 
| OLD | NEW |