Merge remote-tracking branch 'origin/master' into tagyourit
Conflicts: static/css/quay.css static/js/graphing.js static/partials/view-repo.html test/data/test.db
This commit is contained in:
commit
3f42d15335
132 changed files with 4266 additions and 1924 deletions
|
@ -19,7 +19,7 @@ from endpoints.api.build import RepositoryBuildStatus, RepositoryBuildLogs, Repo
|
|||
from endpoints.api.robot import UserRobotList, OrgRobot, OrgRobotList, UserRobot
|
||||
from endpoints.api.trigger import (BuildTriggerActivate, BuildTriggerSources, BuildTriggerSubdirs,
|
||||
TriggerBuildList, ActivateBuildTrigger, BuildTrigger,
|
||||
BuildTriggerList)
|
||||
BuildTriggerList, BuildTriggerAnalyze)
|
||||
from endpoints.api.webhook import Webhook, WebhookList
|
||||
from endpoints.api.user import (PrivateRepositories, ConvertToOrganization, Signout, Signin, User,
|
||||
UserAuthorizationList, UserAuthorization)
|
||||
|
@ -299,6 +299,24 @@ class TestCreateNewUser(ApiTestCase):
|
|||
expected_code=400)
|
||||
|
||||
self.assertEquals('The username already exists', json['message'])
|
||||
|
||||
def test_trycreatetooshort(self):
|
||||
json = self.postJsonResponse(User,
|
||||
data=dict(username='a',
|
||||
password='password',
|
||||
email='test@example.com'),
|
||||
expected_code=400)
|
||||
|
||||
self.assertEquals('Invalid username a: Username must be between 4 and 30 characters in length', json['error_description'])
|
||||
|
||||
def test_trycreateregexmismatch(self):
|
||||
json = self.postJsonResponse(User,
|
||||
data=dict(username='auserName',
|
||||
password='password',
|
||||
email='test@example.com'),
|
||||
expected_code=400)
|
||||
|
||||
self.assertEquals('Invalid username auserName: Username must match expression [a-z0-9_]+', json['error_description'])
|
||||
|
||||
def test_createuser(self):
|
||||
data = self.postResponse(User,
|
||||
|
@ -971,7 +989,7 @@ class TestRequestRepoBuild(ApiTestCase):
|
|||
def test_requestrepobuild(self):
|
||||
self.login(ADMIN_ACCESS_USER)
|
||||
|
||||
# Ensure where not yet building.
|
||||
# Ensure we are not yet building.
|
||||
json = self.getJsonResponse(RepositoryBuildList,
|
||||
params=dict(repository=ADMIN_ACCESS_USER + '/simple'))
|
||||
|
||||
|
@ -989,6 +1007,50 @@ class TestRequestRepoBuild(ApiTestCase):
|
|||
|
||||
assert len(json['builds']) > 0
|
||||
|
||||
def test_requestrepobuild_with_robot(self):
|
||||
self.login(ADMIN_ACCESS_USER)
|
||||
|
||||
# Ensure we are not yet building.
|
||||
json = self.getJsonResponse(RepositoryBuildList,
|
||||
params=dict(repository=ADMIN_ACCESS_USER + '/simple'))
|
||||
|
||||
assert len(json['builds']) == 0
|
||||
|
||||
# Request a (fake) build.
|
||||
pull_robot = ADMIN_ACCESS_USER + '+dtrobot'
|
||||
self.postResponse(RepositoryBuildList,
|
||||
params=dict(repository=ADMIN_ACCESS_USER + '/simple'),
|
||||
data=dict(file_id='foobarbaz', pull_robot=pull_robot),
|
||||
expected_code=201)
|
||||
|
||||
# Check for the build.
|
||||
json = self.getJsonResponse(RepositoryBuildList,
|
||||
params=dict(repository=ADMIN_ACCESS_USER + '/building'))
|
||||
|
||||
assert len(json['builds']) > 0
|
||||
|
||||
|
||||
def test_requestrepobuild_with_invalid_robot(self):
|
||||
self.login(ADMIN_ACCESS_USER)
|
||||
|
||||
# Request a (fake) build.
|
||||
pull_robot = ADMIN_ACCESS_USER + '+invalidrobot'
|
||||
self.postResponse(RepositoryBuildList,
|
||||
params=dict(repository=ADMIN_ACCESS_USER + '/simple'),
|
||||
data=dict(file_id='foobarbaz', pull_robot=pull_robot),
|
||||
expected_code=404)
|
||||
|
||||
def test_requestrepobuild_with_unauthorized_robot(self):
|
||||
self.login(ADMIN_ACCESS_USER)
|
||||
|
||||
# Request a (fake) build.
|
||||
pull_robot = 'freshuser+anotherrobot'
|
||||
self.postResponse(RepositoryBuildList,
|
||||
params=dict(repository=ADMIN_ACCESS_USER + '/simple'),
|
||||
data=dict(file_id='foobarbaz', pull_robot=pull_robot),
|
||||
expected_code=403)
|
||||
|
||||
|
||||
|
||||
class TestWebhooks(ApiTestCase):
|
||||
def test_webhooks(self):
|
||||
|
@ -1595,6 +1657,15 @@ class FakeBuildTrigger(BuildTriggerBase):
|
|||
def manual_start(self, auth_token, config):
|
||||
return ('foo', ['bar'], 'build-name', 'subdir')
|
||||
|
||||
def dockerfile_url(self, auth_token, config):
|
||||
return 'http://some/url'
|
||||
|
||||
def load_dockerfile_contents(self, auth_token, config):
|
||||
if not 'dockerfile' in config:
|
||||
return None
|
||||
|
||||
return config['dockerfile']
|
||||
|
||||
|
||||
class TestBuildTriggers(ApiTestCase):
|
||||
def test_list_build_triggers(self):
|
||||
|
@ -1643,6 +1714,82 @@ class TestBuildTriggers(ApiTestCase):
|
|||
self.assertEquals(0, len(json['triggers']))
|
||||
|
||||
|
||||
def test_analyze_fake_trigger(self):
|
||||
self.login(ADMIN_ACCESS_USER)
|
||||
|
||||
database.BuildTriggerService.create(name='fakeservice')
|
||||
|
||||
# Add a new fake trigger.
|
||||
repo = model.get_repository(ADMIN_ACCESS_USER, 'simple')
|
||||
user = model.get_user(ADMIN_ACCESS_USER)
|
||||
trigger = model.create_build_trigger(repo, 'fakeservice', 'sometoken', user)
|
||||
|
||||
# Analyze the trigger's dockerfile: First, no dockerfile.
|
||||
trigger_config = {}
|
||||
analyze_json = self.postJsonResponse(BuildTriggerAnalyze,
|
||||
params=dict(repository=ADMIN_ACCESS_USER + '/simple', trigger_uuid=trigger.uuid),
|
||||
data={'config': trigger_config})
|
||||
|
||||
self.assertEquals('error', analyze_json['status'])
|
||||
self.assertEquals('Could not read the Dockerfile for the trigger', analyze_json['message'])
|
||||
|
||||
# Analyze the trigger's dockerfile: Second, missing FROM in dockerfile.
|
||||
trigger_config = {'dockerfile': 'MAINTAINER me'}
|
||||
analyze_json = self.postJsonResponse(BuildTriggerAnalyze,
|
||||
params=dict(repository=ADMIN_ACCESS_USER + '/simple', trigger_uuid=trigger.uuid),
|
||||
data={'config': trigger_config})
|
||||
|
||||
self.assertEquals('warning', analyze_json['status'])
|
||||
self.assertEquals('No FROM line found in the Dockerfile', analyze_json['message'])
|
||||
|
||||
# Analyze the trigger's dockerfile: Third, dockerfile with public repo.
|
||||
trigger_config = {'dockerfile': 'FROM somerepo'}
|
||||
analyze_json = self.postJsonResponse(BuildTriggerAnalyze,
|
||||
params=dict(repository=ADMIN_ACCESS_USER + '/simple', trigger_uuid=trigger.uuid),
|
||||
data={'config': trigger_config})
|
||||
|
||||
self.assertEquals('publicbase', analyze_json['status'])
|
||||
|
||||
# Analyze the trigger's dockerfile: Fourth, dockerfile with private repo with an invalid path.
|
||||
trigger_config = {'dockerfile': 'FROM localhost:5000/somepath'}
|
||||
analyze_json = self.postJsonResponse(BuildTriggerAnalyze,
|
||||
params=dict(repository=ADMIN_ACCESS_USER + '/simple', trigger_uuid=trigger.uuid),
|
||||
data={'config': trigger_config})
|
||||
|
||||
self.assertEquals('warning', analyze_json['status'])
|
||||
self.assertEquals('"localhost:5000/somepath" is not a valid Quay repository path', analyze_json['message'])
|
||||
|
||||
# Analyze the trigger's dockerfile: Fifth, dockerfile with private repo that does not exist.
|
||||
trigger_config = {'dockerfile': 'FROM localhost:5000/nothere/randomrepo'}
|
||||
analyze_json = self.postJsonResponse(BuildTriggerAnalyze,
|
||||
params=dict(repository=ADMIN_ACCESS_USER + '/simple', trigger_uuid=trigger.uuid),
|
||||
data={'config': trigger_config})
|
||||
|
||||
self.assertEquals('error', analyze_json['status'])
|
||||
self.assertEquals('Repository "localhost:5000/nothere/randomrepo" was not found', analyze_json['message'])
|
||||
|
||||
# Analyze the trigger's dockerfile: Sixth, dockerfile with private repo that the user cannot see.
|
||||
trigger_config = {'dockerfile': 'FROM localhost:5000/randomuser/randomrepo'}
|
||||
analyze_json = self.postJsonResponse(BuildTriggerAnalyze,
|
||||
params=dict(repository=ADMIN_ACCESS_USER + '/simple', trigger_uuid=trigger.uuid),
|
||||
data={'config': trigger_config})
|
||||
|
||||
self.assertEquals('error', analyze_json['status'])
|
||||
self.assertEquals('Repository "localhost:5000/randomuser/randomrepo" was not found', analyze_json['message'])
|
||||
|
||||
# Analyze the trigger's dockerfile: Seventh, dockerfile with private repo that the user see.
|
||||
trigger_config = {'dockerfile': 'FROM localhost:5000/devtable/complex'}
|
||||
analyze_json = self.postJsonResponse(BuildTriggerAnalyze,
|
||||
params=dict(repository=ADMIN_ACCESS_USER + '/simple', trigger_uuid=trigger.uuid),
|
||||
data={'config': trigger_config})
|
||||
|
||||
self.assertEquals('analyzed', analyze_json['status'])
|
||||
self.assertEquals('devtable', analyze_json['namespace'])
|
||||
self.assertEquals('complex', analyze_json['name'])
|
||||
self.assertEquals(False, analyze_json['is_public'])
|
||||
self.assertEquals(ADMIN_ACCESS_USER + '+dtrobot', analyze_json['robots'][0]['name'])
|
||||
|
||||
|
||||
def test_fake_trigger(self):
|
||||
self.login(ADMIN_ACCESS_USER)
|
||||
|
||||
|
@ -1676,7 +1823,7 @@ class TestBuildTriggers(ApiTestCase):
|
|||
trigger_config = {}
|
||||
activate_json = self.postJsonResponse(BuildTriggerActivate,
|
||||
params=dict(repository=ADMIN_ACCESS_USER + '/simple', trigger_uuid=trigger.uuid),
|
||||
data=trigger_config)
|
||||
data={'config': trigger_config})
|
||||
|
||||
self.assertEquals(True, activate_json['is_active'])
|
||||
|
||||
|
@ -1688,7 +1835,7 @@ class TestBuildTriggers(ApiTestCase):
|
|||
# Make sure we cannot activate again.
|
||||
self.postResponse(BuildTriggerActivate,
|
||||
params=dict(repository=ADMIN_ACCESS_USER + '/simple', trigger_uuid=trigger.uuid),
|
||||
data=trigger_config,
|
||||
data={'config': trigger_config},
|
||||
expected_code=400)
|
||||
|
||||
# Start a manual build.
|
||||
|
@ -1701,6 +1848,69 @@ class TestBuildTriggers(ApiTestCase):
|
|||
self.assertEquals(['bar'], start_json['job_config']['docker_tags'])
|
||||
|
||||
|
||||
def test_invalid_robot_account(self):
|
||||
self.login(ADMIN_ACCESS_USER)
|
||||
|
||||
database.BuildTriggerService.create(name='fakeservice')
|
||||
|
||||
# Add a new fake trigger.
|
||||
repo = model.get_repository(ADMIN_ACCESS_USER, 'simple')
|
||||
user = model.get_user(ADMIN_ACCESS_USER)
|
||||
trigger = model.create_build_trigger(repo, 'fakeservice', 'sometoken', user)
|
||||
|
||||
# Try to activate it with an invalid robot account.
|
||||
trigger_config = {}
|
||||
activate_json = self.postJsonResponse(BuildTriggerActivate,
|
||||
params=dict(repository=ADMIN_ACCESS_USER + '/simple', trigger_uuid=trigger.uuid),
|
||||
data={'config': trigger_config, 'pull_robot': 'someinvalidrobot'},
|
||||
expected_code=404)
|
||||
|
||||
def test_unauthorized_robot_account(self):
|
||||
self.login(ADMIN_ACCESS_USER)
|
||||
|
||||
database.BuildTriggerService.create(name='fakeservice')
|
||||
|
||||
# Add a new fake trigger.
|
||||
repo = model.get_repository(ADMIN_ACCESS_USER, 'simple')
|
||||
user = model.get_user(ADMIN_ACCESS_USER)
|
||||
trigger = model.create_build_trigger(repo, 'fakeservice', 'sometoken', user)
|
||||
|
||||
# Try to activate it with a robot account in the wrong namespace.
|
||||
trigger_config = {}
|
||||
activate_json = self.postJsonResponse(BuildTriggerActivate,
|
||||
params=dict(repository=ADMIN_ACCESS_USER + '/simple', trigger_uuid=trigger.uuid),
|
||||
data={'config': trigger_config, 'pull_robot': 'freshuser+anotherrobot'},
|
||||
expected_code=403)
|
||||
|
||||
def test_robot_account(self):
|
||||
self.login(ADMIN_ACCESS_USER)
|
||||
|
||||
database.BuildTriggerService.create(name='fakeservice')
|
||||
|
||||
# Add a new fake trigger.
|
||||
repo = model.get_repository(ADMIN_ACCESS_USER, 'simple')
|
||||
user = model.get_user(ADMIN_ACCESS_USER)
|
||||
trigger = model.create_build_trigger(repo, 'fakeservice', 'sometoken', user)
|
||||
|
||||
# Try to activate it with a robot account.
|
||||
trigger_config = {}
|
||||
activate_json = self.postJsonResponse(BuildTriggerActivate,
|
||||
params=dict(repository=ADMIN_ACCESS_USER + '/simple', trigger_uuid=trigger.uuid),
|
||||
data={'config': trigger_config, 'pull_robot': ADMIN_ACCESS_USER + '+dtrobot'})
|
||||
|
||||
# Verify that the robot was saved.
|
||||
self.assertEquals(True, activate_json['is_active'])
|
||||
self.assertEquals(ADMIN_ACCESS_USER + '+dtrobot', activate_json['pull_robot']['name'])
|
||||
|
||||
# Start a manual build.
|
||||
start_json = self.postJsonResponse(ActivateBuildTrigger,
|
||||
params=dict(repository=ADMIN_ACCESS_USER + '/simple', trigger_uuid=trigger.uuid),
|
||||
expected_code=201)
|
||||
|
||||
assert 'id' in start_json
|
||||
self.assertEquals("build-name", start_json['display_name'])
|
||||
self.assertEquals(['bar'], start_json['job_config']['docker_tags'])
|
||||
|
||||
|
||||
class TestUserAuthorizations(ApiTestCase):
|
||||
def test_list_get_delete_user_authorizations(self):
|
||||
|
|
Reference in a new issue