Add unit testing of bitbucket trigger handler

This commit is contained in:
Joseph Schorr 2017-02-13 15:01:09 -05:00
parent ba301b401b
commit 497c90e7ea
7 changed files with 217 additions and 51 deletions

View file

@ -412,7 +412,8 @@ class BitbucketBuildTrigger(BuildTriggerHandler):
'id': owner, 'id': owner,
'title': owner, 'title': owner,
'avatar_url': repo['logo'], 'avatar_url': repo['logo'],
'score': 0, 'url': 'https://bitbucket.org/%s' % (owner),
'score': 1,
} }
return list(namespaces.values()) return list(namespaces.values())
@ -464,7 +465,7 @@ class BitbucketBuildTrigger(BuildTriggerHandler):
(result, data, err_msg) = repository.get_raw_path_contents(path, revision='master') (result, data, err_msg) = repository.get_raw_path_contents(path, revision='master')
if not result: if not result:
raise RepositoryReadException(err_msg) return None
return data return data
@ -541,7 +542,7 @@ class BitbucketBuildTrigger(BuildTriggerHandler):
# Lookup the commit SHA for the branch. # Lookup the commit SHA for the branch.
(result, data, _) = repository.get_branch(branch_name) (result, data, _) = repository.get_branch(branch_name)
if not result: if not result:
raise TriggerStartException('Could not find branch commit SHA') raise TriggerStartException('Could not find branch in repository')
return data['target']['hash'] return data['target']['hash']
@ -549,7 +550,7 @@ class BitbucketBuildTrigger(BuildTriggerHandler):
# Lookup the commit SHA for the tag. # Lookup the commit SHA for the tag.
(result, data, _) = repository.get_tag(tag_name) (result, data, _) = repository.get_tag(tag_name)
if not result: if not result:
raise TriggerStartException('Could not find tag commit SHA') raise TriggerStartException('Could not find tag in repository')
return data['target']['hash'] return data['target']['hash']

View file

@ -286,6 +286,7 @@ class GithubBuildTrigger(BuildTriggerHandler):
'id': usr.login, 'id': usr.login,
'title': usr.name or usr.login, 'title': usr.name or usr.login,
'avatar_url': usr.avatar_url, 'avatar_url': usr.avatar_url,
'url': usr.html_url,
'score': usr.plan.private_repos if usr.plan else 0, 'score': usr.plan.private_repos if usr.plan else 0,
} }

View file

