You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
295 lines
11 KiB
Python
295 lines
11 KiB
Python
#!/usr/bin/env vpython3
|
|
# Copyright 2013 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.
|
|
|
|
"""Unit tests for owners_finder.py."""
|
|
|
|
import os
|
|
import sys
|
|
import unittest
|
|
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
from testing_support import filesystem_mock
|
|
|
|
import owners_finder
|
|
import owners
|
|
|
|
|
|
ben = 'ben@example.com'
|
|
brett = 'brett@example.com'
|
|
darin = 'darin@example.com'
|
|
jochen = 'jochen@example.com'
|
|
john = 'john@example.com'
|
|
ken = 'ken@example.com'
|
|
peter = 'peter@example.com'
|
|
tom = 'tom@example.com'
|
|
nonowner = 'nonowner@example.com'
|
|
|
|
|
|
def owners_file(*email_addresses, **kwargs):
|
|
s = ''
|
|
if kwargs.get('comment'):
|
|
s += '# %s\n' % kwargs.get('comment')
|
|
if kwargs.get('noparent'):
|
|
s += 'set noparent\n'
|
|
return s + '\n'.join(email_addresses) + '\n'
|
|
|
|
|
|
def test_repo():
|
|
return filesystem_mock.MockFileSystem(files={
|
|
'/DEPS': '',
|
|
'/OWNERS': owners_file(ken, peter, tom,
|
|
comment='OWNERS_STATUS = build/OWNERS.status'),
|
|
'/build/OWNERS.status': '%s: bar' % jochen,
|
|
'/base/vlog.h': '',
|
|
'/chrome/OWNERS': owners_file(ben, brett),
|
|
'/chrome/browser/OWNERS': owners_file(brett),
|
|
'/chrome/browser/defaults.h': '',
|
|
'/chrome/gpu/OWNERS': owners_file(ken),
|
|
'/chrome/gpu/gpu_channel.h': '',
|
|
'/chrome/renderer/OWNERS': owners_file(peter),
|
|
'/chrome/renderer/gpu/gpu_channel_host.h': '',
|
|
'/chrome/renderer/safe_browsing/scorer.h': '',
|
|
'/content/OWNERS': owners_file(john, darin, comment='foo', noparent=True),
|
|
'/content/content.gyp': '',
|
|
'/content/bar/foo.cc': '',
|
|
'/content/baz/OWNERS': owners_file(brett),
|
|
'/content/baz/froboz.h': '',
|
|
'/content/baz/ugly.cc': '',
|
|
'/content/baz/ugly.h': '',
|
|
'/content/common/OWNERS': owners_file(jochen),
|
|
'/content/common/common.cc': '',
|
|
'/content/foo/OWNERS': owners_file(jochen, comment='foo'),
|
|
'/content/foo/foo.cc': '',
|
|
'/content/views/OWNERS': owners_file(ben, john, owners.EVERYONE,
|
|
noparent=True),
|
|
'/content/views/pie.h': '',
|
|
})
|
|
|
|
|
|
class OutputInterceptedOwnersFinder(owners_finder.OwnersFinder):
|
|
def __init__(self, files, local_root, author, reviewers,
|
|
fopen, os_path, disable_color=False):
|
|
super(OutputInterceptedOwnersFinder, self).__init__(
|
|
files, local_root, author, reviewers, fopen, os_path,
|
|
disable_color=disable_color)
|
|
self.output = []
|
|
self.indentation_stack = []
|
|
|
|
def resetText(self):
|
|
self.output = []
|
|
self.indentation_stack = []
|
|
|
|
def indent(self):
|
|
self.indentation_stack.append(self.output)
|
|
self.output = []
|
|
|
|
def unindent(self):
|
|
block = self.output
|
|
self.output = self.indentation_stack.pop()
|
|
self.output.append(block)
|
|
|
|
def writeln(self, text=''):
|
|
self.output.append(text)
|
|
|
|
|
|
class _BaseTestCase(unittest.TestCase):
|
|
default_files = [
|
|
'base/vlog.h',
|
|
'chrome/browser/defaults.h',
|
|
'chrome/gpu/gpu_channel.h',
|
|
'chrome/renderer/gpu/gpu_channel_host.h',
|
|
'chrome/renderer/safe_browsing/scorer.h',
|
|
'content/content.gyp',
|
|
'content/bar/foo.cc',
|
|
'content/baz/ugly.cc',
|
|
'content/baz/ugly.h',
|
|
'content/views/pie.h'
|
|
]
|
|
|
|
def setUp(self):
|
|
self.repo = test_repo()
|
|
self.root = '/'
|
|
self.fopen = self.repo.open_for_reading
|
|
|
|
def ownersFinder(self, files, author=nonowner, reviewers=None):
|
|
reviewers = reviewers or []
|
|
finder = OutputInterceptedOwnersFinder(files,
|
|
self.root,
|
|
author,
|
|
reviewers,
|
|
fopen=self.fopen,
|
|
os_path=self.repo,
|
|
disable_color=True)
|
|
return finder
|
|
|
|
def defaultFinder(self):
|
|
return self.ownersFinder(self.default_files)
|
|
|
|
|
|
class OwnersFinderTests(_BaseTestCase):
|
|
def test_constructor(self):
|
|
self.assertNotEqual(self.defaultFinder(), None)
|
|
|
|
def test_skip_files_owned_by_reviewers(self):
|
|
files = [
|
|
'chrome/browser/defaults.h', # owned by brett
|
|
'content/bar/foo.cc', # not owned by brett
|
|
]
|
|
finder = self.ownersFinder(files, reviewers=[brett])
|
|
self.assertEqual(finder.unreviewed_files, {'content/bar/foo.cc'})
|
|
|
|
def test_skip_files_owned_by_author(self):
|
|
files = [
|
|
'chrome/browser/defaults.h', # owned by brett
|
|
'content/bar/foo.cc', # not owned by brett
|
|
]
|
|
finder = self.ownersFinder(files, author=brett)
|
|
self.assertEqual(finder.unreviewed_files, {'content/bar/foo.cc'})
|
|
|
|
def test_native_path_sep(self):
|
|
# Create a path with backslashes on Windows to make sure these are handled.
|
|
# This test is a harmless duplicate on other platforms.
|
|
native_slashes_path = 'chrome/browser/defaults.h'.replace('/', os.sep)
|
|
files = [
|
|
native_slashes_path, # owned by brett
|
|
'content/bar/foo.cc', # not owned by brett
|
|
]
|
|
finder = self.ownersFinder(files, reviewers=[brett])
|
|
self.assertEqual(finder.unreviewed_files, {'content/bar/foo.cc'})
|
|
|
|
def test_reset(self):
|
|
finder = self.defaultFinder()
|
|
for _ in range(2):
|
|
expected = [brett, darin, john, peter, ken, ben, tom]
|
|
# darin and john have equal cost, the others have distinct costs.
|
|
# If the owners_queue has those two swapped then swap them in expected.
|
|
if finder.owners_queue[1] != expected[1]:
|
|
expected[1], expected[2] = expected[2], expected[1]
|
|
self.assertEqual(finder.owners_queue, expected)
|
|
self.assertEqual(finder.unreviewed_files, {
|
|
'base/vlog.h',
|
|
'chrome/browser/defaults.h',
|
|
'chrome/gpu/gpu_channel.h',
|
|
'chrome/renderer/gpu/gpu_channel_host.h',
|
|
'chrome/renderer/safe_browsing/scorer.h',
|
|
'content/content.gyp',
|
|
'content/bar/foo.cc',
|
|
'content/baz/ugly.cc',
|
|
'content/baz/ugly.h'
|
|
})
|
|
self.assertEqual(finder.selected_owners, set())
|
|
self.assertEqual(finder.deselected_owners, set())
|
|
self.assertEqual(finder.reviewed_by, {})
|
|
self.assertEqual(finder.output, [])
|
|
|
|
finder.select_owner(john)
|
|
finder.reset()
|
|
finder.resetText()
|
|
|
|
def test_select(self):
|
|
finder = self.defaultFinder()
|
|
finder.select_owner(john)
|
|
self.assertEqual(finder.owners_queue, [brett, peter, ken, ben, tom])
|
|
self.assertEqual(finder.selected_owners, {john})
|
|
self.assertEqual(finder.deselected_owners, {darin})
|
|
self.assertEqual(finder.reviewed_by, {'content/bar/foo.cc': john,
|
|
'content/baz/ugly.cc': john,
|
|
'content/baz/ugly.h': john,
|
|
'content/content.gyp': john})
|
|
self.assertEqual(finder.output,
|
|
['Selected: ' + john, 'Deselected: ' + darin])
|
|
|
|
finder = self.defaultFinder()
|
|
finder.select_owner(darin)
|
|
self.assertEqual(finder.owners_queue, [brett, peter, ken, ben, tom])
|
|
self.assertEqual(finder.selected_owners, {darin})
|
|
self.assertEqual(finder.deselected_owners, {john})
|
|
self.assertEqual(finder.reviewed_by, {'content/bar/foo.cc': darin,
|
|
'content/baz/ugly.cc': darin,
|
|
'content/baz/ugly.h': darin,
|
|
'content/content.gyp': darin})
|
|
self.assertEqual(finder.output,
|
|
['Selected: ' + darin, 'Deselected: ' + john])
|
|
|
|
finder = self.defaultFinder()
|
|
finder.select_owner(brett)
|
|
expected = [darin, john, peter, ken, tom]
|
|
# darin and john have equal cost, the others have distinct costs.
|
|
# If the owners_queue has those two swapped then swap them in expected.
|
|
if finder.owners_queue[0] == john:
|
|
expected[0], expected[1] = expected[1], expected[0]
|
|
|
|
self.assertEqual(finder.owners_queue, expected)
|
|
self.assertEqual(finder.selected_owners, {brett})
|
|
self.assertEqual(finder.deselected_owners, {ben})
|
|
self.assertEqual(finder.reviewed_by,
|
|
{'chrome/browser/defaults.h': brett,
|
|
'chrome/gpu/gpu_channel.h': brett,
|
|
'chrome/renderer/gpu/gpu_channel_host.h': brett,
|
|
'chrome/renderer/safe_browsing/scorer.h': brett,
|
|
'content/baz/ugly.cc': brett,
|
|
'content/baz/ugly.h': brett})
|
|
self.assertEqual(finder.output,
|
|
['Selected: ' + brett, 'Deselected: ' + ben])
|
|
|
|
def test_deselect(self):
|
|
finder = self.defaultFinder()
|
|
finder.deselect_owner(john)
|
|
self.assertEqual(finder.owners_queue, [brett, peter, ken, ben, tom])
|
|
self.assertEqual(finder.selected_owners, {darin})
|
|
self.assertEqual(finder.deselected_owners, {john})
|
|
self.assertEqual(finder.reviewed_by, {'content/bar/foo.cc': darin,
|
|
'content/baz/ugly.cc': darin,
|
|
'content/baz/ugly.h': darin,
|
|
'content/content.gyp': darin})
|
|
self.assertEqual(finder.output,
|
|
['Deselected: ' + john, 'Selected: ' + darin])
|
|
|
|
def test_print_file_info(self):
|
|
finder = self.defaultFinder()
|
|
finder.print_file_info('chrome/browser/defaults.h')
|
|
self.assertEqual(finder.output, ['chrome/browser/defaults.h [5]'])
|
|
finder.resetText()
|
|
|
|
finder.print_file_info('chrome/renderer/gpu/gpu_channel_host.h')
|
|
self.assertEqual(finder.output,
|
|
['chrome/renderer/gpu/gpu_channel_host.h [5]'])
|
|
|
|
def test_print_file_info_detailed(self):
|
|
finder = self.defaultFinder()
|
|
finder.print_file_info_detailed('chrome/browser/defaults.h')
|
|
self.assertEqual(finder.output,
|
|
['chrome/browser/defaults.h',
|
|
[ben, brett, ken, peter, tom]])
|
|
finder.resetText()
|
|
|
|
finder.print_file_info_detailed('chrome/renderer/gpu/gpu_channel_host.h')
|
|
self.assertEqual(finder.output,
|
|
['chrome/renderer/gpu/gpu_channel_host.h',
|
|
[ben, brett, ken, peter, tom]])
|
|
|
|
def test_print_comments(self):
|
|
finder = self.defaultFinder()
|
|
finder.print_comments(darin)
|
|
self.assertEqual(finder.output,
|
|
[darin + ' is commented as:', ['foo (at content)']])
|
|
|
|
def test_print_global_comments(self):
|
|
finder = self.ownersFinder(['content/common/common.cc'])
|
|
finder.print_comments(jochen)
|
|
self.assertEqual(finder.output,
|
|
[jochen + ' is commented as:', ['bar (global status)']])
|
|
|
|
finder = self.ownersFinder(['content/foo/foo.cc'])
|
|
finder.print_comments(jochen)
|
|
self.assertEqual(finder.output,
|
|
[jochen + ' is commented as:', ['bar (global status)',
|
|
'foo (at content/foo)']])
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|