blob: 1d94129dcdfe1e1c8a00d2c487f1efcd021bd195 [file] [log] [blame]
# Copyright 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import unittest
import json
from blinkpy.common.host_mock import MockHost
from blinkpy.common.path_finder import RELATIVE_WEB_TESTS
from blinkpy.common.system.executive_mock import MockExecutive
from blinkpy.common.system.filesystem_mock import MockFileSystem
from blinkpy.w3c.directory_owners_extractor import DirectoryOwnersExtractor, WPTDirMetadata
MOCK_WEB_TESTS = '/mock-checkout/' + RELATIVE_WEB_TESTS
MOCK_WEB_TESTS_WITHOUT_SLASH = MOCK_WEB_TESTS[:-1]
ABS_WPT_BASE = MOCK_WEB_TESTS + 'external/wpt'
REL_WPT_BASE = RELATIVE_WEB_TESTS + 'external/wpt'
class DirectoryOwnersExtractorTest(unittest.TestCase):
def setUp(self):
# We always have an OWNERS file at web_tests/external.
self.host = MockHost()
self.host.filesystem = MockFileSystem(files={
MOCK_WEB_TESTS + 'external/OWNERS':
'ecosystem-infra@chromium.org'
})
self.extractor = DirectoryOwnersExtractor(self.host)
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.host.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':
'a@chromium.org\nc@chromium.org\n',
ABS_WPT_BASE + '/bar/x/y.html':
'',
ABS_WPT_BASE + '/bar/OWNERS':
'a@chromium.org\nc@chromium.org\n',
})
changed_files = [
REL_WPT_BASE + '/foo/x.html',
REL_WPT_BASE + '/bar/x/y.html',
]
self.assertEqual(
self.extractor.list_owners(changed_files), {
('a@chromium.org', 'c@chromium.org'):
['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': 'foo@chromium.org\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),
{('foo@chromium.org', ): ['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':
'foo@chromium.org\n',
})
changed_files = [
REL_WPT_BASE + '/baz/x/y/z.html',
]
self.assertEqual(
self.extractor.list_owners(changed_files),
{('foo@chromium.org', ): ['external/wpt/baz/x']})
def test_list_owners_not_found(self):
self._write_files({
# Although web_tests/external/OWNERS exists, it should not be listed.
ABS_WPT_BASE + '/foo/bar.html':
'',
# Files out of external.
'/mock-checkout/' + RELATIVE_WEB_TESTS + 'TestExpectations':
'',
'/mock-checkout/' + RELATIVE_WEB_TESTS + 'OWNERS':
'foo@chromium.org',
})
changed_files = [
REL_WPT_BASE + '/foo/bar.html',
RELATIVE_WEB_TESTS + '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': 'a@chromium.org'})
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': 'a@chromium.org',
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_WEB_TESTS + '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: 'a@chromium.org',
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/' + RELATIVE_WEB_TESTS + 'OWNERS':
'foo@chromium.org',
'/mock-checkout/' + RELATIVE_WEB_TESTS + 'other/some_file':
'',
})
self.assertIsNone(
self.extractor.find_owners_file(RELATIVE_WEB_TESTS[:-1]))
self.assertIsNone(
self.extractor.find_owners_file(RELATIVE_WEB_TESTS + 'other'))
self.assertIsNone(self.extractor.find_owners_file('third_party'))
def test_extract_owners(self):
self.host.filesystem.files = {
ABS_WPT_BASE + '/foo/OWNERS':
'#This is a comment\n'
'*\n'
'foo@chromium.org\n'
'bar@chromium.org\n'
'foobar\n'
'#foobar@chromium.org\n'
'# TEAM: some-team@chromium.org\n'
'# COMPONENT: Blink>Layout\n'
}
self.assertEqual(
self.extractor.extract_owners(ABS_WPT_BASE + '/foo/OWNERS'),
['foo@chromium.org', 'bar@chromium.org'])
def test_extract_component(self):
self.host.filesystem.files = {
ABS_WPT_BASE + '/foo/OWNERS':
'# TEAM: some-team@chromium.org\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.host.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.host.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.host.filesystem.files = {
ABS_WPT_BASE + '/foo/OWNERS':
'# TEAM: some-team@chromium.org\n'
'# COMPONENT: Blink>Layout\n'
}
self.assertFalse(
self.extractor.is_wpt_notify_enabled(ABS_WPT_BASE + '/foo/OWNERS'))
def test_is_wpt_notify_enabled_with_dir_metadata(self):
self.host.filesystem.files = {
ABS_WPT_BASE + '/foo/OWNERS':
'# TEAM: some-team@chromium.org\n'
'# COMPONENT: Blink>Layout\n'
'# WPT-NOTIFY: true\n'
}
data = (
'{"dirs":{"a/b":{"monorail":'
'{"component":"foo"},"teamEmail":"bar","wpt":{"notify":"YES"}}}}')
self.host.executive = MockExecutive(output=data)
extractor = DirectoryOwnersExtractor(self.host)
self.assertTrue(
extractor.is_wpt_notify_enabled(MOCK_WEB_TESTS + 'a/b/OWNERS'))
def test_is_wpt_notify_enabled_with_dir_metadata_none(self):
self.host.filesystem.files = {
ABS_WPT_BASE + '/foo/OWNERS':
'# COMPONENT: Blink>Layout\n'
'# WPT-NOTIFY: true\n'
}
self.host.executive = MockExecutive(output='error')
extractor = DirectoryOwnersExtractor(self.host)
self.assertTrue(
extractor.is_wpt_notify_enabled(ABS_WPT_BASE + '/foo/OWNERS'))
def test_extract_component_with_dir_metadata(self):
data = (
'{"dirs":{"a/b":{"monorail":'
'{"component":"foo"},"teamEmail":"bar","wpt":{"notify":"YES"}}}}')
self.host.executive = MockExecutive(output=data)
extractor = DirectoryOwnersExtractor(self.host)
self.assertEqual(
extractor.extract_component(MOCK_WEB_TESTS + 'a/b/OWNERS'), 'foo')
def test_read_dir_metadata_success(self):
data = (
'{"dirs":{"a/b":{"monorail":'
'{"component":"foo"},"teamEmail":"bar","wpt":{"notify":"YES"}}}}')
self.host.executive = MockExecutive(output=data)
extractor = DirectoryOwnersExtractor(self.host)
wpt_dir_metadata = extractor._read_dir_metadata(MOCK_WEB_TESTS +
'a/b/OWNERS')
self.assertEqual(self.host.executive.full_calls[0].args, [
'dirmd', 'compute', '-root', MOCK_WEB_TESTS_WITHOUT_SLASH,
MOCK_WEB_TESTS + 'a/b'
])
self.assertEqual(wpt_dir_metadata.team_email, 'bar')
self.assertEqual(wpt_dir_metadata.should_notify, True)
self.assertEqual(wpt_dir_metadata.component, 'foo')
def test_read_dir_metadata_none(self):
self.host.executive = MockExecutive(output='error')
extractor = DirectoryOwnersExtractor(self.host)
wpt_dir_metadata = extractor._read_dir_metadata(MOCK_WEB_TESTS +
'a/b/OWNERS')
self.assertEqual(self.host.executive.full_calls[0].args, [
'dirmd', 'compute', '-root', MOCK_WEB_TESTS_WITHOUT_SLASH,
MOCK_WEB_TESTS + 'a/b'
])
self.assertEqual(wpt_dir_metadata, None)
class WPTDirMetadataTest(unittest.TestCase):
def test_WPTDirMetadata_empty_content(self):
empty_data = '{"dirs":{"a/b":{}}}'
wpt_dir_metadata = WPTDirMetadata(json.loads(empty_data), 'a/b')
self.assertEqual(wpt_dir_metadata.team_email, None)
self.assertEqual(wpt_dir_metadata.should_notify, None)
self.assertEqual(wpt_dir_metadata.component, None)
def test_WPTDirMetadata_all_fields(self):
data = (
'{"dirs":{"a/b":{"monorail":'
'{"component":"foo"},"teamEmail":"bar","wpt":{"notify":"YES"}}}}')
wpt_dir_metadata = WPTDirMetadata(json.loads(data), 'a/b')
self.assertEqual(wpt_dir_metadata.team_email, 'bar')
self.assertEqual(wpt_dir_metadata.should_notify, True)
self.assertEqual(wpt_dir_metadata.component, 'foo')
def test_WPTDirMetadata_empty_wpt(self):
data = ('{"dirs":{"a/b":{"monorail":'
'{"component":"foo"},"teamEmail":"bar"}}}')
wpt_dir_metadata = WPTDirMetadata(json.loads(data), 'a/b')
self.assertEqual(wpt_dir_metadata.team_email, 'bar')
self.assertEqual(wpt_dir_metadata.should_notify, False)
self.assertEqual(wpt_dir_metadata.component, 'foo')