| #!/usr/bin/env vpython |
| # Copyright (c) 2012 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 json |
| import os |
| import posixpath |
| import shutil |
| import subprocess |
| import sys |
| import tempfile |
| import unittest |
| |
| SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) |
| TOOLS_DIR = os.path.dirname(SCRIPT_DIR) |
| DATA_DIR = os.path.join(TOOLS_DIR, 'lib', 'tests', 'data') |
| BUILD_TOOLS_DIR = os.path.join(os.path.dirname(TOOLS_DIR), 'build_tools') |
| CHROME_SRC = os.path.dirname(os.path.dirname(os.path.dirname(TOOLS_DIR))) |
| |
| sys.path.append(TOOLS_DIR) |
| sys.path.append(BUILD_TOOLS_DIR) |
| |
| import build_paths |
| import create_nmf |
| import getos |
| from mock import patch, Mock |
| |
| TOOLCHAIN_OUT = os.path.join(build_paths.OUT_DIR, 'sdk_tests', 'toolchain') |
| X86_GLIBC_TOOLCHAIN = os.path.join(TOOLCHAIN_OUT, |
| '%s_x86' % getos.GetPlatform(), |
| 'nacl_x86_glibc') |
| ARM_GLIBC_TOOLCHAIN = os.path.join(TOOLCHAIN_OUT, |
| '%s_x86' % getos.GetPlatform(), |
| 'nacl_arm_glibc') |
| |
| PosixRelPath = create_nmf.PosixRelPath |
| |
| |
| def StripSo(name): |
| """Strip trailing hexidecimal characters from the name of a shared object. |
| |
| It strips everything after the last '.' in the name, and checks that the new |
| name ends with .so. |
| |
| e.g. |
| |
| libc.so.ad6acbfa => libc.so |
| foo.bar.baz => foo.bar.baz |
| """ |
| if '.' in name: |
| stripped_name, ext = name.rsplit('.', 1) |
| if stripped_name.endswith('.so') and len(ext) > 1: |
| return stripped_name |
| return name |
| |
| |
| class TestPosixRelPath(unittest.TestCase): |
| def testBasic(self): |
| # Note that PosixRelPath only converts from native path format to posix |
| # path format, that's why we have to use os.path.join here. |
| path = os.path.join(os.path.sep, 'foo', 'bar', 'baz.blah') |
| start = os.path.sep + 'foo' |
| self.assertEqual(PosixRelPath(path, start), 'bar/baz.blah') |
| |
| |
| class TestDefaultLibpath(unittest.TestCase): |
| def setUp(self): |
| patcher = patch('create_nmf.GetSDKRoot', Mock(return_value='/dummy/path')) |
| patcher.start() |
| self.addCleanup(patcher.stop) |
| |
| def testUsesSDKRoot(self): |
| paths = create_nmf.GetDefaultLibPath('Debug') |
| for path in paths: |
| self.assertTrue(path.startswith('/dummy/path')) |
| |
| def testFallbackPath(self): |
| paths = create_nmf.GetDefaultLibPath('foo_Debug') |
| if sys.platform == 'win32': |
| paths = [p.replace('\\', '/') for p in paths] |
| path_base = '/dummy/path/lib/glibc_x86_64/foo_Debug' |
| path_fallback = '/dummy/path/lib/glibc_x86_64/Debug' |
| self.assertIn(path_base, paths) |
| self.assertIn(path_fallback, paths) |
| self.assertGreater(paths.index(path_fallback), paths.index(path_base)) |
| |
| paths = create_nmf.GetDefaultLibPath('foo_bar') |
| if sys.platform == 'win32': |
| paths = [p.replace('\\', '/') for p in paths] |
| path_base = '/dummy/path/lib/glibc_x86_64/foo_bar' |
| path_fallback = '/dummy/path/lib/glibc_x86_64/Release' |
| self.assertIn(path_base, paths) |
| self.assertIn(path_fallback, paths) |
| self.assertGreater(paths.index(path_fallback), paths.index(path_base)) |
| |
| |
| class TestNmfUtils(unittest.TestCase): |
| """Tests for the main NmfUtils class in create_nmf.""" |
| |
| def setUp(self): |
| self.tempdir = None |
| self.objdump = os.path.join(X86_GLIBC_TOOLCHAIN, 'bin', 'i686-nacl-objdump') |
| if os.name == 'nt': |
| self.objdump += '.exe' |
| self._Mktemp() |
| |
| # Create dummy elf_loader_arm.nexe by duplicating an existing so. |
| # This nexe is normally build during SDK build but we want these tests |
| # to run standalone, and the contents of the ELF are not important for |
| # these tests. |
| arm_libdir = os.path.join(ARM_GLIBC_TOOLCHAIN, 'arm-nacl', 'lib') |
| shutil.copy(os.path.join(arm_libdir, 'ld-nacl-arm.so.1'), |
| os.path.join(arm_libdir, 'elf_loader_arm.nexe')) |
| |
| |
| def _CreateTestNexe(self, name, arch): |
| """Create an empty test .nexe file for use in create_nmf tests. |
| |
| This is used rather than checking in test binaries since the |
| checked in binaries depend on .so files that only exist in the |
| certain SDK that build them. |
| """ |
| if arch == 'arm': |
| toolchain = ARM_GLIBC_TOOLCHAIN |
| else: |
| toolchain = X86_GLIBC_TOOLCHAIN |
| |
| compiler = os.path.join(toolchain, 'bin', '%s-nacl-g++' % arch) |
| if os.name == 'nt': |
| compiler += '.exe' |
| os.environ['CYGWIN'] = 'nodosfilewarning' |
| program = 'int main() { return 0; }' |
| name = os.path.join(self.tempdir, name) |
| dst_dir = os.path.dirname(name) |
| if not os.path.exists(dst_dir): |
| os.makedirs(dst_dir) |
| self.assertTrue(os.path.exists(compiler), 'compiler missing: %s' % compiler) |
| cmd = [compiler, '-pthread', '-x' , 'c', '-o', name, '-'] |
| p = subprocess.Popen(cmd, stdin=subprocess.PIPE) |
| p.communicate(input=program) |
| self.assertEqual(p.returncode, 0) |
| return name |
| |
| def tearDown(self): |
| if self.tempdir: |
| shutil.rmtree(self.tempdir) |
| |
| def _Mktemp(self): |
| self.tempdir = tempfile.mkdtemp() |
| |
| def _CreateNmfUtils(self, nexes, **kwargs): |
| if not kwargs.get('lib_path'): |
| kwargs['lib_path'] = [ |
| # Use lib instead of lib64 (lib64 is a symlink to lib). |
| os.path.join(X86_GLIBC_TOOLCHAIN, 'x86_64-nacl', 'lib'), |
| os.path.join(X86_GLIBC_TOOLCHAIN, 'x86_64-nacl', 'lib32'), |
| os.path.join(ARM_GLIBC_TOOLCHAIN, 'arm-nacl', 'lib')] |
| return create_nmf.NmfUtils(nexes, |
| objdump=self.objdump, |
| **kwargs) |
| |
| def _CreateStatic(self, arch_path=None, **kwargs): |
| """Copy all static .nexe files from the DATA_DIR to a temporary directory. |
| |
| Args: |
| arch_path: A dictionary mapping architecture to the directory to generate |
| the .nexe for the architecture in. |
| kwargs: Keyword arguments to pass through to create_nmf.NmfUtils |
| constructor. |
| |
| Returns: |
| A tuple with 2 elements: |
| * The generated NMF as a dictionary (i.e. parsed by json.loads) |
| * A list of the generated .nexe paths |
| """ |
| arch_path = arch_path or {} |
| nexes = [] |
| for arch in ('x86_64', 'x86_32', 'arm'): |
| nexe_name = 'test_static_%s.nexe' % arch |
| src_nexe = os.path.join(DATA_DIR, nexe_name) |
| dst_nexe = os.path.join(self.tempdir, arch_path.get(arch, ''), nexe_name) |
| dst_dir = os.path.dirname(dst_nexe) |
| if not os.path.exists(dst_dir): |
| os.makedirs(dst_dir) |
| shutil.copy(src_nexe, dst_nexe) |
| nexes.append(dst_nexe) |
| |
| nexes.sort() |
| nmf_utils = self._CreateNmfUtils(nexes, **kwargs) |
| nmf = json.loads(nmf_utils.GetJson()) |
| return nmf, nexes |
| |
| def _CreateDynamicAndStageDeps(self, arch_path=None, **kwargs): |
| """Create dynamic .nexe files and put them in a temporary directory, with |
| their dependencies staged in the same directory. |
| |
| Args: |
| arch_path: A dictionary mapping architecture to the directory to generate |
| the .nexe for the architecture in. |
| kwargs: Keyword arguments to pass through to create_nmf.NmfUtils |
| constructor. |
| |
| Returns: |
| A tuple with 2 elements: |
| * The generated NMF as a dictionary (i.e. parsed by json.loads) |
| * A list of the generated .nexe paths |
| """ |
| arch_path = arch_path or {} |
| nexes = [] |
| for arch in ('x86_64', 'x86_32', 'arm'): |
| nexe_name = 'test_dynamic_%s.nexe' % arch |
| rel_nexe = os.path.join(arch_path.get(arch, ''), nexe_name) |
| arch_alt = 'i686' if arch == 'x86_32' else arch |
| nexe = self._CreateTestNexe(rel_nexe, arch_alt) |
| nexes.append(nexe) |
| |
| nexes.sort() |
| nmf_utils = self._CreateNmfUtils(nexes, **kwargs) |
| nmf = json.loads(nmf_utils.GetJson()) |
| nmf_utils.StageDependencies(self.tempdir) |
| |
| return nmf, nexes |
| |
| def _CreatePexe(self, **kwargs): |
| """Copy test.pexe from the DATA_DIR to a temporary directory. |
| |
| Args: |
| kwargs: Keyword arguments to pass through to create_nmf.NmfUtils |
| constructor. |
| |
| Returns: |
| A tuple with 2 elements: |
| * The generated NMF as a dictionary (i.e. parsed by json.loads) |
| * A list of the generated .pexe paths |
| """ |
| pexe_name = 'test.pexe' |
| src_pexe = os.path.join(DATA_DIR, pexe_name) |
| dst_pexe = os.path.join(self.tempdir, pexe_name) |
| shutil.copy(src_pexe, dst_pexe) |
| |
| pexes = [dst_pexe] |
| nmf_utils = self._CreateNmfUtils(pexes, **kwargs) |
| nmf = json.loads(nmf_utils.GetJson()) |
| |
| return nmf, pexes |
| |
| def _CreateBitCode(self, **kwargs): |
| """Copy test.bc from the DATA_DIR to a temporary directory. |
| |
| Args: |
| kwargs: Keyword arguments to pass through to create_nmf.NmfUtils |
| constructor. |
| |
| Returns: |
| A tuple with 2 elements: |
| * The generated NMF as a dictionary (i.e. parsed by json.loads) |
| * A list of the generated .bc paths |
| """ |
| bc_name = 'test.bc' |
| src_bc = os.path.join(DATA_DIR, bc_name) |
| dst_bc = os.path.join(self.tempdir, bc_name) |
| shutil.copy(src_bc, dst_bc) |
| |
| bcs = [dst_bc] |
| nmf_utils = self._CreateNmfUtils(bcs, **kwargs) |
| nmf = json.loads(nmf_utils.GetJson()) |
| |
| return nmf, bcs |
| |
| def assertManifestEquals(self, manifest, expected): |
| """Compare two manifest dictionaries. |
| |
| The input manifest is regenerated with all string keys and values being |
| processed through StripSo, to remove the random hexidecimal characters at |
| the end of shared object names. |
| |
| Args: |
| manifest: The generated manifest. |
| expected: The expected manifest. |
| """ |
| def StripSoCopyDict(d): |
| new_d = {} |
| for k, v in d.iteritems(): |
| new_k = StripSo(k) |
| if isinstance(v, (str, unicode)): |
| new_v = StripSo(v) |
| elif isinstance(v, list): |
| new_v = v[:] |
| elif isinstance(v, dict): |
| new_v = StripSoCopyDict(v) |
| else: |
| # Assume that anything else can be copied directly. |
| new_v = v |
| |
| new_d[new_k] = new_v |
| return new_d |
| |
| strip_manifest = StripSoCopyDict(manifest) |
| self.assertEqual(strip_manifest['program'], expected['program']) |
| if 'files' in strip_manifest: |
| for key in strip_manifest['files']: |
| self.assertEqual(strip_manifest['files'][key], expected['files'][key]) |
| |
| self.assertEqual(strip_manifest, expected) |
| |
| def assertStagingEquals(self, expected): |
| """Compare the contents of the temporary directory, to an expected |
| directory layout. |
| |
| Args: |
| expected: The expected directory layout. |
| """ |
| all_files = [] |
| for root, _, files in os.walk(self.tempdir): |
| rel_root_posix = PosixRelPath(root, self.tempdir) |
| for f in files: |
| path = posixpath.join(rel_root_posix, StripSo(f)) |
| if path.startswith('./'): |
| path = path[2:] |
| all_files.append(path) |
| self.assertEqual(set(expected), set(all_files)) |
| |
| arch_dir = {'x86_32': 'x86_32', 'x86_64': 'x86_64', 'arm': 'arm'} |
| |
| def testStatic(self): |
| nmf, _ = self._CreateStatic() |
| expected_manifest = { |
| 'files': {}, |
| 'program': { |
| 'x86-64': {'url': 'test_static_x86_64.nexe'}, |
| 'x86-32': {'url': 'test_static_x86_32.nexe'}, |
| 'arm': {'url': 'test_static_arm.nexe'}, |
| } |
| } |
| self.assertManifestEquals(nmf, expected_manifest) |
| |
| def testStaticWithPath(self): |
| nmf, _ = self._CreateStatic(self.arch_dir, nmf_root=self.tempdir) |
| expected_manifest = { |
| 'files': {}, |
| 'program': { |
| 'x86-32': {'url': 'x86_32/test_static_x86_32.nexe'}, |
| 'x86-64': {'url': 'x86_64/test_static_x86_64.nexe'}, |
| 'arm': {'url': 'arm/test_static_arm.nexe'}, |
| } |
| } |
| self.assertManifestEquals(nmf, expected_manifest) |
| |
| def testStaticWithPathNoNmfRoot(self): |
| # This case is not particularly useful, but it is similar to how create_nmf |
| # used to work. If there is no nmf_root given, all paths are relative to |
| # the first nexe passed on the commandline. I believe the assumption |
| # previously was that all .nexes would be in the same directory. |
| nmf, _ = self._CreateStatic(self.arch_dir) |
| expected_manifest = { |
| 'files': {}, |
| 'program': { |
| 'x86-32': {'url': '../x86_32/test_static_x86_32.nexe'}, |
| 'x86-64': {'url': '../x86_64/test_static_x86_64.nexe'}, |
| 'arm': {'url': 'test_static_arm.nexe'}, |
| } |
| } |
| self.assertManifestEquals(nmf, expected_manifest) |
| |
| def testStaticWithNexePrefix(self): |
| nmf, _ = self._CreateStatic(nexe_prefix='foo') |
| expected_manifest = { |
| 'files': {}, |
| 'program': { |
| 'x86-64': {'url': 'foo/test_static_x86_64.nexe'}, |
| 'x86-32': {'url': 'foo/test_static_x86_32.nexe'}, |
| 'arm': {'url': 'foo/test_static_arm.nexe'}, |
| } |
| } |
| self.assertManifestEquals(nmf, expected_manifest) |
| |
| def testDynamic(self): |
| nmf, nexes = self._CreateDynamicAndStageDeps() |
| expected_manifest = { |
| 'files': { |
| 'main.nexe': { |
| 'x86-32': {'url': 'test_dynamic_x86_32.nexe'}, |
| 'x86-64': {'url': 'test_dynamic_x86_64.nexe'}, |
| 'arm': {'url': 'test_dynamic_arm.nexe'}, |
| }, |
| 'ld-nacl-arm.so.1': { |
| 'arm': {'url': 'libarm/ld-nacl-arm.so.1'}, |
| }, |
| 'libc.so.0.1': { |
| 'arm': {'url': 'libarm/libc.so.0.1'} |
| }, |
| 'libc.so': { |
| 'x86-32': {'url': 'lib32/libc.so'}, |
| 'x86-64': {'url': 'lib64/libc.so'}, |
| }, |
| 'libgcc_s.so.1': { |
| 'arm': {'url': 'libarm/libgcc_s.so.1'}, |
| 'x86-32': {'url': 'lib32/libgcc_s.so.1'}, |
| 'x86-64': {'url': 'lib64/libgcc_s.so.1'}, |
| }, |
| 'libpthread.so.0': { |
| 'arm': { 'url': 'libarm/libpthread.so.0'} |
| }, |
| 'libpthread.so': { |
| 'x86-32': {'url': 'lib32/libpthread.so'}, |
| 'x86-64': {'url': 'lib64/libpthread.so'}, |
| }, |
| }, |
| 'program': { |
| 'arm': {'url': 'libarm/elf_loader_arm.nexe'}, |
| 'x86-32': {'url': 'lib32/runnable-ld.so'}, |
| 'x86-64': {'url': 'lib64/runnable-ld.so'}, |
| } |
| } |
| |
| expected_staging = [os.path.basename(f) for f in nexes] |
| expected_staging.extend([ |
| 'lib32/libc.so', |
| 'lib32/libgcc_s.so.1', |
| 'lib32/libpthread.so', |
| 'lib32/runnable-ld.so', |
| 'lib64/libc.so', |
| 'lib64/libgcc_s.so.1', |
| 'lib64/libpthread.so', |
| 'lib64/runnable-ld.so', |
| 'libarm/elf_loader_arm.nexe', |
| 'libarm/libpthread.so.0', |
| 'libarm/ld-nacl-arm.so.1', |
| 'libarm/libgcc_s.so.1', |
| 'libarm/libc.so.0.1' |
| ]) |
| |
| self.assertManifestEquals(nmf, expected_manifest) |
| self.assertStagingEquals(expected_staging) |
| |
| def testDynamicWithPath(self): |
| nmf, nexes = self._CreateDynamicAndStageDeps(self.arch_dir, |
| nmf_root=self.tempdir) |
| expected_manifest = { |
| 'files': { |
| 'main.nexe': { |
| 'arm': {'url': 'arm/test_dynamic_arm.nexe'}, |
| 'x86-32': {'url': 'x86_32/test_dynamic_x86_32.nexe'}, |
| 'x86-64': {'url': 'x86_64/test_dynamic_x86_64.nexe'}, |
| }, |
| 'libc.so.0.1': { |
| 'arm': {'url': 'arm/libarm/libc.so.0.1'} |
| }, |
| 'ld-nacl-arm.so.1': { |
| 'arm': {'url': 'arm/libarm/ld-nacl-arm.so.1'}, |
| }, |
| 'libc.so': { |
| 'x86-32': {'url': 'x86_32/lib32/libc.so'}, |
| 'x86-64': {'url': 'x86_64/lib64/libc.so'}, |
| }, |
| 'libgcc_s.so.1': { |
| 'arm': {'url': 'arm/libarm/libgcc_s.so.1'}, |
| 'x86-32': {'url': 'x86_32/lib32/libgcc_s.so.1'}, |
| 'x86-64': {'url': 'x86_64/lib64/libgcc_s.so.1'}, |
| }, |
| 'libpthread.so.0': { |
| 'arm': { 'url': 'arm/libarm/libpthread.so.0'} |
| }, |
| 'libpthread.so': { |
| 'x86-32': {'url': 'x86_32/lib32/libpthread.so'}, |
| 'x86-64': {'url': 'x86_64/lib64/libpthread.so'}, |
| }, |
| }, |
| 'program': { |
| 'arm': {'url': 'arm/libarm/elf_loader_arm.nexe'}, |
| 'x86-32': {'url': 'x86_32/lib32/runnable-ld.so'}, |
| 'x86-64': {'url': 'x86_64/lib64/runnable-ld.so'}, |
| } |
| } |
| |
| expected_staging = [PosixRelPath(f, self.tempdir) for f in nexes] |
| expected_staging.extend([ |
| 'x86_32/lib32/libc.so', |
| 'x86_32/lib32/libgcc_s.so.1', |
| 'x86_32/lib32/libpthread.so', |
| 'x86_32/lib32/runnable-ld.so', |
| 'x86_64/lib64/libc.so', |
| 'x86_64/lib64/libgcc_s.so.1', |
| 'x86_64/lib64/libpthread.so', |
| 'x86_64/lib64/runnable-ld.so', |
| 'arm/libarm/elf_loader_arm.nexe', |
| 'arm/libarm/libpthread.so.0', |
| 'arm/libarm/ld-nacl-arm.so.1', |
| 'arm/libarm/libgcc_s.so.1', |
| 'arm/libarm/libc.so.0.1' |
| ]) |
| |
| self.assertManifestEquals(nmf, expected_manifest) |
| self.assertStagingEquals(expected_staging) |
| |
| def testDynamicWithRelPath(self): |
| """Test that when the nmf root is a relative path that things work.""" |
| old_path = os.getcwd() |
| try: |
| os.chdir(self.tempdir) |
| nmf, nexes = self._CreateDynamicAndStageDeps(self.arch_dir, nmf_root='') |
| expected_manifest = { |
| 'files': { |
| 'main.nexe': { |
| 'arm': {'url': 'arm/test_dynamic_arm.nexe'}, |
| 'x86-32': {'url': 'x86_32/test_dynamic_x86_32.nexe'}, |
| 'x86-64': {'url': 'x86_64/test_dynamic_x86_64.nexe'}, |
| }, |
| 'ld-nacl-arm.so.1': { |
| 'arm': {'url': 'arm/libarm/ld-nacl-arm.so.1'}, |
| }, |
| 'libc.so.0.1': { |
| 'arm': {'url': 'arm/libarm/libc.so.0.1'} |
| }, |
| 'libc.so': { |
| 'x86-32': {'url': 'x86_32/lib32/libc.so'}, |
| 'x86-64': {'url': 'x86_64/lib64/libc.so'}, |
| }, |
| 'libgcc_s.so.1': { |
| 'arm': {'url': 'arm/libarm/libgcc_s.so.1'}, |
| 'x86-32': {'url': 'x86_32/lib32/libgcc_s.so.1'}, |
| 'x86-64': {'url': 'x86_64/lib64/libgcc_s.so.1'}, |
| }, |
| 'libpthread.so.0': { |
| 'arm': { 'url': 'arm/libarm/libpthread.so.0'} |
| }, |
| 'libpthread.so': { |
| 'x86-32': {'url': 'x86_32/lib32/libpthread.so'}, |
| 'x86-64': {'url': 'x86_64/lib64/libpthread.so'}, |
| }, |
| }, |
| 'program': { |
| 'arm': {'url': 'arm/libarm/elf_loader_arm.nexe'}, |
| 'x86-32': {'url': 'x86_32/lib32/runnable-ld.so'}, |
| 'x86-64': {'url': 'x86_64/lib64/runnable-ld.so'}, |
| } |
| } |
| |
| expected_staging = [PosixRelPath(f, self.tempdir) for f in nexes] |
| expected_staging.extend([ |
| 'x86_32/lib32/libc.so', |
| 'x86_32/lib32/libgcc_s.so.1', |
| 'x86_32/lib32/libpthread.so', |
| 'x86_32/lib32/runnable-ld.so', |
| 'x86_64/lib64/libc.so', |
| 'x86_64/lib64/libgcc_s.so.1', |
| 'x86_64/lib64/libpthread.so', |
| 'x86_64/lib64/runnable-ld.so', |
| 'arm/libarm/elf_loader_arm.nexe', |
| 'arm/libarm/libpthread.so.0', |
| 'arm/libarm/ld-nacl-arm.so.1', |
| 'arm/libarm/libgcc_s.so.1', |
| 'arm/libarm/libc.so.0.1' |
| ]) |
| |
| self.assertManifestEquals(nmf, expected_manifest) |
| self.assertStagingEquals(expected_staging) |
| finally: |
| os.chdir(old_path) |
| |
| def testDynamicWithPathNoArchPrefix(self): |
| nmf, nexes = self._CreateDynamicAndStageDeps(self.arch_dir, |
| nmf_root=self.tempdir, |
| no_arch_prefix=True) |
| expected_manifest = { |
| 'files': { |
| 'main.nexe': { |
| 'arm': {'url': 'arm/test_dynamic_arm.nexe'}, |
| 'x86-32': {'url': 'x86_32/test_dynamic_x86_32.nexe'}, |
| 'x86-64': {'url': 'x86_64/test_dynamic_x86_64.nexe'}, |
| }, |
| 'ld-nacl-arm.so.1': { |
| 'arm': {'url': 'arm/ld-nacl-arm.so.1'}, |
| }, |
| 'libc.so.0.1': { |
| 'arm': {'url': 'arm/libc.so.0.1'} |
| }, |
| 'libc.so': { |
| 'x86-32': {'url': 'x86_32/libc.so'}, |
| 'x86-64': {'url': 'x86_64/libc.so'}, |
| }, |
| 'libgcc_s.so.1': { |
| 'arm': {'url': 'arm/libgcc_s.so.1'}, |
| 'x86-32': {'url': 'x86_32/libgcc_s.so.1'}, |
| 'x86-64': {'url': 'x86_64/libgcc_s.so.1'}, |
| }, |
| 'libpthread.so.0': { |
| 'arm': { 'url': 'arm/libpthread.so.0'} |
| }, |
| 'libpthread.so': { |
| 'x86-32': {'url': 'x86_32/libpthread.so'}, |
| 'x86-64': {'url': 'x86_64/libpthread.so'}, |
| }, |
| }, |
| 'program': { |
| 'arm': {'url': 'arm/elf_loader_arm.nexe'}, |
| 'x86-32': {'url': 'x86_32/runnable-ld.so'}, |
| 'x86-64': {'url': 'x86_64/runnable-ld.so'}, |
| } |
| } |
| |
| expected_staging = [PosixRelPath(f, self.tempdir) for f in nexes] |
| expected_staging.extend([ |
| 'x86_32/libc.so', |
| 'x86_32/libgcc_s.so.1', |
| 'x86_32/libpthread.so', |
| 'x86_32/runnable-ld.so', |
| 'x86_64/libc.so', |
| 'x86_64/libgcc_s.so.1', |
| 'x86_64/libpthread.so', |
| 'x86_64/runnable-ld.so', |
| 'arm/elf_loader_arm.nexe', |
| 'arm/libpthread.so.0', |
| 'arm/ld-nacl-arm.so.1', |
| 'arm/libgcc_s.so.1', |
| 'arm/libc.so.0.1' |
| ]) |
| |
| self.assertManifestEquals(nmf, expected_manifest) |
| self.assertStagingEquals(expected_staging) |
| |
| def testDynamicWithLibPrefix(self): |
| nmf, nexes = self._CreateDynamicAndStageDeps(lib_prefix='foo') |
| expected_manifest = { |
| 'files': { |
| 'main.nexe': { |
| 'arm': {'url': 'test_dynamic_arm.nexe'}, |
| 'x86-32': {'url': 'test_dynamic_x86_32.nexe'}, |
| 'x86-64': {'url': 'test_dynamic_x86_64.nexe'}, |
| }, |
| 'ld-nacl-arm.so.1': { |
| 'arm': {'url': 'foo/libarm/ld-nacl-arm.so.1'}, |
| }, |
| 'libc.so.0.1': { |
| 'arm': {'url': 'foo/libarm/libc.so.0.1'} |
| }, |
| 'libc.so': { |
| 'x86-32': {'url': 'foo/lib32/libc.so'}, |
| 'x86-64': {'url': 'foo/lib64/libc.so'}, |
| }, |
| 'libgcc_s.so.1': { |
| 'arm': {'url': 'foo/libarm/libgcc_s.so.1'}, |
| 'x86-32': {'url': 'foo/lib32/libgcc_s.so.1'}, |
| 'x86-64': {'url': 'foo/lib64/libgcc_s.so.1'}, |
| }, |
| 'libpthread.so.0': { |
| 'arm': { 'url': 'foo/libarm/libpthread.so.0'} |
| }, |
| 'libpthread.so': { |
| 'x86-32': {'url': 'foo/lib32/libpthread.so'}, |
| 'x86-64': {'url': 'foo/lib64/libpthread.so'}, |
| }, |
| }, |
| 'program': { |
| 'arm': {'url': 'foo/libarm/elf_loader_arm.nexe'}, |
| 'x86-32': {'url': 'foo/lib32/runnable-ld.so'}, |
| 'x86-64': {'url': 'foo/lib64/runnable-ld.so'}, |
| } |
| } |
| |
| expected_staging = [PosixRelPath(f, self.tempdir) for f in nexes] |
| expected_staging.extend([ |
| 'foo/lib32/libc.so', |
| 'foo/lib32/libgcc_s.so.1', |
| 'foo/lib32/libpthread.so', |
| 'foo/lib32/runnable-ld.so', |
| 'foo/lib64/libc.so', |
| 'foo/lib64/libgcc_s.so.1', |
| 'foo/lib64/libpthread.so', |
| 'foo/lib64/runnable-ld.so', |
| 'foo/libarm/elf_loader_arm.nexe', |
| 'foo/libarm/libpthread.so.0', |
| 'foo/libarm/ld-nacl-arm.so.1', |
| 'foo/libarm/libgcc_s.so.1', |
| 'foo/libarm/libc.so.0.1' |
| ]) |
| |
| self.assertManifestEquals(nmf, expected_manifest) |
| self.assertStagingEquals(expected_staging) |
| |
| def testPexe(self): |
| nmf, _ = self._CreatePexe() |
| expected_manifest = { |
| 'program': { |
| 'portable': { |
| 'pnacl-translate': { |
| 'url': 'test.pexe' |
| } |
| } |
| } |
| } |
| self.assertManifestEquals(nmf, expected_manifest) |
| |
| def testPexeOptLevel(self): |
| nmf, _ = self._CreatePexe(pnacl_optlevel=2) |
| expected_manifest = { |
| 'program': { |
| 'portable': { |
| 'pnacl-translate': { |
| 'url': 'test.pexe', |
| 'optlevel': 2, |
| } |
| } |
| } |
| } |
| self.assertManifestEquals(nmf, expected_manifest) |
| |
| def testBitCode(self): |
| nmf, _ = self._CreateBitCode(pnacl_debug_optlevel=0) |
| expected_manifest = { |
| 'program': { |
| 'portable': { |
| 'pnacl-debug': { |
| 'url': 'test.bc', |
| 'optlevel': 0, |
| } |
| } |
| } |
| } |
| self.assertManifestEquals(nmf, expected_manifest) |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |