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,464 @@
|
|
|
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 this 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 this 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 threading
|
|
15
|
+
import logging
|
|
16
|
+
import os
|
|
17
|
+
from holado_core.common.exceptions.technical_exception import TechnicalException
|
|
18
|
+
from holado_multitask.multithreading.context.thread_context import ThreadContext
|
|
19
|
+
from holado_multitask.multiprocessing.context.process_context import ProcessContext
|
|
20
|
+
from holado_core.common.tools.tools import Tools
|
|
21
|
+
from holado_python.standard_library.typing import Typing
|
|
22
|
+
from holado.common.handlers.undefined import default_context
|
|
23
|
+
from holado.common.context.session_context import SessionContext
|
|
24
|
+
import psutil
|
|
25
|
+
import signal
|
|
26
|
+
|
|
27
|
+
logger = logging.getLogger(__name__)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class MultitaskManager(object):
|
|
31
|
+
"""
|
|
32
|
+
Manage resources used by threads/processes run by HolAdo.
|
|
33
|
+
It provides a ThreadContext/ProcessContext for each thread/process.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
SESSION_SCOPE_NAME = "Session"
|
|
37
|
+
SCENARIO_SCOPE_NAME = "Scenario"
|
|
38
|
+
|
|
39
|
+
@classmethod
|
|
40
|
+
def get_scope_name(cls, scope=default_context):
|
|
41
|
+
if scope is default_context:
|
|
42
|
+
if SessionContext.instance().has_scenario_context():
|
|
43
|
+
return MultitaskManager.SCENARIO_SCOPE_NAME
|
|
44
|
+
else:
|
|
45
|
+
return MultitaskManager.SESSION_SCOPE_NAME
|
|
46
|
+
elif scope is not None:
|
|
47
|
+
return scope
|
|
48
|
+
else:
|
|
49
|
+
return MultitaskManager.SESSION_SCOPE_NAME
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@classmethod
|
|
53
|
+
def get_process_id(cls, process=None):
|
|
54
|
+
if process is None:
|
|
55
|
+
return os.getpid()
|
|
56
|
+
else:
|
|
57
|
+
return process.pid
|
|
58
|
+
|
|
59
|
+
@classmethod
|
|
60
|
+
def get_parent_process_id(cls, pid=None):
|
|
61
|
+
if pid is None:
|
|
62
|
+
return os.getppid()
|
|
63
|
+
else:
|
|
64
|
+
process = psutil.Process(pid)
|
|
65
|
+
return process.ppid()
|
|
66
|
+
|
|
67
|
+
@classmethod
|
|
68
|
+
def get_children_process_ids(cls, pid=None, recursive=False):
|
|
69
|
+
if pid is None:
|
|
70
|
+
pid = os.getpid()
|
|
71
|
+
|
|
72
|
+
process = psutil.Process(pid)
|
|
73
|
+
children = process.children(recursive=recursive)
|
|
74
|
+
return [c.pid for c in children]
|
|
75
|
+
|
|
76
|
+
@classmethod
|
|
77
|
+
def kill_process(cls, pid, sig=signal.SIGTERM, do_kill_children=True, recursively=True):
|
|
78
|
+
try:
|
|
79
|
+
process = psutil.Process(pid)
|
|
80
|
+
except psutil.NoSuchProcess:
|
|
81
|
+
return
|
|
82
|
+
|
|
83
|
+
# Kill children
|
|
84
|
+
if do_kill_children:
|
|
85
|
+
children = process.children(recursive=recursively)
|
|
86
|
+
for proc in children:
|
|
87
|
+
try:
|
|
88
|
+
proc.send_signal(sig)
|
|
89
|
+
except signal.SIGTERM:
|
|
90
|
+
pass
|
|
91
|
+
|
|
92
|
+
# Kill process
|
|
93
|
+
try:
|
|
94
|
+
process.send_signal(sig)
|
|
95
|
+
except signal.SIGTERM:
|
|
96
|
+
pass
|
|
97
|
+
|
|
98
|
+
@classmethod
|
|
99
|
+
def has_thread_native_id(cls):
|
|
100
|
+
from holado_multitask.multithreading.threadsmanager import ThreadsManager
|
|
101
|
+
return ThreadsManager.has_native_id()
|
|
102
|
+
|
|
103
|
+
@classmethod
|
|
104
|
+
def get_thread_uid(cls, thread=None):
|
|
105
|
+
tid = cls.get_thread_id(thread=thread)
|
|
106
|
+
if cls.has_thread_native_id():
|
|
107
|
+
return tid
|
|
108
|
+
else:
|
|
109
|
+
return (cls.get_process_id(), tid)
|
|
110
|
+
|
|
111
|
+
@classmethod
|
|
112
|
+
def get_thread_id(cls, thread=None, native=None):
|
|
113
|
+
if thread is None:
|
|
114
|
+
thread = threading.current_thread()
|
|
115
|
+
if native is None:
|
|
116
|
+
native = cls.has_thread_native_id()
|
|
117
|
+
elif native and not cls.has_thread_native_id():
|
|
118
|
+
raise TechnicalException(f"System doesn't support thread native id")
|
|
119
|
+
|
|
120
|
+
if native:
|
|
121
|
+
return thread.native_id
|
|
122
|
+
else:
|
|
123
|
+
return thread.ident
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def __init__(self):
|
|
127
|
+
self.__process_lock = threading.Lock()
|
|
128
|
+
self.__process_context_by_uname = {}
|
|
129
|
+
self.__parent_thread_uid_by_process_uname = {}
|
|
130
|
+
self.__process_id_by_uname = {}
|
|
131
|
+
self.__process_uname_by_id = {}
|
|
132
|
+
self.__thread_uid_by_process_uname = {}
|
|
133
|
+
|
|
134
|
+
self.__thread_lock = threading.Lock()
|
|
135
|
+
self.__main_thread_uid = self.get_thread_uid()
|
|
136
|
+
self.__thread_context_by_uname = {}
|
|
137
|
+
self.__parent_thread_uid_by_thread_uname = {}
|
|
138
|
+
self.__thread_uid_by_uname = {}
|
|
139
|
+
self.__thread_uname_by_uid = {}
|
|
140
|
+
|
|
141
|
+
self.__related_thread_uid_by_uid = {}
|
|
142
|
+
|
|
143
|
+
self.__feature_context_by_thread_uid = {}
|
|
144
|
+
|
|
145
|
+
@property
|
|
146
|
+
def is_main_thread(self):
|
|
147
|
+
thread_uid = self.get_thread_uid()
|
|
148
|
+
return thread_uid == self.__main_thread_uid
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
def main_thread_uid(self):
|
|
152
|
+
return self.__main_thread_uid
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
### Manage processes
|
|
156
|
+
|
|
157
|
+
def prepare_process(self, name, update_parent=True):
|
|
158
|
+
"""
|
|
159
|
+
Create a process context and return a unique name based to given name
|
|
160
|
+
"""
|
|
161
|
+
with self.__process_lock:
|
|
162
|
+
res = name
|
|
163
|
+
name_index = 0
|
|
164
|
+
while res in self.__process_context_by_uname:
|
|
165
|
+
name_index += 1
|
|
166
|
+
res = f"{name}_{name_index}"
|
|
167
|
+
|
|
168
|
+
self.__process_context_by_uname[res] = ProcessContext(name, res)
|
|
169
|
+
|
|
170
|
+
if update_parent:
|
|
171
|
+
uid = self.get_thread_uid()
|
|
172
|
+
self.__parent_thread_uid_by_process_uname[res] = uid
|
|
173
|
+
|
|
174
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
175
|
+
logger.debug(f"New process context: name='{name}' ; unique name='{res}'{{}}".format(f" ; parent thread UID={uid}" if update_parent else ''))
|
|
176
|
+
return res
|
|
177
|
+
|
|
178
|
+
def set_process_id(self, name, pid):
|
|
179
|
+
# logger.print(f"+++++++++ __parent_thread_uid_by_thread_uname: {self.__parent_thread_uid_by_thread_uname}")
|
|
180
|
+
# logger.print(f"+++++++++ __feature_context_by_thread_uid: {self.__feature_context_by_thread_uid}")
|
|
181
|
+
# logger.print(f"+++++++++ __thread_context_by_uname: {self.__thread_context_by_uname}")
|
|
182
|
+
self.__process_id_by_uname[name] = pid
|
|
183
|
+
self.__process_uname_by_id[pid] = name
|
|
184
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
185
|
+
logger.debug(f"Set process PID: name='{name}' ; PID={pid}")
|
|
186
|
+
|
|
187
|
+
def set_process_thread_uid(self, name, thread_uid):
|
|
188
|
+
# Set main thread UID of process
|
|
189
|
+
self.__thread_uid_by_process_uname[name] = thread_uid
|
|
190
|
+
|
|
191
|
+
# Set parent thread of process as parent thread of process main thread
|
|
192
|
+
parent_thread_uid = self.__parent_thread_uid_by_process_uname[name]
|
|
193
|
+
tuname = self._get_thread_unique_name_or_uid(thread_uid)
|
|
194
|
+
self.__parent_thread_uid_by_thread_uname[tuname] = parent_thread_uid
|
|
195
|
+
# logger.print(f"+++++++++ __parent_thread_uid_by_thread_uname: {self.__parent_thread_uid_by_thread_uname}")
|
|
196
|
+
# logger.print(f"+++++++++ __feature_context_by_thread_uid: {self.__feature_context_by_thread_uid}")
|
|
197
|
+
# logger.print(f"+++++++++ __thread_context_by_uname: {self.__thread_context_by_uname}")
|
|
198
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
199
|
+
logger.debug(f"Set process thread UID: process name='{name}' ; thread name='{tuname}' ; thread UID={thread_uid} ; parent thread UID={parent_thread_uid}")
|
|
200
|
+
|
|
201
|
+
def _get_process_unique_name_or_pid(self, pid=None):
|
|
202
|
+
if pid is None:
|
|
203
|
+
pid = self.get_process_id()
|
|
204
|
+
if pid in self.__process_uname_by_id:
|
|
205
|
+
return self.__process_uname_by_id[pid]
|
|
206
|
+
else:
|
|
207
|
+
# logger.debug(f"Using process PID {pid} as unique name")
|
|
208
|
+
return pid
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
### Manage threads
|
|
212
|
+
|
|
213
|
+
def prepare_thread(self, name, update_parent=True):
|
|
214
|
+
"""
|
|
215
|
+
Create a thread context and return a unique name based to given name
|
|
216
|
+
"""
|
|
217
|
+
with self.__thread_lock:
|
|
218
|
+
res = name
|
|
219
|
+
name_index = 0
|
|
220
|
+
while res in self.__thread_context_by_uname:
|
|
221
|
+
name_index += 1
|
|
222
|
+
res = f"{name}_{name_index}"
|
|
223
|
+
|
|
224
|
+
self.__thread_context_by_uname[res] = ThreadContext(name, res)
|
|
225
|
+
|
|
226
|
+
this_uid = self.get_thread_uid()
|
|
227
|
+
# In some cases (ex: on missing thread context), thread uid is used as name, and it can't be its own parent
|
|
228
|
+
if update_parent and res != this_uid:
|
|
229
|
+
# logger.print(f"+++++ Set parent thread UID: {res} -> {this_uid}")
|
|
230
|
+
self.__parent_thread_uid_by_thread_uname[res] = this_uid
|
|
231
|
+
|
|
232
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
233
|
+
logger.debug(f"New thread context: name='{name}' ; unique name='{res}'{{}}".format(f" ; parent thread UID={this_uid}" if update_parent and res != this_uid else ''))
|
|
234
|
+
return res
|
|
235
|
+
|
|
236
|
+
def set_thread_uid(self, name, uid=None):
|
|
237
|
+
if uid is None:
|
|
238
|
+
uid = self.get_thread_uid()
|
|
239
|
+
# logger.print(f"+++++ Set thread UID: {name} -> {uid}")
|
|
240
|
+
self.__thread_uid_by_uname[name] = uid
|
|
241
|
+
self.__thread_uname_by_uid[uid] = name
|
|
242
|
+
self.__thread_context_by_uname[name].thread_uid = uid
|
|
243
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
244
|
+
logger.debug(f"Set thread UID: name='{name}' ; UID={uid}")
|
|
245
|
+
|
|
246
|
+
def _get_thread_unique_name_or_uid(self, uid=None):
|
|
247
|
+
if uid is None:
|
|
248
|
+
uid = self.get_thread_uid()
|
|
249
|
+
if uid in self.__thread_uname_by_uid:
|
|
250
|
+
return self.__thread_uname_by_uid[uid]
|
|
251
|
+
else:
|
|
252
|
+
# logger.debug(f"Using thread UID {uid} as unique name")
|
|
253
|
+
return uid
|
|
254
|
+
|
|
255
|
+
def relate_thread_to(self, from_uid, to_uid):
|
|
256
|
+
self.__related_thread_uid_by_uid[from_uid] = to_uid
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
### Manage process context
|
|
261
|
+
|
|
262
|
+
def get_process_context(self, pid=None):
|
|
263
|
+
if pid is None:
|
|
264
|
+
pid = self.get_process_id()
|
|
265
|
+
uname = self._get_process_unique_name_or_pid(pid=pid)
|
|
266
|
+
# logger.print(f"++++ get_process_context: uid={uid} ; uname={uname}", stack_info=True)
|
|
267
|
+
|
|
268
|
+
if uname not in self.__process_context_by_uname:
|
|
269
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
270
|
+
logger.debug("Creating missing process context for unique name {}".format(f"'{uname}'" if isinstance(uname, str) else f"{uname}"))
|
|
271
|
+
uname = self.prepare_process(uname, update_parent=False)
|
|
272
|
+
self.set_process_id(uname, pid)
|
|
273
|
+
|
|
274
|
+
return self.__process_context_by_uname[uname]
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
### Manage thread context
|
|
280
|
+
|
|
281
|
+
def get_thread_context(self, uid=None):
|
|
282
|
+
if uid is None:
|
|
283
|
+
uid = self.get_thread_uid()
|
|
284
|
+
uname = self._get_thread_unique_name_or_uid(uid=uid)
|
|
285
|
+
# logger.print(f"++++ get_thread_context: uid={uid} ; uname={uname}", stack_info=True)
|
|
286
|
+
|
|
287
|
+
if uname not in self.__thread_context_by_uname:
|
|
288
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
289
|
+
logger.debug("Creating missing thread context for unique name {}".format(f"'{uname}'" if isinstance(uname, str) else f"{uname}"))
|
|
290
|
+
uname = self.prepare_thread(uname, update_parent=False)
|
|
291
|
+
self.set_thread_uid(uname, uid)
|
|
292
|
+
|
|
293
|
+
res = self.__thread_context_by_uname[uname]
|
|
294
|
+
if logger.isEnabledFor(logging.TRACE): # @UndefinedVariable
|
|
295
|
+
logger.trace(f"Thread context for tread UID '{uid}' (uname: '{uname}'): {res}")
|
|
296
|
+
return res
|
|
297
|
+
|
|
298
|
+
def get_parent_thread_context(self, uid=None):
|
|
299
|
+
if uid is None:
|
|
300
|
+
uid = self.get_thread_uid()
|
|
301
|
+
uname = self._get_thread_unique_name_or_uid(uid=uid)
|
|
302
|
+
if uname in self.__parent_thread_uid_by_thread_uname:
|
|
303
|
+
parent_uid = self.__parent_thread_uid_by_thread_uname[uname]
|
|
304
|
+
# logger.print(f"++++ get_parent_thread_context: {uid} -> {parent_uid}", stack_info=True)
|
|
305
|
+
return self.get_thread_context(uid=parent_uid)
|
|
306
|
+
else:
|
|
307
|
+
return None
|
|
308
|
+
|
|
309
|
+
def __find_thread_context_having(self, has_func, uid=None, do_log=False, _internal=None):
|
|
310
|
+
if uid is None:
|
|
311
|
+
uid = self.get_thread_uid()
|
|
312
|
+
if _internal is None:
|
|
313
|
+
_internal = []
|
|
314
|
+
|
|
315
|
+
res = None
|
|
316
|
+
while True:
|
|
317
|
+
if uid in _internal:
|
|
318
|
+
break
|
|
319
|
+
else:
|
|
320
|
+
_internal.append(uid)
|
|
321
|
+
|
|
322
|
+
res = self.__find_thread_context_having__throw_thread_parents(has_func, uid=uid, do_log=do_log, _internal=_internal)
|
|
323
|
+
if res is None:
|
|
324
|
+
if uid in self.__related_thread_uid_by_uid:
|
|
325
|
+
# Try with related thread
|
|
326
|
+
old_uid = uid
|
|
327
|
+
uid = self.__related_thread_uid_by_uid[uid]
|
|
328
|
+
if do_log and Tools.do_log(logger, logging.TRACE): # @UndefinedVariable
|
|
329
|
+
logger.trace(f"[MultitaskManager.__find_thread_context_having] Not found in thread uid '{old_uid}', try in thread uid '{uid}'")
|
|
330
|
+
else:
|
|
331
|
+
if do_log and Tools.do_log(logger, logging.TRACE): # @UndefinedVariable
|
|
332
|
+
logger.trace(f"[MultitaskManager.__find_thread_context_having] Not found in thread uid '{uid}', stop search")
|
|
333
|
+
return None
|
|
334
|
+
else:
|
|
335
|
+
if do_log and Tools.do_log(logger, logging.TRACE): # @UndefinedVariable
|
|
336
|
+
logger.trace(f"[MultitaskManager.__find_thread_context_having] Found in thread uid '{uid}' => {res}")
|
|
337
|
+
break
|
|
338
|
+
|
|
339
|
+
return res
|
|
340
|
+
|
|
341
|
+
def __find_thread_context_having__throw_thread_parents(self, has_func, uid=None, do_log=False, _internal=None):
|
|
342
|
+
if uid is None:
|
|
343
|
+
uid = self.get_thread_uid()
|
|
344
|
+
|
|
345
|
+
# logger.print(f"+++++ Find thread context having feature context: uid={uid}")
|
|
346
|
+
while True:
|
|
347
|
+
uname = self._get_thread_unique_name_or_uid(uid=uid)
|
|
348
|
+
if uname in self.__thread_context_by_uname:
|
|
349
|
+
# logger.print(f"+++++ Find thread context having feature context: {uname} not in __thread_context_by_uname => None")
|
|
350
|
+
# return None
|
|
351
|
+
|
|
352
|
+
thread_context = self.__thread_context_by_uname[uname]
|
|
353
|
+
found = False
|
|
354
|
+
if isinstance(has_func, str):
|
|
355
|
+
if hasattr(thread_context, has_func):
|
|
356
|
+
found = getattr(thread_context, has_func)()
|
|
357
|
+
else:
|
|
358
|
+
found = has_func(thread_context)
|
|
359
|
+
if found:
|
|
360
|
+
# logger.print(f"+++++ Find thread context having feature context => found from uid={uid}")
|
|
361
|
+
if do_log and Tools.do_log(logger, logging.TRACE): # @UndefinedVariable
|
|
362
|
+
logger.trace(f"[MultitaskManager.__find_thread_context_having__throw_thread_parents] Found in thread uid '{uid}' (uname: '{uname}') => {thread_context}")
|
|
363
|
+
return thread_context
|
|
364
|
+
else:
|
|
365
|
+
if do_log and Tools.do_log(logger, logging.TRACE): # @UndefinedVariable
|
|
366
|
+
logger.trace(f"[MultitaskManager.__find_thread_context_having__throw_thread_parents] Thread uid '{uid}' (uname: '{uname}') has a context, but it doesn't verify {has_func}")
|
|
367
|
+
|
|
368
|
+
if uname in self.__parent_thread_uid_by_thread_uname:
|
|
369
|
+
# Retry with parent thread uid
|
|
370
|
+
uid = self.__parent_thread_uid_by_thread_uname[uname]
|
|
371
|
+
if do_log and Tools.do_log(logger, logging.TRACE): # @UndefinedVariable
|
|
372
|
+
logger.trace(f"[MultitaskManager.__find_thread_context_having__throw_thread_parents] Try in parent thread uid '{uid}'")
|
|
373
|
+
# logger.print(f"+++++ Find thread context having feature context: in parent uid={uid}")
|
|
374
|
+
return self.__find_thread_context_having(has_func, uid=uid, do_log=do_log, _internal=_internal)
|
|
375
|
+
else:
|
|
376
|
+
# logger.print(f"+++++ Find thread context having feature context: {uname} not in __parent_thread_uid_by_thread_uname => None")
|
|
377
|
+
if do_log and Tools.do_log(logger, logging.TRACE): # @UndefinedVariable
|
|
378
|
+
logger.trace(f"[MultitaskManager.__find_thread_context_having__throw_thread_parents] Not found in thread uid '{uid}' (uname: '{uname}'), and it has not parent thread")
|
|
379
|
+
return None
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
### Manage feature context
|
|
384
|
+
|
|
385
|
+
def __update_feature_context_for_thread_uid(self, uid):
|
|
386
|
+
if uid not in self.__feature_context_by_thread_uid:
|
|
387
|
+
thread_context = self.__find_thread_context_having(ThreadContext.has_feature_context, uid)
|
|
388
|
+
if thread_context is None:
|
|
389
|
+
feature_context = None
|
|
390
|
+
else:
|
|
391
|
+
feature_context = thread_context.get_feature_context()
|
|
392
|
+
# logger.print(f"+++++ Set feature context for thread UID {uid}: {feature_context}")
|
|
393
|
+
is_reference = (thread_context.thread_uid == uid)
|
|
394
|
+
self.__feature_context_by_thread_uid[uid] = (feature_context, is_reference)
|
|
395
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
396
|
+
# logger.debug(f"Updated feature context for thread: UID='{uid}' ; feature context={feature_context}")
|
|
397
|
+
logger.debug(f"Updated feature context for thread: UID='{uid}' ; feature context={feature_context} (registered list: {self.__feature_context_by_thread_uid})")
|
|
398
|
+
|
|
399
|
+
def __remove_feature_context_for_any_thread_uid(self, feature_context):
|
|
400
|
+
list_uid = list(self.__feature_context_by_thread_uid.keys())
|
|
401
|
+
for uid in list_uid:
|
|
402
|
+
if self.__feature_context_by_thread_uid[uid][0] is feature_context:
|
|
403
|
+
del self.__feature_context_by_thread_uid[uid]
|
|
404
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
405
|
+
logger.debug(f"Removed feature context ({id(feature_context)}) association with thread UID {uid}")
|
|
406
|
+
|
|
407
|
+
def has_feature_context(self, is_reference=True, do_log=False):
|
|
408
|
+
uid = self.get_thread_uid()
|
|
409
|
+
# self.__update_feature_context_for_thread_uid(uid)
|
|
410
|
+
# return self.__feature_context_by_thread_uid[uid] is not None
|
|
411
|
+
|
|
412
|
+
if uid in self.__feature_context_by_thread_uid:
|
|
413
|
+
res = self.__feature_context_by_thread_uid[uid][0] is not None
|
|
414
|
+
if res and is_reference is not None:
|
|
415
|
+
res &= (is_reference == self.__feature_context_by_thread_uid[uid][1])
|
|
416
|
+
if do_log and Tools.do_log(logger, logging.TRACE): # @UndefinedVariable
|
|
417
|
+
logger.trace(f"[MultitaskManager.has_feature_context] Thread uid '{uid}' is in __feature_context_by_thread_uid and is_reference == {is_reference} => {res}")
|
|
418
|
+
return res
|
|
419
|
+
|
|
420
|
+
thread_context = self.__find_thread_context_having(ThreadContext.has_feature_context, uid, do_log=do_log)
|
|
421
|
+
res = thread_context is not None
|
|
422
|
+
if res and is_reference is not None:
|
|
423
|
+
res &= (thread_context.thread_uid == uid)
|
|
424
|
+
|
|
425
|
+
return res
|
|
426
|
+
|
|
427
|
+
def get_feature_context(self):
|
|
428
|
+
uid = self.get_thread_uid()
|
|
429
|
+
self.__update_feature_context_for_thread_uid(uid)
|
|
430
|
+
res = self.__feature_context_by_thread_uid[uid][0]
|
|
431
|
+
if logger.isEnabledFor(logging.TRACE): # @UndefinedVariable
|
|
432
|
+
logger.trace(f"Feature context for tread UID '{uid}': {res}")
|
|
433
|
+
return res
|
|
434
|
+
|
|
435
|
+
def set_feature_context(self, feature_context, is_reference=True):
|
|
436
|
+
thread_context = self.get_thread_context()
|
|
437
|
+
thread_context.set_feature_context(feature_context)
|
|
438
|
+
|
|
439
|
+
self.__feature_context_by_thread_uid[thread_context.thread_uid] = (feature_context, is_reference)
|
|
440
|
+
|
|
441
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
442
|
+
tuname = thread_context.thread_unique_name
|
|
443
|
+
tuname_txt = f"'{tuname}'" if isinstance(tuname, str) else f"{tuname}"
|
|
444
|
+
tuid = thread_context.thread_uid
|
|
445
|
+
logger.debug(f"Set feature context: thread unique name={tuname_txt} ; thread uid={tuid} ; feature context={feature_context} ; is reference={is_reference}")
|
|
446
|
+
|
|
447
|
+
def delete_feature_context(self):
|
|
448
|
+
tuname = self._get_thread_unique_name_or_uid()
|
|
449
|
+
if tuname not in self.__thread_context_by_uname:
|
|
450
|
+
raise TechnicalException(f"No thread context for thread unique name '{tuname}' (type: {Typing.get_object_class_fullname(tuname)})")
|
|
451
|
+
|
|
452
|
+
# Remove any reference to feature context before delete it
|
|
453
|
+
feature_context = self.__thread_context_by_uname[tuname].get_feature_context()
|
|
454
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
455
|
+
tuname_txt = f"'{tuname}'" if isinstance(tuname, str) else f"{tuname}"
|
|
456
|
+
logger.debug(f"Deleting feature context: thread unique name={tuname_txt} ; feature context={feature_context}")
|
|
457
|
+
self.__remove_feature_context_for_any_thread_uid(feature_context)
|
|
458
|
+
|
|
459
|
+
# Delete feature context
|
|
460
|
+
self.__thread_context_by_uname[tuname].delete_feature_context()
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
|
|
File without changes
|
|
@@ -0,0 +1,86 @@
|
|
|
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 this 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 this 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
|
+
from builtins import super
|
|
15
|
+
from holado.common.context.context import Context
|
|
16
|
+
import logging
|
|
17
|
+
from holado_scripting.common.tools.variable_manager import VariableManager
|
|
18
|
+
from holado.common.context.session_context import SessionContext
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ThreadContext(Context):
|
|
24
|
+
def __init__(self, name, unique_name):
|
|
25
|
+
super().__init__(f"Thread[{name};{unique_name}]")
|
|
26
|
+
|
|
27
|
+
self.__thread_uid = None
|
|
28
|
+
self.__thread_name = name
|
|
29
|
+
self.__thread_unique_name = unique_name
|
|
30
|
+
|
|
31
|
+
def __str__(self):
|
|
32
|
+
return f"{{ThreadContext({id(self)}):{self.__thread_uid}:{self.__thread_name}:{self.__thread_unique_name}}}"
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def thread_name(self):
|
|
36
|
+
return self.__thread_name
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def thread_unique_name(self):
|
|
40
|
+
return self.__thread_unique_name
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def thread_uid(self):
|
|
44
|
+
return self.__thread_uid
|
|
45
|
+
|
|
46
|
+
@thread_uid.setter
|
|
47
|
+
def thread_uid(self, uid):
|
|
48
|
+
self.__thread_uid = uid
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def has_variable_manager(self):
|
|
52
|
+
return self.has_object("variable_manager")
|
|
53
|
+
|
|
54
|
+
def get_variable_manager(self) -> VariableManager:
|
|
55
|
+
if not self.has_variable_manager():
|
|
56
|
+
parent_thread_context = SessionContext.instance().multitask_manager.get_parent_thread_context(uid=self.thread_uid)
|
|
57
|
+
if parent_thread_context is not None:
|
|
58
|
+
var_man = parent_thread_context.get_variable_manager()
|
|
59
|
+
else:
|
|
60
|
+
var_man = SessionContext.instance().variable_manager
|
|
61
|
+
|
|
62
|
+
manager = VariableManager(var_man)
|
|
63
|
+
self.set_object("variable_manager", manager)
|
|
64
|
+
file_path = SessionContext.instance().report_manager.get_path("logs", f"variable_update-thread_{self.thread_uid}.log") if SessionContext.instance().with_session_path else None
|
|
65
|
+
manager.initialize(SessionContext.instance().dynamic_text_manager, SessionContext.instance().unique_value_manager,
|
|
66
|
+
variable_update_log_file_path=file_path)
|
|
67
|
+
return self.get_object("variable_manager")
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
### Manage feature context
|
|
71
|
+
|
|
72
|
+
def has_feature_context(self):
|
|
73
|
+
return self.has_object("feature_context")
|
|
74
|
+
|
|
75
|
+
def get_feature_context(self):
|
|
76
|
+
return self.get_object("feature_context")
|
|
77
|
+
|
|
78
|
+
def set_feature_context(self, feature_context):
|
|
79
|
+
return self.set_object("feature_context", feature_context)
|
|
80
|
+
|
|
81
|
+
def delete_feature_context(self):
|
|
82
|
+
self.get_feature_context().delete_object()
|
|
83
|
+
self.remove_object("feature_context")
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
@@ -0,0 +1,129 @@
|
|
|
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 this 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 this 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
|
+
from builtins import super
|
|
15
|
+
import logging
|
|
16
|
+
from holado_core.common.block.function import Function
|
|
17
|
+
from holado_core.common.exceptions.functional_exception import FunctionalException
|
|
18
|
+
import holado_multitask.multithreading.thread as ctt
|
|
19
|
+
from holado_core.common.tools.tools import Tools
|
|
20
|
+
from holado.common.handlers.undefined import default_context
|
|
21
|
+
|
|
22
|
+
logger = logging.getLogger(__name__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class FunctionThreaded(ctt.InterruptableThread):
|
|
26
|
+
'''
|
|
27
|
+
Execute in a thread given function with given arguments
|
|
28
|
+
'''
|
|
29
|
+
|
|
30
|
+
def __init__(self, target, args=None, kwargs=None, name=None, default_wait_timeout=None, register_thread=True, register_scope=default_context, delay_before_run_sec=None, delay_between_run_sec=None, do_log=True, do_log_level=logging.DEBUG):
|
|
31
|
+
super().__init__(name if name is not None else f"FunctionThreaded({repr(target)})", default_wait_timeout=default_wait_timeout, register_thread=register_thread, register_scope=register_scope, delay_before_run_sec=delay_before_run_sec, delay_between_run_sec=delay_between_run_sec)
|
|
32
|
+
|
|
33
|
+
if args is None:
|
|
34
|
+
args = []
|
|
35
|
+
if kwargs is None:
|
|
36
|
+
kwargs = {}
|
|
37
|
+
|
|
38
|
+
self._function = Function(target, *args, **kwargs)
|
|
39
|
+
self.__error = None
|
|
40
|
+
self.__result = None
|
|
41
|
+
|
|
42
|
+
# Manage interrupt
|
|
43
|
+
self.__interrupt_needs_function = True
|
|
44
|
+
self.__interrupt_function = None
|
|
45
|
+
|
|
46
|
+
self.__callback_function = None
|
|
47
|
+
self.__do_log = do_log
|
|
48
|
+
self.__do_log_level = do_log_level
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def error(self):
|
|
52
|
+
return self.__error
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def result(self):
|
|
56
|
+
return self.__result
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def interrupt_function(self):
|
|
60
|
+
return self.__interrupt_function
|
|
61
|
+
|
|
62
|
+
@interrupt_function.setter
|
|
63
|
+
def interrupt_function(self, func):
|
|
64
|
+
"""Set the Function to call on interrupt"""
|
|
65
|
+
self.__interrupt_function = func
|
|
66
|
+
|
|
67
|
+
@property
|
|
68
|
+
def interrupt_needs_function(self):
|
|
69
|
+
return self.__interrupt_needs_function
|
|
70
|
+
|
|
71
|
+
@interrupt_needs_function.setter
|
|
72
|
+
def interrupt_needs_function(self, need_func):
|
|
73
|
+
"""Set if interrupt_function is needed by interrupt"""
|
|
74
|
+
self.__interrupt_needs_function = need_func
|
|
75
|
+
|
|
76
|
+
@property
|
|
77
|
+
def callback_function(self):
|
|
78
|
+
return self.__callback_function
|
|
79
|
+
|
|
80
|
+
@callback_function.setter
|
|
81
|
+
def callback_function(self, func):
|
|
82
|
+
"""Set the callback function"""
|
|
83
|
+
self.__callback_function = func
|
|
84
|
+
|
|
85
|
+
def run(self):
|
|
86
|
+
self.wait_before_run(do_log_exception=self.__do_log)
|
|
87
|
+
|
|
88
|
+
if self.is_interrupted:
|
|
89
|
+
return
|
|
90
|
+
|
|
91
|
+
try:
|
|
92
|
+
# logging.debug("+++++++++ Launching function [{}({})]".format(repr(self._target), repr(self._args)))
|
|
93
|
+
self.__result = self._function.run()
|
|
94
|
+
except Exception as exc:
|
|
95
|
+
if self.__do_log:
|
|
96
|
+
logger.exception(f"[Thread '{self.name}'] Exception catched during threaded function [{self._function.represent()}]")
|
|
97
|
+
self.__error = exc
|
|
98
|
+
|
|
99
|
+
if self.is_interrupted:
|
|
100
|
+
return
|
|
101
|
+
|
|
102
|
+
try:
|
|
103
|
+
if self.__callback_function:
|
|
104
|
+
self.__callback_function.run(self.result, self.error)
|
|
105
|
+
except Exception as exc:
|
|
106
|
+
msg = "Exception catched while calling callback function:\n callback_function: {}\n result: [{}]\n error: [{}]".format(repr(self.__callback_function), Tools.truncate_text(repr(self.result)), repr(self.error))
|
|
107
|
+
if self.__do_log:
|
|
108
|
+
logger.exception(msg)
|
|
109
|
+
raise FunctionalException(msg) from exc
|
|
110
|
+
|
|
111
|
+
if self.__do_log and Tools.do_log(logger, self.__do_log_level):
|
|
112
|
+
# logger.info(f"[Thread '{self.name}'] Thread has finished")
|
|
113
|
+
logger.log(self.__do_log_level, f"[Thread '{self.name}'] Thread has finished (func: {self._function})")
|
|
114
|
+
|
|
115
|
+
def throw_if_error(self):
|
|
116
|
+
if self.error:
|
|
117
|
+
raise FunctionalException("Error during call of function [{}({})]".format(repr(self._target), repr(self._args))) from self.error
|
|
118
|
+
|
|
119
|
+
@property
|
|
120
|
+
def is_interruptable(self):
|
|
121
|
+
return not self.__interrupt_needs_function or self.__interrupt_function is not None
|
|
122
|
+
|
|
123
|
+
def interrupt(self):
|
|
124
|
+
if not self.is_interrupted and self.is_alive():
|
|
125
|
+
super().interrupt()
|
|
126
|
+
if self.interrupt_function is not None:
|
|
127
|
+
self.interrupt_function.run()
|
|
128
|
+
|
|
129
|
+
|