Exemple #1
0
 def get_directory_owners(self):
     """Returns a mapping of email addresses to owners of changed tests."""
     _log.info('Gathering directory owners emails to CC.')
     changed_files = self.host.git().changed_files()
     extractor = DirectoryOwnersExtractor(self.fs)
     extractor.read_owner_map()
     return extractor.list_owners(changed_files)
Exemple #2
0
class DirectoryOwnersExtractorTest(unittest.TestCase):
    def setUp(self):
        self.filesystem = MockFileSystem()
        self.extractor = DirectoryOwnersExtractor(self.filesystem)

    def test_lines_to_owner_map(self):
        lines = [
            'external/wpt/webgl [ Skip ]',
            '## Owners: [email protected]',
            '# external/wpt/webmessaging [ Pass ]',
            '## Owners: [email protected]',
            '# external/wpt/webrtc [ Pass ]',
            'external/wpt/websockets [ Skip ]',
            '## Owners: [email protected],[email protected]',
            '# external/wpt/webstorage [ Pass ]',
            'external/wpt/webvtt [ Skip ]',
        ]

        self.assertEqual(
            self.extractor.lines_to_owner_map(lines), {
                'external/wpt/webmessaging': ['*****@*****.**'],
                'external/wpt/webrtc': ['*****@*****.**'],
                'external/wpt/webstorage':
                ['*****@*****.**', '*****@*****.**'],
            })

    def test_list_owners(self):
        self.extractor.owner_map = {
            'external/wpt/foo': ['*****@*****.**', '*****@*****.**'],
            'external/wpt/bar': ['*****@*****.**'],
            'external/wpt/baz': ['*****@*****.**', '*****@*****.**'],
        }
        self.filesystem.files = {
            '/mock-checkout/third_party/WebKit/LayoutTests/external/wpt/foo/x/y.html':
            '',
            '/mock-checkout/third_party/WebKit/LayoutTests/external/wpt/bar/x/y.html':
            '',
            '/mock-checkout/third_party/WebKit/LayoutTests/external/wpt/baz/x/y.html':
            '',
            '/mock-checkout/third_party/WebKit/LayoutTests/external/wpt/quux/x/y.html':
            '',
        }
        changed_files = [
            'third_party/WebKit/LayoutTests/external/wpt/foo/x/y.html',
            'third_party/WebKit/LayoutTests/external/wpt/baz/x/y.html',
            'third_party/WebKit/LayoutTests/external/wpt/quux/x/y.html',
        ]
        self.assertEqual(
            self.extractor.list_owners(changed_files), {
                ('*****@*****.**', '*****@*****.**'):
                ['external/wpt/foo', 'external/wpt/baz']
            })

    def test_extract_owner_positive_cases(self):
        self.assertEqual(
            self.extractor.extract_owners('## Owners: [email protected]'),
            ['*****@*****.**'])
        self.assertEqual(
            self.extractor.extract_owners('# Owners: [email protected]'),
            ['*****@*****.**'])
        self.assertEqual(
            self.extractor.extract_owners('## Owners: [email protected],[email protected]'),
            ['*****@*****.**', '*****@*****.**'])
        self.assertEqual(
            self.extractor.extract_owners('## Owners: [email protected], [email protected]'),
            ['*****@*****.**', '*****@*****.**'])
        self.assertEqual(
            self.extractor.extract_owners('## Owner: [email protected]'),
            ['*****@*****.**'])

    def test_extract_owner_negative_cases(self):
        self.assertIsNone(self.extractor.extract_owners(''))
        self.assertIsNone(
            self.extractor.extract_owners('## Something: [email protected]'))
        self.assertIsNone(
            self.extractor.extract_owners('## Owners: not an email address'))

    def test_extract_directory_positive_cases(self):
        self.assertEqual(
            self.extractor.extract_directory('external/a/b [ Pass ]'),
            'external/a/b')
        self.assertEqual(
            self.extractor.extract_directory('# external/c/d [ Pass ]'),
            'external/c/d')
        self.assertEqual(
            self.extractor.extract_directory('# external/e/f [ Skip ]'),
            'external/e/f')
        self.assertEqual(
            self.extractor.extract_directory('# external/g/h/i [ Skip ]'),
            'external/g/h/i')

    def test_extract_directory_negative_cases(self):
        self.assertIsNone(self.extractor.extract_directory(''))
        self.assertIsNone(
            self.extractor.extract_directory('external/a/b [ Skip ]'))
        self.assertIsNone(self.extractor.extract_directory('# some comment'))
