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,172 @@
|
|
|
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 logging
|
|
15
|
+
import socket
|
|
16
|
+
from holado_python.standard_library.socket.socket import SocketClient
|
|
17
|
+
import abc
|
|
18
|
+
from holado_multitask.multithreading.loopfunctionthreaded import LoopFunctionThreaded
|
|
19
|
+
import selectors
|
|
20
|
+
from holado.common.handlers.undefined import undefined_argument
|
|
21
|
+
import time
|
|
22
|
+
import ssl
|
|
23
|
+
from holado_core.common.tools.tools import Tools
|
|
24
|
+
|
|
25
|
+
logger = logging.getLogger(__name__)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
##########################################################################
|
|
29
|
+
## Clients
|
|
30
|
+
##########################################################################
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class NonBlockingSocketClient(SocketClient):
|
|
34
|
+
"""
|
|
35
|
+
Base class for blocking socket client.
|
|
36
|
+
"""
|
|
37
|
+
__metaclass__ = abc.ABCMeta
|
|
38
|
+
|
|
39
|
+
def __init__(self, *, name=None, create_ipv4_socket_kwargs=None, idle_sleep_delay=undefined_argument, do_run_with_recv=True, do_run_with_send=True):
|
|
40
|
+
self.__selector = selectors.DefaultSelector()
|
|
41
|
+
|
|
42
|
+
# Note: __selector must be defined before, since Socket.__init__ can execute create_ipv4_socket
|
|
43
|
+
super().__init__(name=name, create_ipv4_socket_kwargs=create_ipv4_socket_kwargs, idle_sleep_delay=idle_sleep_delay, do_run_with_recv=do_run_with_recv, do_run_with_send=do_run_with_send)
|
|
44
|
+
|
|
45
|
+
def _delete_object(self):
|
|
46
|
+
if self.internal_socket:
|
|
47
|
+
# Note: stop must be done before unregistering selector
|
|
48
|
+
self.stop()
|
|
49
|
+
self.__selector.unregister(self.internal_socket)
|
|
50
|
+
|
|
51
|
+
super()._delete_object()
|
|
52
|
+
|
|
53
|
+
def _register_socket(self, sock):
|
|
54
|
+
events = selectors.EVENT_READ | selectors.EVENT_WRITE
|
|
55
|
+
self.__selector.register(sock, events, data=self._data)
|
|
56
|
+
|
|
57
|
+
def start(self, *, read_bufsize=1024, read_kwargs=None, write_kwargs=None):
|
|
58
|
+
"""Start client event loop.
|
|
59
|
+
"""
|
|
60
|
+
kwargs = {'read_bufsize':read_bufsize, 'read_kwargs':read_kwargs, 'write_kwargs':write_kwargs}
|
|
61
|
+
# Note: delay_between_run_sec must be None since _idle_sleep_delay is used to make sleeps
|
|
62
|
+
thread = LoopFunctionThreaded(self._wait_and_process_events, kwargs=kwargs, register_thread=True, delay_before_run_sec=None, delay_between_run_sec=None)
|
|
63
|
+
self._start_thread(thread)
|
|
64
|
+
|
|
65
|
+
def _wait_and_process_events(self, *, read_bufsize=1024, read_kwargs=None, write_kwargs=None):
|
|
66
|
+
if logger.isEnabledFor(logging.TRACE): # @UndefinedVariable
|
|
67
|
+
logger.trace(f"[{self.name}] Wait and process events: begin")
|
|
68
|
+
has_activity = False
|
|
69
|
+
events = self.__selector.select(timeout=None)
|
|
70
|
+
for key, mask in events:
|
|
71
|
+
has_activity |= self._service_connection(key, mask, read_bufsize=read_bufsize, read_kwargs=read_kwargs, write_kwargs=write_kwargs)
|
|
72
|
+
|
|
73
|
+
# Wait before next loop if no data was exchanged
|
|
74
|
+
if not has_activity and self._idle_sleep_delay is not None:
|
|
75
|
+
if logger.isEnabledFor(logging.TRACE): # @UndefinedVariable
|
|
76
|
+
logger.trace(f"[{self.name}] Wait and process events: wait {self._idle_sleep_delay} s")
|
|
77
|
+
time.sleep(self._idle_sleep_delay)
|
|
78
|
+
|
|
79
|
+
if logger.isEnabledFor(logging.TRACE): # @UndefinedVariable
|
|
80
|
+
logger.trace(f"[{self.name}] Wait and process events: end")
|
|
81
|
+
|
|
82
|
+
def _service_connection(self, key, mask, *, read_bufsize=1024, read_kwargs=None, write_kwargs=None):
|
|
83
|
+
if logger.isEnabledFor(logging.TRACE): # @UndefinedVariable
|
|
84
|
+
logger.trace(f"[{self.name}] Process service connection ({key}, {mask}): begin")
|
|
85
|
+
has_activity = False
|
|
86
|
+
read_kwargs = read_kwargs if read_kwargs is not None else {}
|
|
87
|
+
write_kwargs = write_kwargs if write_kwargs is not None else {}
|
|
88
|
+
|
|
89
|
+
if logger.isEnabledFor(logging.TRACE): # @UndefinedVariable
|
|
90
|
+
logger.trace(f"[{self.name}] Process service connection ({key}, {mask}): receive data")
|
|
91
|
+
sock = key.fileobj
|
|
92
|
+
data = key.data
|
|
93
|
+
if self.is_run_with_recv and mask & selectors.EVENT_READ:
|
|
94
|
+
if self.is_with_ssl:
|
|
95
|
+
# ssl doesn't suppôrt flags != 0
|
|
96
|
+
flags = 0
|
|
97
|
+
else:
|
|
98
|
+
flags = read_kwargs.get('flags', 0)
|
|
99
|
+
try:
|
|
100
|
+
recv_data = sock.recv(read_bufsize, flags)
|
|
101
|
+
except ssl.SSLWantReadError as exc:
|
|
102
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
103
|
+
logger.debug(f"[{self.name}] socket recv error: {exc}")
|
|
104
|
+
recv_data = None
|
|
105
|
+
has_activity = True # Socket is not idle
|
|
106
|
+
if recv_data:
|
|
107
|
+
has_activity = True
|
|
108
|
+
with self._data_lock: # data is self._data
|
|
109
|
+
data.in_bytes += recv_data
|
|
110
|
+
if logger.isEnabledFor(logging.DEBUG):
|
|
111
|
+
logger.debug(f"[{self.name}] Received [{recv_data}] (type: {type(recv_data)} ; total: {len(data.in_bytes)})")
|
|
112
|
+
|
|
113
|
+
if logger.isEnabledFor(logging.TRACE): # @UndefinedVariable
|
|
114
|
+
logger.trace(f"[{self.name}] Process service connection ({key}, {mask}): send data")
|
|
115
|
+
if self.is_run_with_send and mask & selectors.EVENT_WRITE:
|
|
116
|
+
with self._data_lock: # data is self._data
|
|
117
|
+
if data.out_bytes:
|
|
118
|
+
has_activity = True
|
|
119
|
+
try:
|
|
120
|
+
sent = sock.send(data.out_bytes)
|
|
121
|
+
except ssl.SSLWantWriteError as exc:
|
|
122
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
123
|
+
logger.debug(f"[{self.name}] socket send error: {exc}")
|
|
124
|
+
sent = 0
|
|
125
|
+
has_activity = True # Socket is not idle
|
|
126
|
+
if sent > 0:
|
|
127
|
+
data.out_bytes = data.out_bytes[sent:]
|
|
128
|
+
if logger.isEnabledFor(logging.DEBUG):
|
|
129
|
+
logger.debug(f"[{self.name}] Sent {sent} data (remaining to send: {len(data.out_bytes)})")
|
|
130
|
+
|
|
131
|
+
if logger.isEnabledFor(logging.TRACE): # @UndefinedVariable
|
|
132
|
+
logger.trace(f"[{self.name}] Process service connection ({key}, {mask}): end => had activity: {has_activity}")
|
|
133
|
+
return has_activity
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class TCPNonBlockingSocketClient(NonBlockingSocketClient):
|
|
137
|
+
"""
|
|
138
|
+
TCP socket client.
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
def __init__(self, *, name=None, create_ipv4_socket_kwargs=None, idle_sleep_delay=undefined_argument, do_run_with_recv=True, do_run_with_send=True):
|
|
142
|
+
super().__init__(name=name, create_ipv4_socket_kwargs=create_ipv4_socket_kwargs, idle_sleep_delay=idle_sleep_delay, do_run_with_recv=do_run_with_recv, do_run_with_send=do_run_with_send)
|
|
143
|
+
|
|
144
|
+
def create_ipv4_socket(self, host, port, **kwargs):
|
|
145
|
+
socket_kwargs = self._new_ssl_context_if_required(**kwargs)
|
|
146
|
+
|
|
147
|
+
if self.is_with_ssl:
|
|
148
|
+
# sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
149
|
+
# sock = Socket.create_connection((host, port), do_connect=False, **socket_kwargs)
|
|
150
|
+
sock = socket.create_connection((host, port), **socket_kwargs)
|
|
151
|
+
sock.setblocking(False)
|
|
152
|
+
|
|
153
|
+
wrap_socket_kwargs = self._ssl_wrap_socket_kwargs
|
|
154
|
+
do_handshake_on_connect = wrap_socket_kwargs.pop('do_handshake_on_connect', False)
|
|
155
|
+
sock = self._ssl_context.wrap_socket(sock, server_hostname=host, do_handshake_on_connect=do_handshake_on_connect, **wrap_socket_kwargs)
|
|
156
|
+
self._set_internal_socket(sock, is_ssl_handshake_done_on_connect=do_handshake_on_connect)
|
|
157
|
+
|
|
158
|
+
# sock.connect((host, port))
|
|
159
|
+
else:
|
|
160
|
+
sock = socket.create_connection((host, port), **socket_kwargs)
|
|
161
|
+
sock.setblocking(False)
|
|
162
|
+
self._set_internal_socket(sock)
|
|
163
|
+
|
|
164
|
+
# Register socket
|
|
165
|
+
self._register_socket(sock)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
|
|
@@ -0,0 +1,411 @@
|
|
|
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 logging
|
|
15
|
+
import socket
|
|
16
|
+
from _socket import SHUT_RDWR, SOCK_STREAM, error
|
|
17
|
+
from holado.common.handlers.object import DeleteableObject
|
|
18
|
+
import abc
|
|
19
|
+
from holado_core.common.exceptions.functional_exception import FunctionalException
|
|
20
|
+
from holado_core.common.tools.tools import Tools
|
|
21
|
+
from holado_python.standard_library.ssl.ssl import SslManager
|
|
22
|
+
import threading
|
|
23
|
+
import types
|
|
24
|
+
from abc import abstractmethod
|
|
25
|
+
from holado.common.handlers.undefined import undefined_argument, default_value
|
|
26
|
+
import copy
|
|
27
|
+
from holado_python.standard_library.typing import Typing
|
|
28
|
+
import ssl
|
|
29
|
+
import select
|
|
30
|
+
from holado_core.common.exceptions.technical_exception import TechnicalException
|
|
31
|
+
from holado_core.common.handlers.wait import WaitFuncResultVerifying
|
|
32
|
+
|
|
33
|
+
logger = logging.getLogger(__name__)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class SocketConfig(object):
|
|
37
|
+
default_idle_sleep_delay = 0.01
|
|
38
|
+
default_read_bufsize = 1024
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class Socket(DeleteableObject):
|
|
42
|
+
"""
|
|
43
|
+
Base class for socket objects.
|
|
44
|
+
|
|
45
|
+
It is implemented internally with standard library socket.
|
|
46
|
+
"""
|
|
47
|
+
__metaclass__ = abc.ABCMeta
|
|
48
|
+
|
|
49
|
+
@classmethod
|
|
50
|
+
def create(cls, name, internal_socket):
|
|
51
|
+
res = cls.__new__(cls, name=name)
|
|
52
|
+
res.__init__(name=name)
|
|
53
|
+
res._set_internal_socket(internal_socket)
|
|
54
|
+
return res
|
|
55
|
+
|
|
56
|
+
@classmethod
|
|
57
|
+
def create_connection(cls, address, timeout=undefined_argument,
|
|
58
|
+
source_address=None, do_connect=True):
|
|
59
|
+
"""Connect to *address* and return the socket object.
|
|
60
|
+
|
|
61
|
+
Convenience function. Connect to *address* (a 2-tuple ``(host,
|
|
62
|
+
port)``) and return the socket object. Passing the optional
|
|
63
|
+
*timeout* parameter will set the timeout on the socket instance
|
|
64
|
+
before attempting to connect. If no *timeout* is supplied, the
|
|
65
|
+
global default timeout setting returned by :func:`getdefaulttimeout`
|
|
66
|
+
is used. If *source_address* is set it must be a tuple of (host, port)
|
|
67
|
+
for the socket to bind as a source address before making the connection.
|
|
68
|
+
A host of '' or port 0 tells the OS to use the default.
|
|
69
|
+
|
|
70
|
+
Note: Implementation is a copy of socket.create_connection, but allowing to not connect.
|
|
71
|
+
If do_connect==True, implementation is identical to socket.create_connection.
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
host, port = address
|
|
75
|
+
err = None
|
|
76
|
+
for res in socket.getaddrinfo(host, port, 0, SOCK_STREAM):
|
|
77
|
+
af, socktype, proto, canonname, sa = res # @UnusedVariable
|
|
78
|
+
sock = None
|
|
79
|
+
try:
|
|
80
|
+
sock = socket.socket(af, socktype, proto)
|
|
81
|
+
if timeout is not undefined_argument:
|
|
82
|
+
sock.settimeout(timeout)
|
|
83
|
+
if source_address:
|
|
84
|
+
sock.bind(source_address)
|
|
85
|
+
if do_connect:
|
|
86
|
+
sock.connect(sa)
|
|
87
|
+
# Break explicitly a reference cycle
|
|
88
|
+
err = None
|
|
89
|
+
return sock
|
|
90
|
+
|
|
91
|
+
except error as _:
|
|
92
|
+
err = _
|
|
93
|
+
if sock is not None:
|
|
94
|
+
sock.close()
|
|
95
|
+
|
|
96
|
+
if err is not None:
|
|
97
|
+
try:
|
|
98
|
+
raise err
|
|
99
|
+
finally:
|
|
100
|
+
# Break explicitly a reference cycle
|
|
101
|
+
err = None
|
|
102
|
+
else:
|
|
103
|
+
raise error("getaddrinfo returns an empty list")
|
|
104
|
+
|
|
105
|
+
def __init__(self, *, name=None, create_ipv4_socket_kwargs=None, idle_sleep_delay=undefined_argument):
|
|
106
|
+
"""Socket constructor
|
|
107
|
+
@param name: Socket name
|
|
108
|
+
@param create_ipv4_socket_kwargs: arguments to create an IPv4 socket
|
|
109
|
+
@param idle_sleep_delay: delay to sleep when socket is idle (used in some clients/servers to control CPU resource impact ; default: 0.01 s)
|
|
110
|
+
"""
|
|
111
|
+
if name is None and create_ipv4_socket_kwargs is not None:
|
|
112
|
+
if not set(create_ipv4_socket_kwargs.keys()).issuperset({'host', 'port'}):
|
|
113
|
+
raise FunctionalException(f"Parameters 'host' and 'port' must be defined")
|
|
114
|
+
name = f"{Typing.get_object_class_name(self)}({create_ipv4_socket_kwargs['host']}:{create_ipv4_socket_kwargs['port']})"
|
|
115
|
+
|
|
116
|
+
super().__init__(name)
|
|
117
|
+
self.__socket = None
|
|
118
|
+
self.__is_started = False
|
|
119
|
+
self.__start_thread = None
|
|
120
|
+
self.__stop_on_close = None
|
|
121
|
+
self.__idle_sleep_delay = idle_sleep_delay if idle_sleep_delay is not undefined_argument else SocketConfig.default_idle_sleep_delay
|
|
122
|
+
|
|
123
|
+
# SSL management
|
|
124
|
+
self.__ssl_kwargs_tuple = None
|
|
125
|
+
self.__ssl_context = None
|
|
126
|
+
self.__is_ssl_handshake_done = False
|
|
127
|
+
|
|
128
|
+
if create_ipv4_socket_kwargs is not None:
|
|
129
|
+
self.create_ipv4_socket(**create_ipv4_socket_kwargs)
|
|
130
|
+
|
|
131
|
+
def __enter__(self):
|
|
132
|
+
return self
|
|
133
|
+
|
|
134
|
+
def __exit__(self, *args):
|
|
135
|
+
self.close()
|
|
136
|
+
|
|
137
|
+
def _delete_object(self):
|
|
138
|
+
self.close()
|
|
139
|
+
|
|
140
|
+
@property
|
|
141
|
+
def internal_socket(self) -> socket.socket:
|
|
142
|
+
return self.__socket
|
|
143
|
+
|
|
144
|
+
@property
|
|
145
|
+
def is_started(self):
|
|
146
|
+
return self.__is_started
|
|
147
|
+
|
|
148
|
+
@property
|
|
149
|
+
def is_with_ssl(self):
|
|
150
|
+
return self.__ssl_context is not None
|
|
151
|
+
|
|
152
|
+
@property
|
|
153
|
+
def _ssl_kwargs(self):
|
|
154
|
+
return copy.copy(self.__ssl_kwargs_tuple[0]) if self.__ssl_kwargs_tuple and self.__ssl_kwargs_tuple[0] is not None else None
|
|
155
|
+
|
|
156
|
+
@property
|
|
157
|
+
def _ssl_context_kwargs(self):
|
|
158
|
+
return copy.copy(self.__ssl_kwargs_tuple[1]) if self.__ssl_kwargs_tuple and self.__ssl_kwargs_tuple[1] is not None else None
|
|
159
|
+
|
|
160
|
+
@property
|
|
161
|
+
def _ssl_wrap_socket_kwargs(self):
|
|
162
|
+
return copy.copy(self.__ssl_kwargs_tuple[2]) if self.__ssl_kwargs_tuple and self.__ssl_kwargs_tuple[2] is not None else None
|
|
163
|
+
|
|
164
|
+
@property
|
|
165
|
+
def _ssl_context(self):
|
|
166
|
+
return self.__ssl_context
|
|
167
|
+
|
|
168
|
+
@property
|
|
169
|
+
def _idle_sleep_delay(self):
|
|
170
|
+
return self.__idle_sleep_delay
|
|
171
|
+
|
|
172
|
+
def _set_internal_socket(self, socket, is_ssl_handshake_done_on_connect=True):
|
|
173
|
+
self.__socket = socket
|
|
174
|
+
self.__is_ssl_handshake_done = is_ssl_handshake_done_on_connect
|
|
175
|
+
|
|
176
|
+
@abc.abstractmethod
|
|
177
|
+
def create_ipv4_socket(self, host, port, **kwargs):
|
|
178
|
+
raise NotImplementedError()
|
|
179
|
+
|
|
180
|
+
def close(self):
|
|
181
|
+
# Stop socket if needed
|
|
182
|
+
if self.is_started and self.__stop_on_close:
|
|
183
|
+
self.stop()
|
|
184
|
+
|
|
185
|
+
# Close socket
|
|
186
|
+
if self.__socket is not None:
|
|
187
|
+
try:
|
|
188
|
+
self.__socket.shutdown(SHUT_RDWR)
|
|
189
|
+
except OSError as exc:
|
|
190
|
+
if 'Errno 9' in str(exc):
|
|
191
|
+
logger.info(f"Got following error on socket shutdown (known to appear when connection is not open correctly or already closed): {exc}")
|
|
192
|
+
elif 'Errno 107' in str(exc):
|
|
193
|
+
logger.info(f"Got following error on socket shutdown (known to appear sometimes during shutdown): {exc}")
|
|
194
|
+
else:
|
|
195
|
+
raise exc
|
|
196
|
+
finally:
|
|
197
|
+
self.__socket.close()
|
|
198
|
+
self.__socket = None
|
|
199
|
+
|
|
200
|
+
@abstractmethod
|
|
201
|
+
def start(self, *, read_bufsize=SocketConfig.default_read_bufsize, read_kwargs=None, write_kwargs=None):
|
|
202
|
+
raise NotImplementedError()
|
|
203
|
+
|
|
204
|
+
def _start_thread(self, thread, stop_on_close=True):
|
|
205
|
+
self.__start_thread = thread
|
|
206
|
+
self.__stop_on_close = stop_on_close
|
|
207
|
+
|
|
208
|
+
# Start thread
|
|
209
|
+
self.__start_thread.start()
|
|
210
|
+
self.__is_started = True
|
|
211
|
+
|
|
212
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
213
|
+
logger.debug(f"[{self.name}] Started")
|
|
214
|
+
|
|
215
|
+
def stop(self):
|
|
216
|
+
if self.__start_thread is not None:
|
|
217
|
+
if self.__start_thread.is_interruptable:
|
|
218
|
+
self.__start_thread.interrupt()
|
|
219
|
+
self.__start_thread.join()
|
|
220
|
+
self.__start_thread = None
|
|
221
|
+
self.__is_started = False
|
|
222
|
+
|
|
223
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
224
|
+
logger.debug(f"[{self.name}] Stopped")
|
|
225
|
+
|
|
226
|
+
def read(self, bufsize=SocketConfig.default_read_bufsize, **kwargs):
|
|
227
|
+
flags = kwargs.get('flags', 0)
|
|
228
|
+
res = self.internal_socket.recv(bufsize, flags)
|
|
229
|
+
if logger.isEnabledFor(logging.DEBUG):
|
|
230
|
+
logger.debug(f"[{self.name}] Received [{res}] (type: {type(res)})")
|
|
231
|
+
return res
|
|
232
|
+
|
|
233
|
+
def write(self, data_bytes, loop_until_all_is_sent=True, **kwargs):
|
|
234
|
+
if loop_until_all_is_sent:
|
|
235
|
+
# Note: no return is done, since sendall return None or raise an exception on error
|
|
236
|
+
self.internal_socket.sendall(data_bytes, **kwargs)
|
|
237
|
+
if logger.isEnabledFor(logging.DEBUG):
|
|
238
|
+
logger.debug(f"[{self.name}] Sent all [{data_bytes}] (type: {type(data_bytes)})")
|
|
239
|
+
else:
|
|
240
|
+
res = self.internal_socket.send(data_bytes, **kwargs)
|
|
241
|
+
if logger.isEnabledFor(logging.DEBUG):
|
|
242
|
+
logger.debug(f"[{self.name}] Sent {res}/{len(data_bytes)} bytes of [{data_bytes}] (type: {type(data_bytes)})")
|
|
243
|
+
return res
|
|
244
|
+
|
|
245
|
+
def _extract_ssl_kwargs(self, socket_kwargs):
|
|
246
|
+
"""Pop from socket kwargs: global ssl kwargs, SSLContext kwargs, and wrap_socket kwargs.
|
|
247
|
+
"""
|
|
248
|
+
ssl_kwargs, context_kwargs, wrap_socket_kwargs = None, {}, {}
|
|
249
|
+
if Tools.has_sub_kwargs(socket_kwargs, 'ssl.'):
|
|
250
|
+
ssl_kwargs = Tools.pop_sub_kwargs(socket_kwargs, 'ssl.')
|
|
251
|
+
if Tools.has_sub_kwargs(ssl_kwargs, 'context.'):
|
|
252
|
+
context_kwargs = Tools.pop_sub_kwargs(ssl_kwargs, 'context.')
|
|
253
|
+
if Tools.has_sub_kwargs(ssl_kwargs, 'wrap_socket.'):
|
|
254
|
+
wrap_socket_kwargs = Tools.pop_sub_kwargs(ssl_kwargs, 'wrap_socket.')
|
|
255
|
+
self.__ssl_kwargs_tuple = (ssl_kwargs, context_kwargs, wrap_socket_kwargs)
|
|
256
|
+
return socket_kwargs
|
|
257
|
+
|
|
258
|
+
def _new_ssl_context_if_required(self, server_side=False, **kwargs):
|
|
259
|
+
"""Return the remaining socket kwargs after ssl kwargs extraction.
|
|
260
|
+
"""
|
|
261
|
+
res = self._extract_ssl_kwargs(kwargs)
|
|
262
|
+
|
|
263
|
+
if self._ssl_kwargs is not None:
|
|
264
|
+
self.__ssl_context = SslManager.new_ssl_context(server_side=server_side, ssl_kwargs=self._ssl_kwargs, context_kwargs=self._ssl_context_kwargs)
|
|
265
|
+
|
|
266
|
+
return res
|
|
267
|
+
|
|
268
|
+
def do_ssl_handshake(self):
|
|
269
|
+
if self.is_with_ssl:
|
|
270
|
+
if self.internal_socket.getblocking():
|
|
271
|
+
self.internal_socket.do_handshake()
|
|
272
|
+
# self.internal_socket.do_handshake(block=True)
|
|
273
|
+
else:
|
|
274
|
+
while True:
|
|
275
|
+
try:
|
|
276
|
+
self.internal_socket.do_handshake()
|
|
277
|
+
break
|
|
278
|
+
except ssl.SSLWantReadError:
|
|
279
|
+
select.select([self.internal_socket], [], [])
|
|
280
|
+
except ssl.SSLWantWriteError:
|
|
281
|
+
select.select([], [self.internal_socket], [])
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
def ensure_ssl_handshake_is_done(self):
|
|
286
|
+
if self.is_with_ssl and not self.__is_ssl_handshake_done:
|
|
287
|
+
self.do_ssl_handshake()
|
|
288
|
+
self.__is_ssl_handshake_done = True
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
class SocketClient(Socket):
|
|
292
|
+
"""
|
|
293
|
+
Base class for socket clients.
|
|
294
|
+
"""
|
|
295
|
+
__metaclass__ = abc.ABCMeta
|
|
296
|
+
|
|
297
|
+
def __init__(self, *, name=None, create_ipv4_socket_kwargs=None, idle_sleep_delay=undefined_argument, do_run_with_recv=True, do_run_with_send=True):
|
|
298
|
+
"""Socket client constructor
|
|
299
|
+
@param name: Socket client name
|
|
300
|
+
@param create_ipv4_socket_kwargs: Arguments to create an IPv4 socket
|
|
301
|
+
@param idle_sleep_delay: delay to sleep when socket is idle (used only in some clients to control CPU resource impact ; default: 0.01 s)
|
|
302
|
+
@param do_run_with_recv: Define if recv is done in run process when client is started
|
|
303
|
+
@param do_run_with_send: Define if send is done in run process when client is started
|
|
304
|
+
"""
|
|
305
|
+
# Data used in start processing
|
|
306
|
+
self.__data_lock = threading.Lock()
|
|
307
|
+
self.__data = types.SimpleNamespace(
|
|
308
|
+
in_bytes = b'',
|
|
309
|
+
out_bytes = b'',
|
|
310
|
+
)
|
|
311
|
+
self.__with_recv = do_run_with_recv
|
|
312
|
+
self.__with_send = do_run_with_send
|
|
313
|
+
|
|
314
|
+
# Note: super().__init__ must be done after self.__data & others initialization since it can execute create_ipv4_socket_kwargs method
|
|
315
|
+
super().__init__(name=name, create_ipv4_socket_kwargs=create_ipv4_socket_kwargs, idle_sleep_delay=idle_sleep_delay)
|
|
316
|
+
|
|
317
|
+
@property
|
|
318
|
+
def is_run_with_recv(self):
|
|
319
|
+
return self.__with_recv
|
|
320
|
+
|
|
321
|
+
@property
|
|
322
|
+
def is_run_with_send(self):
|
|
323
|
+
return self.__with_send
|
|
324
|
+
|
|
325
|
+
@property
|
|
326
|
+
def _data_lock(self):
|
|
327
|
+
return self.__data_lock
|
|
328
|
+
|
|
329
|
+
@property
|
|
330
|
+
def _data(self):
|
|
331
|
+
return self.__data
|
|
332
|
+
|
|
333
|
+
def _start_thread(self, thread, stop_on_close=True):
|
|
334
|
+
# Ensure SSL handshake is done before starting to receive and send data
|
|
335
|
+
self.ensure_ssl_handshake_is_done()
|
|
336
|
+
|
|
337
|
+
# Start thread
|
|
338
|
+
super()._start_thread(thread, stop_on_close=stop_on_close)
|
|
339
|
+
|
|
340
|
+
@property
|
|
341
|
+
def received_data(self):
|
|
342
|
+
with self.__data_lock:
|
|
343
|
+
res = copy.copy(self.__data.in_bytes)
|
|
344
|
+
return res
|
|
345
|
+
|
|
346
|
+
@property
|
|
347
|
+
def received_data_size(self):
|
|
348
|
+
with self.__data_lock:
|
|
349
|
+
res = len(self.__data.in_bytes)
|
|
350
|
+
return res
|
|
351
|
+
|
|
352
|
+
def reset_received_data(self):
|
|
353
|
+
with self.__data_lock:
|
|
354
|
+
self.__data.in_bytes = b''
|
|
355
|
+
|
|
356
|
+
def read(self, bufsize=SocketConfig.default_read_bufsize, **kwargs):
|
|
357
|
+
if self.is_started and self.is_run_with_recv:
|
|
358
|
+
with self.__data_lock:
|
|
359
|
+
if self.__data.in_bytes:
|
|
360
|
+
res = self.__data.in_bytes[:bufsize]
|
|
361
|
+
self.__data.in_bytes = self.__data.in_bytes[bufsize:]
|
|
362
|
+
else:
|
|
363
|
+
res = b''
|
|
364
|
+
if logger.isEnabledFor(logging.DEBUG):
|
|
365
|
+
logger.debug(f"[{self.name}] Read data from received data: [{res}] (type: {type(res)} ; remaining data: {len(self.__data.in_bytes)})")
|
|
366
|
+
return res
|
|
367
|
+
else:
|
|
368
|
+
return super().read(bufsize=bufsize, **kwargs)
|
|
369
|
+
|
|
370
|
+
def write(self, data_bytes, loop_until_all_is_sent=True, **kwargs):
|
|
371
|
+
if self.is_started and self.is_run_with_send:
|
|
372
|
+
with self.__data_lock:
|
|
373
|
+
self.__data.out_bytes += data_bytes
|
|
374
|
+
if logger.isEnabledFor(logging.DEBUG):
|
|
375
|
+
logger.debug(f"[{self.name}] Added data in data to send (total: {len(self.__data.out_bytes)})")
|
|
376
|
+
else:
|
|
377
|
+
return super().write(data_bytes, loop_until_all_is_sent=loop_until_all_is_sent, **kwargs)
|
|
378
|
+
|
|
379
|
+
def wait_data(self, min_length=1, timeout_sec=default_value, do_raise_on_timeout=True):
|
|
380
|
+
wait = WaitFuncResultVerifying("wait data", lambda: self.received_data_size, lambda r: r >= min_length)
|
|
381
|
+
if timeout_sec is not default_value:
|
|
382
|
+
wait.with_timeout(timeout_sec)
|
|
383
|
+
if not do_raise_on_timeout:
|
|
384
|
+
wait.without_raise_on_timeout()
|
|
385
|
+
wait.execute()
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
class SocketServer(Socket):
|
|
389
|
+
"""
|
|
390
|
+
Base class for socket servers.
|
|
391
|
+
"""
|
|
392
|
+
__metaclass__ = abc.ABCMeta
|
|
393
|
+
|
|
394
|
+
def __init__(self, *, name=None, create_ipv4_socket_kwargs=None, idle_sleep_delay=undefined_argument):
|
|
395
|
+
super().__init__(name=name, create_ipv4_socket_kwargs=create_ipv4_socket_kwargs, idle_sleep_delay=idle_sleep_delay)
|
|
396
|
+
|
|
397
|
+
def accept(self):
|
|
398
|
+
if self.internal_socket:
|
|
399
|
+
conn, addr = self.internal_socket.accept()
|
|
400
|
+
res = Socket.create(name=f"[{self.name}] Connection with {addr}", internal_socket=conn)
|
|
401
|
+
return res, addr
|
|
402
|
+
else:
|
|
403
|
+
# Server is stopped
|
|
404
|
+
raise TechnicalException(f"[{self.name}] Server socket is closed")
|
|
405
|
+
|
|
406
|
+
@abc.abstractmethod
|
|
407
|
+
def _process_received_data(self, data):
|
|
408
|
+
raise NotImplementedError()
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
localhost.crt and localhost.key were generated with command:
|
|
2
|
+
openssl req -x509 -out localhost.crt -keyout localhost.key \
|
|
3
|
+
-newkey rsa:2048 -nodes -sha256 \
|
|
4
|
+
-subj '/CN=localhost' -extensions EXT -config <( \
|
|
5
|
+
printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
|
2
|
+
MIIDDzCCAfegAwIBAgIURN+rwAAcCgo1skxp67Fe8gQmfsQwDQYJKoZIhvcNAQEL
|
|
3
|
+
BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI1MDMxODA5Mzg1M1oXDTI1MDQx
|
|
4
|
+
NzA5Mzg1M1owFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF
|
|
5
|
+
AAOCAQ8AMIIBCgKCAQEA0LcxwmvlWDdgvUcTokDXXK/oOCs0gxaIciFGcgLd8vAA
|
|
6
|
+
ghgd38U7lvJFJtIsEZZc2TBchx8AMaucQbnxTmI7cCCSuxRtzDPypFGNxRf1JxZx
|
|
7
|
+
M5lwdww9JVtYmvMlfxnd+Q0yjvCvgl/DcKmbn0lhOmnviFUdfPb/9z5HAkHbl16Q
|
|
8
|
+
XQLI8vnyk2xwZwL9My/n++9X351kOjpwNRL9Ti9uLlD5MqjNOpLwPmBBx2ndy3Id
|
|
9
|
+
7dl38KWSgOO4L8sH1YS0jmfGEX9nnMaki87uxptC5Eah2kMWACEZ3uYl2bapksdl
|
|
10
|
+
byX2623KhxEC1NpElsZkydg2umkTKicpgRBuWDQL1wIDAQABo1kwVzAUBgNVHREE
|
|
11
|
+
DTALgglsb2NhbGhvc3QwCwYDVR0PBAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMB
|
|
12
|
+
MB0GA1UdDgQWBBSTWa2UN+AuGAb68WLJkydR+TYDKjANBgkqhkiG9w0BAQsFAAOC
|
|
13
|
+
AQEAJLui3fct/B0oVR+WYfzpRYm4nWzaSsnmnRjfrMPg43GG5oHEf7wqF2yc7sDx
|
|
14
|
+
SPJgKOqZRrhXDXXPg3tLUZGpY37HusZOLauNko91VF7gl4x2749PMYkOiJw887my
|
|
15
|
+
2lcod7SUh0O2lv0J14YsafcDaBa0kp1ibbvUdUJwiDMhRMVm5WvM1927fWuYBiQ2
|
|
16
|
+
7Po+X/05E3T5HvFFu/W6l54UHFpChwvhNq9JKgxfMSdVKYhDWhbQeh0qucWU2Atg
|
|
17
|
+
0PoB48ykW13/9yImQgtIreu2g2urPYXLCN963pRUDwBKQ/e+Or+I45AmpB6DaKA1
|
|
18
|
+
SL0QdGkPBGuRhPs+ovsteVIFnQ==
|
|
19
|
+
-----END CERTIFICATE-----
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
-----BEGIN PRIVATE KEY-----
|
|
2
|
+
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDQtzHCa+VYN2C9
|
|
3
|
+
RxOiQNdcr+g4KzSDFohyIUZyAt3y8ACCGB3fxTuW8kUm0iwRllzZMFyHHwAxq5xB
|
|
4
|
+
ufFOYjtwIJK7FG3MM/KkUY3FF/UnFnEzmXB3DD0lW1ia8yV/Gd35DTKO8K+CX8Nw
|
|
5
|
+
qZufSWE6ae+IVR189v/3PkcCQduXXpBdAsjy+fKTbHBnAv0zL+f771ffnWQ6OnA1
|
|
6
|
+
Ev1OL24uUPkyqM06kvA+YEHHad3Lch3t2XfwpZKA47gvywfVhLSOZ8YRf2ecxqSL
|
|
7
|
+
zu7Gm0LkRqHaQxYAIRne5iXZtqmSx2VvJfbrbcqHEQLU2kSWxmTJ2Da6aRMqJymB
|
|
8
|
+
EG5YNAvXAgMBAAECggEAF8F3f8I5cmxV2HVUk20p62TM250fTE8Dl2nuKLU8Kes4
|
|
9
|
+
mOtsdbcZ7I5at0EeFEphpbQkHppgB/HucRSxldMHIjYIPWmP2GQ5Q+FRxOh7K3MZ
|
|
10
|
+
zgkIN09Eo7yH6JWwOOKVf0QJ8yG1+Eg0vd1a1ysfo+nBgmpIVvGOJMgJMQU/RzUe
|
|
11
|
+
2PYWg+qeVl98LxjlCRExlyeDWEklTkKUbfp9yn2FeklAzfX38U6wgCXWAuzmSaPS
|
|
12
|
+
vv5u7Y1iOBRTJ32MlyvZVZReW0enzbT8i49coE5msmGm9cNE7Y02boLMIro318Zk
|
|
13
|
+
MYeEkqKPHsAMByXgrbpex9PW8m4Lo92MM1NOasFqUQKBgQDy2o4iy0KWsV/9i1jy
|
|
14
|
+
hQb6YezQEe8gB2HkDDFP5A2EAyO6pTeD8RBYauKdO7VDi9LSKR/1/4uRsjqIwkyV
|
|
15
|
+
nM86W3Dg7jZNlovl37kyZgGFpovwTgenkNFnjdA/pgL1xQ6tRIHfi2KUhluA5PK1
|
|
16
|
+
5zsx3SejmccmDCXTGTH2s6ck0wKBgQDcA45cXkShvwap9H9SKFRDLqqn14CLSHiW
|
|
17
|
+
8JDrly7jeLaq6hnvawHPcMyp2b1NCMDNJcMqW/BNLMq1EumK+bTL5h876M4KcTuy
|
|
18
|
+
dWfj4QLtmsqj7n4CnutBcC65a4Qdtqx62hd+GXG4U2ytjOhdNezsVYxxsOxOMs7L
|
|
19
|
+
UEBVEc5qbQKBgQDtdVh/mwG8OSmjz6okUICXOEMG3FJVngJQqr9Y36N7jlpUORJE
|
|
20
|
+
V+Tkn3Z/yY8ewcxdJEsVDU8aIgxsBpg9vjs+U4TW2vWL/gVCuvPp3KXmWggA6zs+
|
|
21
|
+
1DJ9L8QNSDUivRDxyMe4niDBG3LDYJoV1UgjJJyKsmVwxXYCqGMbV2S6cwKBgEwT
|
|
22
|
+
OrV7rxWSnPZFYYUCBujYCRBSNtNycqgWdLXRp9fl1JvSqLcddBnLcilE7ezmGuyU
|
|
23
|
+
oyBRfAzjcRAdgv2YDEj4wFIR1LTNpIu3hv3HvyBzhqAahh3X35bX+IAKyjsQACHW
|
|
24
|
+
qYrjt2u6BPkZoPsh+1NY3WAugfckIFcy35vKtWodAoGAWTlEW9Qs7KeYVEQbE1nu
|
|
25
|
+
odT5NXgXjXa7xTh8zg8ezpvUnPsC8roG9lA13Wlbgj4cxulzWJAtTdOQ0vwWM1nL
|
|
26
|
+
EHeMjGdHO84O9ulENWT1H1Rths7/5FkLKLGjOIpc8TqTlJnlpS+RV7mJG4JZlHNZ
|
|
27
|
+
Od7K/qyK05io0lnF9lDQfZk=
|
|
28
|
+
-----END PRIVATE KEY-----
|