Add unit testing of gitlab trigger handler
This commit is contained in:
parent
84b298f36b
commit
57528aa2bc
4 changed files with 287 additions and 7 deletions
|
@ -48,6 +48,9 @@ GITLAB_WEBHOOK_PAYLOAD_SCHEMA = {
|
|||
'items': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'id': {
|
||||
'type': 'string',
|
||||
},
|
||||
'url': {
|
||||
'type': 'string',
|
||||
},
|
||||
|
@ -67,7 +70,7 @@ GITLAB_WEBHOOK_PAYLOAD_SCHEMA = {
|
|||
'required': ['email'],
|
||||
},
|
||||
},
|
||||
'required': ['url', 'message', 'timestamp'],
|
||||
'required': ['id', 'url', 'message', 'timestamp'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -282,7 +285,8 @@ class GitLabBuildTrigger(BuildTriggerHandler):
|
|||
'id': namespace['path'],
|
||||
'title': namespace['name'],
|
||||
'avatar_url': repo['owner']['avatar_url'],
|
||||
'score': 0,
|
||||
'score': 1,
|
||||
'url': gl_client.host + '/' + namespace['path'],
|
||||
}
|
||||
|
||||
return list(namespaces.values())
|
||||
|
@ -486,18 +490,18 @@ class GitLabBuildTrigger(BuildTriggerHandler):
|
|||
def get_tag_sha(tag_name):
|
||||
tags = gl_client.getrepositorytags(repo['id'])
|
||||
if tags is False:
|
||||
raise TriggerStartException('Could not find tags')
|
||||
raise TriggerStartException('Could not find tag in repository')
|
||||
|
||||
for tag in tags:
|
||||
if tag['name'] == tag_name:
|
||||
return tag['commit']['id']
|
||||
|
||||
raise TriggerStartException('Could not find commit')
|
||||
raise TriggerStartException('Could not find tag in repository')
|
||||
|
||||
def get_branch_sha(branch_name):
|
||||
branch = gl_client.getbranch(repo['id'], branch_name)
|
||||
if branch is False:
|
||||
raise TriggerStartException('Could not find branch')
|
||||
raise TriggerStartException('Could not find branch in repository')
|
||||
|
||||
return branch['commit']['id']
|
||||
|
||||
|
|
186
buildtrigger/test/gitlabmock.py
Normal file
186
buildtrigger/test/gitlabmock.py
Normal file
|
@ -0,0 +1,186 @@
|
|||
from datetime import datetime
|
||||
from mock import Mock
|
||||
|
||||
from buildtrigger.gitlabhandler import GitLabBuildTrigger
|
||||
from util.morecollections import AttrDict
|
||||
|
||||
def get_gitlab_trigger(subdir=''):
|
||||
trigger_obj = AttrDict(dict(auth_token='foobar', id='sometrigger'))
|
||||
trigger = GitLabBuildTrigger(trigger_obj, {
|
||||
'build_source': 'foo/bar',
|
||||
'subdir': subdir,
|
||||
'username': 'knownuser'
|
||||
})
|
||||
|
||||
trigger._get_authorized_client = get_mock_gitlab
|
||||
return trigger
|
||||
|
||||
def adddeploykey_mock(project_id, name, public_key):
|
||||
return {'id': 'foo'}
|
||||
|
||||
def addprojecthook_mock(project_id, webhook_url, push=False):
|
||||
return {'id': 'foo'}
|
||||
|
||||
def get_currentuser_mock():
|
||||
return {
|
||||
'username': 'knownuser'
|
||||
}
|
||||
|
||||
def project(namespace, name):
|
||||
return {
|
||||
'id': '%s/%s' % (namespace, name),
|
||||
'default_branch': 'master',
|
||||
'namespace': {
|
||||
'id': namespace,
|
||||
'path': namespace,
|
||||
'name': namespace,
|
||||
},
|
||||
'path': name,
|
||||
'path_with_namespace': '%s/%s' % (namespace, name),
|
||||
'description': 'some %s repo' % name,
|
||||
'last_activity_at': str(datetime.utcfromtimestamp(0)),
|
||||
'web_url': 'https://bitbucket.org/%s/%s' % (namespace, name),
|
||||
'ssh_url_to_repo': 'git://%s/%s' % (namespace, name),
|
||||
'public': name != 'somerepo',
|
||||
'permissions': {
|
||||
'project_access': {
|
||||
'access_level': 50 if namespace == 'knownuser' else 0,
|
||||
}
|
||||
},
|
||||
'owner': {
|
||||
'avatar_url': 'avatarurl',
|
||||
}
|
||||
}
|
||||
|
||||
def getprojects_mock(page=1, per_page=100):
|
||||
return [
|
||||
project('knownuser', 'somerepo'),
|
||||
project('someorg', 'somerepo'),
|
||||
project('someorg', 'anotherrepo'),
|
||||
]
|
||||
|
||||
def getproject_mock(project_name):
|
||||
if project_name == 'knownuser/somerepo':
|
||||
return project('knownuser', 'somerepo')
|
||||
|
||||
if project_name == 'foo/bar':
|
||||
return project('foo', 'bar')
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def getbranches_mock(project_id):
|
||||
return [
|
||||
{
|
||||
'name': 'master',
|
||||
'commit': {
|
||||
'id': 'aaaaaaa',
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'otherbranch',
|
||||
'commit': {
|
||||
'id': 'aaaaaaa',
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
def getrepositorytags_mock(project_id):
|
||||
return [
|
||||
{
|
||||
'name': 'sometag',
|
||||
'commit': {
|
||||
'id': 'aaaaaaa',
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'someothertag',
|
||||
'commit': {
|
||||
'id': 'aaaaaaa',
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
def getrepositorytree_mock(project_id, ref_name='master'):
|
||||
return [
|
||||
{'name': 'README'},
|
||||
{'name': 'Dockerfile'},
|
||||
]
|
||||
|
||||
def getrepositorycommit_mock(project_id, commit_sha):
|
||||
if commit_sha != 'aaaaaaa':
|
||||
return False
|
||||
|
||||
return {
|
||||
'id': 'aaaaaaa',
|
||||
'message': 'some message',
|
||||
'committed_date': 'now',
|
||||
}
|
||||
|
||||
def getusers_mock(search=None):
|
||||
if search == 'knownuser':
|
||||
return [
|
||||
{
|
||||
'username': 'knownuser',
|
||||
'avatar_url': 'avatarurl',
|
||||
}
|
||||
]
|
||||
|
||||
return False
|
||||
|
||||
def getbranch_mock(repo_id, branch):
|
||||
if branch != 'master' and branch != 'otherbranch':
|
||||
return False
|
||||
|
||||
return {
|
||||
'name': branch,
|
||||
'commit': {
|
||||
'id': 'aaaaaaa',
|
||||
}
|
||||
}
|
||||
|
||||
def gettag_mock(repo_id, tag):
|
||||
if tag != 'sometag' and tag != 'someothertag':
|
||||
return False
|
||||
|
||||
return {
|
||||
'name': tag,
|
||||
'commit': {
|
||||
'id': 'aaaaaaa',
|
||||
}
|
||||
}
|
||||
|
||||
def getrawfile_mock(repo_id, branch_name, path):
|
||||
if path == '/Dockerfile':
|
||||
return 'hello world'
|
||||
|
||||
if path == 'somesubdir/Dockerfile':
|
||||
return 'hi universe'
|
||||
|
||||
return False
|
||||
|
||||
def get_mock_gitlab():
|
||||
mock_gitlab = Mock()
|
||||
mock_gitlab.host = 'https://bitbucket.org'
|
||||
|
||||
mock_gitlab.currentuser = Mock(side_effect=get_currentuser_mock)
|
||||
mock_gitlab.getusers = Mock(side_effect=getusers_mock)
|
||||
|
||||
mock_gitlab.getprojects = Mock(side_effect=getprojects_mock)
|
||||
mock_gitlab.getproject = Mock(side_effect=getproject_mock)
|
||||
mock_gitlab.getbranches = Mock(side_effect=getbranches_mock)
|
||||
|
||||
mock_gitlab.getbranch = Mock(side_effect=getbranch_mock)
|
||||
mock_gitlab.gettag = Mock(side_effect=gettag_mock)
|
||||
|
||||
mock_gitlab.getrepositorytags = Mock(side_effect=getrepositorytags_mock)
|
||||
mock_gitlab.getrepositorytree = Mock(side_effect=getrepositorytree_mock)
|
||||
mock_gitlab.getrepositorycommit = Mock(side_effect=getrepositorycommit_mock)
|
||||
|
||||
mock_gitlab.getrawfile = Mock(side_effect=getrawfile_mock)
|
||||
|
||||
mock_gitlab.adddeploykey = Mock(side_effect=adddeploykey_mock)
|
||||
mock_gitlab.addprojecthook = Mock(side_effect=addprojecthook_mock)
|
||||
mock_gitlab.deletedeploykey = Mock(return_value=True)
|
||||
mock_gitlab.deleteprojecthook = Mock(return_value=True)
|
||||
return mock_gitlab
|
|
@ -3,9 +3,12 @@ import pytest
|
|||
from buildtrigger.triggerutil import TriggerStartException
|
||||
from buildtrigger.test.bitbucketmock import get_bitbucket_trigger
|
||||
from buildtrigger.test.githubmock import get_github_trigger
|
||||
from buildtrigger.test.gitlabmock import get_gitlab_trigger
|
||||
from endpoints.building import PreparedBuild
|
||||
|
||||
@pytest.fixture(params=[get_github_trigger(), get_bitbucket_trigger()])
|
||||
# Note: This test suite executes a common set of tests against all the trigger types specified
|
||||
# in this fixture. Each trigger's mock is expected to return the same data for all of these calls.
|
||||
@pytest.fixture(params=[get_github_trigger(), get_bitbucket_trigger(), get_gitlab_trigger()])
|
||||
def githost_trigger(request):
|
||||
return request.param
|
||||
|
||||
|
@ -111,7 +114,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 'private_key' in private_key
|
||||
|
||||
|
||||
|
|
88
buildtrigger/test/test_gitlabhandler.py
Normal file
88
buildtrigger/test/test_gitlabhandler.py
Normal file
|
@ -0,0 +1,88 @@
|
|||
import json
|
||||
import pytest
|
||||
|
||||
from buildtrigger.test.gitlabmock import get_gitlab_trigger
|
||||
from buildtrigger.triggerutil import (SkipRequestException, ValidationRequestException,
|
||||
InvalidPayloadException)
|
||||
from endpoints.building import PreparedBuild
|
||||
from util.morecollections import AttrDict
|
||||
|
||||
@pytest.fixture
|
||||
def gitlab_trigger():
|
||||
return get_gitlab_trigger()
|
||||
|
||||
|
||||
def test_list_build_subdirs(gitlab_trigger):
|
||||
assert gitlab_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_gitlab_trigger(subdir)
|
||||
assert trigger.load_dockerfile_contents() == contents
|
||||
|
||||
|
||||
@pytest.mark.parametrize('email, expected_response', [
|
||||
('unknown@email.com', None),
|
||||
('knownuser', {'username': 'knownuser', 'html_url': 'https://bitbucket.org/knownuser',
|
||||
'avatar_url': 'avatarurl'}),
|
||||
])
|
||||
def test_lookup_user(email, expected_response, gitlab_trigger):
|
||||
assert gitlab_trigger.lookup_user(email) == expected_response
|
||||
|
||||
|
||||
@pytest.mark.parametrize('payload, expected_error, expected_message', [
|
||||
('{}', SkipRequestException, ''),
|
||||
|
||||
# Valid payload:
|
||||
('''{
|
||||
"ref": "refs/heads/master",
|
||||
"checkout_sha": "aaaaaaa",
|
||||
"repository": {
|
||||
"git_ssh_url": "foobar"
|
||||
},
|
||||
"commits": [
|
||||
{
|
||||
"id": "aaaaaaa",
|
||||
"url": "someurl",
|
||||
"message": "hello there!",
|
||||
"timestamp": "now"
|
||||
}
|
||||
]
|
||||
}''', None, None),
|
||||
|
||||
# Skip message:
|
||||
('''{
|
||||
"ref": "refs/heads/master",
|
||||
"checkout_sha": "aaaaaaa",
|
||||
"repository": {
|
||||
"git_ssh_url": "foobar"
|
||||
},
|
||||
"commits": [
|
||||
{
|
||||
"id": "aaaaaaa",
|
||||
"url": "someurl",
|
||||
"message": "[skip build] hello there!",
|
||||
"timestamp": "now"
|
||||
}
|
||||
]
|
||||
}''', SkipRequestException, ''),
|
||||
])
|
||||
def test_handle_trigger_request(gitlab_trigger, payload, expected_error, expected_message):
|
||||
def get_payload():
|
||||
return json.loads(payload)
|
||||
|
||||
request = AttrDict(dict(get_json=get_payload))
|
||||
|
||||
if expected_error is not None:
|
||||
with pytest.raises(expected_error) as ipe:
|
||||
gitlab_trigger.handle_trigger_request(request)
|
||||
assert ipe.value.message == expected_message
|
||||
else:
|
||||
assert isinstance(gitlab_trigger.handle_trigger_request(request), PreparedBuild)
|
||||
|
||||
|
Reference in a new issue