1
0
mirror of https://github.com/quay/quay.git synced 2026-01-27 18:42:52 +03:00
Files
quay/buildtrigger/test/gitlabmock.py
Kurtis Mullins 38be6d05d0 Python 3 (#153)
* Convert all Python2 to Python3 syntax.

* Removes oauth2lib dependency

* Replace mockredis with fakeredis

* byte/str conversions

* Removes nonexisting __nonzero__ in Python3

* Python3 Dockerfile and related

* [PROJQUAY-98] Replace resumablehashlib with rehash

* PROJQUAY-123 - replace gpgme with python3-gpg

* [PROJQUAY-135] Fix unhashable class error

* Update external dependencies for Python 3

- Move github.com/app-registry/appr to github.com/quay/appr
- github.com/coderanger/supervisor-stdout
- github.com/DevTable/container-cloud-config
- Update to latest mockldap with changes applied from coreos/mockldap
- Update dependencies in requirements.txt and requirements-dev.txt

* Default FLOAT_REPR function to str in json encoder and removes keyword assignment

True, False, and str were not keywords in Python2...

* [PROJQUAY-165] Replace package `bencode` with `bencode.py`

- Bencode is not compatible with Python 3.x and is no longer
  maintained. Bencode.py appears to be a drop-in replacement/fork
  that is compatible with Python 3.

* Make sure monkey.patch is called before anything else (

* Removes anunidecode dependency and replaces it with text_unidecode

* Base64 encode/decode pickle dumps/loads when storing value in DB

Base64 encodes/decodes the serialized values when storing them in the
DB. Also make sure to return a Python3 string instead of a Bytes when
coercing for db, otherwise, Postgres' TEXT field will convert it into
a hex representation when storing the value.

* Implement __hash__ on Digest class

In Python 3, if a class defines __eq__() but not __hash__(), its
instances will not be usable as items in hashable collections (e.g sets).

* Remove basestring check

* Fix expected message in credentials tests

* Fix usage of Cryptography.Fernet for Python3 (#219)

- Specifically, this addresses the issue where Byte<->String
  conversions weren't being applied correctly.

* Fix utils

- tar+stream layer format utils
- filelike util

* Fix storage tests

* Fix endpoint tests

* Fix workers tests

* Fix docker's empty layer bytes

* Fix registry tests

* Appr

* Enable CI for Python 3.6

* Skip buildman tests

Skip buildman tests while it's being rewritten to allow ci to pass.

* Install swig for CI

* Update expected exception type in redis validation test

* Fix gpg signing calls

Fix gpg calls for updated gpg wrapper, and add signing tests.

* Convert / to // for Python3 integer division

* WIP: Update buildman to use asyncio instead of trollius.

This dependency is considered deprecated/abandoned and was only
used as an implementation/backport of asyncio on Python 2.x
This is a work in progress, and is included in the PR just to get the
rest of the tests passing. The builder is actually being rewritten.

* Target Python 3.8

* Removes unused files

- Removes unused files that were added accidentally while rebasing
- Small fixes/cleanup
- TODO tasks comments

* Add TODO to verify rehash backward compat with resumablehashlib

* Revert "[PROJQUAY-135] Fix unhashable class error" and implements __hash__ instead.

This reverts commit 735e38e3c1d072bf50ea864bc7e119a55d3a8976.
Instead, defines __hash__ for encryped fields class, using the parent
field's implementation.

* Remove some unused files ad imports

Co-authored-by: Kenny Lee Sin Cheong <kenny.lee@redhat.com>
Co-authored-by: Tom McKay <thomasmckay@redhat.com>
2020-06-05 16:50:13 -04:00

594 lines
20 KiB
Python

import base64
import json
from contextlib import contextmanager
import gitlab
from httmock import urlmatch, HTTMock
from buildtrigger.gitlabhandler import GitLabBuildTrigger
from util.morecollections import AttrDict
@urlmatch(netloc=r"fakegitlab")
def catchall_handler(url, request):
return {"status_code": 404}
@urlmatch(netloc=r"fakegitlab", path=r"/api/v4/users$")
def users_handler(url, request):
if not request.headers.get("Authorization") == "Bearer foobar":
return {"status_code": 401}
if url.query.find("knownuser") < 0:
return {
"status_code": 200,
"headers": {"Content-Type": "application/json",},
"content": json.dumps([]),
}
return {
"status_code": 200,
"headers": {"Content-Type": "application/json",},
"content": json.dumps(
[
{
"id": 1,
"username": "knownuser",
"name": "Known User",
"state": "active",
"avatar_url": "avatarurl",
"web_url": "https://bitbucket.org/knownuser",
},
]
),
}
@urlmatch(netloc=r"fakegitlab", path=r"/api/v4/user$")
def user_handler(_, request):
if not request.headers.get("Authorization") == "Bearer foobar":
return {"status_code": 401}
return {
"status_code": 200,
"headers": {"Content-Type": "application/json",},
"content": json.dumps(
{
"id": 1,
"username": "john_smith",
"email": "john@example.com",
"name": "John Smith",
"state": "active",
}
),
}
@urlmatch(netloc=r"fakegitlab", path=r"/api/v4/projects/foo%2Fbar$")
def project_handler(_, request):
if not request.headers.get("Authorization") == "Bearer foobar":
return {"status_code": 401}
return {
"status_code": 200,
"headers": {"Content-Type": "application/json",},
"content": json.dumps(
{
"id": 4,
"description": None,
"default_branch": "master",
"visibility": "private",
"path_with_namespace": "someorg/somerepo",
"ssh_url_to_repo": "git@example.com:someorg/somerepo.git",
"web_url": "http://example.com/someorg/somerepo",
}
),
}
@urlmatch(netloc=r"fakegitlab", path=r"/api/v4/projects/4/repository/tree$")
def project_tree_handler(_, request):
if not request.headers.get("Authorization") == "Bearer foobar":
return {"status_code": 401}
return {
"status_code": 200,
"headers": {"Content-Type": "application/json",},
"content": json.dumps(
[
{
"id": "a1e8f8d745cc87e3a9248358d9352bb7f9a0aeba",
"name": "Dockerfile",
"type": "tree",
"path": "files/Dockerfile",
"mode": "040000",
},
]
),
}
@urlmatch(netloc=r"fakegitlab", path=r"/api/v4/projects/4/repository/tags$")
def project_tags_handler(_, request):
if not request.headers.get("Authorization") == "Bearer foobar":
return {"status_code": 401}
return {
"status_code": 200,
"headers": {"Content-Type": "application/json",},
"content": json.dumps(
[
{"name": "sometag", "commit": {"id": "60a8ff033665e1207714d6670fcd7b65304ec02f",},},
{
"name": "someothertag",
"commit": {"id": "60a8ff033665e1207714d6670fcd7b65304ec02f",},
},
]
),
}
@urlmatch(netloc=r"fakegitlab", path=r"/api/v4/projects/4/repository/branches$")
def project_branches_handler(_, request):
if not request.headers.get("Authorization") == "Bearer foobar":
return {"status_code": 401}
return {
"status_code": 200,
"headers": {"Content-Type": "application/json",},
"content": json.dumps(
[
{"name": "master", "commit": {"id": "60a8ff033665e1207714d6670fcd7b65304ec02f",},},
{
"name": "otherbranch",
"commit": {"id": "60a8ff033665e1207714d6670fcd7b65304ec02f",},
},
]
),
}
@urlmatch(netloc=r"fakegitlab", path=r"/api/v4/projects/4/repository/branches/master$")
def project_branch_handler(_, request):
if not request.headers.get("Authorization") == "Bearer foobar":
return {"status_code": 401}
return {
"status_code": 200,
"headers": {"Content-Type": "application/json",},
"content": json.dumps(
{
"name": "master",
"merged": True,
"protected": True,
"developers_can_push": False,
"developers_can_merge": False,
"commit": {
"author_email": "john@example.com",
"author_name": "John Smith",
"authored_date": "2012-06-27T05:51:39-07:00",
"committed_date": "2012-06-28T03:44:20-07:00",
"committer_email": "john@example.com",
"committer_name": "John Smith",
"id": "60a8ff033665e1207714d6670fcd7b65304ec02f",
"short_id": "7b5c3cc",
"title": "add projects API",
"message": "add projects API",
"parent_ids": ["4ad91d3c1144c406e50c7b33bae684bd6837faf8",],
},
}
),
}
@urlmatch(netloc=r"fakegitlab", path=r"/api/v4/namespaces/someorg$")
def namespace_handler(_, request):
if not request.headers.get("Authorization") == "Bearer foobar":
return {"status_code": 401}
return {
"status_code": 200,
"headers": {"Content-Type": "application/json",},
"content": json.dumps(
{
"id": 2,
"name": "someorg",
"path": "someorg",
"kind": "group",
"full_path": "someorg",
"parent_id": None,
"members_count_with_descendants": 2,
}
),
}
@urlmatch(netloc=r"fakegitlab", path=r"/api/v4/namespaces/knownuser$")
def user_namespace_handler(_, request):
if not request.headers.get("Authorization") == "Bearer foobar":
return {"status_code": 401}
return {
"status_code": 200,
"headers": {"Content-Type": "application/json",},
"content": json.dumps(
{
"id": 1,
"name": "knownuser",
"path": "knownuser",
"kind": "user",
"full_path": "knownuser",
"parent_id": None,
"members_count_with_descendants": 2,
}
),
}
@urlmatch(netloc=r"fakegitlab", path=r"/api/v4/namespaces(/)?$")
def namespaces_handler(_, request):
if not request.headers.get("Authorization") == "Bearer foobar":
return {"status_code": 401}
return {
"status_code": 200,
"headers": {"Content-Type": "application/json",},
"content": json.dumps(
[
{
"id": 2,
"name": "someorg",
"path": "someorg",
"kind": "group",
"full_path": "someorg",
"parent_id": None,
"web_url": "http://gitlab.com/groups/someorg",
"members_count_with_descendants": 2,
}
]
),
}
def get_projects_handler(add_permissions_block):
@urlmatch(netloc=r"fakegitlab", path=r"/api/v4/groups/2/projects$")
def projects_handler(_, request):
if not request.headers.get("Authorization") == "Bearer foobar":
return {"status_code": 401}
permissions_block = {
"project_access": {"access_level": 10, "notification_level": 3},
"group_access": {"access_level": 20, "notification_level": 3},
}
return {
"status_code": 200,
"headers": {"Content-Type": "application/json",},
"content": json.dumps(
[
{
"id": 4,
"name": "Some project",
"description": None,
"default_branch": "master",
"visibility": "private",
"path": "someproject",
"path_with_namespace": "someorg/someproject",
"last_activity_at": "2013-09-30T13:46:02Z",
"web_url": "http://example.com/someorg/someproject",
"permissions": permissions_block if add_permissions_block else None,
},
{
"id": 5,
"name": "Another project",
"description": None,
"default_branch": "master",
"visibility": "public",
"path": "anotherproject",
"path_with_namespace": "someorg/anotherproject",
"last_activity_at": "2013-09-30T13:46:02Z",
"web_url": "http://example.com/someorg/anotherproject",
},
]
),
}
return projects_handler
def get_group_handler(null_avatar):
@urlmatch(netloc=r"fakegitlab", path=r"/api/v4/groups/2$")
def group_handler(_, request):
if not request.headers.get("Authorization") == "Bearer foobar":
return {"status_code": 401}
return {
"status_code": 200,
"headers": {"Content-Type": "application/json",},
"content": json.dumps(
{
"id": 1,
"name": "SomeOrg Group",
"path": "someorg",
"description": "An interesting group",
"visibility": "public",
"lfs_enabled": True,
"avatar_url": "avatar_url" if not null_avatar else None,
"web_url": "http://gitlab.com/groups/someorg",
"request_access_enabled": False,
"full_name": "SomeOrg Group",
"full_path": "someorg",
"parent_id": None,
}
),
}
return group_handler
@urlmatch(netloc=r"fakegitlab", path=r"/api/v4/projects/4/repository/files/Dockerfile$")
def dockerfile_handler(_, request):
if not request.headers.get("Authorization") == "Bearer foobar":
return {"status_code": 401}
return {
"status_code": 200,
"headers": {"Content-Type": "application/json",},
"content": json.dumps(
{
"file_name": "Dockerfile",
"file_path": "Dockerfile",
"size": 10,
"encoding": "base64",
"content": base64.b64encode(b"hello world").decode("ascii"),
"ref": "master",
"blob_id": "79f7bbd25901e8334750839545a9bd021f0e4c83",
"commit_id": "d5a3ff139356ce33e37e73add446f16869741b50",
"last_commit_id": "570e7b2abdd848b95f2f578043fc23bd6f6fd24d",
}
),
}
@urlmatch(
netloc=r"fakegitlab", path=r"/api/v4/projects/4/repository/files/somesubdir%2FDockerfile$"
)
def sub_dockerfile_handler(_, request):
if not request.headers.get("Authorization") == "Bearer foobar":
return {"status_code": 401}
return {
"status_code": 200,
"headers": {"Content-Type": "application/json",},
"content": json.dumps(
{
"file_name": "Dockerfile",
"file_path": "somesubdir/Dockerfile",
"size": 10,
"encoding": "base64",
"content": base64.b64encode(b"hi universe").decode("ascii"),
"ref": "master",
"blob_id": "79f7bbd25901e8334750839545a9bd021f0e4c83",
"commit_id": "d5a3ff139356ce33e37e73add446f16869741b50",
"last_commit_id": "570e7b2abdd848b95f2f578043fc23bd6f6fd24d",
}
),
}
@urlmatch(netloc=r"fakegitlab", path=r"/api/v4/projects/4/repository/tags/sometag$")
def tag_handler(_, request):
if not request.headers.get("Authorization") == "Bearer foobar":
return {"status_code": 401}
return {
"status_code": 200,
"headers": {"Content-Type": "application/json",},
"content": json.dumps(
{
"name": "sometag",
"message": "some cool message",
"target": "60a8ff033665e1207714d6670fcd7b65304ec02f",
"commit": {
"id": "60a8ff033665e1207714d6670fcd7b65304ec02f",
"short_id": "60a8ff03",
"title": "Initial commit",
"created_at": "2017-07-26T11:08:53.000+02:00",
"parent_ids": ["f61c062ff8bcbdb00e0a1b3317a91aed6ceee06b"],
"message": "v5.0.0\n",
"author_name": "Arthur Verschaeve",
"author_email": "contact@arthurverschaeve.be",
"authored_date": "2015-02-01T21:56:31.000+01:00",
"committer_name": "Arthur Verschaeve",
"committer_email": "contact@arthurverschaeve.be",
"committed_date": "2015-02-01T21:56:31.000+01:00",
},
"release": None,
}
),
}
@urlmatch(
netloc=r"fakegitlab",
path=r"/api/v4/projects/foo%2Fbar/repository/commits/60a8ff033665e1207714d6670fcd7b65304ec02f$",
)
def commit_handler(_, request):
if not request.headers.get("Authorization") == "Bearer foobar":
return {"status_code": 401}
return {
"status_code": 200,
"headers": {"Content-Type": "application/json",},
"content": json.dumps(
{
"id": "60a8ff033665e1207714d6670fcd7b65304ec02f",
"short_id": "60a8ff03366",
"title": "Sanitize for network graph",
"author_name": "someguy",
"author_email": "some.guy@gmail.com",
"committer_name": "Some Guy",
"committer_email": "some.guy@gmail.com",
"created_at": "2012-09-20T09:06:12+03:00",
"message": "Sanitize for network graph",
"committed_date": "2012-09-20T09:06:12+03:00",
"authored_date": "2012-09-20T09:06:12+03:00",
"parent_ids": ["ae1d9fb46aa2b07ee9836d49862ec4e2c46fbbba"],
"last_pipeline": {
"id": 8,
"ref": "master",
"sha": "2dc6aa325a317eda67812f05600bdf0fcdc70ab0",
"status": "created",
},
"stats": {"additions": 15, "deletions": 10, "total": 25},
"status": "running",
}
),
}
@urlmatch(netloc=r"fakegitlab", path=r"/api/v4/projects/4/deploy_keys$", method="POST")
def create_deploykey_handler(_, request):
if not request.headers.get("Authorization") == "Bearer foobar":
return {"status_code": 401}
return {
"status_code": 200,
"headers": {"Content-Type": "application/json",},
"content": json.dumps(
{
"id": 1,
"title": "Public key",
"key": "ssh-rsa some stuff",
"created_at": "2013-10-02T10:12:29Z",
"can_push": False,
}
),
}
@urlmatch(netloc=r"fakegitlab", path=r"/api/v4/projects/4/hooks$", method="POST")
def create_hook_handler(_, request):
if not request.headers.get("Authorization") == "Bearer foobar":
return {"status_code": 401}
return {
"status_code": 200,
"headers": {"Content-Type": "application/json",},
"content": json.dumps(
{
"id": 1,
"url": "http://example.com/hook",
"project_id": 4,
"push_events": True,
"issues_events": True,
"confidential_issues_events": True,
"merge_requests_events": True,
"tag_push_events": True,
"note_events": True,
"job_events": True,
"pipeline_events": True,
"wiki_page_events": True,
"enable_ssl_verification": True,
"created_at": "2012-10-12T17:04:47Z",
}
),
}
@urlmatch(netloc=r"fakegitlab", path=r"/api/v4/projects/4/hooks/1$", method="DELETE")
def delete_hook_handler(_, request):
if not request.headers.get("Authorization") == "Bearer foobar":
return {"status_code": 401}
return {
"status_code": 200,
"headers": {"Content-Type": "application/json",},
"content": json.dumps({}),
}
@urlmatch(netloc=r"fakegitlab", path=r"/api/v4/projects/4/deploy_keys/1$", method="DELETE")
def delete_deploykey_handker(_, request):
if not request.headers.get("Authorization") == "Bearer foobar":
return {"status_code": 401}
return {
"status_code": 200,
"headers": {"Content-Type": "application/json",},
"content": json.dumps({}),
}
@urlmatch(netloc=r"fakegitlab", path=r"/api/v4/users/1/projects$")
def user_projects_list_handler(_, request):
if not request.headers.get("Authorization") == "Bearer foobar":
return {"status_code": 401}
return {
"status_code": 200,
"headers": {"Content-Type": "application/json",},
"content": json.dumps(
[
{
"id": 2,
"name": "Another project",
"description": None,
"default_branch": "master",
"visibility": "public",
"path": "anotherproject",
"path_with_namespace": "knownuser/anotherproject",
"last_activity_at": "2013-09-30T13:46:02Z",
"web_url": "http://example.com/knownuser/anotherproject",
}
]
),
}
@contextmanager
def get_gitlab_trigger(dockerfile_path="", add_permissions=True, missing_avatar_url=False):
handlers = [
user_handler,
users_handler,
project_branches_handler,
project_tree_handler,
project_handler,
get_projects_handler(add_permissions),
tag_handler,
project_branch_handler,
get_group_handler(missing_avatar_url),
dockerfile_handler,
sub_dockerfile_handler,
namespace_handler,
user_namespace_handler,
namespaces_handler,
commit_handler,
create_deploykey_handler,
delete_deploykey_handker,
create_hook_handler,
delete_hook_handler,
project_tags_handler,
user_projects_list_handler,
catchall_handler,
]
with HTTMock(*handlers):
trigger_obj = AttrDict(dict(auth_token="foobar", id="sometrigger"))
trigger = GitLabBuildTrigger(
trigger_obj,
{
"build_source": "foo/bar",
"dockerfile_path": dockerfile_path,
"username": "knownuser",
},
)
client = gitlab.Gitlab("http://fakegitlab", oauth_token="foobar", timeout=20, api_version=4)
client.auth()
trigger._get_authorized_client = lambda: client
yield trigger