@ -0,0 +1,161 @@
from datetime import datetime
from mock import Mock
from buildtrigger.bitbuckethandler import BitbucketBuildTrigger
from util.morecollections import AttrDict
def get_bitbucket_trigger(subdir=''):
trigger_obj = AttrDict(dict(auth_token='foobar', id='sometrigger'))
trigger = BitbucketBuildTrigger(trigger_obj, {
'build_source': 'foo/bar',
'subdir': subdir,
'username': 'knownuser'
})
trigger._get_client = get_mock_bitbucket
return trigger
def get_repo_path_contents(path, revision):
if revision != 'master':
return (False, None, None)
data = {
'files': [{'path': 'Dockerfile'}],
}
return (True, data, None)
def get_raw_path_contents(path, revision):
if path == '/Dockerfile':
return (True, 'hello world', None)
if path == 'somesubdir/Dockerfile':
return (True, 'hi universe', None)
return (False, None, None)
def get_branches_and_tags():
data = {
'branches': [{'name': 'master'}, {'name': 'otherbranch'}],
'tags': [{'name': 'sometag'}, {'name': 'someothertag'}],
}
return (True, data, None)
def get_branches():
return (True, {'master': {}, 'otherbranch': {}}, None)
def get_tags():
return (True, {'sometag': {}, 'someothertag': {}}, None)
def get_branch(branch_name):
if branch_name != 'master':
return (False, None, None)
data = {
'target': {
'hash': 'aaaaaaa',
},
}
return (True, data, None)
def get_tag(tag_name):
if tag_name != 'sometag':
return (False, None, None)
data = {
'target': {
'hash': 'aaaaaaa',
},
}
return (True, data, None)
def get_changeset_mock(commit_sha):
if commit_sha != 'aaaaaaa':
return (False, None, 'Not found')
data = {
'node': 'aaaaaaa',
'message': 'some message',
'timestamp': 'now',
'raw_author': 'foo@bar.com',
}
return (True, data, None)
def get_changesets():
changesets_mock = Mock()
changesets_mock.get = Mock(side_effect=get_changeset_mock)
return changesets_mock
def get_deploykeys():
deploykeys_mock = Mock()
deploykeys_mock.create = Mock(return_value=(True, {'pk': 'someprivatekey'}, None))
deploykeys_mock.delete = Mock(return_value=(True, {}, None))
return deploykeys_mock
def get_webhooks():
webhooks_mock = Mock()
webhooks_mock.create = Mock(return_value=(True, {'uuid': 'someuuid'}, None))
webhooks_mock.delete = Mock(return_value=(True, {}, None))
return webhooks_mock
def get_repo_mock(name):
if name != 'bar':
return None
repo_mock = Mock()
repo_mock.get_main_branch = Mock(return_value=(True, {'name': 'master'}, None))
repo_mock.get_path_contents = Mock(side_effect=get_repo_path_contents)
repo_mock.get_raw_path_contents = Mock(side_effect=get_raw_path_contents)
repo_mock.get_branches_and_tags = Mock(side_effect=get_branches_and_tags)
repo_mock.get_branches = Mock(side_effect=get_branches)
repo_mock.get_tags = Mock(side_effect=get_tags)
repo_mock.get_branch = Mock(side_effect=get_branch)
repo_mock.get_tag = Mock(side_effect=get_tag)
repo_mock.changesets = Mock(side_effect=get_changesets)
repo_mock.deploykeys = Mock(side_effect=get_deploykeys)
repo_mock.webhooks = Mock(side_effect=get_webhooks)
return repo_mock
def get_repositories_mock():
repos_mock = Mock()
repos_mock.get = Mock(side_effect=get_repo_mock)
return repos_mock
def get_namespace_mock(namespace):
namespace_mock = Mock()
namespace_mock.repositories = Mock(side_effect=get_repositories_mock)
return namespace_mock
def get_repo(namespace, name):
return {
'owner': namespace,
'logo': 'avatarurl',
'slug': name,
'description': 'some %s repo' % (name),
'utc_last_updated': str(datetime.utcfromtimestamp(0)),
'read_only': namespace != 'knownuser',
'is_private': name == 'somerepo',
}
def get_visible_repos():
repos = [
get_repo('knownuser', 'somerepo'),
get_repo('someorg', 'somerepo'),
get_repo('someorg', 'anotherrepo'),
]
return (True, repos, None)
def get_authed_mock(token, secret):
authed_mock = Mock()
authed_mock.for_namespace = Mock(side_effect=get_namespace_mock)
authed_mock.get_visible_repositories = Mock(side_effect=get_visible_repos)
return authed_mock
def get_mock_bitbucket():
bitbucket_mock = Mock()
bitbucket_mock.get_authorized_client = Mock(side_effect=get_authed_mock)
return bitbucket_mock

View file

@ -54,7 +54,7 @@ def get_mock_github():
repo_mock.name = name repo_mock.name = name
repo_mock.description = 'some %s repo' % (name) repo_mock.description = 'some %s repo' % (name)
repo_mock.pushed_at = datetime.utcfromtimestamp(0) repo_mock.pushed_at = datetime.utcfromtimestamp(0)
repo_mock.html_url = 'http://some/url' repo_mock.html_url = 'https://bitbucket.org/%s/%s' % (namespace, name)
repo_mock.private = name == 'somerepo' repo_mock.private = name == 'somerepo'
repo_mock.permissions = Mock() repo_mock.permissions = Mock()
repo_mock.permissions.admin = namespace == 'knownuser' repo_mock.permissions.admin = namespace == 'knownuser'
@ -76,7 +76,7 @@ def get_mock_github():
user_mock.plan = Mock() user_mock.plan = Mock()
user_mock.plan.private_repos = 1 user_mock.plan.private_repos = 1
user_mock.login = username user_mock.login = username
user_mock.html_url = 'htmlurl' user_mock.html_url = 'https://bitbucket.org/%s' % (username)
user_mock.avatar_url = 'avatarurl' user_mock.avatar_url = 'avatarurl'
user_mock.get_repos = Mock(side_effect=get_user_repos_mock) user_mock.get_repos = Mock(side_effect=get_user_repos_mock)
user_mock.get_orgs = Mock(side_effect=get_orgs_mock) user_mock.get_orgs = Mock(side_effect=get_orgs_mock)
@ -89,7 +89,7 @@ def get_mock_github():
org_mock = Mock() org_mock = Mock()
org_mock.get_repos = Mock(side_effect=get_org_repos_mock) org_mock.get_repos = Mock(side_effect=get_org_repos_mock)
org_mock.login = namespace org_mock.login = namespace
org_mock.html_url = 'htmlurl' org_mock.html_url = 'https://bitbucket.org/%s' % (namespace)
org_mock.avatar_url = 'avatarurl' org_mock.avatar_url = 'avatarurl'
org_mock.name = namespace org_mock.name = namespace
org_mock.plan = Mock() org_mock.plan = Mock()

