holado 0.4.0__py3-none-any.whl → 0.4.2__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.
Potentially problematic release.
This version of holado might be problematic. Click here for more details.
- holado/common/handlers/object.py +6 -0
- {holado-0.4.0.dist-info → holado-0.4.2.dist-info}/METADATA +2 -1
- {holado-0.4.0.dist-info → holado-0.4.2.dist-info}/RECORD +46 -25
- holado_core/tools/abstracts/blocking_command_service.py +9 -1
- 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/tests/behave/steps/__init__.py +16 -0
- holado_django/tests/behave/steps/django_server_steps.py +83 -0
- holado_grpc/tests/behave/steps/private/api/grpc_steps.py +9 -9
- holado_logging/common/logging/log_config.py +4 -3
- holado_multitask/multitasking/multitask_manager.py +36 -10
- holado_python/standard_library/ssl/resources/certificates/tcpbin.crt +16 -16
- holado_python/standard_library/ssl/resources/certificates/tcpbin.key +26 -26
- holado_python/standard_library/ssl/ssl.py +5 -1
- holado_rest/api/rest/TODO.txt +1 -1
- holado_rest/api/rest/rest_client.py +9 -7
- holado_rest/tests/behave/steps/private/api/rest_steps.py +11 -13
- holado_swagger/swagger_hub/mockserver/mockserver_client.py +1 -1
- holado_system/system/command/command.py +31 -9
- holado_system/system/global_system.py +3 -3
- test_holado/environment.py +6 -4
- test_holado/features/NonReg/api/REST.feature +7 -2
- test_holado/features/NonReg/api/gRPC.feature +0 -6
- test_holado/initialize_holado.py +62 -0
- test_holado/logging.conf +4 -0
- test_holado/tools/django/api_rest/db.sqlite3 +0 -0
- {holado-0.4.0.dist-info → holado-0.4.2.dist-info}/WHEEL +0 -0
- {holado-0.4.0.dist-info → holado-0.4.2.dist-info}/licenses/LICENSE +0 -0
- /holado_helper/holado_module_template/{test → tests}/behave/steps/__init__.py +0 -0
- /holado_helper/holado_module_template/{test → tests}/behave/steps/private/__init__.py +0 -0
|
@@ -0,0 +1,110 @@
|
|
|
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.technical_exception import TechnicalException
|
|
15
|
+
import logging
|
|
16
|
+
from holado_core.common.tools.tools import Tools
|
|
17
|
+
import os
|
|
18
|
+
from holado_core.tools.abstracts.blocking_command_service import BlockingCommandService
|
|
19
|
+
from holado_system.system.command.command import CommandStates
|
|
20
|
+
from holado_core.common.handlers.wait import WaitFuncResultVerifying
|
|
21
|
+
from holado.common.handlers.object import DeleteableObject
|
|
22
|
+
|
|
23
|
+
logger = logging.getLogger(__name__)
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
import django # @UnusedImport
|
|
27
|
+
with_django = True
|
|
28
|
+
except Exception as exc:
|
|
29
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
30
|
+
logger.debug(f"DjangoServer is not available. Initialization failed on error: {exc}")
|
|
31
|
+
with_django = False
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class DjangoServer(DeleteableObject):
|
|
35
|
+
"""
|
|
36
|
+
Django server
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
@classmethod
|
|
40
|
+
def is_available(cls):
|
|
41
|
+
return with_django
|
|
42
|
+
|
|
43
|
+
def __init__(self, name, django_project_path, port=8000, runserver_args=None):
|
|
44
|
+
super().__init__(name)
|
|
45
|
+
|
|
46
|
+
self.__django_project_path = django_project_path
|
|
47
|
+
self.__runserver_port = port
|
|
48
|
+
self.__runserver_args = runserver_args
|
|
49
|
+
self.__project_command = None
|
|
50
|
+
|
|
51
|
+
if not os.path.exists(django_project_path):
|
|
52
|
+
raise TechnicalException(f"Django project doesn't exist (project path: '{django_project_path}')")
|
|
53
|
+
|
|
54
|
+
def _delete_object(self):
|
|
55
|
+
if self.__project_command is not None and self.__project_command.status == CommandStates.Running:
|
|
56
|
+
self.stop()
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def django_project_path(self):
|
|
60
|
+
return self.__django_project_path
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def runserver_port(self):
|
|
64
|
+
return self.__runserver_port
|
|
65
|
+
|
|
66
|
+
@property
|
|
67
|
+
def runserver_args(self):
|
|
68
|
+
return self.__runserver_args
|
|
69
|
+
|
|
70
|
+
def start(self):
|
|
71
|
+
self.__start_server_by_command()
|
|
72
|
+
|
|
73
|
+
def __start_server_by_command(self):
|
|
74
|
+
self.__project_command = self._new_project_command()
|
|
75
|
+
self.__project_command.start()
|
|
76
|
+
self._wait_until_server_is_reachable()
|
|
77
|
+
|
|
78
|
+
def _new_project_command(self):
|
|
79
|
+
manage_path = os.path.join(self.django_project_path, "manage.py")
|
|
80
|
+
cmd = f"python {manage_path} runserver {self.runserver_port}"
|
|
81
|
+
if self.runserver_args:
|
|
82
|
+
cmd += f" {self.runserver_args}"
|
|
83
|
+
|
|
84
|
+
res = BlockingCommandService(f"Command running Django server '{self.name}'", cmd)
|
|
85
|
+
res.auto_stop = True
|
|
86
|
+
|
|
87
|
+
return res
|
|
88
|
+
|
|
89
|
+
def _wait_until_server_is_reachable(self):
|
|
90
|
+
import requests
|
|
91
|
+
url = f"http://127.0.0.1:{self.runserver_port}"
|
|
92
|
+
redo = WaitFuncResultVerifying("server is reachable",
|
|
93
|
+
lambda: requests.get(url),
|
|
94
|
+
lambda result: result and result.status_code == 200 )
|
|
95
|
+
redo.ignoring(Exception)
|
|
96
|
+
redo.polling_every(0.01)
|
|
97
|
+
redo.execute()
|
|
98
|
+
|
|
99
|
+
def stop(self):
|
|
100
|
+
if self.__project_command is None or self.__project_command.status != CommandStates.Running:
|
|
101
|
+
raise TechnicalException(f"Django server of project '{self.name}' is not running (status: {self.__project_command.status if self.__project_command else 'Unkown'})")
|
|
102
|
+
self.__project_command.stop()
|
|
103
|
+
|
|
104
|
+
def join(self, timeout=None):
|
|
105
|
+
self.__project_command.join(timeout)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
@@ -0,0 +1,57 @@
|
|
|
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 os
|
|
16
|
+
from holado_core.tools.abstracts.blocking_command_service import BlockingCommandService
|
|
17
|
+
from holado_django.server.django_server import DjangoServer
|
|
18
|
+
from holado_core.common.handlers.wait import WaitFuncResultVerifying
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class GrpcDjangoServer(DjangoServer):
|
|
24
|
+
"""
|
|
25
|
+
gRPC Django server
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(self, name, django_project_path, runserver_args=None):
|
|
29
|
+
super().__init__(name, django_project_path, port=50051, runserver_args=runserver_args)
|
|
30
|
+
|
|
31
|
+
def _new_project_command(self):
|
|
32
|
+
manage_path = os.path.join(self.django_project_path, "manage.py")
|
|
33
|
+
cmd = f"python {manage_path} grpcrunserver"
|
|
34
|
+
if self.runserver_args:
|
|
35
|
+
cmd += f" {self.runserver_args}"
|
|
36
|
+
|
|
37
|
+
res = BlockingCommandService(f"Command running gRPC Django server '{self.name}'", cmd)
|
|
38
|
+
res.auto_stop = True
|
|
39
|
+
|
|
40
|
+
return res
|
|
41
|
+
|
|
42
|
+
def _wait_until_server_is_reachable(self):
|
|
43
|
+
import grpc_requests
|
|
44
|
+
|
|
45
|
+
endpoint = f"localhost:{self.runserver_port}"
|
|
46
|
+
def request_is_unimplemented():
|
|
47
|
+
try:
|
|
48
|
+
grpc_requests.Client.get_by_endpoint(endpoint)
|
|
49
|
+
except Exception as exc:
|
|
50
|
+
if "status = StatusCode.UNIMPLEMENTED" in str(exc):
|
|
51
|
+
return True
|
|
52
|
+
return False
|
|
53
|
+
redo = WaitFuncResultVerifying("server is reachable", request_is_unimplemented, lambda result: result )
|
|
54
|
+
redo.polling_every(0.01)
|
|
55
|
+
redo.execute()
|
|
56
|
+
|
|
57
|
+
|
|
@@ -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 .django_server_steps import *
|
|
@@ -0,0 +1,83 @@
|
|
|
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
|
+
from holado.common.context.session_context import SessionContext
|
|
16
|
+
from holado_test.behave.behave import * # @UnusedWildImport
|
|
17
|
+
import logging
|
|
18
|
+
from holado_test.scenario.step_tools import StepTools
|
|
19
|
+
from holado_django.server.django_server import DjangoServer
|
|
20
|
+
from holado_test.behave.scenario.behave_step_tools import BehaveStepTools
|
|
21
|
+
from holado_value.common.tables.converters.value_table_converter import ValueTableConverter
|
|
22
|
+
from holado_core.common.exceptions.technical_exception import TechnicalException
|
|
23
|
+
from holado_django.server.grpc_django_server import GrpcDjangoServer
|
|
24
|
+
|
|
25
|
+
logger = logging.getLogger(__name__)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def __get_session_context():
|
|
29
|
+
return SessionContext.instance()
|
|
30
|
+
|
|
31
|
+
def __get_scenario_context():
|
|
32
|
+
return __get_session_context().get_scenario_context()
|
|
33
|
+
|
|
34
|
+
def __get_text_interpreter():
|
|
35
|
+
return __get_scenario_context().get_text_interpreter()
|
|
36
|
+
|
|
37
|
+
def __get_variable_manager():
|
|
38
|
+
return __get_scenario_context().get_variable_manager()
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@Given(r"(?P<var_name>{Variable}) = new Django server")
|
|
43
|
+
def step_impl(context, var_name):
|
|
44
|
+
var_name = StepTools.evaluate_variable_name(var_name)
|
|
45
|
+
table = BehaveStepTools.get_step_table(context)
|
|
46
|
+
|
|
47
|
+
kwargs = ValueTableConverter.convert_name_value_table_2_json_object(table)
|
|
48
|
+
if 'django_project_path' not in kwargs:
|
|
49
|
+
raise TechnicalException("Parameter 'django_project_path' is required")
|
|
50
|
+
if 'name' not in kwargs:
|
|
51
|
+
kwargs['name'] = f"Django server ({kwargs['django_project_path']})"
|
|
52
|
+
|
|
53
|
+
server = DjangoServer(**kwargs)
|
|
54
|
+
|
|
55
|
+
__get_variable_manager().register_variable(var_name, server)
|
|
56
|
+
|
|
57
|
+
@Given(r"(?P<var_name>{Variable}) = new gRPC Django server")
|
|
58
|
+
def step_impl(context, var_name):
|
|
59
|
+
var_name = StepTools.evaluate_variable_name(var_name)
|
|
60
|
+
table = BehaveStepTools.get_step_table(context)
|
|
61
|
+
|
|
62
|
+
kwargs = ValueTableConverter.convert_name_value_table_2_json_object(table)
|
|
63
|
+
if 'django_project_path' not in kwargs:
|
|
64
|
+
raise TechnicalException("Parameter 'django_project_path' is required")
|
|
65
|
+
if 'name' not in kwargs:
|
|
66
|
+
kwargs['name'] = f"Django server ({kwargs['django_project_path']})"
|
|
67
|
+
|
|
68
|
+
server = GrpcDjangoServer(**kwargs)
|
|
69
|
+
|
|
70
|
+
__get_variable_manager().register_variable(var_name, server)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@Step(r"start \(Django server: (?P<var_server>{Variable})\)")
|
|
74
|
+
def step_impl(context, var_server):
|
|
75
|
+
server = StepTools.evaluate_variable_value(var_server)
|
|
76
|
+
server.start()
|
|
77
|
+
|
|
78
|
+
@Step(r"stop \(Django server: (?P<var_server>{Variable})\)")
|
|
79
|
+
def step_impl(context, var_server):
|
|
80
|
+
server = StepTools.evaluate_variable_value(var_server)
|
|
81
|
+
server.stop()
|
|
82
|
+
|
|
83
|
+
|
|
@@ -49,18 +49,18 @@ def step_impl(context, var_name):
|
|
|
49
49
|
var_name = StepTools.evaluate_variable_name(var_name)
|
|
50
50
|
|
|
51
51
|
here = os.path.abspath(os.path.dirname(__file__))
|
|
52
|
-
|
|
53
|
-
manage_path = os.path.join(api_grpc_path, "manage.py")
|
|
54
|
-
cmd = f"python {manage_path} grpcrunserver"
|
|
52
|
+
django_project_path = os.path.normpath(os.path.join(here, "..", "..", "..", "..", "..", "..", "..", "tests", "behave", "test_holado", "tools", "django", "api_grpc"))
|
|
55
53
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
54
|
+
execute_steps(u"""
|
|
55
|
+
Given {var_name} = new gRPC Django server
|
|
56
|
+
| Name | Value |
|
|
57
|
+
| 'name' | 'gRPC server for holado tests' |
|
|
58
|
+
| 'django_project_path' | '{django_project_path}' |
|
|
59
|
+
When start (Django server: {var_name})
|
|
60
|
+
""".format(var_name=var_name, django_project_path=django_project_path))
|
|
61
61
|
|
|
62
62
|
# Update imported grpc messages and services
|
|
63
|
-
proto_path = os.path.join(
|
|
63
|
+
proto_path = os.path.join(django_project_path, "api_grpc", "api1", "proto")
|
|
64
64
|
__get_session_context().protobuf_messages.import_all_compiled_proto(proto_path)
|
|
65
65
|
__get_session_context().grpc_services.import_all_compiled_proto(proto_path)
|
|
66
66
|
|
|
@@ -32,6 +32,10 @@ class LogConfig(object):
|
|
|
32
32
|
logging.warning(f"Logging was already configured, it is not possible to configure it twice. This new configuration is skipped.")
|
|
33
33
|
return
|
|
34
34
|
|
|
35
|
+
# Use holado loggers
|
|
36
|
+
if use_holado_logger:
|
|
37
|
+
cls.__set_holado_loggers()
|
|
38
|
+
|
|
35
39
|
# HolAdo needs at least to add logging level TRACE and PRINT
|
|
36
40
|
cls.add_logging_level_trace()
|
|
37
41
|
cls.add_logging_level_print()
|
|
@@ -58,9 +62,6 @@ class LogConfig(object):
|
|
|
58
62
|
log_in_file = True if log_in_file == "True" else False
|
|
59
63
|
cls.log_in_file = log_in_file
|
|
60
64
|
|
|
61
|
-
if use_holado_logger:
|
|
62
|
-
cls.__set_holado_loggers()
|
|
63
|
-
|
|
64
65
|
cls.__is_configured = True
|
|
65
66
|
|
|
66
67
|
@classmethod
|
|
@@ -22,6 +22,8 @@ from holado_core.common.tools.tools import Tools
|
|
|
22
22
|
from holado_python.standard_library.typing import Typing
|
|
23
23
|
from holado.common.handlers.undefined import default_context
|
|
24
24
|
from holado.common.context.session_context import SessionContext
|
|
25
|
+
import psutil
|
|
26
|
+
import signal
|
|
25
27
|
|
|
26
28
|
logger = logging.getLogger(__name__)
|
|
27
29
|
|
|
@@ -60,16 +62,40 @@ class MultitaskManager(object):
|
|
|
60
62
|
if pid is None:
|
|
61
63
|
return os.getppid()
|
|
62
64
|
else:
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
65
|
+
process = psutil.Process(pid)
|
|
66
|
+
return process.ppid()
|
|
67
|
+
|
|
68
|
+
@classmethod
|
|
69
|
+
def get_children_process_ids(cls, pid=None, recursive=False):
|
|
70
|
+
if pid is None:
|
|
71
|
+
pid = os.getpid()
|
|
72
|
+
|
|
73
|
+
process = psutil.Process(pid)
|
|
74
|
+
children = process.children(recursive=recursive)
|
|
75
|
+
return [c.pid for c in children]
|
|
76
|
+
|
|
77
|
+
@classmethod
|
|
78
|
+
def kill_process(cls, pid, sig=signal.SIGTERM, do_kill_children=True, recursively=True):
|
|
79
|
+
try:
|
|
80
|
+
process = psutil.Process(pid)
|
|
81
|
+
except psutil.NoSuchProcess:
|
|
82
|
+
return
|
|
83
|
+
|
|
84
|
+
# Kill children
|
|
85
|
+
if do_kill_children:
|
|
86
|
+
children = process.children(recursive=recursively)
|
|
87
|
+
for proc in children:
|
|
88
|
+
try:
|
|
89
|
+
proc.send_signal(sig)
|
|
90
|
+
except signal.SIGTERM:
|
|
91
|
+
pass
|
|
92
|
+
|
|
93
|
+
# Kill process
|
|
94
|
+
try:
|
|
95
|
+
process.send_signal(sig)
|
|
96
|
+
except signal.SIGTERM:
|
|
97
|
+
pass
|
|
98
|
+
|
|
73
99
|
@classmethod
|
|
74
100
|
def has_thread_native_id(cls):
|
|
75
101
|
from holado_multitask.multithreading.threadsmanager import ThreadsManager
|
|
@@ -2,20 +2,20 @@
|
|
|
2
2
|
MIIDZTCCAk2gAwIBAgIBKjANBgkqhkiG9w0BAQsFADCBizELMAkGA1UEBhMCVVMx
|
|
3
3
|
CzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ8wDQYDVQQKDAZ0
|
|
4
4
|
Y3BiaW4xDDAKBgNVBAsMA29wczETMBEGA1UEAwwKdGNwYmluLmNvbTEjMCEGCSqG
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
FOLuMowBSAZfV5v82LmlaIIOvU/
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
5
|
+
SIb3DQEJARYUaGFycnliYWdkaUBnbWFpbC5jb20wHhcNMjUwNzAxMTQyMDI3WhcN
|
|
6
|
+
MjUwNzAyMTQyMDI3WjAcMRowGAYDVQQDDBF0Y3BiaW4uY29tLWNsaWVudDCCASIw
|
|
7
|
+
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALmLkz54fCoSSM/uG945GvhavQF8
|
|
8
|
+
unsEDd0RuHWZPIBcrlEzhLLiiiegET4UFlywF4wSfbiNGgwr3Uw+6ph3xLrNs91B
|
|
9
|
+
EYqOGesT9wRPMlon88qsaVIFfbqfg4e1m0si+/NwZMk+5bBeYC0blXk7HiTZ5KJt
|
|
10
|
+
QNLeduIYaPSuyq+qxl/xDqWOifbKcgycitgCPKPxohtwa5h6IjU3WYb7+xNPt3cx
|
|
11
|
+
+hoCwfab1NgVBse6ZsUf81nkCEVKKLaNvlDkmXp9ItqZZay+0/yzLCgNyf8gDprU
|
|
12
|
+
8u+nDM+pcz83OtIQWVeN5MtFjkA4nik55yqdlqnB1OWzEzaMSMh6Vsy13xMCAwEA
|
|
13
|
+
AaNCMEAwHQYDVR0OBBYEFG5H5JaQhWehs8VRJu88HbHgK9CvMB8GA1UdIwQYMBaA
|
|
14
|
+
FOLuMowBSAZfV5v82LmlaIIOvU/DMA0GCSqGSIb3DQEBCwUAA4IBAQCs93UG22r0
|
|
15
|
+
ZIF10IAoXVbPWOeXpKJgWpsQYURsGw7sB+Cgr/vK3P1lkZVMl72LUzNazmOQldev
|
|
16
|
+
zUQ0TtOq24go1iAYWc7zYlxo9OHNkbAUDoViKP63K/CkXNCIkXg00vmEUco1PQWU
|
|
17
|
+
+OEaTNrQCeiW2eqYie9WNc4T5a7aUHT3Xno7G8KXTM7gtW35FNI/b0CwVWHRFzev
|
|
18
|
+
n9VhRI9xrNYxpDqqxYu7diIV4TQVmscmNicuEtDB98kJ7yOAhlpzQhIFi1vQEefD
|
|
19
|
+
4gZZ3ihlLd2XJWxiXZgeiz7dzva4oGcr9mU5Uohza3u/sjF34kx02+gNuv8x4Wil
|
|
20
|
+
CU9Rl0WFGJ00
|
|
21
21
|
-----END CERTIFICATE-----
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
-----BEGIN PRIVATE KEY-----
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
2
|
+
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC5i5M+eHwqEkjP
|
|
3
|
+
7hveORr4Wr0BfLp7BA3dEbh1mTyAXK5RM4Sy4oonoBE+FBZcsBeMEn24jRoMK91M
|
|
4
|
+
PuqYd8S6zbPdQRGKjhnrE/cETzJaJ/PKrGlSBX26n4OHtZtLIvvzcGTJPuWwXmAt
|
|
5
|
+
G5V5Ox4k2eSibUDS3nbiGGj0rsqvqsZf8Q6ljon2ynIMnIrYAjyj8aIbcGuYeiI1
|
|
6
|
+
N1mG+/sTT7d3MfoaAsH2m9TYFQbHumbFH/NZ5AhFSii2jb5Q5Jl6fSLamWWsvtP8
|
|
7
|
+
sywoDcn/IA6a1PLvpwzPqXM/NzrSEFlXjeTLRY5AOJ4pOecqnZapwdTlsxM2jEjI
|
|
8
|
+
elbMtd8TAgMBAAECggEAfLWcfSOcSObLO76NyppVT1IlsWc1K9O4wbrUYW5iZOBm
|
|
9
|
+
Zbub2GQ9eY6zqCb2NMxCt2oCSFXGiSG+dy3eniX5+5ig6PiAIsGKGB/uKl5UuJYb
|
|
10
|
+
3UBu9astK49lZ4Sf4Sudbq0/gKge16FHQWpF2BrtEtXFP4rxRAo0m5jOio8lOlYG
|
|
11
|
+
VSBFrkww7aS0pbymELj+Yg0twrUQjeG/hhoA4juiAq8T6oilrNfxhgc8pi2e23Ix
|
|
12
|
+
iokPjVWWAylKr6+oKhgBj/MKoIcEPeyYem1rBCesO2Th5CHy4YwIsZq+456Wo9/z
|
|
13
|
+
efxjnr+1vrsH+WK83nff3wUMruchKbdP1p9sMSkwqQKBgQD0y8b7sK4omV/JRdS3
|
|
14
|
+
sADYETu2wshP22EuUbkDPICe5/ct1LWlTJAI84MkMcg4rOHuLubD32ttRA3SWnK/
|
|
15
|
+
eqXB3gkcstVhipjj5qH5sg3gCIOa5rmePY1Zn5v75BImYzHYBfqQ0Z99czBNQ4un
|
|
16
|
+
MPMxe1IRT+b6aU7EOWjSWG2X/wKBgQDCCZGpv+pFQqxb5YjPQqDn/7M9wE89b22T
|
|
17
|
+
G2weESzoBrnLCUA4M0QEhhgBkcb9grZQ0aCOzjqKTDF/2AnFOhP6IIzEVxkrsC/0
|
|
18
|
+
c150lU8kiIlkymVF7N5vwayPFUeNqaO5NdHOYu0HkEQ8h9FCFurc0OjA/8xRPXkp
|
|
19
|
+
AGar8P/Y7QKBgE+5jjSqdg4C5Y9Hjt/EEoJMGoaLKXHYoO3U78x+B+W45memvwH2
|
|
20
|
+
zXIc3LkM/Yh3xZ0s6TshqHsNjvLTQkvaReG9znnqRFRgLysKEfagZqRwIWxxeEJx
|
|
21
|
+
CXgG42ZGASM/axxP1isUGj1hJnoDZZgt+QZEg5Xfz/n+EgkWKW1YH1lBAoGAMw7L
|
|
22
|
+
ioxae+Egc4oBpvAUYRfStXQOJc9VWPlFSOAiHefvKbMEeAVdZ4dVd8xBPWIQ0VFn
|
|
23
|
+
20v+8Xc9KzPQ1loC+bVo9R0qHWneJIfbGfhT+/wFk0UCwxSiL2waGQhzbJ5v24OC
|
|
24
|
+
8rjrQCtBGWBvuuFG6dX6+RYWUGZJpHVbjvD6kb0CgYAnU00V1AZu39ku1iozaHoY
|
|
25
|
+
STedxCDtGZotOISDFzaqIxaJ1JUeWZ/90ZMIVHdE+pP8n2P8MN7rppBbTN6Mxcbq
|
|
26
|
+
uE9BfZJGN5A8PuugoJWBJwkfnhrEMXXSpz5SPQntCkrET7pkAW2Nx1CWRQKaj1pu
|
|
27
|
+
+CKEVUIhv/elJOdMV9mGbA==
|
|
28
28
|
-----END PRIVATE KEY-----
|
|
@@ -90,7 +90,11 @@ class SslManager(object):
|
|
|
90
90
|
f"Note: step 'Given CACERTS_PATH = CA certs file path (from certifi package)' can be used to get the path to CA file coming with 'certifi' package that is supposed to be installed when using ssl module",
|
|
91
91
|
]
|
|
92
92
|
raise TechnicalException("\n".join(msg_list))
|
|
93
|
-
|
|
93
|
+
try:
|
|
94
|
+
logger.debug(f"Loaded CA certificates: {res.get_ca_certs()})")
|
|
95
|
+
except NotImplementedError:
|
|
96
|
+
# Depending on environment, get_ca_certs can be not implemented (ex: python 3.10 and pip v25.1.1)
|
|
97
|
+
pass
|
|
94
98
|
logger.debug(f"Loaded ciphers: {res.get_ciphers()})")
|
|
95
99
|
|
|
96
100
|
except Exception as exc:
|
holado_rest/api/rest/TODO.txt
CHANGED
|
@@ -66,15 +66,17 @@ class RestClient(object):
|
|
|
66
66
|
self.__kwargs.update(ssl_kwargs)
|
|
67
67
|
|
|
68
68
|
def response_result(self, response, status_ok=200):
|
|
69
|
-
if response.status_code != status_ok:
|
|
70
|
-
raise FunctionalException(f"[{self.name}] Request failed with status {response.status_code} (expected success status: {status_ok}")
|
|
71
|
-
|
|
72
69
|
if "application/json" in response.headers['Content-Type']:
|
|
73
|
-
|
|
70
|
+
res = response.json()
|
|
74
71
|
elif response.headers['Content-Type'].startswith('text'):
|
|
75
|
-
|
|
72
|
+
res = response.text
|
|
76
73
|
else:
|
|
77
|
-
|
|
74
|
+
res = response.content
|
|
75
|
+
|
|
76
|
+
if response.status_code != status_ok:
|
|
77
|
+
raise FunctionalException(f"[{self.name}] Request failed with status {response.status_code} (expected success status: {status_ok}) on error: {res}")
|
|
78
|
+
|
|
79
|
+
return res
|
|
78
80
|
|
|
79
81
|
def request(self, method, path, **kwargs):
|
|
80
82
|
url = self.__build_url(path=path)
|
|
@@ -117,7 +119,7 @@ class RestClient(object):
|
|
|
117
119
|
# Ensure data is in json string format
|
|
118
120
|
if 'data' in request_kwargs:
|
|
119
121
|
data = request_kwargs.pop('data')
|
|
120
|
-
if not isinstance(data, str):
|
|
122
|
+
if data is not None and not isinstance(data, str):
|
|
121
123
|
data = json.dumps(data)
|
|
122
124
|
res['data'] = data
|
|
123
125
|
|
|
@@ -17,6 +17,7 @@ from holado_test.behave.behave import * # @UnusedWildImport
|
|
|
17
17
|
import os.path
|
|
18
18
|
import logging
|
|
19
19
|
from holado_test.scenario.step_tools import StepTools
|
|
20
|
+
from holado_django.server.django_server import DjangoServer
|
|
20
21
|
|
|
21
22
|
logger = logging.getLogger(__name__)
|
|
22
23
|
|
|
@@ -40,22 +41,19 @@ def step_impl(context, var_name):
|
|
|
40
41
|
var_name = StepTools.evaluate_variable_name(var_name)
|
|
41
42
|
|
|
42
43
|
here = os.path.abspath(os.path.dirname(__file__))
|
|
43
|
-
|
|
44
|
-
cmd = f"python {manage_path} runserver"
|
|
44
|
+
django_project_path = os.path.normpath(os.path.join(here, "..", "..", "..", "..", "..", "..", "..", "tests", "behave", "test_holado", "tools", "django", "api_rest"))
|
|
45
45
|
|
|
46
46
|
execute_steps(u"""
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
When wait 5 seconds
|
|
55
|
-
Then command {var_name} has status Running
|
|
56
|
-
""".format(cmd=cmd, var_name=var_name))
|
|
57
|
-
|
|
47
|
+
Given {var_name} = new Django server
|
|
48
|
+
| Name | Value |
|
|
49
|
+
| 'name' | 'REST server for holado tests' |
|
|
50
|
+
| 'django_project_path' | '{django_project_path}' |
|
|
51
|
+
| 'port' | 8000 |
|
|
52
|
+
When start (Django server: {var_name})
|
|
53
|
+
""".format(var_name=var_name, django_project_path=django_project_path))
|
|
58
54
|
|
|
55
|
+
|
|
56
|
+
|
|
59
57
|
@Given(r"(?P<var_name>{Variable}) = new internal REST client")
|
|
60
58
|
def step_impl(context, var_name):
|
|
61
59
|
var_name = StepTools.evaluate_variable_name(var_name)
|
|
@@ -45,7 +45,7 @@ class MockServerClient(RestClient):
|
|
|
45
45
|
params['format'] = format_
|
|
46
46
|
|
|
47
47
|
result = self.put('/mockserver/retrieve', params=params)
|
|
48
|
-
res =
|
|
48
|
+
res = self.response_result(result)
|
|
49
49
|
|
|
50
50
|
if since_datetime is not None:
|
|
51
51
|
if not isinstance(since_datetime, datetime.datetime):
|