| # 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 sys |
| import unittest |
| |
| from mozunit import main |
| |
| from mozbuild.base import MozbuildObject |
| from mozpack.files import FileFinder |
| from mozbuild.frontend.context import Files |
| from mozbuild.frontend.reader import ( |
| BuildReader, |
| EmptyConfig, |
| ) |
| |
| |
| class TestMozbuildReading(unittest.TestCase): |
| # This hack is needed to appease running in automation. |
| def setUp(self): |
| self._old_env = dict(os.environ) |
| os.environ.pop('MOZCONFIG', None) |
| os.environ.pop('MOZ_OBJDIR', None) |
| |
| def tearDown(self): |
| os.environ.clear() |
| os.environ.update(self._old_env) |
| |
| def _mozbuilds(self, reader): |
| if not hasattr(self, '_mozbuild_paths'): |
| self._mozbuild_paths = set(reader.all_mozbuild_paths()) |
| |
| return self._mozbuild_paths |
| |
| @unittest.skip('failing in SpiderMonkey builds') |
| def test_filesystem_traversal_reading(self): |
| """Reading moz.build according to filesystem traversal works. |
| |
| We attempt to read every known moz.build file via filesystem traversal. |
| |
| If this test fails, it means that metadata extraction will fail. |
| """ |
| mb = MozbuildObject.from_environment(detect_virtualenv_mozinfo=False) |
| config = mb.config_environment |
| reader = BuildReader(config) |
| all_paths = self._mozbuilds(reader) |
| paths, contexts = reader.read_relevant_mozbuilds(all_paths) |
| self.assertEqual(set(paths), all_paths) |
| self.assertGreaterEqual(len(contexts), len(paths)) |
| |
| def test_filesystem_traversal_no_config(self): |
| """Reading moz.build files via filesystem traversal mode with no build config. |
| |
| This is similar to the above test except no build config is applied. |
| This will likely fail in more scenarios than the above test because a |
| lot of moz.build files assumes certain variables are present. |
| """ |
| here = os.path.abspath(os.path.dirname(__file__)) |
| root = os.path.normpath(os.path.join(here, '..', '..')) |
| config = EmptyConfig(root) |
| reader = BuildReader(config) |
| all_paths = self._mozbuilds(reader) |
| paths, contexts = reader.read_relevant_mozbuilds(all_paths) |
| self.assertEqual(set(paths.keys()), all_paths) |
| self.assertGreaterEqual(len(contexts), len(paths)) |
| |
| |
| def test_orphan_file_patterns(self): |
| if sys.platform == 'win32': |
| raise unittest.SkipTest('failing on windows builds') |
| |
| mb = MozbuildObject.from_environment(detect_virtualenv_mozinfo=False) |
| |
| try: |
| config = mb.config_environment |
| except Exception as e: |
| if e.message == 'config.status not available. Run configure.': |
| raise unittest.SkipTest('failing without config.status') |
| raise |
| |
| reader = BuildReader(config) |
| all_paths = self._mozbuilds(reader) |
| _, contexts = reader.read_relevant_mozbuilds(all_paths) |
| |
| finder = FileFinder(config.topsrcdir, find_executables=False, |
| ignore=['obj*']) |
| |
| def pattern_exists(pat): |
| return [p for p in finder.find(pat)] != [] |
| |
| for ctx in contexts: |
| if not isinstance(ctx, Files): |
| continue |
| relsrcdir = ctx.relsrcdir |
| if not pattern_exists(os.path.join(relsrcdir, ctx.pattern)): |
| self.fail("The pattern '%s' in a Files() entry in " |
| "'%s' corresponds to no files in the tree.\n" |
| "Please update this entry." % |
| (ctx.pattern, ctx.main_path)) |
| test_files = ctx['IMPACTED_TESTS'].files |
| for p in test_files: |
| if not pattern_exists(os.path.relpath(p.full_path, config.topsrcdir)): |
| self.fail("The pattern '%s' in a dependent tests entry " |
| "in '%s' corresponds to no files in the tree.\n" |
| "Please update this entry." % |
| (p, ctx.main_path)) |
| |
| if __name__ == '__main__': |
| main() |