11import functools
22import inspect
3+ import time
34
45from azure .core .credentials import AzureNamedKeyCredential
5- from devtools_testutils import PowerShellPreparer
6+ from azure .core .exceptions import HttpResponseError
7+ from devtools_testutils import PowerShellPreparer , is_live
68
79CosmosPreparer = functools .partial (
8- PowerShellPreparer , "tables" ,
10+ PowerShellPreparer ,
11+ "tables" ,
912 tables_cosmos_account_name = "fake_cosmos_account" ,
10- tables_primary_cosmos_account_key = "fakecosmosaccountkey"
13+ tables_primary_cosmos_account_key = "fakecosmosaccountkey" ,
1114)
1215
1316TablesPreparer = functools .partial (
14- PowerShellPreparer , "tables" ,
17+ PowerShellPreparer ,
18+ "tables" ,
1519 tables_storage_account_name = "fake_table_account" ,
16- tables_primary_storage_account_key = "faketablesaccountkey"
20+ tables_primary_storage_account_key = "faketablesaccountkey" ,
1721)
1822
1923
2024def trim_kwargs_from_test_function (fn , kwargs ):
2125 # the next function is the actual test function. the kwargs need to be trimmed so
2226 # that parameters which are not required will not be passed to it.
23- if not getattr (fn , ' __is_preparer' , False ):
27+ if not getattr (fn , " __is_preparer" , False ):
2428 try :
2529 args , _ , kw , _ , _ , _ , _ = inspect .getfullargspec (fn )
2630 except AttributeError :
27- args , _ , kw , _ = inspect .getargspec (fn ) # pylint: disable=deprecated-method
31+ args , _ , kw , _ = inspect .getargspec (fn ) # pylint: disable=deprecated-method
2832 if kw is None :
2933 args = set (args )
3034 for key in [k for k in kwargs if k not in args ]:
3135 del kwargs [key ]
3236
3337
3438def tables_decorator (func , ** kwargs ):
35-
3639 @TablesPreparer ()
3740 def wrapper (* args , ** kwargs ):
3841 key = kwargs .pop ("tables_primary_storage_account_key" )
@@ -42,7 +45,7 @@ def wrapper(*args, **kwargs):
4245 kwargs ["tables_primary_storage_account_key" ] = key
4346 kwargs ["tables_storage_account_name" ] = name
4447
45- trimmed_kwargs = {k :v for k , v in kwargs .items ()}
48+ trimmed_kwargs = {k : v for k , v in kwargs .items ()}
4649 trim_kwargs_from_test_function (func , trimmed_kwargs )
4750
4851 func (* args , ** trimmed_kwargs )
@@ -51,7 +54,6 @@ def wrapper(*args, **kwargs):
5154
5255
5356def cosmos_decorator (func , ** kwargs ):
54-
5557 @CosmosPreparer ()
5658 def wrapper (* args , ** kwargs ):
5759 key = kwargs .pop ("tables_primary_cosmos_account_key" )
@@ -61,10 +63,28 @@ def wrapper(*args, **kwargs):
6163 kwargs ["tables_primary_cosmos_account_key" ] = key
6264 kwargs ["tables_cosmos_account_name" ] = name
6365
64- trimmed_kwargs = {k :v for k , v in kwargs .items ()}
66+ trimmed_kwargs = {k : v for k , v in kwargs .items ()}
6567 trim_kwargs_from_test_function (func , trimmed_kwargs )
6668
67- func (* args , ** trimmed_kwargs )
69+ EXPONENTIAL_BACKOFF = 1
70+ RETRY_COUNT = 0
6871
69- return wrapper
72+ try :
73+ return func (* args , ** trimmed_kwargs )
74+ except HttpResponseError as exc :
75+ if exc .status_code != 429 :
76+ raise
77+ print ("Retrying: {} {}" .format (RETRY_COUNT , EXPONENTIAL_BACKOFF ))
78+ while RETRY_COUNT < 6 :
79+ if is_live ():
80+ time .sleep (EXPONENTIAL_BACKOFF )
81+ try :
82+ return func (* args , ** trimmed_kwargs )
83+ except HttpResponseError as exc :
84+ print ("Retrying: {} {}" .format (RETRY_COUNT , EXPONENTIAL_BACKOFF ))
85+ EXPONENTIAL_BACKOFF **= 2
86+ RETRY_COUNT += 1
87+ if exc .status_code != 429 or RETRY_COUNT >= 6 :
88+ raise
7089
90+ return wrapper
0 commit comments