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

View file

@ -286,6 +286,7 @@ class GithubBuildTrigger(BuildTriggerHandler):
'id': usr.login,
'title': usr.name or usr.login,
'avatar_url': usr.avatar_url,
'url': usr.html_url,
'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.description = 'some %s repo' % (name)
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.permissions = Mock()
repo_mock.permissions.admin = namespace == 'knownuser'
@ -76,7 +76,7 @@ def get_mock_github():
user_mock.plan = Mock()
user_mock.plan.private_repos = 1
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.get_repos = Mock(side_effect=get_user_repos_mock)
user_mock.get_orgs = Mock(side_effect=get_orgs_mock)
@ -89,7 +89,7 @@ def get_mock_github():
org_mock = Mock()
org_mock.get_repos = Mock(side_effect=get_org_repos_mock)
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.name = namespace
org_mock.plan = Mock()

View file

@ -1,24 +1,22 @@
import pytest
from mock import Mock
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
from buildtrigger.test.bitbucketmock import get_bitbucket_trigger
@pytest.fixture
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=''):
trigger_obj = AttrDict(dict(auth_token='foobar', id='sometrigger'))
trigger = BitbucketBuildTrigger(trigger_obj, {'build_source': 'foo/bar', 'subdir': subdir})
trigger._get_client = get_mock_bitbucket
return trigger
def test_list_build_subdirs(bitbucket_trigger):
assert bitbucket_trigger.list_build_subdirs() == ['']
@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
from buildtrigger.triggerutil import TriggerStartException
from buildtrigger.test.bitbucketmock import get_bitbucket_trigger
from buildtrigger.test.githubmock import get_github_trigger
from endpoints.building import PreparedBuild
def github_trigger():
return get_github_trigger()
@pytest.fixture(params=[github_trigger()])
@pytest.fixture(params=[get_github_trigger(), get_bitbucket_trigger()])
def githost_trigger(request):
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)
@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', [
('refs', [
{'kind': 'branch', 'name': 'master'},
@ -53,16 +43,17 @@ def test_lookup_user(username, expected_response, githost_trigger):
{'kind': 'tag', 'name': 'sometag'},
{'kind': 'tag', 'name': 'someothertag'},
]),
('tag_name', ['sometag', 'someothertag']),
('branch_name', ['master', 'otherbranch']),
('tag_name', set(['sometag', 'someothertag'])),
('branch_name', set(['master', 'otherbranch'])),
('invalid', None)
])
def test_list_field_values(name, expected, githost_trigger):
assert githost_trigger.list_field_values(name) == expected
def test_list_build_subdirs(githost_trigger):
assert githost_trigger.list_build_subdirs() == ['', 'somesubdir']
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
def test_list_build_source_namespaces(githost_trigger):
@ -72,13 +63,14 @@ def test_list_build_source_namespaces(githost_trigger):
'score': 1,
'avatar_url': 'avatarurl',
'id': 'knownuser',
'title': 'knownuser'
'title': 'knownuser',
'url': 'https://bitbucket.org/knownuser',
},
{
'score': 2,
'title': 'someorg',
'personal': False,
'url': 'htmlurl',
'url': 'https://bitbucket.org/someorg',
'avatar_url': 'avatarurl',
'id': 'someorg'
}
@ -92,20 +84,23 @@ def test_list_build_source_namespaces(githost_trigger):
('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,
'description': 'some somerepo repo'
}]),
('someorg', [
{
'last_updated': 0, 'name': 'somerepo', 'url': 'http://some/url',
'private': True, 'full_name': 'someorg/somerepo', 'has_admin_permissions': False,
'last_updated': 0, 'name': 'somerepo',
'url': 'https://bitbucket.org/someorg/somerepo', 'private': True,
'full_name': 'someorg/somerepo', 'has_admin_permissions': False,
'description': 'some somerepo repo'
},
{
'last_updated': 0, 'name': 'anotherrepo', 'url': 'http://some/url',
'private': False, 'full_name': 'someorg/anotherrepo', 'has_admin_permissions': False,
'last_updated': 0, 'name': 'anotherrepo',
'url': 'https://bitbucket.org/someorg/anotherrepo', 'private': False,
'full_name': 'someorg/anotherrepo', 'has_admin_permissions': False,
'description': 'some anotherrepo repo'
}]),
])
@ -117,7 +112,6 @@ def test_list_build_sources_for_namespace(namespace, expected, githost_trigger):
def test_activate(githost_trigger):
config, private_key = githost_trigger.activate('http://some/url')
assert 'deploy_key_id' in config
assert 'hook_id' in config
assert 'private_key' in private_key

View file

@ -76,3 +76,14 @@ def test_load_dockerfile_contents(subdir, contents):
trigger = get_github_trigger(subdir)
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']