Add unit testing of bitbucket trigger handler
This commit is contained in:
parent
ba301b401b
commit
497c90e7ea
7 changed files with 217 additions and 51 deletions
|
@ -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']
|
||||
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
161
buildtrigger/test/bitbucketmock.py
Normal file
161
buildtrigger/test/bitbucketmock.py
Normal 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
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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']
|
||||
|
|
Reference in a new issue