| # 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. |
| |
| from collections import OrderedDict |
| from contextlib import contextmanager |
| import os |
| import sys |
| import unittest |
| |
| import owners_file_tags |
| |
| import mock |
| |
| @contextmanager |
| def mock_file_tree(tree): |
| os_walk_mocks = [] |
| file_mocks = {} |
| for path in tree: |
| if tree[path] is not None: |
| os_walk_mocks.append((path, ('ignored'), ('OWNERS', 'dummy.cc'))) |
| file_mocks[os.path.join(path, 'OWNERS')] = tree[path] |
| else: |
| os_walk_mocks.append((path, ('ignored'), ('dummy.cc'))) |
| |
| def custom_mock_open(files_data): |
| def inner_open(path, mode='r'): |
| ret_val = mock.MagicMock() |
| if path in files_data and mode == 'r': |
| |
| class mock_opened_file(object): |
| def __enter__(self, *args, **kwargs): |
| return self |
| |
| def __iter__(self, *args, **kwargs): |
| return iter(files_data[path].splitlines()) |
| |
| def __exit__(self, *args, **kwargs): |
| pass |
| |
| ret_val = mock_opened_file() |
| return ret_val |
| return inner_open |
| |
| patchers = [ |
| mock.patch( |
| 'owners_file_tags.open', custom_mock_open(file_mocks), create=True), |
| mock.patch('os.walk', mock.MagicMock(return_value=os_walk_mocks)) |
| ] |
| for patcher in patchers: |
| patcher.start() |
| yield |
| for patcher in patchers: |
| patcher.stop() |
| |
| |
| class OwnersFileTagsTest(unittest.TestCase): |
| |
| """os tag breaking dupe >>""" |
| def setUp(self): |
| super(OwnersFileTagsTest, self).setUp() |
| self.maxDiff = None |
| |
| def testScrapeOwners(self): |
| with mock_file_tree({ |
| 'src': 'boss@chromium.org\n', |
| 'src/dummydir1': |
| 'dummy@chromium.org\n' |
| '# TEAM: dummy-team@chromium.org\n' |
| '# COMPONENT: Dummy>Component\n', |
| 'src/dummydir1/innerdir1': |
| 'dummy@chromium.org\n' |
| '# TEAM: dummy-specialist-team@chromium.org\n', |
| 'src/dummydir1/innerdir2': |
| 'dummy@chromium.org\n' |
| '# COMPONENT: Dummy>Component>Subcomponent\n', |
| 'src/dummydir1/innerdir3': |
| 'dummy@chromium.org\n' |
| '# OS: Mac\n' |
| }): |
| scraped_data = owners_file_tags.scrape_owners('src', False) |
| self.assertEqual({ |
| '.': {}, |
| 'dummydir1': { |
| 'component': 'Dummy>Component', |
| 'team': 'dummy-team@chromium.org', |
| }, |
| 'dummydir1/innerdir1': { |
| 'component': 'Dummy>Component', |
| 'team': 'dummy-specialist-team@chromium.org', |
| }, |
| 'dummydir1/innerdir2': { |
| 'component': 'Dummy>Component>Subcomponent', |
| 'team': 'dummy-team@chromium.org', |
| }, |
| 'dummydir1/innerdir3': { |
| 'component': 'Dummy>Component', |
| 'team': 'dummy-team@chromium.org', |
| 'os': 'Mac' |
| } |
| }, scraped_data) |
| |
| def testScrapeOwnersWithSubdirectories(self): |
| with mock_file_tree(OrderedDict([ |
| ('src', 'boss@chromium.org\n'), |
| ('src/dummydir1', |
| 'dummy@chromium.org\n' |
| '# TEAM: dummy-team@chromium.org\n' |
| '# COMPONENT: Dummy>Component\n'), |
| ('src/dummydir1/innerdir1', |
| 'dummy@chromium.org\n' |
| '# TEAM: dummy-specialist-team@chromium.org\n'), |
| ('src/dummydir1/innerdir2', |
| 'dummy@chromium.org\n' |
| '# COMPONENT: Dummy>Component>Subcomponent\n'), |
| ('src/dummydir1/innerdir3', |
| 'dummy@chromium.org\n# OS: Mac\n'), |
| ('src/dummydir1/innerdir4', None), |
| ])): |
| scraped_data = owners_file_tags.scrape_owners('src', True) |
| self.assertEqual({ |
| '.': {}, |
| 'dummydir1': { |
| 'component': 'Dummy>Component', |
| 'team': 'dummy-team@chromium.org', |
| }, |
| 'dummydir1/innerdir1': { |
| 'component': 'Dummy>Component', |
| 'team': 'dummy-specialist-team@chromium.org', |
| }, |
| 'dummydir1/innerdir2': { |
| 'component': 'Dummy>Component>Subcomponent', |
| 'team': 'dummy-team@chromium.org', |
| }, |
| 'dummydir1/innerdir3': { |
| 'component': 'Dummy>Component', |
| 'team': 'dummy-team@chromium.org', |
| 'os': 'Mac' |
| }, |
| 'dummydir1/innerdir4': { |
| 'component': 'Dummy>Component', |
| 'team': 'dummy-team@chromium.org', |
| }, |
| }, scraped_data) |