2 # Copyright 2014 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.
13 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
14 LIB_DIR = os.path.dirname(SCRIPT_DIR)
15 TOOLS_DIR = os.path.dirname(LIB_DIR)
16 DATA_DIR = os.path.join(SCRIPT_DIR, 'data')
18 sys.path.append(LIB_DIR)
19 sys.path.append(TOOLS_DIR)
22 import get_shared_deps
25 TOOLCHAIN_OUT = os.path.join(build_paths.OUT_DIR, 'sdk_tests', 'toolchain')
26 NACL_X86_GLIBC_TOOLCHAIN = os.path.join(TOOLCHAIN_OUT,
27 '%s_x86' % getos.GetPlatform(),
31 def StripDependencies(deps):
32 '''Strip the dirnames and version suffixes from
33 a list of nexe dependencies.
36 /path/to/libpthread.so.1a2d3fsa -> libpthread.so
40 name = os.path.basename(name)
42 name = name.rsplit('.', 1)[0]
47 class TestGetNeeded(unittest.TestCase):
50 self.toolchain = NACL_X86_GLIBC_TOOLCHAIN
51 self.objdump = os.path.join(self.toolchain, 'bin', 'i686-nacl-objdump')
53 self.objdump += '.exe'
55 self.dyn_nexe = self.createTestNexe('test_dynamic_x86_32.nexe', 'i686')
56 self.dyn_deps = set(['libc.so', 'runnable-ld.so',
57 'libgcc_s.so', 'libpthread.so'])
61 shutil.rmtree(self.tempdir)
64 self.tempdir = tempfile.mkdtemp()
66 def createTestNexe(self, name, arch):
67 '''Create an empty test .nexe file for use in create_nmf tests.
69 This is used rather than checking in test binaries since the
70 checked in binaries depend on .so files that only exist in the
71 certain SDK that built them.
73 compiler = os.path.join(self.toolchain, 'bin', '%s-nacl-g++' % arch)
76 os.environ['CYGWIN'] = 'nodosfilewarning'
77 program = 'int main() { return 0; }'
78 name = os.path.join(self.tempdir, name)
79 cmd = [compiler, '-pthread', '-x' , 'c', '-o', name, '-']
80 p = subprocess.Popen(cmd, stdin=subprocess.PIPE)
81 p.communicate(input=program)
82 self.assertEqual(p.returncode, 0)
86 nexe = os.path.join(DATA_DIR, 'test_static_x86_32.nexe')
87 # GetNeeded should not raise an error if objdump is not set, but the .nexe
88 # is statically linked.
91 needed = get_shared_deps.GetNeeded([nexe], objdump, lib_path)
93 # static nexe should have exactly one needed file
94 self.assertEqual(len(needed), 1)
95 self.assertEqual(needed.keys()[0], nexe)
97 # arch of needed file should be x86-32
98 arch = needed.values()[0]
99 self.assertEqual(arch, 'x86-32')
101 def testDynamic(self):
102 libdir = os.path.join(self.toolchain, 'x86_64-nacl', 'lib32')
103 needed = get_shared_deps.GetNeeded([self.dyn_nexe],
105 objdump=self.objdump)
106 names = needed.keys()
108 # this nexe has 5 dependencies
109 expected = set(self.dyn_deps)
110 expected.add(os.path.basename(self.dyn_nexe))
112 basenames = set(StripDependencies(names))
113 self.assertEqual(expected, basenames)
115 def testMissingArchLibrary(self):
116 libdir = os.path.join(self.toolchain, 'x86_64-nacl', 'lib32')
118 nexes = ['libgcc_s.so.1']
119 # CreateNmfUtils uses the 32-bit library path, but not the 64-bit one
120 # so searching for a 32-bit library should succeed while searching for
121 # a 64-bit one should fail.
122 get_shared_deps.GleanFromObjdump(nexes, 'x86-32', self.objdump, lib_path)
123 self.assertRaises(get_shared_deps.Error,
124 get_shared_deps.GleanFromObjdump,
125 nexes, 'x86-64', self.objdump, lib_path)
127 def testCorrectArch(self):
128 lib_path = [os.path.join(self.toolchain, 'x86_64-nacl', 'lib32'),
129 os.path.join(self.toolchain, 'x86_64-nacl', 'lib')]
131 needed = get_shared_deps.GetNeeded([self.dyn_nexe],
133 objdump=self.objdump)
134 for arch in needed.itervalues():
135 self.assertEqual(arch, 'x86-32')
138 if __name__ == '__main__':