View file

@ -1,24 +1,22 @@
import pytest import pytest
from mock import Mock from buildtrigger.test.bitbucketmock import get_bitbucket_trigger
from datetime import datetime
from buildtrigger.bitbuckethandler import BitbucketBuildTrigger
from buildtrigger.triggerutil import (InvalidPayloadException, SkipRequestException,
TriggerStartException, ValidationRequestException)
from endpoints.building import PreparedBuild
from util.morecollections import AttrDict
@pytest.fixture @pytest.fixture
def bitbucket_trigger(): def bitbucket_trigger():
return _get_bitbucket_trigger() return get_bitbucket_trigger()
def get_mock_bitbucket():
client_mock = Mock()
return client_mock
def _get_bitbucket_trigger(subdir=''): def test_list_build_subdirs(bitbucket_trigger):
trigger_obj = AttrDict(dict(auth_token='foobar', id='sometrigger')) assert bitbucket_trigger.list_build_subdirs() == ['']
trigger = BitbucketBuildTrigger(trigger_obj, {'build_source': 'foo/bar', 'subdir': subdir})
trigger._get_client = get_mock_bitbucket
return trigger @pytest.mark.parametrize('subdir, contents', [
('', 'hello world'),
('somesubdir', 'hi universe'),
('unknownpath', None),
])
def test_load_dockerfile_contents(subdir, contents):
trigger = get_bitbucket_trigger(subdir)
assert trigger.load_dockerfile_contents() == contents

View file

