diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /python/mozbuild/mozbuild/test/test_mozconfig.py | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'python/mozbuild/mozbuild/test/test_mozconfig.py')
-rw-r--r-- | python/mozbuild/mozbuild/test/test_mozconfig.py | 489 |
1 files changed, 489 insertions, 0 deletions
diff --git a/python/mozbuild/mozbuild/test/test_mozconfig.py b/python/mozbuild/mozbuild/test/test_mozconfig.py new file mode 100644 index 000000000..0cd125912 --- /dev/null +++ b/python/mozbuild/mozbuild/test/test_mozconfig.py @@ -0,0 +1,489 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +from __future__ import unicode_literals + +import os +import unittest + +from shutil import rmtree + +from tempfile import ( + gettempdir, + mkdtemp, +) + +from mozfile.mozfile import NamedTemporaryFile + +from mozunit import main + +from mozbuild.mozconfig import ( + MozconfigFindException, + MozconfigLoadException, + MozconfigLoader, +) + + +class TestMozconfigLoader(unittest.TestCase): + def setUp(self): + self._old_env = dict(os.environ) + os.environ.pop('MOZCONFIG', None) + os.environ.pop('MOZ_OBJDIR', None) + os.environ.pop('CC', None) + os.environ.pop('CXX', None) + self._temp_dirs = set() + + def tearDown(self): + os.environ.clear() + os.environ.update(self._old_env) + + for d in self._temp_dirs: + rmtree(d) + + def get_loader(self): + return MozconfigLoader(self.get_temp_dir()) + + def get_temp_dir(self): + d = mkdtemp() + self._temp_dirs.add(d) + + return d + + def test_find_legacy_env(self): + """Ensure legacy mozconfig path definitions result in error.""" + + os.environ[b'MOZ_MYCONFIG'] = '/foo' + + with self.assertRaises(MozconfigFindException) as e: + self.get_loader().find_mozconfig() + + self.assertTrue(e.exception.message.startswith('The MOZ_MYCONFIG')) + + def test_find_multiple_configs(self): + """Ensure multiple relative-path MOZCONFIGs result in error.""" + relative_mozconfig = '.mconfig' + os.environ[b'MOZCONFIG'] = relative_mozconfig + + srcdir = self.get_temp_dir() + curdir = self.get_temp_dir() + dirs = [srcdir, curdir] + loader = MozconfigLoader(srcdir) + for d in dirs: + path = os.path.join(d, relative_mozconfig) + with open(path, 'wb') as f: + f.write(path) + + orig_dir = os.getcwd() + try: + os.chdir(curdir) + with self.assertRaises(MozconfigFindException) as e: + loader.find_mozconfig() + finally: + os.chdir(orig_dir) + + self.assertIn('exists in more than one of', e.exception.message) + for d in dirs: + self.assertIn(d, e.exception.message) + + def test_find_multiple_but_identical_configs(self): + """Ensure multiple relative-path MOZCONFIGs pointing at the same file are OK.""" + relative_mozconfig = '../src/.mconfig' + os.environ[b'MOZCONFIG'] = relative_mozconfig + + topdir = self.get_temp_dir() + srcdir = os.path.join(topdir, 'src') + os.mkdir(srcdir) + curdir = os.path.join(topdir, 'obj') + os.mkdir(curdir) + + loader = MozconfigLoader(srcdir) + path = os.path.join(srcdir, relative_mozconfig) + with open(path, 'w'): + pass + + orig_dir = os.getcwd() + try: + os.chdir(curdir) + self.assertEqual(os.path.realpath(loader.find_mozconfig()), + os.path.realpath(path)) + finally: + os.chdir(orig_dir) + + def test_find_no_relative_configs(self): + """Ensure a missing relative-path MOZCONFIG is detected.""" + relative_mozconfig = '.mconfig' + os.environ[b'MOZCONFIG'] = relative_mozconfig + + srcdir = self.get_temp_dir() + curdir = self.get_temp_dir() + dirs = [srcdir, curdir] + loader = MozconfigLoader(srcdir) + + orig_dir = os.getcwd() + try: + os.chdir(curdir) + with self.assertRaises(MozconfigFindException) as e: + loader.find_mozconfig() + finally: + os.chdir(orig_dir) + + self.assertIn('does not exist in any of', e.exception.message) + for d in dirs: + self.assertIn(d, e.exception.message) + + def test_find_relative_mozconfig(self): + """Ensure a relative MOZCONFIG can be found in the srcdir.""" + relative_mozconfig = '.mconfig' + os.environ[b'MOZCONFIG'] = relative_mozconfig + + srcdir = self.get_temp_dir() + curdir = self.get_temp_dir() + dirs = [srcdir, curdir] + loader = MozconfigLoader(srcdir) + + path = os.path.join(srcdir, relative_mozconfig) + with open(path, 'w'): + pass + + orig_dir = os.getcwd() + try: + os.chdir(curdir) + self.assertEqual(os.path.normpath(loader.find_mozconfig()), + os.path.normpath(path)) + finally: + os.chdir(orig_dir) + + def test_find_abs_path_not_exist(self): + """Ensure a missing absolute path is detected.""" + os.environ[b'MOZCONFIG'] = '/foo/bar/does/not/exist' + + with self.assertRaises(MozconfigFindException) as e: + self.get_loader().find_mozconfig() + + self.assertIn('path that does not exist', e.exception.message) + self.assertTrue(e.exception.message.endswith('/foo/bar/does/not/exist')) + + def test_find_path_not_file(self): + """Ensure non-file paths are detected.""" + + os.environ[b'MOZCONFIG'] = gettempdir() + + with self.assertRaises(MozconfigFindException) as e: + self.get_loader().find_mozconfig() + + self.assertIn('refers to a non-file', e.exception.message) + self.assertTrue(e.exception.message.endswith(gettempdir())) + + def test_find_default_files(self): + """Ensure default paths are used when present.""" + for p in MozconfigLoader.DEFAULT_TOPSRCDIR_PATHS: + d = self.get_temp_dir() + path = os.path.join(d, p) + + with open(path, 'w'): + pass + + self.assertEqual(MozconfigLoader(d).find_mozconfig(), path) + + def test_find_multiple_defaults(self): + """Ensure we error when multiple default files are present.""" + self.assertGreater(len(MozconfigLoader.DEFAULT_TOPSRCDIR_PATHS), 1) + + d = self.get_temp_dir() + for p in MozconfigLoader.DEFAULT_TOPSRCDIR_PATHS: + with open(os.path.join(d, p), 'w'): + pass + + with self.assertRaises(MozconfigFindException) as e: + MozconfigLoader(d).find_mozconfig() + + self.assertIn('Multiple default mozconfig files present', + e.exception.message) + + def test_find_deprecated_path_srcdir(self): + """Ensure we error when deprecated path locations are present.""" + for p in MozconfigLoader.DEPRECATED_TOPSRCDIR_PATHS: + d = self.get_temp_dir() + with open(os.path.join(d, p), 'w'): + pass + + with self.assertRaises(MozconfigFindException) as e: + MozconfigLoader(d).find_mozconfig() + + self.assertIn('This implicit location is no longer', + e.exception.message) + self.assertIn(d, e.exception.message) + + def test_find_deprecated_home_paths(self): + """Ensure we error when deprecated home directory paths are present.""" + + for p in MozconfigLoader.DEPRECATED_HOME_PATHS: + home = self.get_temp_dir() + os.environ[b'HOME'] = home + path = os.path.join(home, p) + + with open(path, 'w'): + pass + + with self.assertRaises(MozconfigFindException) as e: + self.get_loader().find_mozconfig() + + self.assertIn('This implicit location is no longer', + e.exception.message) + self.assertIn(path, e.exception.message) + + def test_read_no_mozconfig(self): + # This is basically to ensure changes to defaults incur a test failure. + result = self.get_loader().read_mozconfig() + + self.assertEqual(result, { + 'path': None, + 'topobjdir': None, + 'configure_args': None, + 'make_flags': None, + 'make_extra': None, + 'env': None, + 'vars': None, + }) + + def test_read_empty_mozconfig(self): + with NamedTemporaryFile(mode='w') as mozconfig: + result = self.get_loader().read_mozconfig(mozconfig.name) + + self.assertEqual(result['path'], mozconfig.name) + self.assertIsNone(result['topobjdir']) + self.assertEqual(result['configure_args'], []) + self.assertEqual(result['make_flags'], []) + self.assertEqual(result['make_extra'], []) + + for f in ('added', 'removed', 'modified'): + self.assertEqual(len(result['vars'][f]), 0) + self.assertEqual(len(result['env'][f]), 0) + + self.assertEqual(result['env']['unmodified'], {}) + + def test_read_capture_ac_options(self): + """Ensures ac_add_options calls are captured.""" + with NamedTemporaryFile(mode='w') as mozconfig: + mozconfig.write('ac_add_options --enable-debug\n') + mozconfig.write('ac_add_options --disable-tests --enable-foo\n') + mozconfig.write('ac_add_options --foo="bar baz"\n') + mozconfig.flush() + + result = self.get_loader().read_mozconfig(mozconfig.name) + self.assertEqual(result['configure_args'], [ + '--enable-debug', '--disable-tests', '--enable-foo', + '--foo=bar baz']) + + def test_read_ac_options_substitution(self): + """Ensure ac_add_options values are substituted.""" + with NamedTemporaryFile(mode='w') as mozconfig: + mozconfig.write('ac_add_options --foo=@TOPSRCDIR@\n') + mozconfig.flush() + + loader = self.get_loader() + result = loader.read_mozconfig(mozconfig.name) + self.assertEqual(result['configure_args'], [ + '--foo=%s' % loader.topsrcdir]) + + def test_read_ac_app_options(self): + with NamedTemporaryFile(mode='w') as mozconfig: + mozconfig.write('ac_add_options --foo=@TOPSRCDIR@\n') + mozconfig.write('ac_add_app_options app1 --bar=@TOPSRCDIR@\n') + mozconfig.write('ac_add_app_options app2 --bar=x\n') + mozconfig.flush() + + loader = self.get_loader() + result = loader.read_mozconfig(mozconfig.name, moz_build_app='app1') + self.assertEqual(result['configure_args'], [ + '--foo=%s' % loader.topsrcdir, + '--bar=%s' % loader.topsrcdir]) + + result = loader.read_mozconfig(mozconfig.name, moz_build_app='app2') + self.assertEqual(result['configure_args'], [ + '--foo=%s' % loader.topsrcdir, + '--bar=x']) + + def test_read_capture_mk_options(self): + """Ensures mk_add_options calls are captured.""" + with NamedTemporaryFile(mode='w') as mozconfig: + mozconfig.write('mk_add_options MOZ_OBJDIR=/foo/bar\n') + mozconfig.write('mk_add_options MOZ_MAKE_FLAGS="-j8 -s"\n') + mozconfig.write('mk_add_options FOO="BAR BAZ"\n') + mozconfig.write('mk_add_options BIZ=1\n') + mozconfig.flush() + + result = self.get_loader().read_mozconfig(mozconfig.name) + self.assertEqual(result['topobjdir'], '/foo/bar') + self.assertEqual(result['make_flags'], ['-j8', '-s']) + self.assertEqual(result['make_extra'], ['FOO=BAR BAZ', 'BIZ=1']) + + vars = result['vars']['added'] + for var in ('MOZ_OBJDIR', 'MOZ_MAKE_FLAGS', 'FOO', 'BIZ'): + self.assertEqual(vars.get('%s_IS_SET' % var), '1') + + def test_read_empty_mozconfig_objdir_environ(self): + os.environ[b'MOZ_OBJDIR'] = b'obj-firefox' + with NamedTemporaryFile(mode='w') as mozconfig: + result = self.get_loader().read_mozconfig(mozconfig.name) + self.assertEqual(result['topobjdir'], 'obj-firefox') + + def test_read_capture_mk_options_objdir_environ(self): + """Ensures mk_add_options calls are captured and override the environ.""" + os.environ[b'MOZ_OBJDIR'] = b'obj-firefox' + with NamedTemporaryFile(mode='w') as mozconfig: + mozconfig.write('mk_add_options MOZ_OBJDIR=/foo/bar\n') + mozconfig.flush() + + result = self.get_loader().read_mozconfig(mozconfig.name) + self.assertEqual(result['topobjdir'], '/foo/bar') + + def test_read_moz_objdir_substitution(self): + """Ensure @TOPSRCDIR@ substitution is recognized in MOZ_OBJDIR.""" + with NamedTemporaryFile(mode='w') as mozconfig: + mozconfig.write('mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/some-objdir') + mozconfig.flush() + + loader = self.get_loader() + result = loader.read_mozconfig(mozconfig.name) + + self.assertEqual(result['topobjdir'], '%s/some-objdir' % + loader.topsrcdir) + + def test_read_new_variables(self): + """New variables declared in mozconfig file are detected.""" + with NamedTemporaryFile(mode='w') as mozconfig: + mozconfig.write('CC=/usr/local/bin/clang\n') + mozconfig.write('CXX=/usr/local/bin/clang++\n') + mozconfig.flush() + + result = self.get_loader().read_mozconfig(mozconfig.name) + + self.assertEqual(result['vars']['added'], { + 'CC': '/usr/local/bin/clang', + 'CXX': '/usr/local/bin/clang++'}) + self.assertEqual(result['env']['added'], {}) + + def test_read_exported_variables(self): + """Exported variables are caught as new variables.""" + with NamedTemporaryFile(mode='w') as mozconfig: + mozconfig.write('export MY_EXPORTED=woot\n') + mozconfig.flush() + + result = self.get_loader().read_mozconfig(mozconfig.name) + + self.assertEqual(result['vars']['added'], {}) + self.assertEqual(result['env']['added'], { + 'MY_EXPORTED': 'woot'}) + + def test_read_modify_variables(self): + """Variables modified by mozconfig are detected.""" + old_path = os.path.realpath(b'/usr/bin/gcc') + new_path = os.path.realpath(b'/usr/local/bin/clang') + os.environ[b'CC'] = old_path + + with NamedTemporaryFile(mode='w') as mozconfig: + mozconfig.write('CC="%s"\n' % new_path) + mozconfig.flush() + + result = self.get_loader().read_mozconfig(mozconfig.name) + + self.assertEqual(result['vars']['modified'], {}) + self.assertEqual(result['env']['modified'], { + 'CC': (old_path, new_path) + }) + + def test_read_unmodified_variables(self): + """Variables modified by mozconfig are detected.""" + cc_path = os.path.realpath(b'/usr/bin/gcc') + os.environ[b'CC'] = cc_path + + with NamedTemporaryFile(mode='w') as mozconfig: + mozconfig.flush() + + result = self.get_loader().read_mozconfig(mozconfig.name) + + self.assertEqual(result['vars']['unmodified'], {}) + self.assertEqual(result['env']['unmodified'], { + 'CC': cc_path + }) + + def test_read_removed_variables(self): + """Variables unset by the mozconfig are detected.""" + cc_path = os.path.realpath(b'/usr/bin/clang') + os.environ[b'CC'] = cc_path + + with NamedTemporaryFile(mode='w') as mozconfig: + mozconfig.write('unset CC\n') + mozconfig.flush() + + result = self.get_loader().read_mozconfig(mozconfig.name) + + self.assertEqual(result['vars']['removed'], {}) + self.assertEqual(result['env']['removed'], { + 'CC': cc_path}) + + def test_read_multiline_variables(self): + """Ensure multi-line variables are captured properly.""" + with NamedTemporaryFile(mode='w') as mozconfig: + mozconfig.write('multi="foo\nbar"\n') + mozconfig.write('single=1\n') + mozconfig.flush() + + result = self.get_loader().read_mozconfig(mozconfig.name) + + self.assertEqual(result['vars']['added'], { + 'multi': 'foo\nbar', + 'single': '1' + }) + self.assertEqual(result['env']['added'], {}) + + def test_read_topsrcdir_defined(self): + """Ensure $topsrcdir references work as expected.""" + with NamedTemporaryFile(mode='w') as mozconfig: + mozconfig.write('TEST=$topsrcdir') + mozconfig.flush() + + loader = self.get_loader() + result = loader.read_mozconfig(mozconfig.name) + + self.assertEqual(result['vars']['added']['TEST'], + loader.topsrcdir.replace(os.sep, '/')) + self.assertEqual(result['env']['added'], {}) + + def test_read_empty_variable_value(self): + """Ensure empty variable values are parsed properly.""" + with NamedTemporaryFile(mode='w') as mozconfig: + mozconfig.write('EMPTY=\n') + mozconfig.write('export EXPORT_EMPTY=\n') + mozconfig.flush() + + result = self.get_loader().read_mozconfig(mozconfig.name) + + self.assertEqual(result['vars']['added'], { + 'EMPTY': '', + }) + self.assertEqual(result['env']['added'], { + 'EXPORT_EMPTY': '' + }) + + def test_read_load_exception(self): + """Ensure non-0 exit codes in mozconfigs are handled properly.""" + with NamedTemporaryFile(mode='w') as mozconfig: + mozconfig.write('echo "hello world"\n') + mozconfig.write('exit 1\n') + mozconfig.flush() + + with self.assertRaises(MozconfigLoadException) as e: + self.get_loader().read_mozconfig(mozconfig.name) + + self.assertTrue(e.exception.message.startswith( + 'Evaluation of your mozconfig exited with an error')) + self.assertEquals(e.exception.path, + mozconfig.name.replace(os.sep, '/')) + self.assertEquals(e.exception.output, ['hello world']) + + +if __name__ == '__main__': + main() |