holado 0.13.22__py3-none-any.whl
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.
- holado/__init__.py +358 -0
- holado/common/__init__.py +25 -0
- holado/common/context/__init__.py +25 -0
- holado/common/context/context.py +248 -0
- holado/common/context/service_manager.py +262 -0
- holado/common/context/session_context.py +516 -0
- holado/common/handlers/__init__.py +19 -0
- holado/common/handlers/enums.py +41 -0
- holado/common/handlers/object.py +175 -0
- holado/common/handlers/undefined.py +55 -0
- holado/common/tools/__init__.py +19 -0
- holado/common/tools/gc_manager.py +155 -0
- holado/holado_config.py +45 -0
- holado-0.13.22.dist-info/METADATA +194 -0
- holado-0.13.22.dist-info/RECORD +698 -0
- holado-0.13.22.dist-info/WHEEL +4 -0
- holado-0.13.22.dist-info/licenses/LICENSE +21 -0
- holado_ais/__init__.py +33 -0
- holado_ais/ais/MaritimeIdentificationDigits.csv +295 -0
- holado_ais/ais/ais_manager.py +151 -0
- holado_ais/ais/ais_messages.py +356 -0
- holado_ais/ais/ais_payload.py +35 -0
- holado_ais/ais/enums.py +37 -0
- holado_ais/ais/patch_pyais.py +1174 -0
- holado_ais/tests/behave/steps/__init__.py +17 -0
- holado_ais/tests/behave/steps/ais/__init__.py +0 -0
- holado_ais/tests/behave/steps/ais/ais_manager_steps.py +50 -0
- holado_ais/tests/behave/steps/ais/ais_messages_steps.py +237 -0
- holado_binary/__init__.py +17 -0
- holado_binary/ipc/binary.py +125 -0
- holado_binary/ipc/bit_series.py +307 -0
- holado_binary/tests/behave/steps/__init__.py +17 -0
- holado_binary/tests/behave/steps/ipc/binary_steps.py +57 -0
- holado_binary/tests/behave/steps/ipc/bit_series_steps.py +132 -0
- holado_context/__init__.py +16 -0
- holado_context/tests/behave/steps/__init__.py +16 -0
- holado_context/tests/behave/steps/private/__init__.py +16 -0
- holado_context/tests/behave/steps/private/common/context_steps.py +68 -0
- holado_core/__init__.py +32 -0
- holado_core/common/__init__.py +0 -0
- holado_core/common/actors/actions.py +97 -0
- holado_core/common/actors/actor.py +226 -0
- holado_core/common/actors/element_actor.py +32 -0
- holado_core/common/actors/find_actor.py +106 -0
- holado_core/common/actors/tree_actor.py +32 -0
- holado_core/common/actors/verify_actions.py +69 -0
- holado_core/common/block/base.py +122 -0
- holado_core/common/block/block_manager.py +173 -0
- holado_core/common/block/block_method.py +46 -0
- holado_core/common/block/block_steps.py +37 -0
- holado_core/common/block/function.py +42 -0
- holado_core/common/block/scope_function.py +28 -0
- holado_core/common/block/scope_manager.py +238 -0
- holado_core/common/block/scope_steps.py +141 -0
- holado_core/common/criterias/and_criteria.py +61 -0
- holado_core/common/criterias/criteria.py +78 -0
- holado_core/common/criterias/or_criteria.py +64 -0
- holado_core/common/criterias/tools/criteria_context.py +20 -0
- holado_core/common/criterias/tools/criteria_parameters.py +18 -0
- holado_core/common/drivers/driver.py +153 -0
- holado_core/common/drivers/element_driver.py +30 -0
- holado_core/common/drivers/element_internal_api.py +239 -0
- holado_core/common/drivers/internal_api.py +40 -0
- holado_core/common/drivers/tree_driver.py +30 -0
- holado_core/common/drivers/tree_internal_api.py +176 -0
- holado_core/common/exceptions/__init__.py +0 -0
- holado_core/common/exceptions/element_exception.py +28 -0
- holado_core/common/exceptions/exceptions.py +24 -0
- holado_core/common/exceptions/functional_exception.py +21 -0
- holado_core/common/exceptions/holado_exception.py +25 -0
- holado_core/common/exceptions/technical_exception.py +27 -0
- holado_core/common/exceptions/timeout_exception.py +20 -0
- holado_core/common/exceptions/verify_exception.py +20 -0
- holado_core/common/finders/after_in_tree_finder.py +87 -0
- holado_core/common/finders/element_finder.py +60 -0
- holado_core/common/finders/else_finder.py +105 -0
- holado_core/common/finders/finder.py +478 -0
- holado_core/common/finders/or_finder.py +98 -0
- holado_core/common/finders/then_finder.py +157 -0
- holado_core/common/finders/tools/enums.py +30 -0
- holado_core/common/finders/tools/find_builder.py +118 -0
- holado_core/common/finders/tools/find_context.py +405 -0
- holado_core/common/finders/tools/find_info.py +27 -0
- holado_core/common/finders/tools/find_parameters.py +240 -0
- holado_core/common/finders/tools/find_updater.py +95 -0
- holado_core/common/finders/tools/finder_info.py +26 -0
- holado_core/common/finders/tree_finder.py +146 -0
- holado_core/common/handlers/__init__.py +0 -0
- holado_core/common/handlers/abstracts/base_redo.py +702 -0
- holado_core/common/handlers/abstracts/get_or_create.py +120 -0
- holado_core/common/handlers/element_holder.py +122 -0
- holado_core/common/handlers/enums.py +23 -0
- holado_core/common/handlers/exceptions/redo_exceptions.py +28 -0
- holado_core/common/handlers/features/resource_by_name.py +187 -0
- holado_core/common/handlers/features/resource_by_type.py +174 -0
- holado_core/common/handlers/redo.py +119 -0
- holado_core/common/handlers/wait.py +127 -0
- holado_core/common/inspectors/element_inspector.py +57 -0
- holado_core/common/inspectors/inspector.py +221 -0
- holado_core/common/inspectors/tools/inspect_builder.py +169 -0
- holado_core/common/inspectors/tools/inspect_context.py +69 -0
- holado_core/common/inspectors/tools/inspect_parameters.py +181 -0
- holado_core/common/inspectors/tree_inspector.py +73 -0
- holado_core/common/resource/persisted_data_manager.py +113 -0
- holado_core/common/resource/persisted_method_to_call_manager.py +263 -0
- holado_core/common/resource/resource_manager.py +126 -0
- holado_core/common/resource/table_data_manager.py +110 -0
- holado_core/common/tables/__init__.py +1 -0
- holado_core/common/tables/comparators/__init__.py +0 -0
- holado_core/common/tables/comparators/boolean_table_cell_comparator.py +25 -0
- holado_core/common/tables/comparators/bytes_table_cell_comparator.py +25 -0
- holado_core/common/tables/comparators/datetime_table_cell_comparator.py +24 -0
- holado_core/common/tables/comparators/float_table_cell_comparator.py +31 -0
- holado_core/common/tables/comparators/integer_table_cell_comparator.py +25 -0
- holado_core/common/tables/comparators/internal_table_cell_comparator.py +30 -0
- holado_core/common/tables/comparators/string_table_cell_comparator.py +24 -0
- holado_core/common/tables/comparators/string_table_comparator.py +29 -0
- holado_core/common/tables/comparators/string_table_row_comparator.py +29 -0
- holado_core/common/tables/comparators/table_cell_comparator.py +40 -0
- holado_core/common/tables/comparators/table_comparator.py +209 -0
- holado_core/common/tables/comparators/table_comparator_manager.py +60 -0
- holado_core/common/tables/comparators/table_row_comparator.py +116 -0
- holado_core/common/tables/comparators/table_with_header_comparator.py +68 -0
- holado_core/common/tables/converters/__init__.py +0 -0
- holado_core/common/tables/converters/table_converter.py +233 -0
- holado_core/common/tables/enums.py +23 -0
- holado_core/common/tables/table.py +261 -0
- holado_core/common/tables/table_cell.py +126 -0
- holado_core/common/tables/table_manager.py +365 -0
- holado_core/common/tables/table_row.py +169 -0
- holado_core/common/tables/table_with_header.py +242 -0
- holado_core/common/tools/__init__.py +0 -0
- holado_core/common/tools/comparators/comparator.py +151 -0
- holado_core/common/tools/comparators/object_comparator.py +21 -0
- holado_core/common/tools/converters/converter.py +118 -0
- holado_core/common/tools/path_manager.py +238 -0
- holado_core/common/tools/string_tools.py +144 -0
- holado_core/common/tools/tools.py +197 -0
- holado_core/tests/behave/steps/__init__.py +20 -0
- holado_core/tests/behave/steps/common/__init__.py +0 -0
- holado_core/tests/behave/steps/common/common_steps.py +137 -0
- holado_core/tests/behave/steps/common/config_steps.py +42 -0
- holado_core/tests/behave/steps/common/resource_steps.py +62 -0
- holado_core/tests/behave/steps/common/tables_steps.py +560 -0
- holado_core/tools/__init__.py +0 -0
- holado_core/tools/abstracts/__init__.py +0 -0
- holado_core/tools/abstracts/blocking_command_service.py +64 -0
- holado_core/tools/abstracts/service.py +48 -0
- holado_crypto/__init__.py +31 -0
- holado_crypto/crypto/crypto.py +108 -0
- holado_crypto/crypto/key.py +92 -0
- holado_crypto/crypto/tcpbin.py +105 -0
- holado_crypto/crypto/transport/__init__.py +0 -0
- holado_crypto/crypto/transport/crc.py +40 -0
- holado_crypto/tests/behave/steps/__init__.py +18 -0
- holado_crypto/tests/behave/steps/crypto_steps.py +112 -0
- holado_crypto/tests/behave/steps/key_steps.py +82 -0
- holado_crypto/tests/behave/steps/tcpbin_steps.py +79 -0
- holado_data/__init__.py +31 -0
- holado_data/data/generator/base.py +93 -0
- holado_data/data/generator/generator_manager.py +27 -0
- holado_data/data/generator/python_generator.py +30 -0
- holado_data/tests/behave/steps/__init__.py +17 -0
- holado_data/tests/behave/steps/data/generator_steps.py +91 -0
- holado_data/tests/behave/steps/tools/utils_steps.py +59 -0
- holado_db/__init__.py +32 -0
- holado_db/tests/behave/steps/__init__.py +18 -0
- holado_db/tests/behave/steps/tools/db/db_client_steps.py +134 -0
- holado_db/tests/behave/steps/tools/db/postgresql_client_steps.py +59 -0
- holado_db/tests/behave/steps/tools/db/sqlite_client_steps.py +57 -0
- holado_db/tools/db/clients/base/db_audit.py +94 -0
- holado_db/tools/db/clients/base/db_client.py +344 -0
- holado_db/tools/db/clients/postgresql/postgresql_audit.py +75 -0
- holado_db/tools/db/clients/postgresql/postgresql_client.py +84 -0
- holado_db/tools/db/clients/sqlite/sqlite_audit.py +70 -0
- holado_db/tools/db/clients/sqlite/sqlite_client.py +60 -0
- holado_db/tools/db/db_manager.py +109 -0
- holado_db/tools/db/query/base/query_builder.py +138 -0
- holado_db/tools/db/query/pypika/pypika_query_builder.py +244 -0
- holado_db/tools/db/query/query_manager.py +77 -0
- holado_django/__init__.py +31 -0
- holado_django/server/HOWTO.txt +27 -0
- holado_django/server/django_projects/rest_api/db.sqlite3 +0 -0
- holado_django/server/django_projects/rest_api/manage.py +22 -0
- holado_django/server/django_projects/rest_api/rest_api/__init__.py +0 -0
- holado_django/server/django_projects/rest_api/rest_api/application/__init__.py +0 -0
- holado_django/server/django_projects/rest_api/rest_api/application/admin.py +3 -0
- holado_django/server/django_projects/rest_api/rest_api/application/apps.py +9 -0
- holado_django/server/django_projects/rest_api/rest_api/application/migrations/__init__.py +0 -0
- holado_django/server/django_projects/rest_api/rest_api/application/models.py +3 -0
- holado_django/server/django_projects/rest_api/rest_api/application/tests.py +3 -0
- holado_django/server/django_projects/rest_api/rest_api/application/views.py +6 -0
- holado_django/server/django_projects/rest_api/rest_api/asgi.py +16 -0
- holado_django/server/django_projects/rest_api/rest_api/settings.py +130 -0
- holado_django/server/django_projects/rest_api/rest_api/urls.py +35 -0
- holado_django/server/django_projects/rest_api/rest_api/wsgi.py +16 -0
- holado_django/server/django_server.py +110 -0
- holado_django/server/grpc_django_server.py +57 -0
- holado_django/server/patch_djangogrpcframework.py +46 -0
- holado_django/tests/behave/steps/__init__.py +16 -0
- holado_django/tests/behave/steps/django_server_steps.py +83 -0
- holado_docker/__init__.py +25 -0
- holado_docker/sdk/docker/container_logs.py +447 -0
- holado_docker/sdk/docker/docker_client.py +537 -0
- holado_docker/sdk/docker/docker_service.py +71 -0
- holado_docker/tests/behave/steps/__init__.py +16 -0
- holado_docker/tests/behave/steps/sdk/docker/container_logs_steps.py +47 -0
- holado_examples/projects/server_rest/server_rest_example/initialize_holado.py +72 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/db.sqlite3 +0 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/manage.py +22 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/__init__.py +0 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/__init__.py +0 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/admin.py +3 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/apps.py +7 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/migrations/__init__.py +0 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/models.py +3 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/serializers.py +15 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/tests.py +3 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/views.py +24 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/asgi.py +16 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/settings.py +130 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/urls.py +31 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/wsgi.py +16 -0
- holado_examples/projects/server_rest/server_rest_example/rest_server.py +37 -0
- holado_examples/scripts/script_custom_initialization.py +16 -0
- holado_examples/scripts/script_minimal_initialization.py +23 -0
- holado_examples/tests/behave/testing_solution/__main__.py +13 -0
- holado_examples/tests/behave/testing_solution/behave_environment.py +35 -0
- holado_examples/tests/behave/testing_solution/environment.py +36 -0
- holado_examples/tests/behave/testing_solution/features/Configuration/Actions/configure_system.feature +10 -0
- holado_examples/tests/behave/testing_solution/features/NonReg/example.feature +26 -0
- holado_examples/tests/behave/testing_solution/initialize_holado.py +62 -0
- holado_examples/tests/behave/testing_solution/logging.conf +102 -0
- holado_examples/tests/behave/testing_solution/requirements.txt +5 -0
- holado_examples/tests/behave/testing_solution/run_test.sh +7 -0
- holado_examples/tests/behave/testing_solution/run_test_nonreg.sh +6 -0
- holado_examples/tests/behave/testing_solution/src/common/tools/path_manager.py +40 -0
- holado_examples/tests/behave/testing_solution/src/config/config_manager.py +30 -0
- holado_examples/tests/behave/testing_solution/src/context/session_context.py +45 -0
- holado_examples/tests/behave/testing_solution/steps/config_steps.py +21 -0
- holado_examples/tests/behave/testing_solution/steps/public_steps.py +10 -0
- holado_grpc/TODO +8 -0
- holado_grpc/__init__.py +40 -0
- holado_grpc/api/rpc/TODO.txt +4 -0
- holado_grpc/api/rpc/grpc_client.py +210 -0
- holado_grpc/api/rpc/grpc_manager.py +81 -0
- holado_grpc/ipc/rpc/__init__.py +0 -0
- holado_grpc/ipc/rpc/grpc_compiler.py +45 -0
- holado_grpc/ipc/rpc/grpc_services.py +165 -0
- holado_grpc/tests/behave/steps/__init__.py +16 -0
- holado_grpc/tests/behave/steps/api/grpc_client_steps.py +173 -0
- holado_grpc/tests/behave/steps/private/__init__.py +16 -0
- holado_grpc/tests/behave/steps/private/api/grpc_steps.py +77 -0
- holado_helper/__init__.py +35 -0
- holado_helper/debug/README.txt +32 -0
- holado_helper/debug/memory/memory_profiler.py +106 -0
- holado_helper/docker/init_user.sh +24 -0
- holado_helper/docker/logging.conf +44 -0
- holado_helper/docker/run_holado_test_nonreg_in_docker.sh +120 -0
- holado_helper/docker/run_terminal_in_docker.sh +101 -0
- holado_helper/holado_module_template/__init__.py +38 -0
- holado_helper/holado_module_template/tests/behave/steps/__init__.py +16 -0
- holado_helper/holado_module_template/tests/behave/steps/private/__init__.py +16 -0
- holado_helper/initialize_holado.py +72 -0
- holado_helper/script/action.py +130 -0
- holado_helper/script/action_script.py +477 -0
- holado_helper/script/any_action_script.py +126 -0
- holado_helper/script/behave_action_script.py +99 -0
- holado_helper/script/csv_action_script.py +142 -0
- holado_helper/script/initialize_script.py +95 -0
- holado_helper/script/input_output_script.py +136 -0
- holado_helper/script/job.py +75 -0
- holado_helper/script/json_action_script.py +104 -0
- holado_helper/script/script.py +110 -0
- holado_json/__init__.py +16 -0
- holado_json/filesystem/json_file.py +94 -0
- holado_json/filesystem/stream_json_file.py +117 -0
- holado_json/ipc/json.py +146 -0
- holado_json/ipc/json_converter.py +69 -0
- holado_json/ipc/json_types.py +183 -0
- holado_json/tests/behave/steps/__init__.py +16 -0
- holado_json/tests/behave/steps/ipc/__init__.py +0 -0
- holado_json/tests/behave/steps/ipc/json_steps.py +131 -0
- holado_keycloak/__init__.py +16 -0
- holado_keycloak/tests/behave/steps/__init__.py +16 -0
- holado_keycloak/tests/behave/steps/tools/keycloak_client_steps.py +73 -0
- holado_keycloak/tools/keycloak/__init__.py +0 -0
- holado_keycloak/tools/keycloak/keycloak_client.py +90 -0
- holado_logging/__init__.py +38 -0
- holado_logging/common/logging/holado_logger.py +71 -0
- holado_logging/common/logging/log_config.py +163 -0
- holado_logging/common/logging/log_manager.py +335 -0
- holado_multitask/__init__.py +33 -0
- holado_multitask/multiprocessing/context/process_context.py +35 -0
- holado_multitask/multiprocessing/function_process.py +102 -0
- holado_multitask/multiprocessing/periodic_function_process.py +137 -0
- holado_multitask/multiprocessing/process.py +213 -0
- holado_multitask/multiprocessing/processesmanager.py +137 -0
- holado_multitask/multitasking/multitask_manager.py +464 -0
- holado_multitask/multithreading/__init__.py +0 -0
- holado_multitask/multithreading/context/thread_context.py +86 -0
- holado_multitask/multithreading/functionthreaded.py +129 -0
- holado_multitask/multithreading/loopfunctionthreaded.py +45 -0
- holado_multitask/multithreading/loopthread.py +110 -0
- holado_multitask/multithreading/periodicfunctionthreaded.py +135 -0
- holado_multitask/multithreading/reflection/inspect.py +47 -0
- holado_multitask/multithreading/reflection/sys.py +29 -0
- holado_multitask/multithreading/reflection/traceback.py +35 -0
- holado_multitask/multithreading/thread.py +203 -0
- holado_multitask/multithreading/threadsmanager.py +167 -0
- holado_multitask/multithreading/timer.py +51 -0
- holado_multitask/tests/behave/steps/__init__.py +17 -0
- holado_multitask/tests/behave/steps/multiprocessing_steps.py +138 -0
- holado_multitask/tests/behave/steps/multithreading_steps.py +129 -0
- holado_protobuf/__init__.py +61 -0
- holado_protobuf/ipc/protobuf/__init__.py +0 -0
- holado_protobuf/ipc/protobuf/abstracts/type.py +45 -0
- holado_protobuf/ipc/protobuf/protobuf_compiler.py +118 -0
- holado_protobuf/ipc/protobuf/protobuf_converter.py +153 -0
- holado_protobuf/ipc/protobuf/protobuf_messages.py +968 -0
- holado_protobuf/ipc/protobuf/protobuf_modifier.py +65 -0
- holado_protobuf/ipc/protobuf/types/__init__.py +0 -0
- holado_protobuf/ipc/protobuf/types/google/__init__.py +0 -0
- holado_protobuf/ipc/protobuf/types/google/protobuf.py +124 -0
- holado_protobuf/tests/behave/steps/__init__.py +16 -0
- holado_protobuf/tests/behave/steps/ipc/protobuf_steps.py +297 -0
- holado_python/__init__.py +36 -0
- holado_python/common/enums.py +34 -0
- holado_python/common/iterables.py +38 -0
- holado_python/common/tools/comparators/boolean_comparator.py +37 -0
- holado_python/common/tools/comparators/bytes_comparator.py +48 -0
- holado_python/common/tools/comparators/datetime_comparator.py +74 -0
- holado_python/common/tools/comparators/float_comparator.py +97 -0
- holado_python/common/tools/comparators/integer_comparator.py +37 -0
- holado_python/common/tools/comparators/string_comparator.py +99 -0
- holado_python/common/tools/comparators/type_comparator.py +31 -0
- holado_python/common/tools/datetime.py +341 -0
- holado_python/standard_library/csv.py +207 -0
- holado_python/standard_library/hashlib.py +110 -0
- holado_python/standard_library/multiprocessing.py +62 -0
- holado_python/standard_library/queue.py +79 -0
- holado_python/standard_library/socket/blocking_socket.py +219 -0
- holado_python/standard_library/socket/echo_server.py +29 -0
- holado_python/standard_library/socket/message_socket.py +152 -0
- holado_python/standard_library/socket/non_blocking_socket.py +172 -0
- holado_python/standard_library/socket/socket.py +411 -0
- holado_python/standard_library/ssl/resources/certificates/NOTES.txt +5 -0
- holado_python/standard_library/ssl/resources/certificates/localhost.crt +19 -0
- holado_python/standard_library/ssl/resources/certificates/localhost.key +28 -0
- holado_python/standard_library/ssl/ssl.py +131 -0
- holado_python/standard_library/typing.py +192 -0
- holado_python/tests/behave/steps/__init__.py +27 -0
- holado_python/tests/behave/steps/builtins/str_steps.py +45 -0
- holado_python/tests/behave/steps/convert_steps.py +59 -0
- holado_python/tests/behave/steps/iterable_steps.py +87 -0
- holado_python/tests/behave/steps/standard_library/csv_steps.py +134 -0
- holado_python/tests/behave/steps/standard_library/datetime_steps.py +163 -0
- holado_python/tests/behave/steps/standard_library/hashlib_steps.py +57 -0
- holado_python/tests/behave/steps/standard_library/multiprocessing_steps.py +56 -0
- holado_python/tests/behave/steps/standard_library/queue_steps.py +358 -0
- holado_python/tests/behave/steps/standard_library/socket_steps.py +384 -0
- holado_python/tests/behave/steps/standard_library/ssl_steps.py +71 -0
- holado_rabbitmq/__init__.py +28 -0
- holado_rabbitmq/tests/behave/steps/__init__.py +17 -0
- holado_rabbitmq/tests/behave/steps/tools/rabbitmq_client_steps.py +565 -0
- holado_rabbitmq/tests/behave/steps/tools/rabbitmq_server_steps.py +64 -0
- holado_rabbitmq/tools/rabbitmq/rabbitmq_blocking_client.py +333 -0
- holado_rabbitmq/tools/rabbitmq/rabbitmq_client.py +678 -0
- holado_rabbitmq/tools/rabbitmq/rabbitmq_manager.py +146 -0
- holado_rabbitmq/tools/rabbitmq/rabbitmq_select_client.py +428 -0
- holado_rabbitmq/tools/rabbitmq/rabbitmq_server.py +24 -0
- holado_redis/__init__.py +17 -0
- holado_redis/tests/behave/steps/__init__.py +16 -0
- holado_redis/tests/behave/steps/tools/redis_client_steps.py +101 -0
- holado_redis/tools/redis/TODO.txt +7 -0
- holado_redis/tools/redis/redis_client.py +190 -0
- holado_redis/tools/redis/redis_manager.py +38 -0
- holado_report/__init__.py +36 -0
- holado_report/campaign/campaign_manager.py +348 -0
- holado_report/report/analyze/execution_historic_manager.py +96 -0
- holado_report/report/analyze/scenario_duration_manager.py +245 -0
- holado_report/report/builders/detailed_scenario_report_builder.py +172 -0
- holado_report/report/builders/execution_historic_report_builder.py +132 -0
- holado_report/report/builders/failure_report_builder.py +150 -0
- holado_report/report/builders/report_builder.py +64 -0
- holado_report/report/builders/short_scenario_report_builder.py +94 -0
- holado_report/report/builders/summary_by_category_report_builder.py +103 -0
- holado_report/report/builders/summary_report_builder.py +110 -0
- holado_report/report/builders/summary_scenario_by_category_report_builder.py +109 -0
- holado_report/report/builders/summary_scenario_report_builder.py +81 -0
- holado_report/report/execution_historic.py +144 -0
- holado_report/report/report_manager.py +424 -0
- holado_report/report/reports/base_report.py +163 -0
- holado_report/report/reports/feature_report.py +106 -0
- holado_report/report/reports/scenario_report.py +64 -0
- holado_rest/__init__.py +32 -0
- holado_rest/api/rest/TODO.txt +2 -0
- holado_rest/api/rest/rest_client.py +200 -0
- holado_rest/api/rest/rest_manager.py +72 -0
- holado_rest/tests/behave/steps/__init__.py +16 -0
- holado_rest/tests/behave/steps/api/__init__.py +0 -0
- holado_rest/tests/behave/steps/api/rest_client_steps.py +181 -0
- holado_rest/tests/behave/steps/private/__init__.py +16 -0
- holado_rest/tests/behave/steps/private/api/__init__.py +0 -0
- holado_rest/tests/behave/steps/private/api/rest_steps.py +75 -0
- holado_s3/__init__.py +17 -0
- holado_s3/tests/behave/steps/__init__.py +17 -0
- holado_s3/tests/behave/steps/private/__init__.py +16 -0
- holado_s3/tests/behave/steps/private/tools/s3_steps.py +89 -0
- holado_s3/tests/behave/steps/tools/s3_client_steps.py +403 -0
- holado_s3/tests/behave/steps/tools/s3_server_steps.py +57 -0
- holado_s3/tools/s3/__init__.py +0 -0
- holado_s3/tools/s3/boto3_s3_client.py +59 -0
- holado_s3/tools/s3/minio_client.py +75 -0
- holado_s3/tools/s3/moto_server.py +52 -0
- holado_scripting/__init__.py +54 -0
- holado_scripting/common/tools/dynamic_text_manager.py +73 -0
- holado_scripting/common/tools/evaluate_parameters.py +228 -0
- holado_scripting/common/tools/expression_evaluator.py +389 -0
- holado_scripting/common/tools/variable_manager.py +354 -0
- holado_scripting/tests/behave/steps/__init__.py +22 -0
- holado_scripting/tests/behave/steps/common/tools/variable_convert_steps.py +159 -0
- holado_scripting/tests/behave/steps/common/tools/variable_new_steps.py +130 -0
- holado_scripting/tests/behave/steps/common/tools/variable_steps.py +108 -0
- holado_scripting/tests/behave/steps/common/tools/variable_verify_steps.py +160 -0
- holado_scripting/tests/behave/steps/scenario/function_steps.py +77 -0
- holado_scripting/tests/behave/steps/scenario/if_steps.py +87 -0
- holado_scripting/tests/behave/steps/scenario/loop_steps.py +119 -0
- holado_scripting/text/base/base_function.py +25 -0
- holado_scripting/text/base/base_verify_function.py +25 -0
- holado_scripting/text/base/text_inspecter.py +204 -0
- holado_scripting/text/interpreter/exceptions/interpreter_exception.py +25 -0
- holado_scripting/text/interpreter/functions/function_apply_function.py +60 -0
- holado_scripting/text/interpreter/functions/function_cast.py +60 -0
- holado_scripting/text/interpreter/functions/function_convert.py +57 -0
- holado_scripting/text/interpreter/functions/function_dynamic_value.py +40 -0
- holado_scripting/text/interpreter/functions/function_escape_all_bytes.py +35 -0
- holado_scripting/text/interpreter/functions/function_exists_variable.py +39 -0
- holado_scripting/text/interpreter/functions/function_hex_to_bytes.py +49 -0
- holado_scripting/text/interpreter/functions/function_hex_to_int.py +53 -0
- holado_scripting/text/interpreter/functions/function_to_base_64.py +41 -0
- holado_scripting/text/interpreter/functions/function_to_bytes.py +50 -0
- holado_scripting/text/interpreter/functions/function_to_hex.py +42 -0
- holado_scripting/text/interpreter/functions/function_to_string.py +50 -0
- holado_scripting/text/interpreter/text_interpreter.py +219 -0
- holado_scripting/text/verifier/exceptions/verifier_exception.py +21 -0
- holado_scripting/text/verifier/functions/verify_function_extract_in.py +35 -0
- holado_scripting/text/verifier/functions/verify_function_match_pattern.py +63 -0
- holado_scripting/text/verifier/text_verifier.py +103 -0
- holado_sftp/__init__.py +16 -0
- holado_sftp/tests/behave/steps/__init__.py +17 -0
- holado_sftp/tests/behave/steps/private/__init__.py +16 -0
- holado_sftp/tests/behave/steps/private/tools/sftp_steps.py +78 -0
- holado_sftp/tests/behave/steps/tools/sftp_client_steps.py +94 -0
- holado_sftp/tests/behave/steps/tools/sftp_server_steps.py +82 -0
- holado_sftp/tools/sftp/__init__.py +0 -0
- holado_sftp/tools/sftp/sftp_client.py +103 -0
- holado_sftp/tools/sftp/sftp_server.py +39 -0
- holado_swagger/__init__.py +31 -0
- holado_swagger/swagger_hub/mockserver/mockserver_client.py +82 -0
- holado_swagger/swagger_hub/mockserver/mockserver_manager.py +33 -0
- holado_swagger/tests/behave/steps/__init__.py +16 -0
- holado_swagger/tests/behave/steps/swagger_hub/mockserver_steps.py +74 -0
- holado_system/system/command/command.py +247 -0
- holado_system/system/command/command_result.py +128 -0
- holado_system/system/command/curl_command.py +101 -0
- holado_system/system/command/exceptions.py +59 -0
- holado_system/system/filesystem/file.py +150 -0
- holado_system/system/global_system.py +187 -0
- holado_system/tests/behave/steps/__init__.py +18 -0
- holado_system/tests/behave/steps/system/commands_steps.py +92 -0
- holado_system/tests/behave/steps/system/file_steps.py +231 -0
- holado_system/tests/behave/steps/system/system_steps.py +84 -0
- holado_test/__init__.py +30 -0
- holado_test/behave/__init__.py +0 -0
- holado_test/behave/behave.py +400 -0
- holado_test/behave/behave_environment.py +169 -0
- holado_test/behave/behave_function.py +33 -0
- holado_test/behave/behave_manager.py +558 -0
- holado_test/behave/independant_runner.py +66 -0
- holado_test/behave/scenario/__init__.py +0 -0
- holado_test/behave/scenario/behave_step_tools.py +157 -0
- holado_test/common/context/feature_context.py +81 -0
- holado_test/common/context/scenario_context.py +169 -0
- holado_test/common/context/step_context.py +66 -0
- holado_test/common/exceptions/undefined_step_exception.py +21 -0
- holado_test/scenario/step_tools.py +547 -0
- holado_test/scenario/tester_tools.py +57 -0
- holado_test/test_config.py +26 -0
- holado_test/tests/behave/steps/__init__.py +18 -0
- holado_test/tests/behave/steps/scenario/exception_steps.py +87 -0
- holado_test/tests/behave/steps/scenario/scenario_steps.py +100 -0
- holado_test/tests/behave/steps/scenario/tester_steps.py +65 -0
- holado_test/tools/test_server/client/rest/test_server_client.py +150 -0
- holado_test/tools/test_server/server/Dockerfile +60 -0
- holado_test/tools/test_server/server/core/server_context.py +42 -0
- holado_test/tools/test_server/server/core/server_manager.py +41 -0
- holado_test/tools/test_server/server/requirements.txt +2 -0
- holado_test/tools/test_server/server/rest/README +2 -0
- holado_test/tools/test_server/server/rest/api/__init__.py +24 -0
- holado_test/tools/test_server/server/rest/api/campaign/__init__.py +32 -0
- holado_test/tools/test_server/server/rest/api/campaign/scenario.py +40 -0
- holado_test/tools/test_server/server/rest/initialize_holado.py +72 -0
- holado_test/tools/test_server/server/rest/logging.conf +51 -0
- holado_test/tools/test_server/server/rest/openapi.yaml +57 -0
- holado_test/tools/test_server/server/rest/run.py +41 -0
- holado_test/tools/test_server/server/run.sh +6 -0
- holado_test/tools/test_server/server/run_test_server_in_docker.sh +104 -0
- holado_tools/__init__.py +38 -0
- holado_tools/scripts/execute_persisted_post_processes/execute_persisted_post_processes.py +36 -0
- holado_tools/scripts/execute_persisted_post_processes/execute_persisted_post_processes.sh +6 -0
- holado_tools/scripts/execute_persisted_post_processes/initialize_holado.py +62 -0
- holado_tools/tests/behave/steps/__init__.py +16 -0
- holado_tools/tests/behave/steps/tools/host_controller/client_steps.py +97 -0
- holado_tools/tools/host_controller/client/rest/host_controller_client.py +275 -0
- holado_tools/tools/host_controller/server/Dockerfile +60 -0
- holado_tools/tools/host_controller/server/requirements.txt +2 -0
- holado_tools/tools/host_controller/server/rest/README +2 -0
- holado_tools/tools/host_controller/server/rest/api/__init__.py +24 -0
- holado_tools/tools/host_controller/server/rest/api/config.py +88 -0
- holado_tools/tools/host_controller/server/rest/api/docker/__init__.py +66 -0
- holado_tools/tools/host_controller/server/rest/api/docker/container.py +144 -0
- holado_tools/tools/host_controller/server/rest/api/docker/logs.py +66 -0
- holado_tools/tools/host_controller/server/rest/api/os.py +58 -0
- holado_tools/tools/host_controller/server/rest/initialize_holado.py +72 -0
- holado_tools/tools/host_controller/server/rest/openapi.yaml +561 -0
- holado_tools/tools/host_controller/server/rest/run.py +31 -0
- holado_tools/tools/host_controller/server/run_host_controller_in_docker.sh +107 -0
- holado_tools/tools/host_viewer/client/rest/host_viewer_client.py +190 -0
- holado_tools/tools/host_viewer/server/Dockerfile +60 -0
- holado_tools/tools/host_viewer/server/requirements.txt +2 -0
- holado_tools/tools/host_viewer/server/rest/README +2 -0
- holado_tools/tools/host_viewer/server/rest/api/__init__.py +24 -0
- holado_tools/tools/host_viewer/server/rest/api/docker/__init__.py +65 -0
- holado_tools/tools/host_viewer/server/rest/api/docker/container.py +87 -0
- holado_tools/tools/host_viewer/server/rest/api/os.py +58 -0
- holado_tools/tools/host_viewer/server/rest/initialize_holado.py +72 -0
- holado_tools/tools/host_viewer/server/rest/openapi.yaml +301 -0
- holado_tools/tools/host_viewer/server/rest/run.py +31 -0
- holado_tools/tools/host_viewer/server/run_host_viewer_in_docker.sh +107 -0
- holado_value/__init__.py +24 -0
- holado_value/common/tables/comparators/table_2_value_table_cell_comparator.py +196 -0
- holado_value/common/tables/comparators/table_2_value_table_comparator.py +27 -0
- holado_value/common/tables/comparators/table_2_value_table_row_comparator.py +27 -0
- holado_value/common/tables/comparators/table_2_value_table_with_header_comparator.py +27 -0
- holado_value/common/tables/converters/value_table_converter.py +267 -0
- holado_value/common/tables/value_table.py +29 -0
- holado_value/common/tables/value_table_cell.py +76 -0
- holado_value/common/tables/value_table_manager.py +48 -0
- holado_value/common/tables/value_table_row.py +43 -0
- holado_value/common/tables/value_table_with_header.py +28 -0
- holado_value/common/tools/unique_value_manager.py +109 -0
- holado_value/common/tools/value.py +191 -0
- holado_value/common/tools/value_types.py +41 -0
- holado_value/tests/behave/steps/__init__.py +16 -0
- holado_value/tests/behave/steps/private/__init__.py +16 -0
- holado_ws/__init__.py +16 -0
- holado_ws/api/ws/TODO.txt +2 -0
- holado_ws/tests/behave/steps/__init__.py +16 -0
- holado_ws/tests/behave/steps/api/web_service_steps.py +189 -0
- holado_xml/__init__.py +38 -0
- holado_xml/tests/behave/steps/__init__.py +16 -0
- holado_xml/tests/behave/steps/private/__init__.py +16 -0
- holado_xml/xml/stream_xml_file.py +181 -0
- holado_xml/xml/xml_file.py +97 -0
- holado_xml/xml/xml_manager.py +35 -0
- holado_yaml/__init__.py +31 -0
- holado_yaml/tests/behave/steps/__init__.py +16 -0
- holado_yaml/tests/behave/steps/yaml_steps.py +161 -0
- holado_yaml/yaml/enums.py +28 -0
- holado_yaml/yaml/pyyaml/pyyaml_client.py +72 -0
- holado_yaml/yaml/ruamel/ruamel_yaml_client.py +80 -0
- holado_yaml/yaml/yaml_client.py +203 -0
- holado_yaml/yaml/yaml_manager.py +94 -0
- test_holado/Dockerfile_test_holado +82 -0
- test_holado/__init__.py +4 -0
- test_holado/__main__.py +25 -0
- test_holado/build_docker_image_to_test_holado_in_docker.sh +7 -0
- test_holado/environment.py +60 -0
- test_holado/features/Configuration/Actions/execute_persisted_post_processes.feature +13 -0
- test_holado/features/NonReg/api/REST.feature +26 -0
- test_holado/features/NonReg/api/gRPC.feature +116 -0
- test_holado/features/NonReg/common/multiprocessing/simple.feature +60 -0
- test_holado/features/NonReg/common/system/commands.feature +43 -0
- test_holado/features/NonReg/common/system/system.feature +20 -0
- test_holado/features/NonReg/common/tables/table.feature +245 -0
- test_holado/features/NonReg/common/tables/value_table_conversion.feature +29 -0
- test_holado/features/NonReg/common/tools/DateTime.feature +88 -0
- test_holado/features/NonReg/common/tools/UniqueValueManager.feature +43 -0
- test_holado/features/NonReg/holado_ais/ais_message-bitarray_to_nmea.feature +135 -0
- test_holado/features/NonReg/holado_ais/ais_message-nmea_raw_to_dict.feature +93 -0
- test_holado/features/NonReg/holado_ais/message_types/type-10.feature +38 -0
- test_holado/features/NonReg/holado_ais/message_types/type-12.feature +37 -0
- test_holado/features/NonReg/holado_ais/message_types/type-14.feature +36 -0
- test_holado/features/NonReg/holado_ais/message_types/type-15.feature +36 -0
- test_holado/features/NonReg/holado_ais/message_types/type-16.feature +38 -0
- test_holado/features/NonReg/holado_ais/message_types/type-17.feature +46 -0
- test_holado/features/NonReg/holado_ais/message_types/type-18.feature +37 -0
- test_holado/features/NonReg/holado_ais/message_types/type-19.feature +38 -0
- test_holado/features/NonReg/holado_ais/message_types/type-1_2_3.feature +42 -0
- test_holado/features/NonReg/holado_ais/message_types/type-20.feature +38 -0
- test_holado/features/NonReg/holado_ais/message_types/type-21.feature +37 -0
- test_holado/features/NonReg/holado_ais/message_types/type-22.feature +84 -0
- test_holado/features/NonReg/holado_ais/message_types/type-23.feature +49 -0
- test_holado/features/NonReg/holado_ais/message_types/type-24.feature +72 -0
- test_holado/features/NonReg/holado_ais/message_types/type-25.feature +143 -0
- test_holado/features/NonReg/holado_ais/message_types/type-26.feature +144 -0
- test_holado/features/NonReg/holado_ais/message_types/type-27.feature +36 -0
- test_holado/features/NonReg/holado_ais/message_types/type-4_11.feature +39 -0
- test_holado/features/NonReg/holado_ais/message_types/type-5.feature +33 -0
- test_holado/features/NonReg/holado_ais/message_types/type-6.feature +37 -0
- test_holado/features/NonReg/holado_ais/message_types/type-7_13.feature +43 -0
- test_holado/features/NonReg/holado_ais/message_types/type-8.feature +37 -0
- test_holado/features/NonReg/holado_ais/message_types/type-9.feature +37 -0
- test_holado/features/NonReg/holado_binary/bit_series.error.feature +33 -0
- test_holado/features/NonReg/holado_binary/bit_series.feature +144 -0
- test_holado/features/NonReg/holado_protobuf/protobuf.feature +291 -0
- test_holado/features/NonReg/holado_python/convert.feature +20 -0
- test_holado/features/NonReg/holado_python/iterable.feature +61 -0
- test_holado/features/NonReg/holado_python/standard_library/socket/local_echo_server/socket_reset.feature +191 -0
- test_holado/features/NonReg/holado_python/standard_library/socket/local_echo_server/socket_with_tls_and_verify.feature +279 -0
- test_holado/features/NonReg/holado_python/standard_library/socket/local_echo_server/socket_with_tls_without_verify.feature +299 -0
- test_holado/features/NonReg/holado_python/standard_library/socket/local_echo_server/socket_without_tls.feature +163 -0
- test_holado/features/NonReg/holado_python/standard_library/socket/tcpbin.com/socket_with_mtls.feature +214 -0
- test_holado/features/NonReg/holado_python/standard_library/socket/tcpbin.com/socket_with_tls.feature +184 -0
- test_holado/features/NonReg/holado_python/standard_library/socket/tcpbin.com/socket_without_tls.feature +169 -0
- test_holado/features/NonReg/holado_scripting/common/tools/dynamic_text_manager.feature +18 -0
- test_holado/features/NonReg/holado_scripting/common/tools/expression_evaluator.feature +185 -0
- test_holado/features/NonReg/holado_scripting/common/tools/variable_manager.feature +71 -0
- test_holado/features/NonReg/holado_scripting/text/interpreter/interpreter.error.feature +21 -0
- test_holado/features/NonReg/holado_scripting/text/interpreter/interpreter.feature +120 -0
- test_holado/features/NonReg/holado_yaml/yaml.feature +514 -0
- test_holado/features/NonReg/ipc/json.feature +20 -0
- test_holado/features/NonReg/scenario/scenario.feature +183 -0
- test_holado/features/NonReg/test_steps/behave.feature +275 -0
- test_holado/features/NonReg/test_steps/common.feature +100 -0
- test_holado/features/NonReg/tools/RabbitMQ.feature +445 -0
- test_holado/features/NonReg/tools/RabbitMQ_steps.feature +276 -0
- test_holado/features/NonReg/tools/S3/boto3_client.feature +73 -0
- test_holado/features/NonReg/tools/S3/minio_client.feature +75 -0
- test_holado/features/NonReg/tools/db_sqlite3.feature +41 -0
- test_holado/features/NonReg/tools/sFTP.feature +25 -0
- test_holado/features/Test/logger.feature +28 -0
- test_holado/features/Test/test_host_controller.feature +13 -0
- test_holado/features/Test/test_parameter.feature +15 -0
- test_holado/features/__init__.py +0 -0
- test_holado/initialize_holado.py +62 -0
- test_holado/logging.conf +53 -0
- test_holado/resources/proto/definitions/protobuf/custom_types/field_types.proto +24 -0
- test_holado/resources/proto/definitions/protobuf/protobuf.dev/tutorial/addressbook.proto +56 -0
- test_holado/resources/proto/generated/protobuf/custom_types/field_types_pb2.py +34 -0
- test_holado/resources/proto/generated/protobuf/protobuf/dev/tutorial/addressbook_pb2.py +34 -0
- test_holado/resources/scripts/list_tags.sh +2 -0
- test_holado/resources/scripts/update_resources_proto_generated.py +70 -0
- test_holado/steps/__init__.py +0 -0
- test_holado/steps/private_steps.py +20 -0
- test_holado/steps/public_steps.py +23 -0
- test_holado/test_holado_session_context.py +43 -0
- test_holado/tools/connexion/api_rest/openapi.yaml +16 -0
- test_holado/tools/connexion/api_rest/run.py +19 -0
- test_holado/tools/django/README.txt +3 -0
- test_holado/tools/django/api_grpc/api_grpc/__init__.py +0 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/__init__.py +0 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/admin.py +3 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/apps.py +6 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/migrations/__init__.py +0 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/models.py +3 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/proto/__init__.py +0 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/proto/account.proto +27 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/proto/account_pb2.py +33 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/proto/account_pb2_grpc.py +199 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/serializers.py +12 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/services.py +11 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/tests.py +3 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/views.py +3 -0
- test_holado/tools/django/api_grpc/api_grpc/asgi.py +16 -0
- test_holado/tools/django/api_grpc/api_grpc/settings.py +126 -0
- test_holado/tools/django/api_grpc/api_grpc/urls.py +27 -0
- test_holado/tools/django/api_grpc/api_grpc/wsgi.py +16 -0
- test_holado/tools/django/api_grpc/db.sqlite3 +0 -0
- test_holado/tools/django/api_grpc/manage.py +29 -0
- test_holado/tools/django/api_grpc/manual_test_commands.txt +25 -0
- test_holado/tools/django/api_grpc/patch_djangogrpcframework.py +42 -0
- test_holado/tools/django/api_rest/api_rest/__init__.py +0 -0
- test_holado/tools/django/api_rest/api_rest/api1/__init__.py +0 -0
- test_holado/tools/django/api_rest/api_rest/api1/admin.py +3 -0
- test_holado/tools/django/api_rest/api_rest/api1/apps.py +6 -0
- test_holado/tools/django/api_rest/api_rest/api1/migrations/__init__.py +0 -0
- test_holado/tools/django/api_rest/api_rest/api1/models.py +3 -0
- test_holado/tools/django/api_rest/api_rest/api1/serializers.py +15 -0
- test_holado/tools/django/api_rest/api_rest/api1/tests.py +3 -0
- test_holado/tools/django/api_rest/api_rest/api1/views.py +24 -0
- test_holado/tools/django/api_rest/api_rest/asgi.py +16 -0
- test_holado/tools/django/api_rest/api_rest/settings.py +133 -0
- test_holado/tools/django/api_rest/api_rest/urls.py +32 -0
- test_holado/tools/django/api_rest/api_rest/wsgi.py +16 -0
- test_holado/tools/django/api_rest/db.sqlite3 +0 -0
- test_holado/tools/django/api_rest/manage.py +22 -0
|
@@ -0,0 +1,702 @@
|
|
|
1
|
+
|
|
2
|
+
#################################################
|
|
3
|
+
# HolAdo (Holistic Automation do)
|
|
4
|
+
#
|
|
5
|
+
# (C) Copyright 2021-2025 by Eric Klumpp
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of self software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
8
|
+
#
|
|
9
|
+
# The above copyright notice and self permission notice shall be included in all copies or substantial portions of the Software.
|
|
10
|
+
|
|
11
|
+
# The Software is provided “as is”, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the Software.
|
|
12
|
+
#################################################
|
|
13
|
+
|
|
14
|
+
import logging
|
|
15
|
+
import abc
|
|
16
|
+
import time
|
|
17
|
+
from holado_multitask.multithreading.functionthreaded import FunctionThreaded
|
|
18
|
+
from holado_core.common.tools.tools import Tools
|
|
19
|
+
from holado_core.common.exceptions.timeout_exception import TimeoutException
|
|
20
|
+
from holado_core.common.exceptions.technical_exception import TechnicalException
|
|
21
|
+
from holado_core.common.exceptions.functional_exception import FunctionalException
|
|
22
|
+
from holado_core.common.handlers.exceptions.redo_exceptions import RedoIgnoredException,\
|
|
23
|
+
RedoStopRetryException
|
|
24
|
+
from holado.holado_config import Config
|
|
25
|
+
from holado_python.standard_library.typing import Typing
|
|
26
|
+
|
|
27
|
+
logger = logging.getLogger(__name__)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class BaseRedo(object):
|
|
31
|
+
""" Base class managing redo of a process until timeout.
|
|
32
|
+
"""
|
|
33
|
+
__metaclass__ = abc.ABCMeta
|
|
34
|
+
|
|
35
|
+
"""
|
|
36
|
+
Default timeout.
|
|
37
|
+
"""
|
|
38
|
+
DEFAULT_TIMEOUT_S = 30
|
|
39
|
+
"""
|
|
40
|
+
Default timeout for each process.
|
|
41
|
+
"""
|
|
42
|
+
DEFAULT_PROCESS_TIMEOUT_S = None
|
|
43
|
+
"""
|
|
44
|
+
Default polling delay between each process.
|
|
45
|
+
"""
|
|
46
|
+
DEFAULT_POLLING_INTERVAL_S = 0.1
|
|
47
|
+
"""
|
|
48
|
+
Default number of allowed retries.
|
|
49
|
+
"""
|
|
50
|
+
DEFAULT_NB_RETRIES = 0
|
|
51
|
+
"""
|
|
52
|
+
Number of successive failures that must appear before throwing an error.
|
|
53
|
+
"""
|
|
54
|
+
DEFAULT_NB_SUCCESSIVE_FAILURES_BEFORE_ERROR = 1
|
|
55
|
+
"""
|
|
56
|
+
Default waiting interval after a failure and before a new retry.
|
|
57
|
+
"""
|
|
58
|
+
DEFAULT_WAITING_INTERVAL_AFTER_FAILURE_S = 0.1
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def __init__(self, name):
|
|
62
|
+
"""
|
|
63
|
+
@param name Name describing redo
|
|
64
|
+
"""
|
|
65
|
+
self.__name = name
|
|
66
|
+
|
|
67
|
+
self.__timeout = BaseRedo.DEFAULT_TIMEOUT_S
|
|
68
|
+
self.__process_timeout = BaseRedo.DEFAULT_PROCESS_TIMEOUT_S
|
|
69
|
+
self.__accepted_time = None
|
|
70
|
+
self.__interval = BaseRedo.DEFAULT_POLLING_INTERVAL_S
|
|
71
|
+
self.__interval_after_failure = BaseRedo.DEFAULT_WAITING_INTERVAL_AFTER_FAILURE_S
|
|
72
|
+
self.__nb_retries = BaseRedo.DEFAULT_NB_RETRIES
|
|
73
|
+
self.__nb_successive_failures_before_error = BaseRedo.DEFAULT_NB_SUCCESSIVE_FAILURES_BEFORE_ERROR
|
|
74
|
+
|
|
75
|
+
self.__ignored_exceptions = [RedoIgnoredException]
|
|
76
|
+
self.__stop_retry_exceptions = [RedoStopRetryException]
|
|
77
|
+
self.__do_process_in_thread = True
|
|
78
|
+
self.__do_raise_on_stop_retry = True
|
|
79
|
+
self.__do_raise_on_timeout = True # Specify if a TimeoutException must be raised on timeout
|
|
80
|
+
self.__do_raise_last_exception = True # Specify if last exception must be raised after timeout, whereas it is configured to not raise a timeout exception
|
|
81
|
+
|
|
82
|
+
self.__run_counter = 0
|
|
83
|
+
self.__interrupt_counter = 0
|
|
84
|
+
self.__failure_counter = 0
|
|
85
|
+
|
|
86
|
+
self.__current_process_result = None
|
|
87
|
+
self.__current_process_exception = None
|
|
88
|
+
self.__previous_process_exception_stack_trace = None
|
|
89
|
+
self.__previous_process_exception_counter = 0
|
|
90
|
+
|
|
91
|
+
self.__start_time = None
|
|
92
|
+
self.__end_time = None
|
|
93
|
+
|
|
94
|
+
@property
|
|
95
|
+
def name(self):
|
|
96
|
+
"""
|
|
97
|
+
@return redo name
|
|
98
|
+
"""
|
|
99
|
+
return self.__name
|
|
100
|
+
|
|
101
|
+
@property
|
|
102
|
+
def process_timeout(self):
|
|
103
|
+
"""
|
|
104
|
+
@return The process timeout in seconds
|
|
105
|
+
"""
|
|
106
|
+
if self.__process_timeout is not None:
|
|
107
|
+
return self.__process_timeout
|
|
108
|
+
else:
|
|
109
|
+
return self.timeout
|
|
110
|
+
|
|
111
|
+
@property
|
|
112
|
+
def timeout(self):
|
|
113
|
+
"""
|
|
114
|
+
@return The timeout in seconds
|
|
115
|
+
"""
|
|
116
|
+
return self.__timeout
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def accepted_time(self):
|
|
120
|
+
"""
|
|
121
|
+
@return The accepted spent time
|
|
122
|
+
"""
|
|
123
|
+
return self.__accepted_time
|
|
124
|
+
|
|
125
|
+
@property
|
|
126
|
+
def run_counter(self):
|
|
127
|
+
return self.__run_counter
|
|
128
|
+
|
|
129
|
+
@property
|
|
130
|
+
def start_time(self):
|
|
131
|
+
return self.__start_time
|
|
132
|
+
|
|
133
|
+
@property
|
|
134
|
+
def end_time(self):
|
|
135
|
+
return self.__end_time
|
|
136
|
+
|
|
137
|
+
@property
|
|
138
|
+
def spent_time(self):
|
|
139
|
+
if self.start_time is None:
|
|
140
|
+
return None
|
|
141
|
+
elif self.__end_time is None:
|
|
142
|
+
return Tools.timer_s() - self.start_time
|
|
143
|
+
else:
|
|
144
|
+
return self.__end_time - self.start_time
|
|
145
|
+
|
|
146
|
+
def _process(self):
|
|
147
|
+
"""
|
|
148
|
+
@return Result of a run
|
|
149
|
+
"""
|
|
150
|
+
raise NotImplementedError
|
|
151
|
+
|
|
152
|
+
def _process_interrupt(self, thread):
|
|
153
|
+
"""
|
|
154
|
+
Method launched after a run interruption
|
|
155
|
+
Note: for process implementation that launch uninterruptible code, self method can be used to stop the thread by calling thread.stop()
|
|
156
|
+
@param thread Thread running the process method
|
|
157
|
+
"""
|
|
158
|
+
# Nothing by default
|
|
159
|
+
pass
|
|
160
|
+
|
|
161
|
+
def _is_redo_needed(self, result):
|
|
162
|
+
"""
|
|
163
|
+
@param result Current run result.
|
|
164
|
+
@return True if a redo is needed according given result.
|
|
165
|
+
"""
|
|
166
|
+
raise NotImplementedError
|
|
167
|
+
|
|
168
|
+
def execute(self):
|
|
169
|
+
"""
|
|
170
|
+
@return Result of execution
|
|
171
|
+
"""
|
|
172
|
+
if self.__do_process_in_thread:
|
|
173
|
+
return self.__execute_with_thread()
|
|
174
|
+
else:
|
|
175
|
+
return self.__execute_without_thread()
|
|
176
|
+
|
|
177
|
+
def __execute_without_thread(self):
|
|
178
|
+
"""
|
|
179
|
+
@return Result of execution without executing process in a thread
|
|
180
|
+
"""
|
|
181
|
+
result = None
|
|
182
|
+
last_exception = None
|
|
183
|
+
stop_retry = False
|
|
184
|
+
self.__start_time = Tools.timer_s()
|
|
185
|
+
|
|
186
|
+
try:
|
|
187
|
+
while not stop_retry:
|
|
188
|
+
try:
|
|
189
|
+
self.__run_counter += 1
|
|
190
|
+
if logger.isEnabledFor(logging.TRACE): # @UndefinedVariable
|
|
191
|
+
logger.trace(f"[{self.name} - {self.__run_counter}] Processing run {self.__run_counter}")
|
|
192
|
+
|
|
193
|
+
self.__execute_process()
|
|
194
|
+
|
|
195
|
+
if logger.isEnabledFor(logging.TRACE): # @UndefinedVariable
|
|
196
|
+
logger.trace(f"[{self.name} - {self.__run_counter}] Post processing")
|
|
197
|
+
do_return, result = self.__post_process(interrupted=False)
|
|
198
|
+
if logger.isEnabledFor(logging.TRACE): # @UndefinedVariable
|
|
199
|
+
logger.trace(f"[{self.name} - {self.__run_counter}] do return: {do_return} ; result: [{result}] (type: {Typing.get_object_class_fullname(result)})")
|
|
200
|
+
except Exception as exc:
|
|
201
|
+
has_failure, stop_retry = self.__manage_process_exception(exc, last_exception)
|
|
202
|
+
last_exception = exc
|
|
203
|
+
else:
|
|
204
|
+
has_failure = False
|
|
205
|
+
self.__failure_counter = 0
|
|
206
|
+
if do_return: # Expected result has appeared
|
|
207
|
+
# Verify result doesn't appeared too late compared to accepted time
|
|
208
|
+
self.__raise_accepted_time_if_needed()
|
|
209
|
+
# Return obtained result
|
|
210
|
+
return result
|
|
211
|
+
|
|
212
|
+
if not stop_retry:
|
|
213
|
+
stop_retry = self.__manage_process_timeout(last_exception)
|
|
214
|
+
if stop_retry:
|
|
215
|
+
# Timeout is reached, but it is configured to not raise an exception ; return last polled result
|
|
216
|
+
return result
|
|
217
|
+
self.__wait_after_process(has_failure)
|
|
218
|
+
finally:
|
|
219
|
+
self.__end_time = Tools.timer_s()
|
|
220
|
+
if self.run_counter > 1 or self.__interrupt_counter > 0:
|
|
221
|
+
logger.info(f"redo [{self.name}] has made {self.run_counter} runs and {self.__interrupt_counter} interrupts (process timeout: {self.process_timeout} s)")
|
|
222
|
+
|
|
223
|
+
return result
|
|
224
|
+
|
|
225
|
+
def __execute_with_thread(self):
|
|
226
|
+
"""
|
|
227
|
+
@return Result of execution with process execution in a thread
|
|
228
|
+
"""
|
|
229
|
+
result = None
|
|
230
|
+
last_exception = None
|
|
231
|
+
stop_retry = False
|
|
232
|
+
self.__start_time = Tools.timer_s()
|
|
233
|
+
|
|
234
|
+
try:
|
|
235
|
+
while not stop_retry:
|
|
236
|
+
# Create new thread to process
|
|
237
|
+
thread = self.__get_execute_thread()
|
|
238
|
+
|
|
239
|
+
try:
|
|
240
|
+
self.__run_counter += 1
|
|
241
|
+
if logger.isEnabledFor(logging.TRACE): # @UndefinedVariable
|
|
242
|
+
logger.trace(f"[{self.name} - {self.__run_counter}] Processing run {self.__run_counter}")
|
|
243
|
+
|
|
244
|
+
thread.start()
|
|
245
|
+
self.__wait_process(thread)
|
|
246
|
+
interrupted = self.__interrupt_thread_if_still_alive(thread)
|
|
247
|
+
|
|
248
|
+
if logger.isEnabledFor(logging.TRACE): # @UndefinedVariable
|
|
249
|
+
logger.trace(f"[{self.name} - {self.__run_counter}] Post processing (interrupted: {interrupted})")
|
|
250
|
+
do_return, result = self.__post_process(interrupted)
|
|
251
|
+
if logger.isEnabledFor(logging.TRACE): # @UndefinedVariable
|
|
252
|
+
logger.trace(f"[{self.name} - {self.__run_counter}] do return: {do_return} ; result: [{result}] (type: {Typing.get_object_class_fullname(result)})")
|
|
253
|
+
except Exception as exc:
|
|
254
|
+
has_failure, stop_retry = self.__manage_process_exception(exc, last_exception)
|
|
255
|
+
last_exception = exc
|
|
256
|
+
else:
|
|
257
|
+
has_failure = False
|
|
258
|
+
self.__failure_counter = 0
|
|
259
|
+
if do_return: # Expected result has appeared
|
|
260
|
+
# Verify result doesn't appeared too late compared to accepted time
|
|
261
|
+
self.__raise_accepted_time_if_needed()
|
|
262
|
+
# Return obtained result
|
|
263
|
+
return result
|
|
264
|
+
|
|
265
|
+
if not stop_retry:
|
|
266
|
+
stop_retry = self.__manage_process_timeout(last_exception)
|
|
267
|
+
if stop_retry:
|
|
268
|
+
# Timeout is reached, but it is configured to not raise an exception ; return last polled result
|
|
269
|
+
return result
|
|
270
|
+
self.__wait_after_process(has_failure)
|
|
271
|
+
finally:
|
|
272
|
+
self.__end_time = Tools.timer_s()
|
|
273
|
+
if self.run_counter > 1 or self.__interrupt_counter > 0:
|
|
274
|
+
logger.info(f"redo [{self.name}] has made {self.run_counter} runs and {self.__interrupt_counter} interrupts (process timeout: {self.process_timeout} s)")
|
|
275
|
+
|
|
276
|
+
return result
|
|
277
|
+
|
|
278
|
+
def __execute_process(self):
|
|
279
|
+
self.__current_process_result = None
|
|
280
|
+
self.__current_process_exception = None
|
|
281
|
+
|
|
282
|
+
try:
|
|
283
|
+
# Execute before run
|
|
284
|
+
self._execute_before_process()
|
|
285
|
+
|
|
286
|
+
# Process
|
|
287
|
+
self.__current_process_result = self._process()
|
|
288
|
+
|
|
289
|
+
# Execute after run
|
|
290
|
+
self._execute_after_process(self.__current_process_result)
|
|
291
|
+
except Exception as exc:
|
|
292
|
+
self.__current_process_exception = exc
|
|
293
|
+
|
|
294
|
+
def __get_execute_thread(self):
|
|
295
|
+
return FunctionThreaded(self.__execute_process, [])
|
|
296
|
+
|
|
297
|
+
def __wait_process(self, thread, wait_interval_s = None):
|
|
298
|
+
if wait_interval_s is None:
|
|
299
|
+
refs = filter(lambda x: x is not None, (Config.redo_wait_process_max_interval_s, self.__interval/100, self.__interval_after_failure/100))
|
|
300
|
+
wait_interval_s = max(Config.redo_wait_process_min_interval_s, min(refs))
|
|
301
|
+
|
|
302
|
+
while True:
|
|
303
|
+
if not thread.is_alive():
|
|
304
|
+
break
|
|
305
|
+
|
|
306
|
+
# Stop wait on timeout
|
|
307
|
+
if Tools.timer_s() > self.start_time + self.timeout:
|
|
308
|
+
logger.warning(f"redo [{self.name}] - run {self.run_counter} - stop waiting process, timeout of {self.timeout} s is reached")
|
|
309
|
+
break
|
|
310
|
+
|
|
311
|
+
# Stop wait on process timeout
|
|
312
|
+
if self.spent_time > self.process_timeout:
|
|
313
|
+
logger.warning(f"redo [{self.name}] - run {self.run_counter} - stop waiting process, process timeout of {self.process_timeout} s is reached")
|
|
314
|
+
break
|
|
315
|
+
|
|
316
|
+
time.sleep(wait_interval_s)
|
|
317
|
+
|
|
318
|
+
def __interrupt_thread_if_still_alive(self, thread):
|
|
319
|
+
res = False
|
|
320
|
+
if thread.is_alive():
|
|
321
|
+
self.__interrupt_counter += 1
|
|
322
|
+
if thread.is_interruptable:
|
|
323
|
+
thread.interrupt()
|
|
324
|
+
|
|
325
|
+
# Manage specific interrupt
|
|
326
|
+
# Note: for process implementation that launch uninterruptible code, this method can be used to stop the thread by calling thread.stop()
|
|
327
|
+
self._process_interrupt(thread)
|
|
328
|
+
|
|
329
|
+
res = True
|
|
330
|
+
logger.warning(f"redo [{self.name}] interrupted after {self.spent_time} seconds ({self.run_counter} runs ; {self.__interrupt_counter} interrupts ; process timeout: {self.process_timeout} s)")
|
|
331
|
+
return res
|
|
332
|
+
|
|
333
|
+
def __post_process(self, interrupted):
|
|
334
|
+
if interrupted:
|
|
335
|
+
self.__current_process_exception = None
|
|
336
|
+
|
|
337
|
+
# Manage exception logs
|
|
338
|
+
self.__previous_process_exception_stack_trace = None
|
|
339
|
+
self.__previous_process_exception_counter = 0
|
|
340
|
+
elif self.__current_process_exception is None:
|
|
341
|
+
if not self._is_redo_needed(self.__current_process_result):
|
|
342
|
+
# logger.trace(" --- redo [{}] -> return: {}", name, (self.__current_process_result != None ? self.__current_process_result.toString() : "None")))
|
|
343
|
+
return True, self.__current_process_result
|
|
344
|
+
|
|
345
|
+
# Manage exception logs
|
|
346
|
+
self.__previous_process_exception_stack_trace = None
|
|
347
|
+
self.__previous_process_exception_counter = 0
|
|
348
|
+
else:
|
|
349
|
+
# Manage exception logs
|
|
350
|
+
current_process_exception_stack_trace = Tools.represent_exception(self.__current_process_exception)
|
|
351
|
+
if self.__previous_process_exception_stack_trace is not None and current_process_exception_stack_trace == self.__previous_process_exception_stack_trace:
|
|
352
|
+
self.__previous_process_exception_counter += 1
|
|
353
|
+
|
|
354
|
+
if self.__previous_process_exception_counter % 10 == 0:
|
|
355
|
+
logger.warning(f"redo [{self.name}] - run {self.run_counter} - got previous process exception 10 more times ({self.__previous_process_exception_counter} times in total): {self.__get_error_description(self.__current_process_exception)}")
|
|
356
|
+
else:
|
|
357
|
+
logger.warning(f"redo [{self.name}] - run {self.run_counter} - got process exception {self.__get_error_description(self.__current_process_exception)}:\n{Tools.indent_string(4, current_process_exception_stack_trace)}")
|
|
358
|
+
self.__previous_process_exception_stack_trace = current_process_exception_stack_trace
|
|
359
|
+
self.__previous_process_exception_counter = 1
|
|
360
|
+
|
|
361
|
+
raise self.__current_process_exception
|
|
362
|
+
|
|
363
|
+
# Don't stop retries, and return current result
|
|
364
|
+
return False, self.__current_process_result
|
|
365
|
+
|
|
366
|
+
def __manage_process_exception(self, exc, last_exception):
|
|
367
|
+
has_failure = False
|
|
368
|
+
stop_retry = False
|
|
369
|
+
|
|
370
|
+
# Begin by calling _execute_after_failure enabling to replace exception considered ignored or stopping retry
|
|
371
|
+
try:
|
|
372
|
+
self._execute_after_failure(exc)
|
|
373
|
+
except Exception as exc_2:
|
|
374
|
+
exc = exc_2
|
|
375
|
+
|
|
376
|
+
# Manage stop, ignored, failure
|
|
377
|
+
if self._is_stop_retry(exc):
|
|
378
|
+
stop_retry = True
|
|
379
|
+
self.__process_stop_retry(exc)
|
|
380
|
+
elif self._is_ignored(exc):
|
|
381
|
+
self.__process_ignored(exc)
|
|
382
|
+
else:
|
|
383
|
+
has_failure = True
|
|
384
|
+
self.__process_failure(exc, last_exception)
|
|
385
|
+
|
|
386
|
+
return has_failure, stop_retry
|
|
387
|
+
|
|
388
|
+
def __process_ignored(self, exc):
|
|
389
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
390
|
+
logger.debug(f"redo [{self.name}] - run {self.run_counter} - ignored process exception {self.__get_error_description(exc)}")
|
|
391
|
+
self._execute_after_ignored(exc)
|
|
392
|
+
|
|
393
|
+
def __process_stop_retry(self, exc):
|
|
394
|
+
logger.info(f"redo [{self.name}] - run {self.run_counter} - stop retries due to exception {self.__get_error_description(exc)}")
|
|
395
|
+
self._execute_after_stop_retry(exc)
|
|
396
|
+
if self.__do_raise_on_stop_retry:
|
|
397
|
+
raise exc
|
|
398
|
+
|
|
399
|
+
def __process_failure(self, exception, last_exception):
|
|
400
|
+
self.__failure_counter += 1
|
|
401
|
+
if self.__failure_counter >= self.__nb_successive_failures_before_error:
|
|
402
|
+
if self.__failure_counter > 1:
|
|
403
|
+
logger.info(f"redo [{self.name}] - run {self.run_counter} - maximum successive failure ({self.__nb_successive_failures_before_error}) is reached - following previous failure is skipped: {self.__get_error_description(last_exception) if last_exception else '[None]'}")
|
|
404
|
+
logger.info(f"redo [{self.name}] - run {self.run_counter} - maximum successive failure ({self.__nb_successive_failures_before_error}) is reached - following failure is considered as an error: {self.__get_error_description(exception)}")
|
|
405
|
+
|
|
406
|
+
# Raise exception
|
|
407
|
+
new_message = f"redo [{self.name}] - run {self.run_counter} - maximum successive failure ({self.__nb_successive_failures_before_error}) is reached"
|
|
408
|
+
Tools.raise_same_exception_type(exception, new_message)
|
|
409
|
+
else:
|
|
410
|
+
if self.__failure_counter > 1:
|
|
411
|
+
logger.info(f"redo [{self.name}] - run {self.run_counter} - {self.__failure_counter}'th successive failure - following previous failure is skipped: {self.__get_error_description(last_exception) if last_exception else '[None]'}")
|
|
412
|
+
|
|
413
|
+
def __raise_accepted_time_if_needed(self):
|
|
414
|
+
if self.accepted_time is not None and self.spent_time > self.accepted_time:
|
|
415
|
+
accepted_msg = self._get_accepted_time_message()
|
|
416
|
+
accepted_msg = f"{accepted_msg}\n -> " if accepted_msg is not None and len(accepted_msg) > 0 else ""
|
|
417
|
+
msg = f"{accepted_msg}Too long after {self.spent_time} s in redo [{self.name}] ({self.run_counter} runs ; {self.__interrupt_counter} interrupts ; timeout: {self.timeout} s ; process timeout: {self.process_timeout} s ; allowed retries: {self.__nb_retries})"
|
|
418
|
+
raise FunctionalException(msg)
|
|
419
|
+
|
|
420
|
+
def __manage_process_timeout(self, last_exception):
|
|
421
|
+
res = False
|
|
422
|
+
if self.spent_time > self.timeout or self.__nb_retries > 0 and self.run_counter >= self.__nb_retries:
|
|
423
|
+
if self.__do_raise_on_timeout:
|
|
424
|
+
timeout_msg = self._get_timeout_message()
|
|
425
|
+
timeout_msg = f"{timeout_msg}\n -> " if timeout_msg is not None and len(timeout_msg) > 0 else ""
|
|
426
|
+
msg = f"{timeout_msg}Timed out after {self.spent_time} s in redo [{self.name}] ({self.run_counter} runs ; {self.__interrupt_counter} interrupts ; timeout: {self.timeout} s ; process timeout: {self.process_timeout} s ; allowed retries: {self.__nb_retries})"
|
|
427
|
+
raise TimeoutException(msg) from last_exception
|
|
428
|
+
elif self.__do_raise_last_exception and last_exception is not None:
|
|
429
|
+
raise last_exception
|
|
430
|
+
else:
|
|
431
|
+
# Return a timeout has occured to stop retries
|
|
432
|
+
res = True
|
|
433
|
+
return res
|
|
434
|
+
|
|
435
|
+
def __wait_after_process(self, has_failure):
|
|
436
|
+
# Manage waits
|
|
437
|
+
if has_failure:
|
|
438
|
+
if self.__interval_after_failure > 0:
|
|
439
|
+
try:
|
|
440
|
+
time.sleep(self.__interval_after_failure)
|
|
441
|
+
except InterruptedError as e:
|
|
442
|
+
# Thread.currentThread().interrupt()
|
|
443
|
+
raise TechnicalException(self.__get_error_message(e)) from e
|
|
444
|
+
elif self.__interval > 0:
|
|
445
|
+
try:
|
|
446
|
+
time.sleep(self.__interval)
|
|
447
|
+
except InterruptedError as e:
|
|
448
|
+
# Thread.currentThread().interrupt()
|
|
449
|
+
raise TechnicalException(self.__get_error_message(e)) from e
|
|
450
|
+
|
|
451
|
+
def _get_waited_description(self):
|
|
452
|
+
return None
|
|
453
|
+
|
|
454
|
+
def _get_timeout_message(self):
|
|
455
|
+
waited_description = self._get_waited_description()
|
|
456
|
+
if waited_description is not None:
|
|
457
|
+
return f"Timeout ({self.timeout} s) when waiting {waited_description}"
|
|
458
|
+
else:
|
|
459
|
+
return None
|
|
460
|
+
|
|
461
|
+
def _get_accepted_time_message(self):
|
|
462
|
+
waited_description = self._get_waited_description()
|
|
463
|
+
if waited_description is not None:
|
|
464
|
+
return f"Too long ({self.spent_time} s) to wait {waited_description} (accepted time: {self.__accepted_time} s)"
|
|
465
|
+
else:
|
|
466
|
+
return None
|
|
467
|
+
|
|
468
|
+
def __get_error_description(self, exc):
|
|
469
|
+
return f"{Typing.get_object_class_name(exc)}('{self.__get_error_message(exc)}')"
|
|
470
|
+
|
|
471
|
+
def __get_error_message(self, exc):
|
|
472
|
+
if hasattr(exc, 'message'):
|
|
473
|
+
return exc.message
|
|
474
|
+
else:
|
|
475
|
+
return str(exc)
|
|
476
|
+
|
|
477
|
+
def _execute_before_process(self):
|
|
478
|
+
"""
|
|
479
|
+
Method launched before each run.
|
|
480
|
+
If an exception occurs in self method, the run will not be done.
|
|
481
|
+
"""
|
|
482
|
+
# Nothing is done by default
|
|
483
|
+
pass
|
|
484
|
+
|
|
485
|
+
def _execute_after_process(self, result):
|
|
486
|
+
"""
|
|
487
|
+
Method launched after each run.
|
|
488
|
+
If an exception occurs in self method, it is managed as a run failure exception.
|
|
489
|
+
"""
|
|
490
|
+
# Nothing is done by default
|
|
491
|
+
pass
|
|
492
|
+
|
|
493
|
+
def _execute_after_failure(self, exception):
|
|
494
|
+
"""
|
|
495
|
+
Method launched after a failure and before considering if an exception is ignored or stopping retry.
|
|
496
|
+
By implementing this method, it is possible to ignore/stop retry on an exception with a specific message,
|
|
497
|
+
by replacing it by a custom exception (or dedicated RedoIgnoredException and RedoStopRetryException).
|
|
498
|
+
"""
|
|
499
|
+
# Nothing is done by default
|
|
500
|
+
pass
|
|
501
|
+
|
|
502
|
+
def _execute_after_ignored(self, exception):
|
|
503
|
+
"""
|
|
504
|
+
Method launched after an exception is ignored and before a redo.
|
|
505
|
+
"""
|
|
506
|
+
# Nothing is done by default
|
|
507
|
+
pass
|
|
508
|
+
|
|
509
|
+
def _execute_after_stop_retry(self, exception):
|
|
510
|
+
"""
|
|
511
|
+
Method launched after an exception is stopping retry.
|
|
512
|
+
"""
|
|
513
|
+
# Nothing is done by default
|
|
514
|
+
pass
|
|
515
|
+
|
|
516
|
+
def with_unlimited_number_retries(self):
|
|
517
|
+
"""
|
|
518
|
+
Sets unlimited number of allowed retries.
|
|
519
|
+
@return A self reference.
|
|
520
|
+
"""
|
|
521
|
+
return self.with_allowed_number_retries(0)
|
|
522
|
+
|
|
523
|
+
def with_allowed_number_retries(self, nb_retries):
|
|
524
|
+
"""
|
|
525
|
+
Sets the number of allowed retries.
|
|
526
|
+
If not successful after self number of retries, a timeout exception is thrown.
|
|
527
|
+
If the number of retries is set to 0, it retries infinitely until timeout.
|
|
528
|
+
{@link #DEFAULT_NB_RETRIES}.
|
|
529
|
+
@param nb_retries Number of allowed retries.
|
|
530
|
+
@return A self reference.
|
|
531
|
+
"""
|
|
532
|
+
self.__nb_retries = nb_retries
|
|
533
|
+
return self
|
|
534
|
+
|
|
535
|
+
def with_accepted_time(self, accepted_time):
|
|
536
|
+
"""
|
|
537
|
+
Sets the max waiting time that is acceptable, otherwise it is considered as an error.
|
|
538
|
+
@param accepted_time Accepted time in seconds.
|
|
539
|
+
@return A self reference.
|
|
540
|
+
"""
|
|
541
|
+
self.__accepted_time = accepted_time
|
|
542
|
+
return self
|
|
543
|
+
|
|
544
|
+
def with_timeout(self, timeout):
|
|
545
|
+
"""
|
|
546
|
+
Sets how long to wait for the evaluated condition to be True. The default timeout is
|
|
547
|
+
{@link #DEFAULT_TIMEOUT_S}.
|
|
548
|
+
@param timeout Timeout in seconds.
|
|
549
|
+
@return A self reference.
|
|
550
|
+
"""
|
|
551
|
+
self.__timeout = timeout
|
|
552
|
+
return self
|
|
553
|
+
|
|
554
|
+
def update_timeout(self, timeout):
|
|
555
|
+
"""
|
|
556
|
+
Update how long to still wait from now for the evaluated condition to be True.
|
|
557
|
+
@param timeout Timeout in seconds.
|
|
558
|
+
@return A self reference.
|
|
559
|
+
"""
|
|
560
|
+
self.__timeout = self.spent_time + timeout
|
|
561
|
+
return self
|
|
562
|
+
|
|
563
|
+
def without_timeout(self):
|
|
564
|
+
"""
|
|
565
|
+
@return A self reference.
|
|
566
|
+
"""
|
|
567
|
+
self.__timeout = 24 * 3600
|
|
568
|
+
return self
|
|
569
|
+
|
|
570
|
+
def with_raise_on_timeout(self, do_raise=True):
|
|
571
|
+
"""
|
|
572
|
+
@param do_raise If raise the exception that has stopped retry
|
|
573
|
+
@return A self reference.
|
|
574
|
+
"""
|
|
575
|
+
self.__do_raise_on_timeout = do_raise
|
|
576
|
+
return self
|
|
577
|
+
|
|
578
|
+
def without_raise_on_timeout(self):
|
|
579
|
+
"""
|
|
580
|
+
@return A self reference.
|
|
581
|
+
"""
|
|
582
|
+
return self.with_raise_on_timeout(False)
|
|
583
|
+
|
|
584
|
+
def with_process_in_thread(self, do_process_in_thread=True):
|
|
585
|
+
"""
|
|
586
|
+
Set if 'process' must be executed in a thread.
|
|
587
|
+
@return A self reference.
|
|
588
|
+
"""
|
|
589
|
+
self.__do_process_in_thread = do_process_in_thread
|
|
590
|
+
return self
|
|
591
|
+
|
|
592
|
+
def without_process_in_thread(self):
|
|
593
|
+
"""
|
|
594
|
+
Set 'process' must be executed without thread.
|
|
595
|
+
@return A self reference.
|
|
596
|
+
"""
|
|
597
|
+
return self.with_process_in_thread(do_process_in_thread=False)
|
|
598
|
+
|
|
599
|
+
def with_process_timeout(self, timeout):
|
|
600
|
+
"""
|
|
601
|
+
Sets how much time is let to process method until it is interrupted and relaunched. The default timeout is
|
|
602
|
+
{@link #DEFAULT_PROCESS_TIMEOUT_S}.
|
|
603
|
+
@param timeout Timeout in seconds.
|
|
604
|
+
@return A self reference.
|
|
605
|
+
"""
|
|
606
|
+
self.__process_timeout = timeout
|
|
607
|
+
return self
|
|
608
|
+
|
|
609
|
+
def with_process_timeout_for_retry(self, nb_retry):
|
|
610
|
+
"""
|
|
611
|
+
Set appropriate process timeout in order to make at least given number of retries until global timeout.
|
|
612
|
+
@param nb_retry Number of retries to do at least.
|
|
613
|
+
@return A self reference.
|
|
614
|
+
"""
|
|
615
|
+
return self.with_process_timeout(self.timeout / nb_retry)
|
|
616
|
+
|
|
617
|
+
def polling_every(self, duration):
|
|
618
|
+
"""
|
|
619
|
+
Sets how often the condition should be evaluated.
|
|
620
|
+
|
|
621
|
+
In reality, the interval may be greater as the cost of actually evaluating a condition function
|
|
622
|
+
is not factored in. The default polling interval is {@link #DEFAULT_POLLING_INTERVAL_S}.
|
|
623
|
+
@param duration The duration between two polling.
|
|
624
|
+
@return A self reference.
|
|
625
|
+
"""
|
|
626
|
+
self.__interval = duration
|
|
627
|
+
return self
|
|
628
|
+
|
|
629
|
+
def with_nb_successive_failure_before_error(self, nb_successive_failures_before_error):
|
|
630
|
+
"""
|
|
631
|
+
Sets the number of successive failures that must occur before considering being in error.
|
|
632
|
+
{@link #DEFAULT_NB_SUCCESSIVE_FAILURES_BEFORE_ERROR}.
|
|
633
|
+
@param nb_successive_failures_before_error Number of successive failures.
|
|
634
|
+
@return A self reference.
|
|
635
|
+
"""
|
|
636
|
+
self.__nb_successive_failures_before_error = nb_successive_failures_before_error
|
|
637
|
+
return self
|
|
638
|
+
|
|
639
|
+
def with_waiting_after_failure(self, duration):
|
|
640
|
+
"""
|
|
641
|
+
Sets how much time must be waited after a failure before a new retry.
|
|
642
|
+
The default interval is {@link #DEFAULT_WAITING_INTERVAL_AFTER_FAILURE_S}.
|
|
643
|
+
@param duration Duration to wait in seconds.
|
|
644
|
+
@return A self reference.
|
|
645
|
+
"""
|
|
646
|
+
self.__interval_after_failure = duration
|
|
647
|
+
return self
|
|
648
|
+
|
|
649
|
+
def ignoring(self, *exception_types):
|
|
650
|
+
"""
|
|
651
|
+
Configures to ignore specific types of exceptions while waiting for a condition.
|
|
652
|
+
Any exceptions not whitelisted will be allowed to propagate, terminating the wait.
|
|
653
|
+
@param exception_types The types of exceptions to ignore.
|
|
654
|
+
@return A self reference.
|
|
655
|
+
"""
|
|
656
|
+
if exception_types:
|
|
657
|
+
self.__ignored_exceptions.extend(exception_types)
|
|
658
|
+
return self
|
|
659
|
+
|
|
660
|
+
def _is_ignored(self, exception):
|
|
661
|
+
for exception_type in self.__ignored_exceptions:
|
|
662
|
+
if isinstance(exception, exception_type):
|
|
663
|
+
return True
|
|
664
|
+
return False
|
|
665
|
+
|
|
666
|
+
def stop_retry_on(self, *exception_types):
|
|
667
|
+
"""
|
|
668
|
+
Configures to stop retries on specific types of exceptions while waiting for a condition.
|
|
669
|
+
@param exception_types The types of exceptions that would stop retries.
|
|
670
|
+
@return A self reference.
|
|
671
|
+
"""
|
|
672
|
+
if exception_types:
|
|
673
|
+
self.__stop_retry_exceptions.extend(exception_types)
|
|
674
|
+
return self
|
|
675
|
+
|
|
676
|
+
def _is_stop_retry(self, exception):
|
|
677
|
+
for exception_type in self.__stop_retry_exceptions:
|
|
678
|
+
if isinstance(exception, exception_type):
|
|
679
|
+
return True
|
|
680
|
+
return False
|
|
681
|
+
|
|
682
|
+
def with_raise_on_stop_retry(self, do_raise=True):
|
|
683
|
+
"""
|
|
684
|
+
@param do_raise If raise the exception that has stopped retry
|
|
685
|
+
@return A self reference.
|
|
686
|
+
"""
|
|
687
|
+
self.__do_raise_on_stop_retry = do_raise
|
|
688
|
+
return self
|
|
689
|
+
|
|
690
|
+
def without_raise_on_stop_retry(self):
|
|
691
|
+
"""
|
|
692
|
+
@return A self reference.
|
|
693
|
+
"""
|
|
694
|
+
return self.with_raise_on_stop_retry(False)
|
|
695
|
+
|
|
696
|
+
def _print_run_counter(self):
|
|
697
|
+
if Tools.do_log(logger, logging.TRACE): # @UndefinedVariable
|
|
698
|
+
logger.trace(f" --- redo ({self.name}) : run {self.run_counter}")
|
|
699
|
+
|
|
700
|
+
|
|
701
|
+
|
|
702
|
+
|