MCPcopy Index your code
hub / github.com/ccxt/ccxt / test_safe

Method test_safe

python/ccxt/test/tests_async.py:281–353  ·  view source on GitHub ↗
(self, method_name, exchange, args=[], is_public=False)

Source from the content-addressed store, hash-verified

279 return final_skips
280
281 async def test_safe(self, method_name, exchange, args=[], is_public=False):
282 # `testSafe` method does not throw an exception, instead mutes it. The reason we
283 # mute the thrown exceptions here is because we don't want to stop the whole
284 # tests queue if any single test-method fails. Instead, they are echoed with
285 # formatted message "[TEST_FAILURE] ..." and that output is then regex-matched by
286 # run-tests.js, so the exceptions are still printed out to console from there.
287 max_retries = 3
288 args_stringified = exchange.json(args) # args.join() breaks when we provide a list of symbols or multidimensional array; "args.toString()" breaks bcz of "array to string conversion"
289 for i in range(0, max_retries):
290 try:
291 await self.test_method(method_name, exchange, args, is_public)
292 return True
293 except Exception as ex:
294 e = get_root_exception(ex)
295 is_load_markets = (method_name == 'loadMarkets')
296 is_auth_error = (isinstance(e, AuthenticationError))
297 is_not_supported = (isinstance(e, NotSupported))
298 is_operation_failed = (isinstance(e, OperationFailed)) # includes "DDoSProtection", "RateLimitExceeded", "RequestTimeout", "ExchangeNotAvailable", "OperationFailed", "InvalidNonce", ...
299 last_url_msg = '' if self.ws_tests else ' (Last url: ' + exchange.last_request_url + ' )'
300 if is_operation_failed:
301 # if last retry was gone with same `tempFailure` error, then let's eventually return false
302 if i == max_retries - 1:
303 is_on_maintenance = (isinstance(e, OnMaintenance))
304 is_exchange_not_available = (isinstance(e, ExchangeNotAvailable))
305 should_fail = None
306 ret_success = None
307 if is_load_markets:
308 # if "loadMarkets" does not succeed, we must return "false" to caller method, to stop tests continual
309 ret_success = False
310 # we might not break exchange tests, if exchange is on maintenance at this moment
311 if is_on_maintenance:
312 should_fail = False
313 else:
314 should_fail = True
315 else:
316 # for any other method tests:
317 if is_exchange_not_available and not is_on_maintenance:
318 # break exchange tests if "ExchangeNotAvailable" exception is thrown, but it's not maintenance
319 should_fail = True
320 ret_success = False
321 else:
322 # in all other cases of OperationFailed, show Warning, but don't mark test as failed
323 should_fail = False
324 ret_success = True
325 # output the message
326 fail_type = '[TEST_FAILURE]' if should_fail else '[TEST_WARNING]'
327 dump(fail_type, exchange.id, method_name, args_stringified, last_url_msg, 'Method could not be tested due to a repeated Network/Availability issues', ' | ', exception_message(e))
328 return ret_success
329 else:
330 # wait and retry again
331 # (increase wait time on every retry)
332 await exchange.sleep((i + 1) * 1000)
333 else:
334 # if it's loadMarkets, then fail test, because it's mandatory for tests
335 if is_load_markets:
336 dump('[TEST_FAILURE]', exchange.id, method_name, args_stringified, last_url_msg, 'Exchange can not load markets', exception_message(e))
337 return False
338 # if the specific arguments to the test method throws "NotSupported" exception

Callers 2

run_testsMethod · 0.95
load_exchangeMethod · 0.95

Calls 7

test_methodMethod · 0.95
get_root_exceptionFunction · 0.90
dumpFunction · 0.90
exception_messageFunction · 0.90
rangeFunction · 0.50
jsonMethod · 0.45
sleepMethod · 0.45

Tested by

no test coverage detected