config/tests/unit-expandlibs.py

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/config/tests/unit-expandlibs.py	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,420 @@
     1.4 +import subprocess
     1.5 +import unittest
     1.6 +import sys
     1.7 +import os
     1.8 +import imp
     1.9 +from tempfile import mkdtemp
    1.10 +from shutil import rmtree
    1.11 +import mozunit
    1.12 +
    1.13 +from UserString import UserString
    1.14 +# Create a controlled configuration for use by expandlibs
    1.15 +config_win = {
    1.16 +    'AR': 'lib',
    1.17 +    'AR_EXTRACT': '',
    1.18 +    'DLL_PREFIX': '',
    1.19 +    'LIB_PREFIX': '',
    1.20 +    'OBJ_SUFFIX': '.obj',
    1.21 +    'LIB_SUFFIX': '.lib',
    1.22 +    'DLL_SUFFIX': '.dll',
    1.23 +    'IMPORT_LIB_SUFFIX': '.lib',
    1.24 +    'LIBS_DESC_SUFFIX': '.desc',
    1.25 +    'EXPAND_LIBS_LIST_STYLE': 'list',
    1.26 +}
    1.27 +config_unix = {
    1.28 +    'AR': 'ar',
    1.29 +    'AR_EXTRACT': 'ar -x',
    1.30 +    'DLL_PREFIX': 'lib',
    1.31 +    'LIB_PREFIX': 'lib',
    1.32 +    'OBJ_SUFFIX': '.o',
    1.33 +    'LIB_SUFFIX': '.a',
    1.34 +    'DLL_SUFFIX': '.so',
    1.35 +    'IMPORT_LIB_SUFFIX': '',
    1.36 +    'LIBS_DESC_SUFFIX': '.desc',
    1.37 +    'EXPAND_LIBS_LIST_STYLE': 'linkerscript',
    1.38 +}
    1.39 +
    1.40 +config = sys.modules['expandlibs_config'] = imp.new_module('expandlibs_config')
    1.41 +
    1.42 +from expandlibs import LibDescriptor, ExpandArgs, relativize, ExpandLibsDeps
    1.43 +from expandlibs_gen import generate
    1.44 +from expandlibs_exec import ExpandArgsMore, SectionFinder
    1.45 +
    1.46 +def Lib(name):
    1.47 +    return config.LIB_PREFIX + name + config.LIB_SUFFIX
    1.48 +
    1.49 +def Obj(name):
    1.50 +    return name + config.OBJ_SUFFIX
    1.51 +
    1.52 +def Dll(name):
    1.53 +    return config.DLL_PREFIX + name + config.DLL_SUFFIX
    1.54 +
    1.55 +def ImportLib(name):
    1.56 +    if not len(config.IMPORT_LIB_SUFFIX): return Dll(name)
    1.57 +    return config.LIB_PREFIX + name + config.IMPORT_LIB_SUFFIX
    1.58 +
    1.59 +class TestRelativize(unittest.TestCase):
    1.60 +    def test_relativize(self):
    1.61 +        '''Test relativize()'''
    1.62 +        os_path_exists = os.path.exists
    1.63 +        def exists(path):
    1.64 +            return True
    1.65 +        os.path.exists = exists
    1.66 +        self.assertEqual(relativize(os.path.abspath(os.curdir)), os.curdir)
    1.67 +        self.assertEqual(relativize(os.path.abspath(os.pardir)), os.pardir)
    1.68 +        self.assertEqual(relativize(os.path.join(os.curdir, 'a')), 'a')
    1.69 +        self.assertEqual(relativize(os.path.join(os.path.abspath(os.curdir), 'a')), 'a')
    1.70 +        # relativize is expected to return the absolute path if it is shorter
    1.71 +        self.assertEqual(relativize(os.sep), os.sep)
    1.72 +        os.path.exists = os.path.exists
    1.73 +
    1.74 +class TestLibDescriptor(unittest.TestCase):
    1.75 +    def test_serialize(self):
    1.76 +        '''Test LibDescriptor's serialization'''
    1.77 +        desc = LibDescriptor()
    1.78 +        desc[LibDescriptor.KEYS[0]] = ['a', 'b']
    1.79 +        self.assertEqual(str(desc), "{0} = a b".format(LibDescriptor.KEYS[0]))
    1.80 +        desc['unsupported-key'] = ['a']
    1.81 +        self.assertEqual(str(desc), "{0} = a b".format(LibDescriptor.KEYS[0]))
    1.82 +        desc[LibDescriptor.KEYS[1]] = ['c', 'd', 'e']
    1.83 +        self.assertEqual(str(desc),
    1.84 +                         "{0} = a b\n{1} = c d e"
    1.85 +                         .format(LibDescriptor.KEYS[0], LibDescriptor.KEYS[1]))
    1.86 +        desc[LibDescriptor.KEYS[0]] = []
    1.87 +        self.assertEqual(str(desc), "{0} = c d e".format(LibDescriptor.KEYS[1]))
    1.88 +
    1.89 +    def test_read(self):
    1.90 +        '''Test LibDescriptor's initialization'''
    1.91 +        desc_list = ["# Comment",
    1.92 +                     "{0} = a b".format(LibDescriptor.KEYS[1]),
    1.93 +                     "", # Empty line
    1.94 +                     "foo = bar", # Should be discarded
    1.95 +                     "{0} = c d e".format(LibDescriptor.KEYS[0])]
    1.96 +        desc = LibDescriptor(desc_list)
    1.97 +        self.assertEqual(desc[LibDescriptor.KEYS[1]], ['a', 'b'])
    1.98 +        self.assertEqual(desc[LibDescriptor.KEYS[0]], ['c', 'd', 'e'])
    1.99 +        self.assertEqual(False, 'foo' in desc)
   1.100 +
   1.101 +def wrap_method(conf, wrapped_method):
   1.102 +    '''Wrapper used to call a test with a specific configuration'''
   1.103 +    def _method(self):
   1.104 +        for key in conf:
   1.105 +            setattr(config, key, conf[key])
   1.106 +        self.init()
   1.107 +        try:
   1.108 +            wrapped_method(self)
   1.109 +        except:
   1.110 +            raise
   1.111 +        finally:
   1.112 +            self.cleanup()
   1.113 +    return _method
   1.114 +
   1.115 +class ReplicateTests(type):
   1.116 +    '''Replicates tests for unix and windows variants'''
   1.117 +    def __new__(cls, clsName, bases, dict):
   1.118 +        for name in [key for key in dict if key.startswith('test_')]:
   1.119 +            dict[name + '_unix'] = wrap_method(config_unix, dict[name])
   1.120 +            dict[name + '_unix'].__doc__ = dict[name].__doc__ + ' (unix)'
   1.121 +            dict[name + '_win'] = wrap_method(config_win, dict[name])
   1.122 +            dict[name + '_win'].__doc__ = dict[name].__doc__ + ' (win)'
   1.123 +            del dict[name]
   1.124 +        return type.__new__(cls, clsName, bases, dict)
   1.125 +
   1.126 +class TestCaseWithTmpDir(unittest.TestCase):
   1.127 +    __metaclass__ = ReplicateTests
   1.128 +    def init(self):
   1.129 +        self.tmpdir = os.path.abspath(mkdtemp(dir=os.curdir))
   1.130 +
   1.131 +    def cleanup(self):
   1.132 +        rmtree(self.tmpdir)
   1.133 +
   1.134 +    def touch(self, files):
   1.135 +        for f in files:
   1.136 +            open(f, 'w').close()
   1.137 +
   1.138 +    def tmpfile(self, *args):
   1.139 +        return os.path.join(self.tmpdir, *args)
   1.140 +
   1.141 +class TestExpandLibsGen(TestCaseWithTmpDir):
   1.142 +    def test_generate(self):
   1.143 +        '''Test library descriptor generation'''
   1.144 +        files = [self.tmpfile(f) for f in
   1.145 +                 [Lib('a'), Obj('b'), Lib('c'), Obj('d'), Obj('e'), Lib('f')]]
   1.146 +        self.touch(files[:-1])
   1.147 +        self.touch([files[-1] + config.LIBS_DESC_SUFFIX])
   1.148 +
   1.149 +        desc = generate(files)
   1.150 +        self.assertEqual(desc['OBJS'], [self.tmpfile(Obj(s)) for s in ['b', 'd', 'e']])
   1.151 +        self.assertEqual(desc['LIBS'], [self.tmpfile(Lib(s)) for s in ['a', 'c', 'f']])
   1.152 +
   1.153 +        self.assertRaises(Exception, generate, files + [self.tmpfile(Obj('z'))])
   1.154 +        self.assertRaises(Exception, generate, files + [self.tmpfile(Lib('y'))])
   1.155 +
   1.156 +class TestExpandInit(TestCaseWithTmpDir):
   1.157 +    def init(self):
   1.158 +        ''' Initializes test environment for library expansion tests'''
   1.159 +        super(TestExpandInit, self).init()
   1.160 +        # Create 2 fake libraries, each containing 3 objects, and the second
   1.161 +        # including the first one and another library.
   1.162 +        os.mkdir(self.tmpfile('libx'))
   1.163 +        os.mkdir(self.tmpfile('liby'))
   1.164 +        self.libx_files = [self.tmpfile('libx', Obj(f)) for f in ['g', 'h', 'i']]
   1.165 +        self.liby_files = [self.tmpfile('liby', Obj(f)) for f in ['j', 'k', 'l']] + [self.tmpfile('liby', Lib('z'))]
   1.166 +        self.touch(self.libx_files + self.liby_files)
   1.167 +        with open(self.tmpfile('libx', Lib('x') + config.LIBS_DESC_SUFFIX), 'w') as f:
   1.168 +            f.write(str(generate(self.libx_files)))
   1.169 +        with open(self.tmpfile('liby', Lib('y') + config.LIBS_DESC_SUFFIX), 'w') as f:
   1.170 +            f.write(str(generate(self.liby_files + [self.tmpfile('libx', Lib('x'))])))
   1.171 +
   1.172 +        # Create various objects and libraries 
   1.173 +        self.arg_files = [self.tmpfile(f) for f in [Lib('a'), Obj('b'), Obj('c'), Lib('d'), Obj('e')]]
   1.174 +        # We always give library names (LIB_PREFIX/SUFFIX), even for
   1.175 +        # dynamic/import libraries
   1.176 +        self.files = self.arg_files + [self.tmpfile(ImportLib('f'))]
   1.177 +        self.arg_files += [self.tmpfile(Lib('f'))]
   1.178 +        self.touch(self.files)
   1.179 +
   1.180 +    def assertRelEqual(self, args1, args2):
   1.181 +        self.assertEqual(args1, [relativize(a) for a in args2])
   1.182 +
   1.183 +class TestExpandArgs(TestExpandInit):
   1.184 +    def test_expand(self):
   1.185 +        '''Test library expansion'''
   1.186 +        # Expanding arguments means libraries with a descriptor are expanded
   1.187 +        # with the descriptor content, and import libraries are used when
   1.188 +        # a library doesn't exist
   1.189 +        args = ExpandArgs(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))])
   1.190 +        self.assertRelEqual(args, ['foo', '-bar'] + self.files + self.liby_files + self.libx_files) 
   1.191 +
   1.192 +        # When a library exists at the same time as a descriptor, we just use
   1.193 +        # the library
   1.194 +        self.touch([self.tmpfile('libx', Lib('x'))])
   1.195 +        args = ExpandArgs(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))])
   1.196 +        self.assertRelEqual(args, ['foo', '-bar'] + self.files + self.liby_files + [self.tmpfile('libx', Lib('x'))]) 
   1.197 +
   1.198 +        self.touch([self.tmpfile('liby', Lib('y'))])
   1.199 +        args = ExpandArgs(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))])
   1.200 +        self.assertRelEqual(args, ['foo', '-bar'] + self.files + [self.tmpfile('liby', Lib('y'))])
   1.201 +
   1.202 +class TestExpandLibsDeps(TestExpandInit):
   1.203 +    def test_expandlibsdeps(self):
   1.204 +        '''Test library expansion for dependencies'''
   1.205 +        # Dependency list for a library with a descriptor is equivalent to
   1.206 +        # the arguments expansion, to which we add each descriptor
   1.207 +        args = self.arg_files + [self.tmpfile('liby', Lib('y'))]
   1.208 +        self.assertRelEqual(ExpandLibsDeps(args), ExpandArgs(args) + [self.tmpfile('libx', Lib('x') + config.LIBS_DESC_SUFFIX), self.tmpfile('liby', Lib('y') + config.LIBS_DESC_SUFFIX)])
   1.209 +
   1.210 +        # When a library exists at the same time as a descriptor, the
   1.211 +        # descriptor is not a dependency
   1.212 +        self.touch([self.tmpfile('libx', Lib('x'))])
   1.213 +        args = self.arg_files + [self.tmpfile('liby', Lib('y'))]
   1.214 +        self.assertRelEqual(ExpandLibsDeps(args), ExpandArgs(args) + [self.tmpfile('liby', Lib('y') + config.LIBS_DESC_SUFFIX)])
   1.215 +
   1.216 +        self.touch([self.tmpfile('liby', Lib('y'))])
   1.217 +        args = self.arg_files + [self.tmpfile('liby', Lib('y'))]
   1.218 +        self.assertRelEqual(ExpandLibsDeps(args), ExpandArgs(args))
   1.219 +
   1.220 +class TestExpandArgsMore(TestExpandInit):
   1.221 +    def test_makelist(self):
   1.222 +        '''Test grouping object files in lists'''
   1.223 +        # ExpandArgsMore does the same as ExpandArgs
   1.224 +        with ExpandArgsMore(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))]) as args:
   1.225 +            self.assertRelEqual(args, ['foo', '-bar'] + self.files + self.liby_files + self.libx_files) 
   1.226 +
   1.227 +            # But also has an extra method replacing object files with a list
   1.228 +            args.makelist()
   1.229 +            # self.files has objects at #1, #2, #4
   1.230 +            self.assertRelEqual(args[:3], ['foo', '-bar'] + self.files[:1])
   1.231 +            self.assertRelEqual(args[4:], [self.files[3]] + self.files[5:] + [self.tmpfile('liby', Lib('z'))])
   1.232 +
   1.233 +            # Check the list file content
   1.234 +            objs = [f for f in self.files + self.liby_files + self.libx_files if f.endswith(config.OBJ_SUFFIX)]
   1.235 +            if config.EXPAND_LIBS_LIST_STYLE == "linkerscript":
   1.236 +                self.assertNotEqual(args[3][0], '@')
   1.237 +                filename = args[3]
   1.238 +                content = ['INPUT("{0}")'.format(relativize(f)) for f in objs]
   1.239 +                with open(filename, 'r') as f:
   1.240 +                    self.assertEqual([l.strip() for l in f.readlines() if len(l.strip())], content)
   1.241 +            elif config.EXPAND_LIBS_LIST_STYLE == "list":
   1.242 +                self.assertEqual(args[3][0], '@')
   1.243 +                filename = args[3][1:]
   1.244 +                content = objs
   1.245 +                with open(filename, 'r') as f:
   1.246 +                    self.assertRelEqual([l.strip() for l in f.readlines() if len(l.strip())], content)
   1.247 +
   1.248 +            tmp = args.tmp
   1.249 +        # Check that all temporary files are properly removed
   1.250 +        self.assertEqual(True, all([not os.path.exists(f) for f in tmp]))
   1.251 +
   1.252 +    def test_extract(self):
   1.253 +        '''Test library extraction'''
   1.254 +        # Divert subprocess.call
   1.255 +        subprocess_call = subprocess.call
   1.256 +        extracted = {}
   1.257 +        def call(args, **kargs):
   1.258 +            if config.AR == 'lib':
   1.259 +                self.assertEqual(args[:2], [config.AR, '-NOLOGO'])
   1.260 +                self.assertTrue(args[2].startswith('-EXTRACT:'))
   1.261 +                extract = [args[2][len('-EXTRACT:'):]]
   1.262 +                self.assertTrue(extract)
   1.263 +                args = args[3:]
   1.264 +            else:
   1.265 +                # The command called is always AR_EXTRACT
   1.266 +                ar_extract = config.AR_EXTRACT.split()
   1.267 +                self.assertEqual(args[:len(ar_extract)], ar_extract)
   1.268 +                args = args[len(ar_extract):]
   1.269 +            # Remaining argument is always one library
   1.270 +            self.assertEqual(len(args), 1)
   1.271 +            arg = args[0]
   1.272 +            self.assertEqual(os.path.splitext(arg)[1], config.LIB_SUFFIX)
   1.273 +            # Simulate file extraction
   1.274 +            lib = os.path.splitext(os.path.basename(arg))[0]
   1.275 +            if config.AR != 'lib':
   1.276 +                extract = [lib, lib + '2']
   1.277 +            extract = [os.path.join(kargs['cwd'], f) for f in extract]
   1.278 +            if config.AR != 'lib':
   1.279 +                extract = [Obj(f) for f in extract]
   1.280 +            if not lib in extracted:
   1.281 +                extracted[lib] = []
   1.282 +            extracted[lib].extend(extract)
   1.283 +            self.touch(extract)
   1.284 +        subprocess.call = call
   1.285 +
   1.286 +        def check_output(args, **kargs):
   1.287 +            # The command called is always AR
   1.288 +            ar = config.AR
   1.289 +            self.assertEqual(args[0:3], [ar, '-NOLOGO', '-LIST'])
   1.290 +            # Remaining argument is always one library
   1.291 +            self.assertRelEqual([os.path.splitext(arg)[1] for arg in args[3:]],
   1.292 +[config.LIB_SUFFIX])
   1.293 +            # Simulate LIB -NOLOGO -LIST
   1.294 +            lib = os.path.splitext(os.path.basename(args[3]))[0]
   1.295 +            return '%s\n%s\n' % (Obj(lib), Obj(lib + '2'))
   1.296 +        subprocess.check_output = check_output
   1.297 +
   1.298 +        # ExpandArgsMore does the same as ExpandArgs
   1.299 +        self.touch([self.tmpfile('liby', Lib('y'))])
   1.300 +        with ExpandArgsMore(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))]) as args:
   1.301 +            self.assertRelEqual(args, ['foo', '-bar'] + self.files + [self.tmpfile('liby', Lib('y'))])
   1.302 +
   1.303 +            # ExpandArgsMore also has an extra method extracting static libraries
   1.304 +            # when possible
   1.305 +            args.extract()
   1.306 +
   1.307 +            files = self.files + self.liby_files + self.libx_files
   1.308 +            # With AR_EXTRACT, it uses the descriptors when there are, and
   1.309 +            # actually
   1.310 +            # extracts the remaining libraries
   1.311 +            extracted_args = []
   1.312 +            for f in files:
   1.313 +                if f.endswith(config.LIB_SUFFIX):
   1.314 +                    extracted_args.extend(sorted(extracted[os.path.splitext(os.path.basename(f))[0]]))
   1.315 +                else:
   1.316 +                    extracted_args.append(f)
   1.317 +            self.assertRelEqual(args, ['foo', '-bar'] + extracted_args)
   1.318 +
   1.319 +            tmp = args.tmp
   1.320 +        # Check that all temporary files are properly removed
   1.321 +        self.assertEqual(True, all([not os.path.exists(f) for f in tmp]))
   1.322 +
   1.323 +        # Restore subprocess.call
   1.324 +        subprocess.call = subprocess_call
   1.325 +
   1.326 +class FakeProcess(object):
   1.327 +    def __init__(self, out, err = ''):
   1.328 +        self.out = out
   1.329 +        self.err = err
   1.330 +
   1.331 +    def communicate(self):
   1.332 +        return (self.out, self.err)
   1.333 +
   1.334 +OBJDUMPS = {
   1.335 +'foo.o': '''
   1.336 +00000000 g     F .text\t00000001 foo
   1.337 +00000000 g     F .text._Z6foobarv\t00000001 _Z6foobarv
   1.338 +00000000 g     F .text.hello\t00000001 hello
   1.339 +00000000 g     F .text._ZThn4_6foobarv\t00000001 _ZThn4_6foobarv
   1.340 +''',
   1.341 +'bar.o': '''
   1.342 +00000000 g     F .text.hi\t00000001 hi
   1.343 +00000000 g     F .text.hot._Z6barbazv\t00000001 .hidden _Z6barbazv
   1.344 +''',
   1.345 +}
   1.346 +
   1.347 +PRINT_ICF = '''
   1.348 +ld: ICF folding section '.text.hello' in file 'foo.o'into '.text.hi' in file 'bar.o'
   1.349 +ld: ICF folding section '.foo' in file 'foo.o'into '.foo' in file 'bar.o'
   1.350 +'''
   1.351 +
   1.352 +class SubprocessPopen(object):
   1.353 +    def __init__(self, test):
   1.354 +        self.test = test
   1.355 +
   1.356 +    def __call__(self, args, stdout = None, stderr = None):
   1.357 +        self.test.assertEqual(stdout, subprocess.PIPE)
   1.358 +        self.test.assertEqual(stderr, subprocess.PIPE)
   1.359 +        if args[0] == 'objdump':
   1.360 +            self.test.assertEqual(args[1], '-t')
   1.361 +            self.test.assertTrue(args[2] in OBJDUMPS)
   1.362 +            return FakeProcess(OBJDUMPS[args[2]])
   1.363 +        else:
   1.364 +            return FakeProcess('', PRINT_ICF)
   1.365 +
   1.366 +class TestSectionFinder(unittest.TestCase):
   1.367 +    def test_getSections(self):
   1.368 +        '''Test SectionFinder'''
   1.369 +        # Divert subprocess.Popen
   1.370 +        subprocess_popen = subprocess.Popen
   1.371 +        subprocess.Popen = SubprocessPopen(self)
   1.372 +        config.EXPAND_LIBS_ORDER_STYLE = 'linkerscript'
   1.373 +        config.OBJ_SUFFIX = '.o'
   1.374 +        config.LIB_SUFFIX = '.a'
   1.375 +        finder = SectionFinder(['foo.o', 'bar.o'])
   1.376 +        self.assertEqual(finder.getSections('foobar'), [])
   1.377 +        self.assertEqual(finder.getSections('_Z6barbazv'), ['.text.hot._Z6barbazv'])
   1.378 +        self.assertEqual(finder.getSections('_Z6foobarv'), ['.text._Z6foobarv', '.text._ZThn4_6foobarv'])
   1.379 +        self.assertEqual(finder.getSections('_ZThn4_6foobarv'), ['.text._Z6foobarv', '.text._ZThn4_6foobarv'])
   1.380 +        subprocess.Popen = subprocess_popen
   1.381 +
   1.382 +class TestSymbolOrder(unittest.TestCase):
   1.383 +    def test_getOrderedSections(self):
   1.384 +        '''Test ExpandMoreArgs' _getOrderedSections'''
   1.385 +        # Divert subprocess.Popen
   1.386 +        subprocess_popen = subprocess.Popen
   1.387 +        subprocess.Popen = SubprocessPopen(self)
   1.388 +        config.EXPAND_LIBS_ORDER_STYLE = 'linkerscript'
   1.389 +        config.OBJ_SUFFIX = '.o'
   1.390 +        config.LIB_SUFFIX = '.a'
   1.391 +        config.LD_PRINT_ICF_SECTIONS = ''
   1.392 +        args = ExpandArgsMore(['foo', '-bar', 'bar.o', 'foo.o'])
   1.393 +        self.assertEqual(args._getOrderedSections(['_Z6foobarv', '_Z6barbazv']), ['.text._Z6foobarv', '.text._ZThn4_6foobarv', '.text.hot._Z6barbazv'])
   1.394 +        self.assertEqual(args._getOrderedSections(['_ZThn4_6foobarv', '_Z6barbazv']), ['.text._Z6foobarv', '.text._ZThn4_6foobarv', '.text.hot._Z6barbazv'])
   1.395 +        subprocess.Popen = subprocess_popen
   1.396 +
   1.397 +    def test_getFoldedSections(self):
   1.398 +        '''Test ExpandMoreArgs' _getFoldedSections'''
   1.399 +        # Divert subprocess.Popen
   1.400 +        subprocess_popen = subprocess.Popen
   1.401 +        subprocess.Popen = SubprocessPopen(self)
   1.402 +        config.LD_PRINT_ICF_SECTIONS = '-Wl,--print-icf-sections'
   1.403 +        args = ExpandArgsMore(['foo', '-bar', 'bar.o', 'foo.o'])
   1.404 +        self.assertEqual(args._getFoldedSections(), {'.text.hello': ['.text.hi'], '.text.hi': ['.text.hello']})
   1.405 +        subprocess.Popen = subprocess_popen
   1.406 +
   1.407 +    def test_getOrderedSectionsWithICF(self):
   1.408 +        '''Test ExpandMoreArgs' _getOrderedSections, with ICF'''
   1.409 +        # Divert subprocess.Popen
   1.410 +        subprocess_popen = subprocess.Popen
   1.411 +        subprocess.Popen = SubprocessPopen(self)
   1.412 +        config.EXPAND_LIBS_ORDER_STYLE = 'linkerscript'
   1.413 +        config.OBJ_SUFFIX = '.o'
   1.414 +        config.LIB_SUFFIX = '.a'
   1.415 +        config.LD_PRINT_ICF_SECTIONS = '-Wl,--print-icf-sections'
   1.416 +        args = ExpandArgsMore(['foo', '-bar', 'bar.o', 'foo.o'])
   1.417 +        self.assertEqual(args._getOrderedSections(['hello', '_Z6barbazv']), ['.text.hello', '.text.hi', '.text.hot._Z6barbazv'])
   1.418 +        self.assertEqual(args._getOrderedSections(['_ZThn4_6foobarv', 'hi', '_Z6barbazv']), ['.text._Z6foobarv', '.text._ZThn4_6foobarv', '.text.hi', '.text.hello', '.text.hot._Z6barbazv'])
   1.419 +        subprocess.Popen = subprocess_popen
   1.420 +
   1.421 +
   1.422 +if __name__ == '__main__':
   1.423 +    mozunit.main()

mercurial