@ -1,13 +1,11 @@
import pytest import pytest
from buildtrigger.triggerutil import TriggerStartException from buildtrigger.triggerutil import TriggerStartException
from buildtrigger.test.bitbucketmock import get_bitbucket_trigger
from buildtrigger.test.githubmock import get_github_trigger from buildtrigger.test.githubmock import get_github_trigger
from endpoints.building import PreparedBuild from endpoints.building import PreparedBuild
def github_trigger(): @pytest.fixture(params=[get_github_trigger(), get_bitbucket_trigger()])
return get_github_trigger()
@pytest.fixture(params=[github_trigger()])
def githost_trigger(request): def githost_trigger(request):
return request.param return request.param
@ -38,14 +36,6 @@ def test_manual_start(run_parameters, expected_error, expected_message, githost_
assert isinstance(githost_trigger.manual_start(run_parameters), PreparedBuild) assert isinstance(githost_trigger.manual_start(run_parameters), PreparedBuild)
@pytest.mark.parametrize('username, expected_response', [
('unknownuser', None),
('knownuser', {'html_url': 'htmlurl', 'avatar_url': 'avatarurl'}),
])
def test_lookup_user(username, expected_response, githost_trigger):
assert githost_trigger.lookup_user(username) == expected_response
@pytest.mark.parametrize('name, expected', [ @pytest.mark.parametrize('name, expected', [
('refs', [ ('refs', [
{'kind': 'branch', 'name': 'master'}, {'kind': 'branch', 'name': 'master'},
@ -53,18 +43,19 @@ def test_lookup_user(username, expected_response, githost_trigger):
{'kind': 'tag', 'name': 'sometag'}, {'kind': 'tag', 'name': 'sometag'},
{'kind': 'tag', 'name': 'someothertag'}, {'kind': 'tag', 'name': 'someothertag'},
]), ]),
('tag_name', ['sometag', 'someothertag']), ('tag_name', set(['sometag', 'someothertag'])),
('branch_name', ['master', 'otherbranch']), ('branch_name', set(['master', 'otherbranch'])),
('invalid', None) ('invalid', None)
]) ])
def test_list_field_values(name, expected, githost_trigger): def test_list_field_values(name, expected, githost_trigger):
if expected is None:
assert githost_trigger.list_field_values(name) is None
elif isinstance(expected, set):
assert set(githost_trigger.list_field_values(name)) == set(expected)
else:
assert githost_trigger.list_field_values(name) == expected assert githost_trigger.list_field_values(name) == expected
def test_list_build_subdirs(githost_trigger):
assert githost_trigger.list_build_subdirs() == ['', 'somesubdir']
def test_list_build_source_namespaces(githost_trigger): def test_list_build_source_namespaces(githost_trigger):
namespaces_expected = [ namespaces_expected = [
{ {
@ -72,13 +63,14 @@ def test_list_build_source_namespaces(githost_trigger):
'score': 1, 'score': 1,
'avatar_url': 'avatarurl', 'avatar_url': 'avatarurl',
'id': 'knownuser', 'id': 'knownuser',
'title': 'knownuser' 'title': 'knownuser',
'url': 'https://bitbucket.org/knownuser',
}, },
{ {
'score': 2, 'score': 2,
'title': 'someorg', 'title': 'someorg',
'personal': False, 'personal': False,
'url': 'htmlurl', 'url': 'https://bitbucket.org/someorg',
'avatar_url': 'avatarurl', 'avatar_url': 'avatarurl',
'id': 'someorg' 'id': 'someorg'
} }
@ -92,20 +84,23 @@ def test_list_build_source_namespaces(githost_trigger):
('knownuser', [ ('knownuser', [
{ {
'last_updated': 0, 'name': 'somerepo', 'url': 'http://some/url', 'private': True, 'last_updated': 0, 'name': 'somerepo',
'url': 'https://bitbucket.org/knownuser/somerepo', 'private': True,
'full_name': 'knownuser/somerepo', 'has_admin_permissions': True, 'full_name': 'knownuser/somerepo', 'has_admin_permissions': True,
'description': 'some somerepo repo' 'description': 'some somerepo repo'
}]), }]),
('someorg', [ ('someorg', [
{ {
'last_updated': 0, 'name': 'somerepo', 'url': 'http://some/url', 'last_updated': 0, 'name': 'somerepo',
'private': True, 'full_name': 'someorg/somerepo', 'has_admin_permissions': False, 'url': 'https://bitbucket.org/someorg/somerepo', 'private': True,
'full_name': 'someorg/somerepo', 'has_admin_permissions': False,
'description': 'some somerepo repo' 'description': 'some somerepo repo'
}, },
{ {
'last_updated': 0, 'name': 'anotherrepo', 'url': 'http://some/url', 'last_updated': 0, 'name': 'anotherrepo',
'private': False, 'full_name': 'someorg/anotherrepo', 'has_admin_permissions': False, 'url': 'https://bitbucket.org/someorg/anotherrepo', 'private': False,
'full_name': 'someorg/anotherrepo', 'has_admin_permissions': False,
'description': 'some anotherrepo repo' 'description': 'some anotherrepo repo'
}]), }]),
]) ])
@ -117,7 +112,6 @@ def test_list_build_sources_for_namespace(namespace, expected, githost_trigger):
def test_activate(githost_trigger): def test_activate(githost_trigger):
config, private_key = githost_trigger.activate('http://some/url') config, private_key = githost_trigger.activate('http://some/url')
assert 'deploy_key_id' in config assert 'deploy_key_id' in config
assert 'hook_id' in config
assert 'private_key' in private_key assert 'private_key' in private_key

View file

@ -76,3 +76,14 @@ def test_load_dockerfile_contents(subdir, contents):
trigger = get_github_trigger(subdir) trigger = get_github_trigger(subdir)
assert trigger.load_dockerfile_contents() == contents assert trigger.load_dockerfile_contents() == contents
@pytest.mark.parametrize('username, expected_response', [
('unknownuser', None),
('knownuser', {'html_url': 'https://bitbucket.org/knownuser', 'avatar_url': 'avatarurl'}),
])
def test_lookup_user(username, expected_response, github_trigger):
assert github_trigger.lookup_user(username) == expected_response
def test_list_build_subdirs(github_trigger):
assert github_trigger.list_build_subdirs() == ['', 'somesubdir']