class DirectoryOwnersExtractorTest(unittest.TestCase):

    def setUp(self):
        self.filesystem = MockFileSystem()
        self.extractor = DirectoryOwnersExtractor(self.filesystem)

    def test_list_owners(self):
        self.filesystem.files = {
            ABS_WPT_BASE + '/foo/x.html': '',
            ABS_WPT_BASE + '/foo/OWNERS': '[email protected]\[email protected]\n',
            ABS_WPT_BASE + '/bar/x/y.html': '',
            ABS_WPT_BASE + '/bar/OWNERS': '[email protected]\[email protected]\n',
            ABS_WPT_BASE + '/baz/x/y.html': '',
            ABS_WPT_BASE + '/baz/x/OWNERS': '[email protected]\n',
            ABS_WPT_BASE + '/quux/x/y.html': '',
        }
        changed_files = [
            # Same owners:
            REL_WPT_BASE + '/foo/x.html',
            REL_WPT_BASE + '/bar/x/y.html',
            # Same owned directories:
            REL_WPT_BASE + '/baz/x/y.html',
            REL_WPT_BASE + '/baz/x/z.html',
            # Owners not found:
            REL_WPT_BASE + '/quux/x/y.html',
        ]
        self.assertEqual(
            self.extractor.list_owners(changed_files),
            {('*****@*****.**', '*****@*****.**'): ['external/wpt/bar', 'external/wpt/foo'],
             ('*****@*****.**',): ['external/wpt/baz/x']}
        )

    def test_find_and_extract_owners_current_dir(self):
        self.filesystem.files = {
            ABS_WPT_BASE + '/foo/OWNERS': '*****@*****.**'
        }
        self.assertEqual(self.extractor.find_and_extract_owners(REL_WPT_BASE + '/foo'),
                         (ABS_WPT_BASE + '/foo/OWNERS', ['*****@*****.**']))

    def test_find_and_extract_owners_ancestor(self):
        self.filesystem.files = {
            ABS_WPT_BASE + '/x/OWNERS': '*****@*****.**',
            ABS_WPT_BASE + '/x/y/z.html': '',
        }
        self.assertEqual(self.extractor.find_and_extract_owners(REL_WPT_BASE + '/x/y'),
                         (ABS_WPT_BASE + '/x/OWNERS', ['*****@*****.**']))

    def test_find_and_extract_owners_not_found(self):
        self.filesystem.files = {
            ABS_WPT_BASE + '/foo/OWNERS': '*****@*****.**',
            '/mock-checkout/third_party/WebKit/LayoutTests/external/OWNERS': '*****@*****.**',
            ABS_WPT_BASE + '/x/y/z.html': '',
        }
        self.assertEqual(self.extractor.find_and_extract_owners(REL_WPT_BASE + '/x/y'),
                         (None, None))

    def test_find_and_extract_owners_skip_empty(self):
        self.filesystem.files = {
            ABS_WPT_BASE + '/x/OWNERS': '*****@*****.**',
            ABS_WPT_BASE + '/x/y/OWNERS': '# [email protected]',
            ABS_WPT_BASE + '/x/y/z.html': '',
        }
        self.assertEqual(self.extractor.find_and_extract_owners(REL_WPT_BASE + '/x/y'),
                         (ABS_WPT_BASE + '/x/OWNERS', ['*****@*****.**']))

    def test_find_and_extract_owners_absolute_path(self):
        with self.assertRaises(AssertionError):
            self.extractor.find_and_extract_owners('/absolute/path')

    def test_find_and_extract_owners_out_of_tree(self):
        with self.assertRaises(AssertionError):
            self.extractor.find_and_extract_owners('third_party/WebKit/LayoutTests/other')
        self.assertEqual(
            self.extractor.find_and_extract_owners('third_party/WebKit/LayoutTests'),
            (None, None))
        self.assertEqual(
            self.extractor.find_and_extract_owners('third_party/WebKit/LayoutTests/FlagExpectations/foo-bar'),
            (None, None))

    def test_extract_owners(self):
        self.filesystem.files = {
            ABS_WPT_BASE + '/foo/OWNERS':
            '#This is a comment\n'
            '*\n'
            '[email protected]\n'
            '[email protected]\n'
            'foobar\n'
            '#[email protected]\n'
            '# TEAM: [email protected]\n'
            '# COMPONENT: Blink>Layout\n'
        }
        self.assertEqual(self.extractor.extract_owners(ABS_WPT_BASE + '/foo/OWNERS'),
                         ['*****@*****.**', '*****@*****.**'])
