Skip to content

Commit 38d734a

Browse files
committed
Add --trace to the phabricator command if it fails
This required rewriting @Retry Fixes #400
1 parent b2d9556 commit 38d734a

File tree

3 files changed

+56
-25
lines changed

3 files changed

+56
-25
lines changed

apis/phabricator.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@ def submit_patches(self, bug_id, has_patches):
4141
phab_revisions = []
4242

4343
@retry
44-
def submit_to_phabricator(rev_id):
44+
def submit_to_phabricator(rev_id, retry_attempt=None):
4545
cmd = [_arc(), "diff", "--verbatim", "--conduit-uri", self.url]
46+
if retry_attempt > 1:
47+
cmd.append("--trace")
4648
if rev_id:
4749
cmd.append(rev_id)
4850
cmd.append("--")

components/utilities.py

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
66

77
import copy
8+
import inspect
89
import pickle
910
import functools
1011
import time
@@ -144,28 +145,25 @@ def decorate(func):
144145
# Retry calling a function `times` times, sleeping between each tries, with an exponential backoff
145146
# This is to be used on API calls, that are likely to fail
146147

147-
RETRY_TIMES = 10
148+
def retry(_func=None, *, times=10, sleep_s=1, exp=2, exceptions=(Exception,), attempt_kw="retry_attempt"):
149+
def decorator(func):
150+
sig = inspect.signature(func)
151+
accepts_attempt = attempt_kw in sig.parameters
148152

149-
150-
def retry(_func=None, *, sleep_s=1, exp=2):
151-
def decorator_retry(func):
152153
@functools.wraps(func)
153-
def wrapper_retry(*args, **kwargs):
154-
global RETRY_TIMES
155-
retries_try = RETRY_TIMES
156-
sleep_duration = sleep_s
157-
while retries_try > 0:
154+
def wrapper(*args, **kwargs):
155+
backoff = sleep_s
156+
for attempt in range(1, times + 1):
158157
try:
159-
return func(*args, **kwargs)
160-
except BaseException as e:
161-
retries_try -= 1
162-
time.sleep(sleep_duration)
163-
sleep_duration *= exp
164-
if retries_try == 0:
165-
raise e
166-
return wrapper_retry
167-
168-
if _func is None:
169-
return decorator_retry
170-
else:
171-
return decorator_retry(_func)
158+
call_kwargs = dict(kwargs)
159+
if accepts_attempt:
160+
call_kwargs[attempt_kw] = attempt
161+
return func(*args, **call_kwargs)
162+
except exceptions:
163+
if attempt == times:
164+
raise # preserves the original traceback
165+
time.sleep(backoff)
166+
backoff *= exp
167+
return wrapper
168+
169+
return decorator if _func is None else decorator(_func)

tests/functionality_all_platforms.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
from apis.taskcluster import TaskclusterProvider
3333
from apis.phabricator import PhabricatorProvider
3434

35-
from tests.functionality_utilities import SHARED_COMMAND_MAPPINGS, TRY_OUTPUT, TRY_LOCKED_OUTPUT, CONDUIT_EDIT_OUTPUT, MockedBugzillaProvider, treeherder_response
35+
from tests.functionality_utilities import SHARED_COMMAND_MAPPINGS, TRY_OUTPUT, TRY_LOCKED_OUTPUT, ARC_OUTPUT, CONDUIT_EDIT_OUTPUT, MockedBugzillaProvider, treeherder_response
3636
from tests.mock_commandprovider import TestCommandProvider
3737
from tests.mock_libraryprovider import MockLibraryProvider
3838
from tests.mock_treeherder_server import MockTreeherderServerFactory, TYPE_HEALTH
@@ -662,7 +662,7 @@ def treeherder(request_type, fullpath):
662662

663663
def try_submit(cmd):
664664
nonlocal try_fails
665-
if try_fails == 0:
665+
if try_fails < 2:
666666
try_fails += 1
667667
raise Exception("No worky!")
668668
if "./mach try auto" in cmd:
@@ -697,6 +697,37 @@ def try_submit(cmd):
697697
finally:
698698
self._cleanup(u, expected_values)
699699

700+
# Fail the first time, then work.
701+
@logEntryExitHeaderLine
702+
def testPhabRetryFunctionality(self):
703+
try_fails = 0
704+
705+
def phab_submit(cmd):
706+
nonlocal try_fails
707+
if try_fails == 0:
708+
try_fails += 1
709+
raise Exception("No worky!")
710+
if "--trace" not in cmd:
711+
raise Exception("Expected to see --trace in the phabricator command")
712+
return ARC_OUTPUT % (83000 + 50, 83000 + 50)
713+
714+
library_filter = 'dav1d'
715+
(u, expected_values, _check_jobs) = self._setup(
716+
library_filter,
717+
lambda b: ["try_rev|2021-02-09 15:30:04 -0500|2021-02-12 17:40:01 +0000"],
718+
lambda: 50, # get_filed_bug_id_func,
719+
lambda b: {}, # filed_bug_ids_func
720+
AssertFalse, # treeherder_response
721+
command_callbacks={'phab_submit': phab_submit}
722+
)
723+
try:
724+
# Run it
725+
u.run(library_filter=library_filter)
726+
# Check that we created the job successfully
727+
_check_jobs(JOBSTATUS.AWAITING_SECOND_PLATFORMS_TRY_RESULTS, JOBOUTCOME.PENDING)
728+
finally:
729+
self._cleanup(u, expected_values)
730+
700731
@logEntryExitHeaderLine
701732
def testAllNewFuzzyPathJobs(self):
702733
@treeherder_response

0 commit comments

Comments
 (0)