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,537 @@
|
|
|
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 holado_core.common.exceptions.functional_exception import FunctionalException
|
|
15
|
+
import logging
|
|
16
|
+
from holado_core.common.exceptions.technical_exception import TechnicalException
|
|
17
|
+
from holado.common.handlers.object import DeleteableObject
|
|
18
|
+
from holado_core.common.tools.tools import Tools
|
|
19
|
+
from holado_docker.sdk.docker.container_logs import DockerContainerLogsFollower
|
|
20
|
+
import re
|
|
21
|
+
from holado_python.common.tools.datetime import DateTime
|
|
22
|
+
from holado.common.handlers.undefined import default_value
|
|
23
|
+
from holado_core.common.handlers.wait import WaitFuncResult
|
|
24
|
+
import time
|
|
25
|
+
|
|
26
|
+
logger = logging.getLogger(__name__)
|
|
27
|
+
|
|
28
|
+
try:
|
|
29
|
+
import docker
|
|
30
|
+
with_docker = True
|
|
31
|
+
except Exception as exc:
|
|
32
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
33
|
+
logger.debug(f"DockerClient is not available. Initialization failed on error: {exc}")
|
|
34
|
+
with_docker = False
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class DockerClient(object):
|
|
38
|
+
@classmethod
|
|
39
|
+
def is_available(cls):
|
|
40
|
+
return with_docker
|
|
41
|
+
|
|
42
|
+
def __init__(self):
|
|
43
|
+
self.__client = docker.from_env()
|
|
44
|
+
self.__containers = {}
|
|
45
|
+
self.__volumes = {}
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def client(self):
|
|
49
|
+
return self.__client
|
|
50
|
+
|
|
51
|
+
def has_container(self, name, in_list=True, all_=False, reset_if_removed=True):
|
|
52
|
+
# Note: Even if name exists in __containers, it is possible that the container has been removed
|
|
53
|
+
if in_list:
|
|
54
|
+
c = self.__get_container_from_list(name, all_=all_)
|
|
55
|
+
res = c is not None
|
|
56
|
+
|
|
57
|
+
if reset_if_removed and not res and name in self.__containers:
|
|
58
|
+
del self.__containers[name]
|
|
59
|
+
else:
|
|
60
|
+
res = name in self.__containers
|
|
61
|
+
|
|
62
|
+
if reset_if_removed and res:
|
|
63
|
+
if self.__containers[name].status == "removed":
|
|
64
|
+
del self.__containers[name]
|
|
65
|
+
res = False
|
|
66
|
+
return res
|
|
67
|
+
|
|
68
|
+
def get_container(self, name, all_=False, reset_if_removed=True):
|
|
69
|
+
# Reset container if removed
|
|
70
|
+
if reset_if_removed and name in self.__containers:
|
|
71
|
+
if self.__containers[name].status == "removed":
|
|
72
|
+
del self.__containers[name]
|
|
73
|
+
|
|
74
|
+
# Get container from list if needed
|
|
75
|
+
if name not in self.__containers:
|
|
76
|
+
c = self.__get_container_from_list(name, all_=all_)
|
|
77
|
+
if c:
|
|
78
|
+
self.__containers[name] = DockerContainer(self, c)
|
|
79
|
+
|
|
80
|
+
return self.__containers.get(name, None)
|
|
81
|
+
|
|
82
|
+
def update_containers(self, all_=False, sparse=False, reset_if_removed=True):
|
|
83
|
+
# Add new containers
|
|
84
|
+
updated_names = set()
|
|
85
|
+
for c in self.__client.containers.list(all=all_, sparse=sparse, ignore_removed=True):
|
|
86
|
+
try:
|
|
87
|
+
c_name = c.name
|
|
88
|
+
except docker.errors.NotFound:
|
|
89
|
+
# Container 'c' doesn't exist anymore
|
|
90
|
+
continue
|
|
91
|
+
|
|
92
|
+
if c_name not in self.__containers:
|
|
93
|
+
self.__containers[c_name] = DockerContainer(self, c)
|
|
94
|
+
updated_names.add(c_name)
|
|
95
|
+
|
|
96
|
+
if reset_if_removed:
|
|
97
|
+
for name in set(self.__containers.keys()).difference(updated_names):
|
|
98
|
+
del self.__containers[name]
|
|
99
|
+
|
|
100
|
+
def get_container_names(self, in_list=True, all_=False, sparse=False, include_patterns=None, exclude_patterns=None):
|
|
101
|
+
incl_patterns = [ip if isinstance(ip, re.Pattern) else re.compile(ip) for ip in include_patterns] if include_patterns is not None else None
|
|
102
|
+
excl_patterns = [ep if isinstance(ep, re.Pattern) else re.compile(ep) for ep in exclude_patterns] if exclude_patterns is not None else None
|
|
103
|
+
|
|
104
|
+
if in_list:
|
|
105
|
+
res = []
|
|
106
|
+
for c in self.__client.containers.list(all=all_, sparse=sparse, ignore_removed=True):
|
|
107
|
+
try:
|
|
108
|
+
c_name = c.name
|
|
109
|
+
if c_name is None:
|
|
110
|
+
c.reload()
|
|
111
|
+
c_name = c.name
|
|
112
|
+
except docker.errors.NotFound:
|
|
113
|
+
# Container 'c' doesn't exist anymore
|
|
114
|
+
continue
|
|
115
|
+
|
|
116
|
+
# Manage included and excluded patterns
|
|
117
|
+
if excl_patterns is not None:
|
|
118
|
+
excluded = False
|
|
119
|
+
for ep in excl_patterns:
|
|
120
|
+
if ep.match(c_name):
|
|
121
|
+
excluded = True
|
|
122
|
+
break
|
|
123
|
+
if excluded:
|
|
124
|
+
continue
|
|
125
|
+
if incl_patterns is not None:
|
|
126
|
+
included = False
|
|
127
|
+
for ip in incl_patterns:
|
|
128
|
+
if ip.match(c_name):
|
|
129
|
+
included = True
|
|
130
|
+
break
|
|
131
|
+
if not included:
|
|
132
|
+
continue
|
|
133
|
+
|
|
134
|
+
res.append(c_name)
|
|
135
|
+
else:
|
|
136
|
+
res = list(self.__containers.keys())
|
|
137
|
+
return res
|
|
138
|
+
|
|
139
|
+
def __get_container_from_list(self, name, all_=False):
|
|
140
|
+
res = None
|
|
141
|
+
for c in self.__client.containers.list(all=all_, ignore_removed=True):
|
|
142
|
+
try:
|
|
143
|
+
c_name = c.name
|
|
144
|
+
except docker.errors.NotFound:
|
|
145
|
+
# Container 'c' doesn't exist anymore
|
|
146
|
+
continue
|
|
147
|
+
|
|
148
|
+
if c_name == name:
|
|
149
|
+
res = c
|
|
150
|
+
break
|
|
151
|
+
return res
|
|
152
|
+
|
|
153
|
+
def has_volume(self, name, in_list = False):
|
|
154
|
+
res = name in self.__volumes
|
|
155
|
+
if not res and in_list:
|
|
156
|
+
v = self.__get_volume_from_list(name)
|
|
157
|
+
res = v is not None
|
|
158
|
+
return res
|
|
159
|
+
|
|
160
|
+
def get_volume(self, name):
|
|
161
|
+
if name not in self.__volumes:
|
|
162
|
+
v = self.__get_volume_from_list(name)
|
|
163
|
+
if v:
|
|
164
|
+
self.__volumes[name] = DockerVolume(v)
|
|
165
|
+
return self.__volumes.get(name)
|
|
166
|
+
|
|
167
|
+
def get_all_volume_names(self):
|
|
168
|
+
return [v.name for v in self.__client.volumes.list()]
|
|
169
|
+
|
|
170
|
+
def __get_volume_from_list(self, name):
|
|
171
|
+
res = None
|
|
172
|
+
for v in self.__client.volumes.list():
|
|
173
|
+
if v.name == name:
|
|
174
|
+
res = v
|
|
175
|
+
break
|
|
176
|
+
return res
|
|
177
|
+
|
|
178
|
+
def run_container(self, name, image, remove_existing=False, wait_started=True, auto_stop=True, **kwargs):
|
|
179
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
180
|
+
logger.debug(f"Running docker container '{name}' with image '{image}' and arguments {kwargs}{', and waiting it is started' if wait_started else ''}")
|
|
181
|
+
|
|
182
|
+
# Manage remove if already existing
|
|
183
|
+
cont = self.get_container(name)
|
|
184
|
+
if cont:
|
|
185
|
+
if remove_existing:
|
|
186
|
+
if cont.status == "running":
|
|
187
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
188
|
+
logger.debug(f"Docker container '{name}' is running, stopping it before remove")
|
|
189
|
+
self.stop_container(name)
|
|
190
|
+
|
|
191
|
+
if self.has_container(name): # After stop, container is able to be automatically removed depending on its run parameters
|
|
192
|
+
self.remove_container(name)
|
|
193
|
+
else:
|
|
194
|
+
logger.info(f"Docker container '{name}' is already running")
|
|
195
|
+
return
|
|
196
|
+
|
|
197
|
+
# Run container
|
|
198
|
+
c = self.__client.containers.run(image, name=name, detach=True, **kwargs)
|
|
199
|
+
container = DockerContainer(self, c)
|
|
200
|
+
self.__containers[name] = container
|
|
201
|
+
|
|
202
|
+
# Manage wait running status
|
|
203
|
+
if wait_started:
|
|
204
|
+
try:
|
|
205
|
+
container.await_started()
|
|
206
|
+
except:
|
|
207
|
+
raise TechnicalException(f"Failed to run container of name '{name}' (status: {container.status})")
|
|
208
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
209
|
+
logger.debug(f"Run docker container '{name}' with image '{image}' and arguments {kwargs}{', and waited it is started' if wait_started else ''}")
|
|
210
|
+
|
|
211
|
+
# Set properties
|
|
212
|
+
container.auto_stop = auto_stop
|
|
213
|
+
|
|
214
|
+
return container
|
|
215
|
+
|
|
216
|
+
def restart_container(self, name, wait_started=True, timeout=default_value, **kwargs):
|
|
217
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
218
|
+
logger.debug(f"Restarting docker container '{name}' with arguments {kwargs}{', and waiting it is started' if wait_started else ''}")
|
|
219
|
+
container = self.get_container(name)
|
|
220
|
+
if not container:
|
|
221
|
+
raise FunctionalException("Container of name '{}' doesn't exist")
|
|
222
|
+
|
|
223
|
+
container.restart(**kwargs)
|
|
224
|
+
|
|
225
|
+
if wait_started:
|
|
226
|
+
try:
|
|
227
|
+
container.await_started(timeout=timeout)
|
|
228
|
+
except:
|
|
229
|
+
raise TechnicalException(f"Failed to restart container of name '{name}' (status: {container.status})")
|
|
230
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
231
|
+
logger.debug(f"Restarted docker container '{name}' with arguments {kwargs}{', and waited it is started' if wait_started else ''}")
|
|
232
|
+
|
|
233
|
+
def start_container(self, name, wait_started=True, timeout=default_value, **kwargs):
|
|
234
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
235
|
+
logger.debug(f"Starting docker container '{name}' with arguments {kwargs}{', and waiting it is started' if wait_started else ''}")
|
|
236
|
+
container = self.get_container(name, all_=True)
|
|
237
|
+
if not container:
|
|
238
|
+
raise FunctionalException("Container of name '{}' doesn't exist")
|
|
239
|
+
|
|
240
|
+
container.start(**kwargs)
|
|
241
|
+
|
|
242
|
+
if wait_started:
|
|
243
|
+
try:
|
|
244
|
+
container.await_started(timeout=timeout)
|
|
245
|
+
except:
|
|
246
|
+
raise TechnicalException(f"Failed to start container of name '{name}' (status: {container.status})")
|
|
247
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
248
|
+
logger.debug(f"Started docker container '{name}' with arguments {kwargs}{', and waited it is started' if wait_started else ''}")
|
|
249
|
+
|
|
250
|
+
def stop_container(self, name, wait_stopped=True, timeout=default_value, stop_kwargs=None, wait_kwargs=None):
|
|
251
|
+
stop_kwargs = stop_kwargs if stop_kwargs is not None else {}
|
|
252
|
+
wait_kwargs = wait_kwargs if wait_kwargs is not None else {}
|
|
253
|
+
if timeout is not default_value:
|
|
254
|
+
wait_kwargs['timeout'] = timeout
|
|
255
|
+
|
|
256
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
257
|
+
logger.debug(f"Stopping docker container of name '{name}'{', and waiting it is stopped' if wait_stopped else ''}")
|
|
258
|
+
if name not in self.__containers:
|
|
259
|
+
raise FunctionalException("Unknown container of name '{}'".format(name))
|
|
260
|
+
elif self.__containers[name].status != "running":
|
|
261
|
+
raise FunctionalException("Container of name '{}' is not running (status: {})".format(name, self.__containers[name].status))
|
|
262
|
+
|
|
263
|
+
self.__containers[name].stop(**stop_kwargs)
|
|
264
|
+
if wait_stopped:
|
|
265
|
+
try:
|
|
266
|
+
self.__containers[name].wait(**wait_kwargs)
|
|
267
|
+
except docker.errors.NotFound:
|
|
268
|
+
# This exception occurs on containers automatically removed on stop
|
|
269
|
+
pass
|
|
270
|
+
|
|
271
|
+
if wait_stopped and self.__containers[name].status == "running":
|
|
272
|
+
raise FunctionalException("Failed to stop container of name '{}' (status: {})".format(name, self.__containers[name].status))
|
|
273
|
+
else:
|
|
274
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
275
|
+
logger.debug(f"Stopped docker container of name '{name}'{', and waited it is stopped' if wait_stopped else ''}")
|
|
276
|
+
|
|
277
|
+
def remove_container(self, name):
|
|
278
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
279
|
+
logger.debug(f"Removing docker container of name '{name}'")
|
|
280
|
+
if not self.has_container(name, in_list=True, all_=True):
|
|
281
|
+
raise FunctionalException(f"Container of name '{name}' doesn't exist")
|
|
282
|
+
|
|
283
|
+
if name in self.__containers:
|
|
284
|
+
del self.__containers[name]
|
|
285
|
+
self.client.api.remove_container(name)
|
|
286
|
+
|
|
287
|
+
if self.has_container(name, in_list=True, all_=True):
|
|
288
|
+
raise FunctionalException(f"Failed to remove container of name '{name}'")
|
|
289
|
+
else:
|
|
290
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
291
|
+
logger.debug(f"Removed docker container of name '{name}'")
|
|
292
|
+
|
|
293
|
+
def await_container_exists(self, name, timeout=default_value):
|
|
294
|
+
wait_status = WaitFuncResult(f"wait container '{name}' exists",
|
|
295
|
+
lambda: self.has_container(name, in_list=True, all_=True, reset_if_removed=False) )
|
|
296
|
+
wait_status.redo_until(True)
|
|
297
|
+
if timeout is not default_value:
|
|
298
|
+
wait_status.with_timeout(timeout)
|
|
299
|
+
return wait_status.execute()
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
class DockerContainer(DeleteableObject):
|
|
303
|
+
def __init__(self, docker_client, container):
|
|
304
|
+
super().__init__(container.name)
|
|
305
|
+
|
|
306
|
+
self.__docker_client = docker_client
|
|
307
|
+
self.__container = container
|
|
308
|
+
self.__auto_stop = False
|
|
309
|
+
|
|
310
|
+
# Manage logs
|
|
311
|
+
self.__logs_follower = None
|
|
312
|
+
self.__logs_formatter = None
|
|
313
|
+
|
|
314
|
+
def _delete_object(self):
|
|
315
|
+
if self.auto_stop and self.status == "running" and self.__docker_client and self.__docker_client.has_container(self.name):
|
|
316
|
+
self.__docker_client.stop_container(self.name)
|
|
317
|
+
|
|
318
|
+
@property
|
|
319
|
+
def container(self):
|
|
320
|
+
return self.__container
|
|
321
|
+
|
|
322
|
+
@property
|
|
323
|
+
def information(self):
|
|
324
|
+
try:
|
|
325
|
+
self.__container.reload()
|
|
326
|
+
except docker.errors.NotFound:
|
|
327
|
+
# Container doesn't exist anymore, use last known information
|
|
328
|
+
pass
|
|
329
|
+
return self.__container.attrs
|
|
330
|
+
|
|
331
|
+
@property
|
|
332
|
+
def status(self):
|
|
333
|
+
""" Container status (created, restarting, running, removing, paused, exited, dead, or removed)
|
|
334
|
+
"""
|
|
335
|
+
try:
|
|
336
|
+
self.__container.reload()
|
|
337
|
+
except docker.errors.NotFound:
|
|
338
|
+
return "removed"
|
|
339
|
+
return self.__container.status
|
|
340
|
+
|
|
341
|
+
@property
|
|
342
|
+
def health_status(self):
|
|
343
|
+
""" Container health status (starting, healthy, unhealthy, or removed).
|
|
344
|
+
"""
|
|
345
|
+
try:
|
|
346
|
+
self.__container.reload()
|
|
347
|
+
except docker.errors.NotFound:
|
|
348
|
+
return "removed"
|
|
349
|
+
|
|
350
|
+
res = self.__container.health
|
|
351
|
+
if res == 'unknown':
|
|
352
|
+
return None
|
|
353
|
+
else:
|
|
354
|
+
return res
|
|
355
|
+
|
|
356
|
+
@property
|
|
357
|
+
def auto_stop(self):
|
|
358
|
+
self.__auto_stop
|
|
359
|
+
|
|
360
|
+
@auto_stop.setter
|
|
361
|
+
def auto_stop(self, auto_stop):
|
|
362
|
+
self.__auto_stop = auto_stop
|
|
363
|
+
|
|
364
|
+
def reload(self, ignore_removed=True):
|
|
365
|
+
try:
|
|
366
|
+
self.__container.reload()
|
|
367
|
+
except docker.errors.NotFound:
|
|
368
|
+
if not ignore_removed:
|
|
369
|
+
raise
|
|
370
|
+
|
|
371
|
+
def restart(self, **kwargs):
|
|
372
|
+
return self.__container.restart(**kwargs)
|
|
373
|
+
|
|
374
|
+
def start(self, **kwargs):
|
|
375
|
+
return self.__container.start(**kwargs)
|
|
376
|
+
|
|
377
|
+
def stop(self, **kwargs):
|
|
378
|
+
return self.__container.stop(**kwargs)
|
|
379
|
+
|
|
380
|
+
def wait(self, **kwargs):
|
|
381
|
+
return self.__container.wait(**kwargs)
|
|
382
|
+
|
|
383
|
+
def await_started(self, timeout=default_value):
|
|
384
|
+
health_status = self.health_status
|
|
385
|
+
if health_status == "healthy":
|
|
386
|
+
return
|
|
387
|
+
elif health_status not in [None, 'removed']:
|
|
388
|
+
return self.await_health_status("healthy", timeout=timeout)
|
|
389
|
+
else:
|
|
390
|
+
# Container hasn't healthy mechanism
|
|
391
|
+
return self.await_status("running", timeout=timeout)
|
|
392
|
+
#TODO: for containers that haven't healthy mechanism, add a mechanism to customize how health is computed
|
|
393
|
+
|
|
394
|
+
def await_status(self, status, timeout=default_value):
|
|
395
|
+
wait_status = WaitFuncResult(f"wait container '{self.name}' has status '{status}'",
|
|
396
|
+
lambda: self.status)
|
|
397
|
+
wait_status.with_process_in_thread(False) \
|
|
398
|
+
.redo_until(status)
|
|
399
|
+
if timeout is not default_value:
|
|
400
|
+
wait_status.with_timeout(timeout)
|
|
401
|
+
return wait_status.execute()
|
|
402
|
+
|
|
403
|
+
def await_health_status(self, status, timeout=default_value):
|
|
404
|
+
wait_status = WaitFuncResult(f"wait container '{self.name}' has health status '{status}'",
|
|
405
|
+
lambda: self.health_status)
|
|
406
|
+
wait_status.with_process_in_thread(False) \
|
|
407
|
+
.redo_until(status)
|
|
408
|
+
if timeout is not default_value:
|
|
409
|
+
wait_status.with_timeout(timeout)
|
|
410
|
+
return wait_status.execute()
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
# Manage logs
|
|
415
|
+
|
|
416
|
+
@property
|
|
417
|
+
def is_following_logs(self):
|
|
418
|
+
return self.__logs_follower is not None
|
|
419
|
+
|
|
420
|
+
@property
|
|
421
|
+
def logs_formatter(self):
|
|
422
|
+
return self.__logs_formatter
|
|
423
|
+
|
|
424
|
+
@logs_formatter.setter
|
|
425
|
+
def logs_formatter(self, formatter):
|
|
426
|
+
self.__logs_formatter = formatter
|
|
427
|
+
|
|
428
|
+
def get_container_logs(self, stdout=True, stderr=True, timestamps=False, tail='all', since=None, until=None, wait_before_s=0.1):
|
|
429
|
+
""" Get logs from Docker Engine
|
|
430
|
+
Note: There is a latency between the moment a container makes a log and the moment it is available in Docker Engine.
|
|
431
|
+
Thus this method waits by default a little time (wait_before_s) before getting logs.
|
|
432
|
+
This feature can be neutralized by passing wait_before_s=None.
|
|
433
|
+
@param stdout: If True, get stdout logs (default: True)
|
|
434
|
+
@param stderr: If True, get stderr logs (default: True)
|
|
435
|
+
@param timestamps: If True, add timestamps in logs (default: False)
|
|
436
|
+
@param tail: Get specified number of lines at the end of logs. Either an integer of number of lines or the string 'all' (default: 'all')
|
|
437
|
+
@param since: Since datetime (default: None)
|
|
438
|
+
@param until: Until datetime (default: None)
|
|
439
|
+
@param wait_before_s: None or number of seconds to wait before getting logs (default: 0.1)
|
|
440
|
+
"""
|
|
441
|
+
if wait_before_s is not None:
|
|
442
|
+
time.sleep(wait_before_s)
|
|
443
|
+
|
|
444
|
+
if isinstance(since, str):
|
|
445
|
+
since = DateTime.str_2_datetime(since)
|
|
446
|
+
if isinstance(until, str):
|
|
447
|
+
until = DateTime.str_2_datetime(until)
|
|
448
|
+
|
|
449
|
+
logs_bytes = self.__container.logs(stdout=stdout, stderr=stderr, timestamps=timestamps, tail=tail, since=since, until=until)
|
|
450
|
+
return self._get_logs_from_logs_bytes(logs_bytes, with_timestamps=timestamps)
|
|
451
|
+
|
|
452
|
+
def _get_logs_from_logs_bytes(self, logs_bytes, with_timestamps=False):
|
|
453
|
+
log_bytes_list = logs_bytes.split(b'\n')
|
|
454
|
+
|
|
455
|
+
res = []
|
|
456
|
+
for log_bytes in log_bytes_list:
|
|
457
|
+
if not log_bytes:
|
|
458
|
+
continue
|
|
459
|
+
res.append(self._get_log_from_log_bytes(log_bytes, with_timestamps))
|
|
460
|
+
|
|
461
|
+
return res
|
|
462
|
+
|
|
463
|
+
def _get_log_from_log_bytes(self, log_bytes, with_timestamps=False):
|
|
464
|
+
if with_timestamps:
|
|
465
|
+
t_bytes, log_bytes = log_bytes.split(b' ', maxsplit=1)
|
|
466
|
+
log_time = t_bytes.decode()
|
|
467
|
+
|
|
468
|
+
try:
|
|
469
|
+
log = log_bytes.decode()
|
|
470
|
+
except:
|
|
471
|
+
log = log_bytes
|
|
472
|
+
|
|
473
|
+
if with_timestamps:
|
|
474
|
+
res = (log_time, log)
|
|
475
|
+
else:
|
|
476
|
+
res = log
|
|
477
|
+
|
|
478
|
+
return res
|
|
479
|
+
|
|
480
|
+
def follow_logs(self, stdout=True, stderr=True, tail='all', since=None):
|
|
481
|
+
"""Follow logs from Docker Engine
|
|
482
|
+
"""
|
|
483
|
+
if self.__logs_follower is not None:
|
|
484
|
+
raise TechnicalException(f"Logs of container '{self.name}' are already followed")
|
|
485
|
+
|
|
486
|
+
self.__logs_follower = DockerContainerLogsFollower(self)
|
|
487
|
+
self.__logs_follower.follow_logs(stdout, stderr, tail, since)
|
|
488
|
+
|
|
489
|
+
def reset_logs(self):
|
|
490
|
+
"""Reset followed logs
|
|
491
|
+
"""
|
|
492
|
+
if self.__logs_follower is None:
|
|
493
|
+
raise TechnicalException(f"Logs of container '{self.name}' are not followed")
|
|
494
|
+
|
|
495
|
+
self.__logs_follower.reset()
|
|
496
|
+
|
|
497
|
+
def get_logs(self, stdout=True, stderr=True, timestamps=False, tail='all', since=None, until=None, wait_before_s=0.1, formatter=None):
|
|
498
|
+
if self.is_following_logs:
|
|
499
|
+
logs = self.__logs_follower.get_logs(stdout=stdout, stderr=stderr, timestamps=timestamps, tail=tail, since=since, until=until, wait_before_s=wait_before_s)
|
|
500
|
+
else:
|
|
501
|
+
logs = self.get_container_logs(stdout=stdout, stderr=stderr, timestamps=timestamps, tail=tail, since=since, until=until, wait_before_s=wait_before_s)
|
|
502
|
+
|
|
503
|
+
formatter = formatter if formatter is not None else self.__logs_formatter
|
|
504
|
+
if formatter is not None:
|
|
505
|
+
res = formatter.format_logs(logs, with_timestamps=timestamps)
|
|
506
|
+
else:
|
|
507
|
+
res = logs
|
|
508
|
+
|
|
509
|
+
return res
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
class DockerVolume(object):
|
|
515
|
+
def __init__(self, volume):
|
|
516
|
+
self.__volume = volume
|
|
517
|
+
|
|
518
|
+
@property
|
|
519
|
+
def volume(self):
|
|
520
|
+
self.__volume
|
|
521
|
+
|
|
522
|
+
@property
|
|
523
|
+
def attributes(self):
|
|
524
|
+
self.__volume.reload()
|
|
525
|
+
return self.__volume.attrs
|
|
526
|
+
|
|
527
|
+
def get_attribute(self, attr_path):
|
|
528
|
+
names = attr_path.split('.')
|
|
529
|
+
attrs = self.attributes
|
|
530
|
+
res = attrs
|
|
531
|
+
for i, name in enumerate(names):
|
|
532
|
+
if name in res:
|
|
533
|
+
res = res[name]
|
|
534
|
+
else:
|
|
535
|
+
raise FunctionalException(f"Attribute '{'.'.join(names[:i+1])}' doesn't exist (requested attribute: '{attr_path}' ; volume attributes: {attrs})")
|
|
536
|
+
return res
|
|
537
|
+
|
|
@@ -0,0 +1,71 @@
|
|
|
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 holado_docker.sdk.docker.docker_client import DockerClient
|
|
15
|
+
from holado_core.common.exceptions.technical_exception import TechnicalException
|
|
16
|
+
import logging
|
|
17
|
+
from holado_core.tools.abstracts.service import Service
|
|
18
|
+
from holado_system.system.command.command import CommandStates
|
|
19
|
+
from holado_core.common.tools.tools import Tools
|
|
20
|
+
|
|
21
|
+
logger = logging.getLogger(__name__)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class DockerService(Service):
|
|
25
|
+
@classmethod
|
|
26
|
+
def is_available(cls):
|
|
27
|
+
return DockerClient.is_available()
|
|
28
|
+
|
|
29
|
+
def __init__(self, name):
|
|
30
|
+
super().__init__(name)
|
|
31
|
+
self.__docker_client = None
|
|
32
|
+
self.__docker_container = None
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def status(self):
|
|
36
|
+
if self.__docker_container is not None and self.__docker_client.has_container(self.name):
|
|
37
|
+
status = self.__docker_container.status
|
|
38
|
+
if status in ["running", "paused", "restarting"]:
|
|
39
|
+
return CommandStates.Running
|
|
40
|
+
elif status == "exited":
|
|
41
|
+
result = self.__docker_container.wait(timeout=10)
|
|
42
|
+
error_code = result["StatusCode"]
|
|
43
|
+
if error_code == 0:
|
|
44
|
+
return CommandStates.Success
|
|
45
|
+
else:
|
|
46
|
+
return CommandStates.Error
|
|
47
|
+
else:
|
|
48
|
+
raise TechnicalException(f"Unmanaged docker status '{status}'")
|
|
49
|
+
else:
|
|
50
|
+
return None
|
|
51
|
+
|
|
52
|
+
def run_as_docker(self, image, remove_existing=True, remove=True, auto_stop=True, **kwargs):
|
|
53
|
+
"""
|
|
54
|
+
Run the service as a docker image.
|
|
55
|
+
|
|
56
|
+
:param image: Image name
|
|
57
|
+
:param remove_existing: If true (default) and docker already exists, remove docker before creating a new one
|
|
58
|
+
:param remove: If true (default), remove the docker at stop
|
|
59
|
+
:param auto_stop: If true (default), automatically stop docker when docker instance is released
|
|
60
|
+
"""
|
|
61
|
+
self.__docker_client = DockerClient()
|
|
62
|
+
self.__docker_container = self.__docker_client.run_container(self.name, image, remove_existing=remove_existing, remove=remove, auto_stop=auto_stop, **kwargs)
|
|
63
|
+
|
|
64
|
+
def stop(self):
|
|
65
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
66
|
+
logger.debug(f"Stopping service '{self.name}'")
|
|
67
|
+
if self.__docker_container is not None:
|
|
68
|
+
if self.__docker_client.has_container(self.name) and self.__docker_client.get_container(self.name).status == "running":
|
|
69
|
+
self.__docker_client.stop_container(self.name)
|
|
70
|
+
else:
|
|
71
|
+
raise TechnicalException(f"Service '{self.name}' is not started")
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
#################################################
|
|
4
|
+
# HolAdo (Holistic Automation do)
|
|
5
|
+
#
|
|
6
|
+
# (C) Copyright 2021-2025 by Eric Klumpp
|
|
7
|
+
#
|
|
8
|
+
# 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:
|
|
9
|
+
#
|
|
10
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
11
|
+
|
|
12
|
+
# 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.
|
|
13
|
+
#################################################
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# from .xxx import *
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
#################################################
|
|
4
|
+
# HolAdo (Holistic Automation do)
|
|
5
|
+
#
|
|
6
|
+
# (C) Copyright 2021-2025 by Eric Klumpp
|
|
7
|
+
#
|
|
8
|
+
# 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:
|
|
9
|
+
#
|
|
10
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
11
|
+
|
|
12
|
+
# 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.
|
|
13
|
+
#################################################
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
from holado_test.scenario.step_tools import StepTools
|
|
17
|
+
from holado.common.context.session_context import SessionContext
|
|
18
|
+
from holado_test.behave.behave import * # @UnusedWildImport
|
|
19
|
+
import logging
|
|
20
|
+
from holado_docker.sdk.docker.container_logs import JsonDockerContainerLogsFormatter
|
|
21
|
+
|
|
22
|
+
logger = logging.getLogger(__name__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def __get_scenario_context():
|
|
26
|
+
return SessionContext.instance().get_scenario_context()
|
|
27
|
+
|
|
28
|
+
def __get_text_interpreter():
|
|
29
|
+
return __get_scenario_context().get_text_interpreter()
|
|
30
|
+
|
|
31
|
+
def __get_variable_manager():
|
|
32
|
+
return __get_scenario_context().get_variable_manager()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@Step(r"(?P<var_name>{Variable}) = logs of container (?P<container_name>{Str})(?: since (?P<since_str>{Str}))?")
|
|
36
|
+
def step_impl(context, var_name, container_name, since_str):
|
|
37
|
+
var_name = StepTools.evaluate_variable_name(var_name)
|
|
38
|
+
container_name = StepTools.evaluate_scenario_parameter(container_name)
|
|
39
|
+
since_str = StepTools.evaluate_scenario_parameter(since_str)
|
|
40
|
+
|
|
41
|
+
cont = SessionContext.instance().docker_client.get_container(container_name)
|
|
42
|
+
res = cont.get_logs(since=since_str, formatter=JsonDockerContainerLogsFormatter())
|
|
43
|
+
|
|
44
|
+
__get_variable_manager().register_variable(var_name, res)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|