Exemple #4
0
class DirectoryOwnersExtractorTest(unittest.TestCase):
    def setUp(self):
        # We always have an OWNERS file at LayoutTests/external.
        self.filesystem = MockFileSystem(
            files={
                '/mock-checkout/third_party/WebKit/LayoutTests/external/OWNERS':
                '*****@*****.**'
            })
        self.extractor = DirectoryOwnersExtractor(self.filesystem)

    def _write_files(self, files):
        # Use write_text_file instead of directly assigning to filesystem.files
        # so that intermediary directories are correctly created, too.
        for path, contents in files.iteritems():
            self.filesystem.write_text_file(path, contents)

    def test_list_owners_combines_same_owners(self):
        self._write_files({
            ABS_WPT_BASE + '/foo/x.html':
            '',
            ABS_WPT_BASE + '/foo/OWNERS':
            '[email protected]\[email protected]\n',
            ABS_WPT_BASE + '/bar/x/y.html':
            '',
            ABS_WPT_BASE + '/bar/OWNERS':
            '[email protected]\[email protected]\n',
        })
        changed_files = [
            REL_WPT_BASE + '/foo/x.html',
            REL_WPT_BASE + '/bar/x/y.html',
        ]
        self.assertEqual(
            self.extractor.list_owners(changed_files), {
                ('*****@*****.**', '*****@*****.**'):
                ['external/wpt/bar', 'external/wpt/foo']
            })

    def test_list_owners_combines_same_directory(self):
        self._write_files({
            ABS_WPT_BASE + '/baz/x/y.html': '',
            ABS_WPT_BASE + '/baz/x/y/z.html': '',
            ABS_WPT_BASE + '/baz/x/OWNERS': '[email protected]\n',
        })
        changed_files = [
            REL_WPT_BASE + '/baz/x/y.html',
            REL_WPT_BASE + '/baz/x/y/z.html',
        ]
        self.assertEqual(self.extractor.list_owners(changed_files),
                         {('*****@*****.**', ): ['external/wpt/baz/x']})

    def test_list_owners_skips_empty_owners(self):
        self._write_files({
            ABS_WPT_BASE + '/baz/x/y/z.html': '',
            ABS_WPT_BASE + '/baz/x/y/OWNERS': '# Some comments\n',
            ABS_WPT_BASE + '/baz/x/OWNERS': '[email protected]\n',
        })
        changed_files = [
            REL_WPT_BASE + '/baz/x/y/z.html',
        ]
        self.assertEqual(self.extractor.list_owners(changed_files),
                         {('*****@*****.**', ): ['external/wpt/baz/x']})

    def test_list_owners_not_found(self):
        self._write_files({
            # Although LayoutTests/external/OWNERS exists, it should not be listed.
            ABS_WPT_BASE + '/foo/bar.html':
            '',
            # Files out of external.
            '/mock-checkout/third_party/WebKit/LayoutTests/TestExpectations':
            '',
            '/mock-checkout/third_party/WebKit/LayoutTests/OWNERS':
            '*****@*****.**',
        })
        changed_files = [
            REL_WPT_BASE + '/foo/bar.html',
            'third_party/WebKit/LayoutTests/TestExpectations',
        ]
        self.assertEqual(self.extractor.list_owners(changed_files), {})

    def test_find_owners_file_at_current_dir(self):
        self._write_files({ABS_WPT_BASE + '/foo/OWNERS': '*****@*****.**'})
        self.assertEqual(
            self.extractor.find_owners_file(REL_WPT_BASE + '/foo'),
            ABS_WPT_BASE + '/foo/OWNERS')

    def test_find_owners_file_at_ancestor(self):
        self._write_files({
            ABS_WPT_BASE + '/x/OWNERS': '*****@*****.**',
            ABS_WPT_BASE + '/x/y/z.html': '',
        })
        self.assertEqual(
            self.extractor.find_owners_file(REL_WPT_BASE + '/x/y'),
            ABS_WPT_BASE + '/x/OWNERS')

    def test_find_owners_file_stops_at_external_root(self):
        self._write_files({
            ABS_WPT_BASE + '/x/y/z.html': '',
        })
        self.assertEqual(
            self.extractor.find_owners_file(REL_WPT_BASE + '/x/y'),
            '/mock-checkout/third_party/WebKit/LayoutTests/external/OWNERS')

    def test_find_owners_file_takes_four_kinds_of_paths(self):
        owners_path = ABS_WPT_BASE + '/foo/OWNERS'
        self._write_files({
            owners_path: '*****@*****.**',
            ABS_WPT_BASE + '/foo/bar.html': '',
        })
        # Absolute paths of directories.
        self.assertEqual(
            self.extractor.find_owners_file(ABS_WPT_BASE + '/foo'),
            owners_path)
        # Relative paths of directories.
        self.assertEqual(
            self.extractor.find_owners_file(REL_WPT_BASE + '/foo'),
            owners_path)
        # Absolute paths of files.
        self.assertEqual(
            self.extractor.find_owners_file(ABS_WPT_BASE + '/foo/bar.html'),
            owners_path)
        # Relative paths of files.
        self.assertEqual(
            self.extractor.find_owners_file(REL_WPT_BASE + '/foo/bar.html'),
            owners_path)

    def test_find_owners_file_out_of_external(self):
        self._write_files({
            '/mock-checkout/third_party/WebKit/LayoutTests/OWNERS':
            '*****@*****.**',
            '/mock-checkout/third_party/WebKit/LayoutTests/other/some_file':
            '',
        })
        self.assertIsNone(
            self.extractor.find_owners_file('third_party/WebKit/LayoutTests'))
        self.assertIsNone(
            self.extractor.find_owners_file(
                'third_party/WebKit/LayoutTests/other'))
        self.assertIsNone(self.extractor.find_owners_file('third_party'))

    def test_extract_owners(self):
        self.filesystem.files = {
            ABS_WPT_BASE + '/foo/OWNERS':
            '#This is a comment\n'
            '*\n'
            '[email protected]\n'
            '[email protected]\n'
            'foobar\n'
            '#[email protected]\n'
            '# TEAM: [email protected]\n'
            '# COMPONENT: Blink>Layout\n'
        }
        self.assertEqual(
            self.extractor.extract_owners(ABS_WPT_BASE + '/foo/OWNERS'),
            ['*****@*****.**', '*****@*****.**'])

    def test_extract_component(self):
        self.filesystem.files = {
            ABS_WPT_BASE + '/foo/OWNERS':
            '# TEAM: [email protected]\n'
            '# COMPONENT: Blink>Layout\n'
        }
        self.assertEqual(
            self.extractor.extract_component(ABS_WPT_BASE + '/foo/OWNERS'),
            'Blink>Layout')

    def test_is_wpt_notify_enabled_true(self):
        self.filesystem.files = {
            ABS_WPT_BASE + '/foo/OWNERS':
            '# COMPONENT: Blink>Layout\n'
            '# WPT-NOTIFY: true\n'
        }
        self.assertTrue(
            self.extractor.is_wpt_notify_enabled(ABS_WPT_BASE + '/foo/OWNERS'))

    def test_is_wpt_notify_enabled_false(self):
        self.filesystem.files = {
            ABS_WPT_BASE + '/foo/OWNERS':
            '# COMPONENT: Blink>Layout\n'
            '# WPT-NOTIFY: false\n'
        }
        self.assertFalse(
            self.extractor.is_wpt_notify_enabled(ABS_WPT_BASE + '/foo/OWNERS'))

    def test_is_wpt_notify_enabled_absence_is_false(self):
        self.filesystem.files = {
            ABS_WPT_BASE + '/foo/OWNERS':
            '# TEAM: [email protected]\n'
            '# COMPONENT: Blink>Layout\n'
        }
        self.assertFalse(
            self.extractor.is_wpt_notify_enabled(ABS_WPT_BASE + '/foo/OWNERS'))