| # 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.frontend.reader import BuildReaderError |
| from mozbuild.frontend.reader import BuildReader |
| |
| from mozbuild.test.common import MockConfig |
| |
| |
| if sys.version_info.major == 2: |
| text_type = 'unicode' |
| else: |
| text_type = 'str' |
| |
| data_path = os.path.abspath(os.path.dirname(__file__)) |
| data_path = os.path.join(data_path, 'data') |
| |
| |
| class TestBuildReader(unittest.TestCase): |
| def config(self, name): |
| path = os.path.join(data_path, name) |
| |
| return MockConfig(path) |
| |
| def reader(self, name, enable_tests=False): |
| config = self.config(name) |
| |
| if enable_tests: |
| config.substs['ENABLE_TESTS'] = '1' |
| |
| return BuildReader(config) |
| |
| def file_path(self, name, *args): |
| return os.path.join(data_path, name, *args) |
| |
| def test_dirs_traversal_simple(self): |
| reader = self.reader('traversal-simple') |
| |
| sandboxes = list(reader.read_topsrcdir()) |
| |
| self.assertEqual(len(sandboxes), 4) |
| |
| def test_dirs_traversal_no_descend(self): |
| reader = self.reader('traversal-simple') |
| |
| path = os.path.join(reader.topsrcdir, 'moz.build') |
| self.assertTrue(os.path.exists(path)) |
| |
| sandboxes = list(reader.read_mozbuild(path, |
| filesystem_absolute=True, descend=False)) |
| |
| self.assertEqual(len(sandboxes), 1) |
| |
| def test_dirs_traversal_all_variables(self): |
| reader = self.reader('traversal-all-vars', enable_tests=True) |
| |
| sandboxes = list(reader.read_topsrcdir()) |
| self.assertEqual(len(sandboxes), 6) |
| |
| def test_tiers_traversal(self): |
| reader = self.reader('traversal-tier-simple') |
| |
| sandboxes = list(reader.read_topsrcdir()) |
| self.assertEqual(len(sandboxes), 4) |
| |
| def test_tier_subdir(self): |
| # add_tier_dir() should fail when not in the top directory. |
| reader = self.reader('traversal-tier-fails-in-subdir') |
| |
| with self.assertRaises(Exception): |
| list(reader.read_topsrcdir()) |
| |
| def test_relative_dirs(self): |
| # Ensure relative directories are traversed. |
| reader = self.reader('traversal-relative-dirs') |
| |
| sandboxes = list(reader.read_topsrcdir()) |
| self.assertEqual(len(sandboxes), 3) |
| |
| def test_repeated_dirs_ignored(self): |
| # Ensure repeated directories are ignored. |
| reader = self.reader('traversal-repeated-dirs') |
| |
| sandboxes = list(reader.read_topsrcdir()) |
| self.assertEqual(len(sandboxes), 3) |
| |
| def test_outside_topsrcdir(self): |
| # References to directories outside the topsrcdir should fail. |
| reader = self.reader('traversal-outside-topsrcdir') |
| |
| with self.assertRaises(Exception): |
| list(reader.read_topsrcdir()) |
| |
| def test_error_basic(self): |
| reader = self.reader('reader-error-basic') |
| |
| with self.assertRaises(BuildReaderError) as bre: |
| list(reader.read_topsrcdir()) |
| |
| e = bre.exception |
| self.assertEqual(e.actual_file, self.file_path('reader-error-basic', |
| 'moz.build')) |
| |
| self.assertIn('The error occurred while processing the', str(e)) |
| |
| def test_error_included_from(self): |
| reader = self.reader('reader-error-included-from') |
| |
| with self.assertRaises(BuildReaderError) as bre: |
| list(reader.read_topsrcdir()) |
| |
| e = bre.exception |
| self.assertEqual(e.actual_file, |
| self.file_path('reader-error-included-from', 'child.build')) |
| self.assertEqual(e.main_file, |
| self.file_path('reader-error-included-from', 'moz.build')) |
| |
| self.assertIn('This file was included as part of processing', str(e)) |
| |
| def test_error_syntax_error(self): |
| reader = self.reader('reader-error-syntax') |
| |
| with self.assertRaises(BuildReaderError) as bre: |
| list(reader.read_topsrcdir()) |
| |
| e = bre.exception |
| self.assertIn('Python syntax error on line 5', str(e)) |
| self.assertIn(' foo =', str(e)) |
| self.assertIn(' ^', str(e)) |
| |
| def test_error_read_unknown_global(self): |
| reader = self.reader('reader-error-read-unknown-global') |
| |
| with self.assertRaises(BuildReaderError) as bre: |
| list(reader.read_topsrcdir()) |
| |
| e = bre.exception |
| self.assertIn('The error was triggered on line 5', str(e)) |
| self.assertIn('The underlying problem is an attempt to read', str(e)) |
| self.assertIn(' FOO', str(e)) |
| |
| def test_error_write_unknown_global(self): |
| reader = self.reader('reader-error-write-unknown-global') |
| |
| with self.assertRaises(BuildReaderError) as bre: |
| list(reader.read_topsrcdir()) |
| |
| e = bre.exception |
| self.assertIn('The error was triggered on line 7', str(e)) |
| self.assertIn('The underlying problem is an attempt to write', str(e)) |
| self.assertIn(' FOO', str(e)) |
| |
| def test_error_write_bad_value(self): |
| reader = self.reader('reader-error-write-bad-value') |
| |
| with self.assertRaises(BuildReaderError) as bre: |
| list(reader.read_topsrcdir()) |
| |
| e = bre.exception |
| self.assertIn('The error was triggered on line 5', str(e)) |
| self.assertIn('is an attempt to write an illegal value to a special', |
| str(e)) |
| |
| self.assertIn('variable whose value was rejected is:\n\n DIRS', |
| str(e)) |
| |
| self.assertIn('written to it was of the following type:\n\n %s' % text_type, |
| str(e)) |
| |
| self.assertIn('expects the following type(s):\n\n list', str(e)) |
| |
| def test_error_illegal_path(self): |
| reader = self.reader('reader-error-outside-topsrcdir') |
| |
| with self.assertRaises(BuildReaderError) as bre: |
| list(reader.read_topsrcdir()) |
| |
| e = bre.exception |
| self.assertIn('The underlying problem is an illegal file access', |
| str(e)) |
| |
| def test_error_missing_include_path(self): |
| reader = self.reader('reader-error-missing-include') |
| |
| with self.assertRaises(BuildReaderError) as bre: |
| list(reader.read_topsrcdir()) |
| |
| e = bre.exception |
| self.assertIn('we referenced a path that does not exist', str(e)) |
| |
| def test_error_script_error(self): |
| reader = self.reader('reader-error-script-error') |
| |
| with self.assertRaises(BuildReaderError) as bre: |
| list(reader.read_topsrcdir()) |
| |
| e = bre.exception |
| self.assertIn('The error appears to be the fault of the script', |
| str(e)) |
| self.assertIn(' ["TypeError: unsupported operand', str(e)) |
| |
| def test_error_bad_dir(self): |
| reader = self.reader('reader-error-bad-dir') |
| |
| with self.assertRaises(BuildReaderError) as bre: |
| list(reader.read_topsrcdir()) |
| |
| e = bre.exception |
| self.assertIn('we referenced a path that does not exist', str(e)) |
| |
| def test_error_repeated_dir(self): |
| reader = self.reader('reader-error-repeated-dir') |
| |
| with self.assertRaises(BuildReaderError) as bre: |
| list(reader.read_topsrcdir()) |
| |
| e = bre.exception |
| self.assertIn('Directory (foo) registered multiple times in DIRS', |
| str(e)) |
| |
| def test_error_error_func(self): |
| reader = self.reader('reader-error-error-func') |
| |
| with self.assertRaises(BuildReaderError) as bre: |
| list(reader.read_topsrcdir()) |
| |
| e = bre.exception |
| self.assertIn('A moz.build file called the error() function.', str(e)) |
| self.assertIn(' Some error.', str(e)) |
| |
| |
| if __name__ == '__main__': |
| main() |