Exercise github auth handling in tests

So far almost all of the github auth handling has been overridden in
the fake test classes. We can increase the test coverage and gain more
confidence when doing changes related to this by not replacing
getGithubClient. Instead call the super method and enhance the
resulting client with the relevant test data.

Change-Id: Icaa9cfb9f28f8faec2dc86f7e6393f5b23765cac
This commit is contained in:
Tobias Henkel
2020-09-03 13:45:57 +02:00
parent 9fc87bbdf5
commit 0986673990
4 changed files with 85 additions and 15 deletions

View File

@ -2271,6 +2271,8 @@ class FakeGithubPullRequest(object):
class FakeGithubClientManager(GithubClientManager):
github_class = tests.fakegithub.FakeGithubClient
github_enterprise_class = tests.fakegithub.FakeGithubEnterpriseClient
def __init__(self, connection_config):
super().__init__(connection_config)
@ -2280,15 +2282,19 @@ class FakeGithubClientManager(GithubClientManager):
def getGithubClient(self,
project_name=None,
user_id=None,
zuul_event_id=None):
client = super().getGithubClient(
project_name=project_name,
zuul_event_id=zuul_event_id)
# Some tests expect the installation id as part of the
if self.app_id:
inst_id = self.installation_map.get(project_name)
client = tests.fakegithub.FakeGithubClient(
self.github_data, inst_id=inst_id)
else:
client = tests.fakegithub.FakeGithubClient(self.github_data)
client.setInstId(inst_id)
# The super method creates a fake github client with empty data so
# add it here.
client.setData(self.github_data)
if self.record_clients:
self.recorded_clients.append(client)
@ -2400,7 +2406,7 @@ class FakeGithubConnection(githubconnection.GithubConnection):
# use the original method here and additionally register it in the
# fake github
super(FakeGithubConnection, self).addProject(project)
self.getGithubClient(project).addProject(project)
self.getGithubClient(project.name).addProject(project)
def getGitUrl(self, project):
if self.git_url_with_auth:

View File

@ -16,6 +16,7 @@
import urllib
from collections import defaultdict
import datetime
import github3.exceptions
import re
import time
@ -25,6 +26,7 @@ from requests import HTTPError
from requests.structures import CaseInsensitiveDict
from tests.fake_graphql import FakeGithubQuery
from zuul.driver.github.githubconnection import utc
FAKE_BASE_URL = 'https://example.com/api/v3/'
@ -262,7 +264,7 @@ class FakeRepository(object):
return FAKE_BASE_URL + fakepath
def _get(self, url, headers=None):
client = FakeGithubClient(self.data)
client = FakeGithubClient(data=self.data)
return client.session.get(url, headers)
def _create_branch(self, branch):
@ -493,7 +495,8 @@ class FakePull(object):
@property
def head(self):
client = FakeGithubClient(self._fake_pull_request.github.github_data)
client = FakeGithubClient(
data=self._fake_pull_request.github.github_data)
repo = client.repo_from_project(self._fake_pull_request.project)
return repo.commit(self._fake_pull_request.head_sha)
@ -592,6 +595,11 @@ class FakeGithubSession(object):
self._base_url = None
self.schema = graphene.Schema(query=FakeGithubQuery)
# Imitate hooks dict. This will be unused and ignored in the tests.
self.hooks = {
'response': []
}
def build_url(self, *args):
fakepath = '/'.join(args)
return FAKE_BASE_URL + fakepath
@ -629,6 +637,16 @@ class FakeGithubSession(object):
pull_request.addComment(json['body'])
return FakeResponse(None, 200)
# Handle access token creation
if re.match(r'.*/app/installations/.*/access_tokens', url):
expiry = (datetime.datetime.now(utc) + datetime.timedelta(
minutes=60)).replace(microsecond=0).isoformat()
data = {
'token': 'fake',
'expires_at': expiry,
}
return FakeResponse(data, 201)
return FakeResponse(None, 404)
def get_repo(self, request, params=None):
@ -639,6 +657,10 @@ class FakeGithubSession(object):
return repo.get_url(request, params=params)
def mount(self, prefix, adapter):
# Don't care in tests
pass
class FakeBranchProtectionRule:
@ -657,11 +679,18 @@ class FakeGithubData(object):
class FakeGithubClient(object):
def __init__(self, data, inst_id=None):
def __init__(self, session=None, data=None):
self._data = data
self._inst_id = inst_id
self._inst_id = None
self.session = FakeGithubSession(self)
def setData(self, data):
self._data = data
def setInstId(self, inst_id):
self._inst_id = inst_id
def user(self, login):
return FakeUser(login)
@ -727,3 +756,9 @@ class FakeGithubClient(object):
break
return iter(results)
class FakeGithubEnterpriseClient(FakeGithubClient):
def __init__(self, url, session=None, verify=True):
super().__init__(session=session)

View File

