mirror of
https://github.com/odoo/runbot.git
synced 2025-03-16 07:55:45 +07:00
[FIX] *: handle rate limit in pylint tests
With a concurrency of 3 or more, it ends up being pretty easy to hit github's rate limit (5000 requests/h), at which point the run hits a cascading failure where every test from thereon blows up to the rate limiting. Add a handling for that case in some of the early github-querying fixtures, so they can wait for the ratelimit delay to be restored. This increases the need for a proper fake github thingie I could run on a per-test basis.
This commit is contained in:
parent
0b1b36d10c
commit
916fb30e75
27
conftest.py
27
conftest.py
@ -55,6 +55,7 @@ import time
|
||||
import uuid
|
||||
import xmlrpc.client
|
||||
from contextlib import closing
|
||||
from datetime import datetime
|
||||
|
||||
import psutil
|
||||
import pytest
|
||||
@ -105,7 +106,9 @@ def config(pytestconfig):
|
||||
return cnf
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
def rolemap(config):
|
||||
def rolemap(request, config):
|
||||
# hack because capsys is not session-scoped
|
||||
capmanager = request.config.pluginmanager.getplugin("capturemanager")
|
||||
# only fetch github logins once per session
|
||||
rolemap = {}
|
||||
for k, data in config.items():
|
||||
@ -116,7 +119,8 @@ def rolemap(config):
|
||||
else:
|
||||
continue
|
||||
|
||||
r = requests.get('https://api.github.com/user', headers={'Authorization': 'token %s' % data['token']})
|
||||
with capmanager.global_and_fixture_disabled():
|
||||
r = _rate_limited(lambda: requests.get('https://api.github.com/user', headers={'Authorization': 'token %s' % data['token']}))
|
||||
r.raise_for_status()
|
||||
|
||||
rolemap[role] = data['user'] = r.json()['login']
|
||||
@ -336,14 +340,15 @@ def env(port, server, db, default_crons):
|
||||
# users is just so I can avoid autouse on toplevel users fixture b/c it (seems
|
||||
# to) break the existing local tests
|
||||
@pytest.fixture
|
||||
def make_repo(request, config, tunnel, users):
|
||||
def make_repo(capsys, request, config, tunnel, users):
|
||||
owner = config['github']['owner']
|
||||
github = requests.Session()
|
||||
github.headers['Authorization'] = 'token %s' % config['github']['token']
|
||||
|
||||
# check whether "owner" is a user or an org, as repo-creation endpoint is
|
||||
# different
|
||||
q = github.get('https://api.github.com/users/{}'.format(owner))
|
||||
with capsys.disabled():
|
||||
q = _rate_limited(lambda: github.get('https://api.github.com/users/{}'.format(owner)))
|
||||
q.raise_for_status()
|
||||
if q.json().get('type') == 'Organization':
|
||||
endpoint = 'https://api.github.com/orgs/{}/repos'.format(owner)
|
||||
@ -399,6 +404,20 @@ def make_repo(request, config, tunnel, users):
|
||||
for repo in reversed(repos):
|
||||
repo.delete()
|
||||
|
||||
|
||||
def _rate_limited(req):
|
||||
while True:
|
||||
q = req()
|
||||
if not q.ok and q.headers.get('X-RateLimit-Remaining') == '0':
|
||||
reset = int(q.headers['X-RateLimit-Reset'])
|
||||
delay = round(reset - time.time() + 1.0)
|
||||
print("Hit rate limit, sleeping for", delay, "seconds")
|
||||
time.sleep(delay)
|
||||
continue
|
||||
break
|
||||
return q
|
||||
|
||||
|
||||
Commit = collections.namedtuple('Commit', 'id tree message author committer parents')
|
||||
class Repo:
|
||||
def __init__(self, session, fullname, repos):
|
||||
|
Loading…
Reference in New Issue
Block a user