testit-python-commons 4.1.14__tar.gz → 4.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/PKG-INFO +1 -1
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/setup.py +1 -1
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/client/api_client.py +65 -13
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/client/helpers/bulk_autotest_helper.py +31 -7
- testit_python_commons-4.2.0/src/testit_python_commons/services/retry.py +92 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons.egg-info/PKG-INFO +1 -1
- testit_python_commons-4.1.14/src/testit_python_commons/services/retry.py +0 -29
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/README.md +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/setup.cfg +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/__init__.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/api/__init__.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/api/completion_api.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/api/health_api.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/api/system_api.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/api/test_results_api.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/api/workers_api.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/api_client.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/apis/__init__.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/configuration.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/exceptions.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/model/__init__.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/model/completion_response.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/model/health_status_response.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/model/register_request.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/model/register_response.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/model/set_worker_status_request.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/model/set_worker_status_response.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/model/shutdown_response.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/model/test_result_cut_api_model.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/model/test_result_save_response.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/model_utils.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/models/__init__.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/rest.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/__init__.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/app_properties.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/client/__init__.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/client/client_configuration.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/client/converter.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/client/helpers/__init__.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/client/helpers/threads_manager.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/client/models/__init__.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/client/models/threads_for_create_and_result.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/client/models/threads_for_update_and_result.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/configurations/__init__.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/configurations/properties_names.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/decorators.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/dynamic_methods.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/models/__init__.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/models/adapter_mode.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/models/fixture.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/models/link.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/models/link_type.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/models/outcome_type.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/models/status_type.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/models/step_result.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/models/test_result.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/models/test_result_with_all_fixture_step_results_model.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/services/__init__.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/services/adapter_manager.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/services/adapter_manager_configuration.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/services/fixture_manager.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/services/fixture_storage.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/services/logger.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/services/plugin_manager.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/services/step_manager.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/services/step_result_storage.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/services/sync_storage/__init__.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/services/sync_storage/sync_storage_runner.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/services/utils.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/step.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/utils/__init__.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/utils/html_escape_utils.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons.egg-info/SOURCES.txt +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons.egg-info/dependency_links.txt +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons.egg-info/requires.txt +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons.egg-info/top_level.txt +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/tests/test_app_properties.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/tests/test_dynamic_methods.py +0 -0
- {testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/tests/test_html_escape_utils.py +0 -0
|
@@ -2,6 +2,7 @@ import logging
|
|
|
2
2
|
import os
|
|
3
3
|
from datetime import datetime
|
|
4
4
|
|
|
5
|
+
import testit_api_client
|
|
5
6
|
from testit_api_client import ApiClient, Configuration
|
|
6
7
|
from testit_api_client.apis import (
|
|
7
8
|
AttachmentsApi,
|
|
@@ -32,7 +33,12 @@ from testit_python_commons.client.converter import Converter
|
|
|
32
33
|
from testit_python_commons.client.helpers.bulk_autotest_helper import BulkAutotestHelper
|
|
33
34
|
from testit_python_commons.models.test_result import TestResult
|
|
34
35
|
from testit_python_commons.services.logger import adapter_logger
|
|
35
|
-
from testit_python_commons.services.retry import
|
|
36
|
+
from testit_python_commons.services.retry import (
|
|
37
|
+
is_non_retriable_api_exception,
|
|
38
|
+
is_retriable_connection_error,
|
|
39
|
+
retry,
|
|
40
|
+
retry_on_connection_error,
|
|
41
|
+
)
|
|
36
42
|
from typing import List
|
|
37
43
|
|
|
38
44
|
|
|
@@ -164,6 +170,7 @@ class ApiClientWorker:
|
|
|
164
170
|
return self.__autotest_api.api_v2_auto_tests_search_post(api_v2_auto_tests_search_post_request=model)
|
|
165
171
|
|
|
166
172
|
@adapter_logger
|
|
173
|
+
@retry
|
|
167
174
|
def write_test(self, test_result: TestResult) -> str:
|
|
168
175
|
model = Converter.project_id_and_external_id_to_auto_tests_search_post_request(
|
|
169
176
|
self.__config.get_project_id(),
|
|
@@ -198,6 +205,7 @@ class ApiClientWorker:
|
|
|
198
205
|
return self.__load_test_result(test_result)
|
|
199
206
|
|
|
200
207
|
@adapter_logger
|
|
208
|
+
@retry
|
|
201
209
|
def write_tests(self, test_results: List[TestResult], fixture_containers: dict) -> None:
|
|
202
210
|
logging.debug("call __write_tests")
|
|
203
211
|
bulk_autotest_helper = BulkAutotestHelper(self.__autotest_api, self.__test_run_api, self.__config)
|
|
@@ -335,11 +343,20 @@ class ApiClientWorker:
|
|
|
335
343
|
# logging.debug(f'Got workitem {work_item}')
|
|
336
344
|
|
|
337
345
|
return work_item.id
|
|
346
|
+
except testit_api_client.exceptions.ApiException as exc:
|
|
347
|
+
if is_retriable_connection_error(exc):
|
|
348
|
+
raise
|
|
349
|
+
if is_non_retriable_api_exception(exc):
|
|
350
|
+
logging.warning(f'Getting workitem by id {work_item_id} status: {exc}')
|
|
351
|
+
return
|
|
352
|
+
raise
|
|
338
353
|
except Exception as exc:
|
|
354
|
+
if is_retriable_connection_error(exc):
|
|
355
|
+
raise
|
|
339
356
|
logging.error(f'Getting workitem by id {work_item_id} status: {exc}')
|
|
340
357
|
|
|
341
358
|
@adapter_logger
|
|
342
|
-
|
|
359
|
+
@retry_on_connection_error
|
|
343
360
|
def __get_work_items_linked_to_autotest(self, autotest_global_id: str) -> List[AutoTestWorkItemIdentifierApiResult]:
|
|
344
361
|
return self.__autotest_api.get_work_items_linked_to_auto_test(id=autotest_global_id)
|
|
345
362
|
|
|
@@ -400,6 +417,8 @@ class ApiClientWorker:
|
|
|
400
417
|
try:
|
|
401
418
|
self.__autotest_api.update_auto_test(update_auto_test_request=model)
|
|
402
419
|
except Exception as exc:
|
|
420
|
+
if is_retriable_connection_error(exc):
|
|
421
|
+
raise
|
|
403
422
|
logging.error(f'Cannot update autotest "{test_result.get_autotest_name()}" status: {exc}')
|
|
404
423
|
|
|
405
424
|
logging.debug(f'Autotest "{test_result.get_autotest_name()}" was updated')
|
|
@@ -416,18 +435,40 @@ class ApiClientWorker:
|
|
|
416
435
|
@adapter_logger
|
|
417
436
|
@retry
|
|
418
437
|
def __unlink_test_to_work_item(self, autotest_global_id: str, work_item_id: str) -> None:
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
438
|
+
try:
|
|
439
|
+
self.__autotest_api.delete_auto_test_link_from_work_item(
|
|
440
|
+
id=autotest_global_id,
|
|
441
|
+
work_item_id=work_item_id)
|
|
442
|
+
except testit_api_client.exceptions.ApiException as exc:
|
|
443
|
+
if is_non_retriable_api_exception(exc):
|
|
444
|
+
logging.warning(
|
|
445
|
+
'Cannot unlink autotest %s from work item %s: %s',
|
|
446
|
+
autotest_global_id,
|
|
447
|
+
work_item_id,
|
|
448
|
+
exc,
|
|
449
|
+
)
|
|
450
|
+
return
|
|
451
|
+
raise
|
|
422
452
|
|
|
423
453
|
logging.debug(f'Autotest was unlinked with workItem "{work_item_id}" by global id "{autotest_global_id}')
|
|
424
454
|
|
|
425
455
|
@adapter_logger
|
|
426
456
|
@retry
|
|
427
457
|
def __link_test_to_work_item(self, autotest_global_id: str, work_item_id: str) -> None:
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
458
|
+
try:
|
|
459
|
+
self.__autotest_api.link_auto_test_to_work_item(
|
|
460
|
+
autotest_global_id,
|
|
461
|
+
link_auto_test_to_work_item_request=LinkAutoTestToWorkItemRequest(id=work_item_id))
|
|
462
|
+
except testit_api_client.exceptions.ApiException as exc:
|
|
463
|
+
if is_non_retriable_api_exception(exc):
|
|
464
|
+
logging.warning(
|
|
465
|
+
'Cannot link autotest %s to work item %s: %s',
|
|
466
|
+
autotest_global_id,
|
|
467
|
+
work_item_id,
|
|
468
|
+
exc,
|
|
469
|
+
)
|
|
470
|
+
return
|
|
471
|
+
raise
|
|
431
472
|
|
|
432
473
|
logging.debug(f'Autotest was linked with workItem "{work_item_id}" by global id "{autotest_global_id}')
|
|
433
474
|
|
|
@@ -472,7 +513,17 @@ class ApiClientWorker:
|
|
|
472
513
|
id=test_result.get_test_result_id(),
|
|
473
514
|
api_v2_test_results_id_put_request=model)
|
|
474
515
|
except Exception as exc:
|
|
475
|
-
|
|
516
|
+
if is_retriable_connection_error(exc):
|
|
517
|
+
raise
|
|
518
|
+
logging.error(
|
|
519
|
+
f'Cannot update test result with id "{test_result.get_test_result_id()}" status: {exc}')
|
|
520
|
+
|
|
521
|
+
@adapter_logger
|
|
522
|
+
@retry
|
|
523
|
+
def __upload_attachment(self, path: str) -> AttachmentPutModel:
|
|
524
|
+
with open(path, "rb") as file:
|
|
525
|
+
attachment_response = self.__attachments_api.api_v2_attachments_post(file=file)
|
|
526
|
+
return AttachmentPutModel(attachment_response['id'])
|
|
476
527
|
|
|
477
528
|
@adapter_logger
|
|
478
529
|
def load_attachments(self, attach_paths: list or tuple) -> List[AttachmentPutModel]:
|
|
@@ -481,12 +532,11 @@ class ApiClientWorker:
|
|
|
481
532
|
for path in attach_paths:
|
|
482
533
|
if os.path.isfile(path):
|
|
483
534
|
try:
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
attachments.append(AttachmentPutModel(attachment_response['id']))
|
|
487
|
-
|
|
535
|
+
attachments.append(self.__upload_attachment(path))
|
|
488
536
|
logging.debug(f'Attachment "{path}" was uploaded')
|
|
489
537
|
except Exception as exc:
|
|
538
|
+
if is_retriable_connection_error(exc):
|
|
539
|
+
raise
|
|
490
540
|
logging.error(f'Upload attachment "{path}" status: {exc}')
|
|
491
541
|
else:
|
|
492
542
|
logging.error(f'File "{path}" was not found!')
|
|
@@ -496,10 +546,12 @@ class ApiClientWorker:
|
|
|
496
546
|
return self.__config.get_configuration_id()
|
|
497
547
|
|
|
498
548
|
@adapter_logger
|
|
549
|
+
@retry
|
|
499
550
|
def __get_project(self) -> ProjectModel:
|
|
500
551
|
return self.__projects_api.get_project_by_id(id=self.__config.get_project_id())
|
|
501
552
|
|
|
502
553
|
@adapter_logger
|
|
554
|
+
@retry
|
|
503
555
|
def __get_workflow_by_id(self, workflow_id: str) -> WorkflowApiResult:
|
|
504
556
|
return self.__workflows_api.api_v2_workflows_id_get(id=workflow_id)
|
|
505
557
|
|
|
@@ -18,7 +18,9 @@ from testit_python_commons.client.models import (
|
|
|
18
18
|
ThreadsForUpdateAndResult
|
|
19
19
|
)
|
|
20
20
|
from testit_python_commons.services.logger import adapter_logger
|
|
21
|
-
|
|
21
|
+
import testit_api_client
|
|
22
|
+
|
|
23
|
+
from testit_python_commons.services.retry import is_non_retriable_api_exception, retry
|
|
22
24
|
from testit_python_commons.utils.html_escape_utils import HtmlEscapeUtils
|
|
23
25
|
from typing import Dict, List
|
|
24
26
|
|
|
@@ -186,9 +188,20 @@ class BulkAutotestHelper:
|
|
|
186
188
|
@adapter_logger
|
|
187
189
|
@retry
|
|
188
190
|
def __unlink_test_to_work_item(self, autotest_global_id: str, work_item_id: str):
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
191
|
+
try:
|
|
192
|
+
self.__autotests_api.delete_auto_test_link_from_work_item(
|
|
193
|
+
id=autotest_global_id,
|
|
194
|
+
work_item_id=work_item_id)
|
|
195
|
+
except testit_api_client.exceptions.ApiException as exc:
|
|
196
|
+
if is_non_retriable_api_exception(exc):
|
|
197
|
+
logging.warning(
|
|
198
|
+
'Cannot unlink autotest %s from work item %s: %s',
|
|
199
|
+
autotest_global_id,
|
|
200
|
+
work_item_id,
|
|
201
|
+
exc,
|
|
202
|
+
)
|
|
203
|
+
return
|
|
204
|
+
raise
|
|
192
205
|
|
|
193
206
|
logging.debug(f'Autotest was unlinked with workItem "{work_item_id}" by global id "{autotest_global_id}')
|
|
194
207
|
|
|
@@ -196,9 +209,20 @@ class BulkAutotestHelper:
|
|
|
196
209
|
@adapter_logger
|
|
197
210
|
@retry
|
|
198
211
|
def __link_test_to_work_item(self, autotest_global_id: str, work_item_id: str):
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
212
|
+
try:
|
|
213
|
+
self.__autotests_api.link_auto_test_to_work_item(
|
|
214
|
+
autotest_global_id,
|
|
215
|
+
link_auto_test_to_work_item_request=LinkAutoTestToWorkItemRequest(id=work_item_id))
|
|
216
|
+
except testit_api_client.exceptions.ApiException as exc:
|
|
217
|
+
if is_non_retriable_api_exception(exc):
|
|
218
|
+
logging.warning(
|
|
219
|
+
'Cannot link autotest %s to work item %s: %s',
|
|
220
|
+
autotest_global_id,
|
|
221
|
+
work_item_id,
|
|
222
|
+
exc,
|
|
223
|
+
)
|
|
224
|
+
return
|
|
225
|
+
raise
|
|
202
226
|
|
|
203
227
|
logging.debug(f'Autotest was linked with workItem "{work_item_id}" by global id "{autotest_global_id}')
|
|
204
228
|
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import random
|
|
3
|
+
import time
|
|
4
|
+
from http.client import RemoteDisconnected
|
|
5
|
+
|
|
6
|
+
import testit_api_client
|
|
7
|
+
import urllib3
|
|
8
|
+
|
|
9
|
+
CONNECTION_RETRIES = 3
|
|
10
|
+
CONNECTION_RETRY_DELAY_SEC = 1
|
|
11
|
+
API_EXCEPTION_RETRIES = 10
|
|
12
|
+
NON_RETRIABLE_API_STATUS_CODES = (400, 404)
|
|
13
|
+
|
|
14
|
+
_RETRIABLE_CONNECTION_TYPES = (
|
|
15
|
+
urllib3.exceptions.ProtocolError,
|
|
16
|
+
urllib3.exceptions.NewConnectionError,
|
|
17
|
+
ConnectionError,
|
|
18
|
+
ConnectionResetError,
|
|
19
|
+
ConnectionAbortedError,
|
|
20
|
+
RemoteDisconnected,
|
|
21
|
+
TimeoutError,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def is_non_retriable_api_exception(exc: BaseException) -> bool:
|
|
26
|
+
return (
|
|
27
|
+
isinstance(exc, testit_api_client.exceptions.ApiException)
|
|
28
|
+
and int(exc.status) in NON_RETRIABLE_API_STATUS_CODES
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def is_retriable_connection_error(exc: BaseException) -> bool:
|
|
33
|
+
seen = set()
|
|
34
|
+
current = exc
|
|
35
|
+
while current is not None and id(current) not in seen:
|
|
36
|
+
seen.add(id(current))
|
|
37
|
+
if isinstance(current, _RETRIABLE_CONNECTION_TYPES):
|
|
38
|
+
return True
|
|
39
|
+
current = current.__cause__ or current.__context__
|
|
40
|
+
return False
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _execute_with_connection_retries(func, args, kwargs):
|
|
44
|
+
connection_attempts = 0
|
|
45
|
+
|
|
46
|
+
while True:
|
|
47
|
+
try:
|
|
48
|
+
return func(*args, **kwargs)
|
|
49
|
+
except BaseException as e:
|
|
50
|
+
if not is_retriable_connection_error(e):
|
|
51
|
+
raise
|
|
52
|
+
|
|
53
|
+
connection_attempts += 1
|
|
54
|
+
logging.warning(
|
|
55
|
+
'Connection error in %s (attempt %d/%d): %s',
|
|
56
|
+
func.__name__,
|
|
57
|
+
connection_attempts,
|
|
58
|
+
CONNECTION_RETRIES,
|
|
59
|
+
e,
|
|
60
|
+
)
|
|
61
|
+
if connection_attempts > CONNECTION_RETRIES:
|
|
62
|
+
raise
|
|
63
|
+
|
|
64
|
+
time.sleep(CONNECTION_RETRY_DELAY_SEC)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def retry_on_connection_error(func):
|
|
68
|
+
def retry_wrapper(*args, **kwargs):
|
|
69
|
+
return _execute_with_connection_retries(func, args, kwargs)
|
|
70
|
+
|
|
71
|
+
return retry_wrapper
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def retry(func):
|
|
75
|
+
def retry_wrapper(*args, **kwargs):
|
|
76
|
+
api_attempts = 0
|
|
77
|
+
|
|
78
|
+
while True:
|
|
79
|
+
try:
|
|
80
|
+
return _execute_with_connection_retries(func, args, kwargs)
|
|
81
|
+
except testit_api_client.exceptions.ApiException as e:
|
|
82
|
+
if is_non_retriable_api_exception(e):
|
|
83
|
+
raise
|
|
84
|
+
|
|
85
|
+
api_attempts += 1
|
|
86
|
+
logging.error(e)
|
|
87
|
+
if api_attempts >= API_EXCEPTION_RETRIES:
|
|
88
|
+
raise
|
|
89
|
+
|
|
90
|
+
time.sleep(random.randrange(0, 100) / 100)
|
|
91
|
+
|
|
92
|
+
return retry_wrapper
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
import random
|
|
3
|
-
import time
|
|
4
|
-
|
|
5
|
-
import testit_api_client
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def retry(func):
|
|
9
|
-
def retry_wrapper(*args, **kwargs):
|
|
10
|
-
attempts = 0
|
|
11
|
-
retries = 10
|
|
12
|
-
|
|
13
|
-
while attempts < retries:
|
|
14
|
-
try:
|
|
15
|
-
return func(*args, **kwargs)
|
|
16
|
-
except testit_api_client.exceptions.ApiException as e:
|
|
17
|
-
sleep_time = random.randrange(0, 100)
|
|
18
|
-
time.sleep(sleep_time/100)
|
|
19
|
-
attempts += 1
|
|
20
|
-
|
|
21
|
-
logging.error(e)
|
|
22
|
-
if e.status == '404':
|
|
23
|
-
attempts = retries
|
|
24
|
-
return
|
|
25
|
-
if e.status == '400':
|
|
26
|
-
attempts = retries
|
|
27
|
-
return
|
|
28
|
-
|
|
29
|
-
return retry_wrapper
|
|
File without changes
|
|
File without changes
|
{testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/api_client_syncstorage/rest.py
RENAMED
|
File without changes
|
|
File without changes
|
{testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/decorators.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/src/testit_python_commons/step.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{testit_python_commons-4.1.14 → testit_python_commons-4.2.0}/tests/test_html_escape_utils.py
RENAMED
|
File without changes
|