@ -1 +1,27 @@
fake
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAoc8R0SStVa2xopdpr3nqqOFjkZLBlC6VBr/amLkZmABomD20
4+N5Lor+ZW/ZI+FDjzq7rcCVFU/CxPJ9nrFkkmTBOBlyvemZUwvn08xWAtkNGb3/
q/8N1coADdxuX4wjsFKTCgc8Oz2AGS6g4/yiA0wcHzsnvaYooUbiyDt9hGCzC2g8
PHMSiZev7U+fw9EnFRQwXRLU4C7dbexnnEYG4TCLP3Koh+OFqfIR9vCIBRNfaqIz
DQFVahvydWMO31UpeJeE9MyH6UHe+upG3Hcz9R4v9XJ8eLGTQw2BCydLdcAbqMfL
tHEf+WD13Q+IMPDkFJXaSYGfiZKTwu09LDCbZwIDAQABAoIBAFVMR2QtJYLpEZ9Y
mkn6xw1H46k15/4poD3ynVWtHiTW8kxvGxCXNaandvwaPil/8pFqsM0jnHOjnFUe
T8J8WTwjCQh9wdMDdeQlfoxUR3Mw4IsVcdZFmhF9bxHfhf+wbI/it8itj77a6NBd
mEsXPoDmelysXoLHONvr9lj/o2dIi8yOJCpRUZA+y+fOA5J6S0dQGxmf19ijAICe
AqTKf/Si2/3Xz+w8U9uPvWKI6V1OO6x1gbhvc7ofEuUAQJuSiV9c6PxJFn0RPNRx
eIDi/sjIJeFHZ9anLoe8Igcw7Nbm9esvy8BXKL1mvYLHqIpwe6Zi5OXXxrPoL5EM
EkwEEeECgYEA1PZ3CNIwvGiQzhiXtECFqDHeTbC6sTvJKqagc/DgAg63klSWcpWd
FU4yDhPS0p8oS8IZEX5MWZWGw0YbgF8vYC4pkBiMPgz41y8g7yD9gxMnmVGvPoEn
IZXo6PQKljdHjx2iGpRnfrwuYZC45X66U6dHJI+S+jBBAJ8z/tCZV60CgYEAwoIu
OV6KVSs//0YTsJXGwUx3ZsP5ouH/X3aoULfWu+J8pJ3Eqd4l1ZRdg8Q+borSrQZl
hHOT54PxAFLLYhJWiXZAAxQi+9UOHzL5xG8gav5OkdPUP0F/6cF0yWLwVjg/fG7j
Pz9gBa9Bfwj85BD24dObCbhqY3YyODmKkMkm8eMCgYEA0j/Z2S2azAf4HmENNPoW
eq1xKgZ26o951c/XzV9b6OwatC8qsUmgYe5nYJqVozdakyC3mxuzySXkfFl0wVI3
9Z7djdOOcZxg+CEhRLSvVH7Os4F/oBfmSDQ2U/bLlO5SiarZ5Z/qZabnq48z2+83
iWs2w5OzqamGI1UKAmJzYakCgYEAm0ODVnQrBFVj3oe3y+ujHkXFwhiJuwWf7jov
nU9Cb/QY/uaZR+d2WAj4pOgP1fmmtks22gXQeKwPwuxUQVLWFSB5dHuseU3W2fy8
95qlTAL4ANwQvvWv/45XhTIfGxQHSXLSn3gdVCxToe4wwHTyPc3GIno9ImwFJnB4
NZ78IXUCgYEAnF8C7nBN2LoWgbj+AsgSabM4oh4tgnJw06Oi7skz6hBuUoqAMza/
wryjE942HZatAdovq1i/VXHLWkBwGBeVUj7l2ha+42VSIWhzDAXX5z2Zsg+iBAKP
d/TzNcE4X2n04XGvUGy/+KRgUp1LdtLNSd4JzbDQEehR++cLvrA2roI=
-----END RSA PRIVATE KEY-----

View File

@ -809,6 +809,8 @@ class GithubUser(collections.Mapping):
class GithubClientManager:
log = logging.getLogger('zuul.GithubConnection.GithubClientManager')
github_class = github3.GitHub
github_enterprise_class = github3.GitHubEnterprise
def __init__(self, connection_config):
self.connection_config = connection_config
@ -916,10 +918,10 @@ class GithubClientManager:
# disabling ssl verification is evil so emit a warning
self.log.warning("SSL verification disabled for "
"GitHub Enterprise")
github = github3.GitHubEnterprise(url, session=session,
verify=self.verify_ssl)
github = self.github_enterprise_class(
url, session=session, verify=self.verify_ssl)
else:
github = github3.GitHub(session=session)
github = self.github_class(session=session)
# anything going through requests to http/s goes through cache
github.session.mount('http://', self.cache_adapter)
@ -986,7 +988,8 @@ class GithubClientManager:
url = "%s/app/installations/%s/access_tokens" % (
self.base_url, installation_id)
response = requests.post(url, headers=headers, json=None)
github = self._createGithubClient()
response = github.session.post(url, headers=headers, json=None)
response.raise_for_status()
data = response.json()