holado 0.8.1__py3-none-any.whl → 0.8.3__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.

@@ -39,12 +39,12 @@ not_applicable = Undefined("Not Applicable", 2)
39
39
  to_be_defined = Undefined("To be defined", 3) # Usage: initial variable value defining it is to be defined. It is useful when undefined_value can be a possible value.
40
40
 
41
41
 
42
-
43
42
  # Define specific default values
44
43
  # Note: Real value is defined by methods managing these values as argument.
45
44
 
46
- default_value = Undefined("Default value", 10)
47
- default_context = Undefined("Default context", 11) # Example of real value: for ThreadsManager it means "current ScenarioContext" if a scenario context exists else "SessionContext".
45
+ default = Undefined("Default", 10)
46
+ default_value = Undefined("Default value", 11)
47
+ default_context = Undefined("Default context", 12) # Example of real value: for ThreadsManager it means "current ScenarioContext" if a scenario context exists else "SessionContext".
48
48
 
49
49
 
50
50
  # Define symbolic values
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: holado
3
- Version: 0.8.1
3
+ Version: 0.8.3
4
4
  Summary: HolAdo framework
5
5
  Project-URL: Homepage, https://gitlab.com/holado_framework/python
6
6
  Project-URL: Issues, https://gitlab.com/holado_framework/python/-/issues
@@ -8,7 +8,7 @@ holado/common/context/session_context.py,sha256=pNiJlyLsIiwdBCUb3aMQmTJB7ZnO0NsD
8
8
  holado/common/handlers/__init__.py,sha256=d0KDUpaAAw1eBXyX08gaRh4RECnJlXjYQ0TcU-Ndicc,1372
9
9
  holado/common/handlers/enums.py,sha256=ieqKVoukEiNyfE3KrKmMOImdbFS1ocUMud8JHe2xNLs,1662
10
10
  holado/common/handlers/object.py,sha256=rDaav8zHTYfKVEaLtEdeXMxYXATGVcs2a7um1f5MvCs,7205
11
- holado/common/handlers/undefined.py,sha256=yXZRPIDZI8R0vT4kdf87JPkFhnltLcQwwc3zmKhmv30,2529
11
+ holado/common/handlers/undefined.py,sha256=IzWu2HA8P7eaSEbJvdbZZ89ce-EGjb4Q_LgMA9Y1M0s,2563
12
12
  holado/common/tools/__init__.py,sha256=z-T6zX_tOVkJjniTDA0KSKmdtosjfEhjaNa1-3g8wTs,1374
13
13
  holado/common/tools/gc_manager.py,sha256=TjQg7MisGRhxuiQ22hB3IuqNhnWCVEWpU253-rOjR0w,7611
14
14
  holado_ais/__init__.py,sha256=Mudcgu_7p1hBDBs6LpSz757H4haB0yLHgT70sznG82c,1807
@@ -194,7 +194,7 @@ holado_docker/sdk/docker/docker_service.py,sha256=SvMSIZ7XTCbC7q5rur03lJhJVSHL3u
194
194
  holado_docker/tests/behave/steps/__init__.py,sha256=lrP0btKLA3qQD2wp3zbOp0ug8RmgpaYWCrOAWehcPiI,1298
195
195
  holado_docker/tests/behave/steps/tools/docker_controller/client_steps.py,sha256=Y26ZstOZrI3uVX6MGBQr88jjDEsCsNuik0ZBmpT5kDg,4800
196
196
  holado_docker/tools/docker_controller/docker_controller_manager.py,sha256=q3oac2KIK9wGfMQqGIol65nHUmeuuV0rQ61tfH2APAk,2477
197
- holado_docker/tools/docker_controller/client/rest/docker_controller_client.py,sha256=TP3GBgtZusl9y6mNd8rFsOoF9K7u_M8mLFq3ZTsCHUM,4316
197
+ holado_docker/tools/docker_controller/client/rest/docker_controller_client.py,sha256=FRJ30e7WMFK9jmAMERJUwSkrfMYLS0pkH9qgrHJqa40,4519
198
198
  holado_docker/tools/docker_controller/server/Dockerfile,sha256=zuSkj3HYDhvpjOSXmxL4oDqhN7dRB1YTX5Fyur1cuDY,1774
199
199
  holado_docker/tools/docker_controller/server/requirements.txt,sha256=0RvLV3t2DyBR2FsbAd1WVEcbsVc6FVUN2horQJU4POo,57
200
200
  holado_docker/tools/docker_controller/server/run_docker_controller_in_docker.sh,sha256=Q56P8VA895I29kVSaSa2FpzvjxJUwLVZ9-7vjScXfc0,3406
@@ -207,7 +207,7 @@ holado_docker/tools/docker_controller/server/rest/initialize_holado.py,sha256=Ux
207
207
  holado_docker/tools/docker_controller/server/rest/openapi.yaml,sha256=HUD7CHasVGjpd6yW9mU0sWOKs4tuG_VSoefa7NuQWFI,6773
208
208
  holado_docker/tools/docker_controller/server/rest/run.py,sha256=8w5Xl7uOnjsYW59cmuUMOUd71fcXQn30k2jVis7cVNs,1748
209
209
  holado_docker/tools/docker_controller/server/rest/api/__init__.py,sha256=FlLRagAiw1LDxnF0CmW7Y6bVXuj8x6volT8-DuHTTVY,2427
210
- holado_docker/tools/docker_controller/server/rest/api/config.py,sha256=pe76IMkdNoljRsDRyhZW6BwkSSu6LsvnSEGqgd8_Ro4,2459
210
+ holado_docker/tools/docker_controller/server/rest/api/config.py,sha256=Ln__1bsigSzJZ-Iy3MQgmiZMnpBxC3TCQE0O72g5cAs,2459
211
211
  holado_docker/tools/docker_controller/server/rest/api/container.py,sha256=6D612WF4chpDCzr4MBzZXzELxi-yOwrgxCxSBBVMcVo,2673
212
212
  holado_docker/tools/docker_controller/server/rest/api/os.py,sha256=ZdAbx_ZzwMaqHseOWWSf9ZPL_CEdRa2RvEXGvkk5c1o,1830
213
213
  holado_docker/tools/docker_viewer/docker_viewer_manager.py,sha256=tSLuIUdYjJoZIFUc1k4WnrRTUtjjTAmNTbrDmS-8SjI,2287
@@ -300,7 +300,7 @@ holado_keycloak/tests/behave/steps/tools/keycloak_client_steps.py,sha256=Dc1xB3q
300
300
  holado_keycloak/tools/keycloak/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
301
301
  holado_keycloak/tools/keycloak/keycloak_client.py,sha256=QXAsf9rF0pKq1dHhXeZFZOxuEg_1uzp6vqXnwWDnegg,4019
302
302
  holado_logging/__init__.py,sha256=EMmwm_jHe739gftVCmf6lb_dT20IVseVg0bbGGADn8w,2176
303
- holado_logging/common/logging/holado_logger.py,sha256=PuHy9ne96MhO1f_YFQn9wUJvQrys7kuUoUUWF74hDz4,3083
303
+ holado_logging/common/logging/holado_logger.py,sha256=FB5J_YbG41FGljAywMdCPVFJ2BdpMBS8AWPsT9B52S8,3160
304
304
  holado_logging/common/logging/log_config.py,sha256=DdYEW-2YSZ6QZDZCeVn_IZOKQlwWvqi2NWEbPhvExxw,6578
305
305
  holado_logging/common/logging/log_manager.py,sha256=gq92IAfnKEX-GKUHexNVgEI0UUrUdiWaC5GLcSTAaUE,13604
306
306
  holado_multitask/__init__.py,sha256=EwuwiBmp8ICbPZ8CKPju8tHRTh2rG68PB_wGXczY9rw,2143
@@ -409,14 +409,14 @@ holado_report/report/reports/feature_report.py,sha256=i0wpk3LQLArVjWDsP9UcNSJzAU
409
409
  holado_report/report/reports/scenario_report.py,sha256=eMyqw9EzaKMmX3pGFJN1rqAOQ5eqO2ISZdxAfK3XQR4,2945
410
410
  holado_rest/__init__.py,sha256=BOeE6t6ejeqRYd44SE4vYJVTNz01BwcVCIWfwRQ5axg,1526
411
411
  holado_rest/api/rest/TODO.txt,sha256=Oz8BYPkBEs9OAEgyYLLm7i5tJ1bRE5POBpT3SRFWTi4,29
412
- holado_rest/api/rest/rest_client.py,sha256=SHJCXOUs1lUuMrBmQrTyLa6gsOwklmaCPF1WfYrzKqk,8022
412
+ holado_rest/api/rest/rest_client.py,sha256=jC9fFz5rsiiCSa-pnUs6uOhprGYUX0wH_iiq649S25M,9549
413
413
  holado_rest/api/rest/rest_manager.py,sha256=XldPjNgj73GlzAmlsEcQYaHiDRk7SGU6VEFOLBnHjQM,4010
414
414
  holado_rest/tests/behave/steps/__init__.py,sha256=lEH5NYkKtpgDV2ZAO1qAGNN4ipwILWMpgvQgnamgYKk,1283
415
415
  holado_rest/tests/behave/steps/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
416
416
  holado_rest/tests/behave/steps/api/rest_client_steps.py,sha256=naN0YcRVQyM--RhV0jPhnlsjZS6luijwGvVC5lM0XCY,9749
417
417
  holado_rest/tests/behave/steps/private/__init__.py,sha256=TGsd7qLZpPQRxphFzgepFa22NhHSoZgxAWSIqwvA4L8,1276
418
418
  holado_rest/tests/behave/steps/private/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
419
- holado_rest/tests/behave/steps/private/api/rest_steps.py,sha256=acQ2K676fB7tHycwYmCPzL7E8JcQkit_aBhNggZZVgw,3264
419
+ holado_rest/tests/behave/steps/private/api/rest_steps.py,sha256=RpaGaMjOcqMJKrCx0Fp5Ks_e89GGpLaxaBbJmZ0jChk,3674
420
420
  holado_s3/__init__.py,sha256=Gl285tg-QaPE-3etWwZql9sH26G7EnVoQn97B0NMvOI,1248
421
421
  holado_s3/tests/behave/steps/__init__.py,sha256=q64qGCCey5QivEezEXq9LjABSBnjavTpq03PpaMSLkY,1320
422
422
  holado_s3/tests/behave/steps/private/__init__.py,sha256=JmVFxoOewwdE3uAgX4u2Y3tLWL_GdYW3h2ZawNdpn38,1276
@@ -475,15 +475,15 @@ holado_swagger/swagger_hub/mockserver/mockserver_client.py,sha256=L7P8aNi5Zuh2xR
475
475
  holado_swagger/swagger_hub/mockserver/mockserver_manager.py,sha256=eN843He06PLrEvT6M6UoT4xX_4Ks9GEd_3i-xJrGblw,1631
476
476
  holado_swagger/tests/behave/steps/__init__.py,sha256=joCT_nKaotXBBMNTXxOBcmr98gjmjDkY1Zbu5lCL8B4,1290
477
477
  holado_swagger/tests/behave/steps/swagger_hub/mockserver_steps.py,sha256=_M5WyF35qBjvDnXbohhMA9kV3D1H1aRnTBQ1iOtmxHA,3749
478
- holado_system/system/global_system.py,sha256=ZuC7Hbs3EMm2QQ6CRLYKMOS7ACcpi1N9vRuDhQT2jS8,8253
478
+ holado_system/system/global_system.py,sha256=ImNNXim2fvpcj4Wf-iLgCwWuCW6WQlNL7IrtDBUimk8,8253
479
479
  holado_system/system/command/command.py,sha256=9lv9kgvvIq4Fqx6fJXU_HQA8pCO80Ws9rpd2FwzAn0I,9053
480
480
  holado_system/system/command/command_result.py,sha256=sunGDegNVOtpK9s9r4HCAJlREu4iKS0w3HY4KKDEQkw,4613
481
481
  holado_system/system/command/curl_command.py,sha256=CEMaO0_qLyKe4tLytMlHzmCuS_gi-oU479hwOaEyZ60,3743
482
482
  holado_system/system/command/exceptions.py,sha256=InT6t8GVeGCiBE-NpRr4NzycWVAvzmc6WpM6mk7_1yk,2363
483
- holado_system/system/filesystem/file.py,sha256=Y5uq2n-ttimdRvLh3QQjpECoOSUzcj9DesuT2HerYuk,2840
483
+ holado_system/system/filesystem/file.py,sha256=stIFMNPeJuQNYlrm-wQPdwnRP8SgLoah7hkjz0hvx5g,4084
484
484
  holado_system/tests/behave/steps/__init__.py,sha256=7LrCSTHk5oHNuEsr4IhJuNDsohtR2cq3YT1owXrhdjc,1351
485
485
  holado_system/tests/behave/steps/system/commands_steps.py,sha256=uYiojPpYPkfif8l8afRrJ0sj-wFBE4j1x67BDMNs76Q,3901
486
- holado_system/tests/behave/steps/system/file_steps.py,sha256=kJ7qEzaKkzErRpWCWmq1mJhqO3kHlMa-u5RmsG4664g,10388
486
+ holado_system/tests/behave/steps/system/file_steps.py,sha256=-RPUGEjsYfzWIMRDiQRalmvspPZIPP8YMzSZvSI4-p8,9966
487
487
  holado_system/tests/behave/steps/system/system_steps.py,sha256=2XrZwuAaYDjB_HvPgxZq9MpYB_Zo7FVZ0DYcmtKht2s,3778
488
488
  holado_test/__init__.py,sha256=A0edMOLhnuU-A_NazQ50WghvKvB889KNCBddtBPa9Ag,1539
489
489
  holado_test/test_config.py,sha256=yQK2jNHEGltGc3fmsAgcsKN4y3_nuldZHD45XEMrsQA,1575
@@ -529,7 +529,7 @@ holado_yaml/__init__.py,sha256=KpbIi2cm1BYZgoWf0LuhE0ei3ZCE15UcUtjC1cSA55M,1653
529
529
  holado_yaml/tests/behave/steps/__init__.py,sha256=mXzHzGy9gkIDjYXdlxQ6BzaT4AfithgRmL_1sMxr63g,1272
530
530
  holado_yaml/tests/behave/steps/yaml_steps.py,sha256=cxNgDywCopT_RCeqKiWfcJYyKZM3mlc39bAtGm2rgfc,8531
531
531
  holado_yaml/yaml/enums.py,sha256=WD7mM_VhXtv8l0n08s6CSe7k2RUZDf_70mNCFsjjo94,1625
532
- holado_yaml/yaml/yaml_client.py,sha256=I7Xkhk0KIBVucEBNzTN2vWNOjuSQ-7W_D8ZiPHl1M7k,9042
532
+ holado_yaml/yaml/yaml_client.py,sha256=sg0UEBD33MqiY-8CxlZT4mT_blkp5Z926vvQjkhiNFA,9288
533
533
  holado_yaml/yaml/yaml_manager.py,sha256=iAg-WyXgHeIq_7WzYiVYE8G19Mcalqie8cD3_eyxogg,4363
534
534
  holado_yaml/yaml/pyyaml/pyyaml_client.py,sha256=yZrx42Y3fGt6psBsLXTzMTWH30oiOfzsm5dVPkpJjQE,3086
535
535
  holado_yaml/yaml/ruamel/ruamel_yaml_client.py,sha256=i4fJi-gbKJMfUPd3KfJPFaF7ZP6shMNfCPu8NPhAJVg,3201
@@ -655,7 +655,7 @@ test_holado/tools/django/api_rest/api_rest/api1/serializers.py,sha256=o_YxFr-tgC
655
655
  test_holado/tools/django/api_rest/api_rest/api1/tests.py,sha256=mrbGGRNg5jwbTJtWWa7zSKdDyeB4vmgZCRc2nk6VY-g,60
656
656
  test_holado/tools/django/api_rest/api_rest/api1/views.py,sha256=kOt2xT6bxO47_z__5yYR9kcYIWWv4qYzpX0K8Tqonik,758
657
657
  test_holado/tools/django/api_rest/api_rest/api1/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
658
- holado-0.8.1.dist-info/METADATA,sha256=96tNajEz2ibDQX0118wv3VNay6ndeo-YNIOGQvMo2bI,7671
659
- holado-0.8.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
660
- holado-0.8.1.dist-info/licenses/LICENSE,sha256=IgGmNlcFHnbp7UWrLJqAFvs_HIgjJDTmjCNRircJLsk,1070
661
- holado-0.8.1.dist-info/RECORD,,
658
+ holado-0.8.3.dist-info/METADATA,sha256=vtZF0ROL3qKomaWJjJAw2hWppZBqg5i9JwwFd-XuMh8,7671
659
+ holado-0.8.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
660
+ holado-0.8.3.dist-info/licenses/LICENSE,sha256=IgGmNlcFHnbp7UWrLJqAFvs_HIgjJDTmjCNRircJLsk,1070
661
+ holado-0.8.3.dist-info/RECORD,,
@@ -13,6 +13,7 @@
13
13
 
14
14
  import logging
15
15
  from holado_rest.api.rest.rest_client import RestClient
16
+ from holado.common.handlers.undefined import default_value
16
17
 
17
18
  logger = logging.getLogger(__name__)
18
19
 
@@ -26,12 +27,12 @@ class DockerControllerClient(RestClient):
26
27
 
27
28
  def get_environment_variable_value(self, var_name):
28
29
  data = [var_name]
29
- response = self.get(f"os/env", data=data)
30
+ response = self.get(f"os/env", json=data)
30
31
  return self.response_result(response, status_ok=[200])
31
32
 
32
33
  def get_directory_filenames(self, path):
33
34
  data = {'path':path}
34
- response = self.get(f"os/ls", data=data)
35
+ response = self.get(f"os/ls", json=data)
35
36
  return self.response_result(response, status_ok=[200])
36
37
 
37
38
 
@@ -45,11 +46,14 @@ class DockerControllerClient(RestClient):
45
46
  return self.response_result(response, status_ok=[200,204])
46
47
 
47
48
  def get_container_info(self, name, all_=False):
49
+ """Get container info
50
+ @return container info if found, else None
51
+ """
48
52
  if all_:
49
53
  response = self.get(f"container/{name}?all=true")
50
54
  else:
51
55
  response = self.get(f"container/{name}")
52
- return self.response_result(response, status_ok=[200,204])
56
+ return self.response_result(response, status_ok=[200,204], result_on_statuses={204:None, default_value:None})
53
57
 
54
58
  def restart_container(self, name, start_if_gone=False):
55
59
  response = self.put(f"container/{name}/restart")
@@ -86,7 +90,7 @@ class DockerControllerClient(RestClient):
86
90
  'with_backup': with_backup,
87
91
  'backup_extension': backup_extension
88
92
  }
89
- response = self.patch(f"config/yaml_file", data=data)
93
+ response = self.patch(f"config/yaml_file", json=data)
90
94
  return self.response_result(response, status_ok=[200,204])
91
95
 
92
96
  def restore_yaml_file(self, file_path, backup_extension='.ha_bak'):
@@ -95,7 +99,7 @@ class DockerControllerClient(RestClient):
95
99
  'file_path': file_path,
96
100
  'backup_extension': backup_extension
97
101
  }
98
- response = self.put(f"config/yaml_file", data=data)
102
+ response = self.put(f"config/yaml_file", json=data)
99
103
  return self.response_result(response, status_ok=[200,204])
100
104
 
101
105
 
@@ -18,7 +18,7 @@ def _get_session_context():
18
18
  return SessionContext.instance()
19
19
 
20
20
 
21
- class YamlfileView(MethodView):
21
+ class YamlFileView(MethodView):
22
22
 
23
23
  def get(self, body: dict):
24
24
  file_path = body['file_path']
@@ -12,6 +12,7 @@
12
12
  #################################################
13
13
 
14
14
  import logging
15
+ from holado.common.handlers.undefined import default_value
15
16
 
16
17
  logger = logging.getLogger(__name__)
17
18
 
@@ -22,7 +23,7 @@ class HALogger(logging.Logger):
22
23
  def __init__(self, name, level=logging.NOTSET):
23
24
  super().__init__(name, level)
24
25
 
25
- def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False, stacklevel=1, msg_size_limit=None):
26
+ def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False, stacklevel=1, msg_size_limit=default_value):
26
27
  # def find_handlers(logger_):
27
28
  # index = 0
28
29
  # while len(logger_.handlers) == 0:
@@ -41,7 +42,7 @@ class HALogger(logging.Logger):
41
42
  else:
42
43
  raise exc
43
44
 
44
- if msg_size_limit is None:
45
+ if msg_size_limit is default_value:
45
46
  msg_size_limit = HALogger.default_message_size_limit
46
47
  msg_to_log = Tools.truncate_text(msg, msg_size_limit)
47
48
 
@@ -20,6 +20,7 @@ from holado_core.common.tools.converters.converter import Converter
20
20
  from holado_json.ipc.json_converter import JsonConverter
21
21
  from holado.common.handlers.object import Object
22
22
  from holado.holado_config import Config
23
+ from holado.common.handlers.undefined import to_be_defined, default
23
24
 
24
25
  logger = logging.getLogger(__name__)
25
26
 
@@ -38,6 +39,11 @@ class RestClient(Object):
38
39
  REST client
39
40
  """
40
41
 
42
+ default_result_on_statuses = {
43
+ # 204 == "No Content" => result is None
44
+ 204: None
45
+ }
46
+
41
47
  @classmethod
42
48
  def is_available(cls):
43
49
  return with_requests
@@ -82,12 +88,34 @@ class RestClient(Object):
82
88
  res += "&".join([f"{k}={v}" for k,v in parameters.items()])
83
89
  return res
84
90
 
85
- def response_result(self, response, status_ok=200):
86
- # Get result
87
- if response.status_code == 204:
88
- # 204 == "No Content" => return None
89
- res = None
90
- else:
91
+ def response_result(self, response, status_ok=200, result_on_statuses=default_result_on_statuses):
92
+ """Return the result of the request associated to given response
93
+ @param response Response of the request
94
+ @param status_ok The status code, or a list of status codes, for which the request is considered in success
95
+ @param result_on_statuses A dictionary with defined result associated to a status
96
+ Notes:
97
+ - If response status is not status_ok (or in status_ok if it is a list), an exception is raised telling request has failed
98
+ - result_on_statuses is by default RestClient.default_result_on_statuses (={204: None})
99
+ - When holado.common.handlers.undefined.default is in result_on_statuses as status, the associated result is returned in any other case and no failing exception is raised
100
+ """
101
+ res = to_be_defined
102
+ is_res_default = False
103
+ is_ok = isinstance(status_ok, list) and response.status_code in status_ok or response.status_code == status_ok
104
+
105
+ # Find a result associated to response status
106
+ if result_on_statuses is not None:
107
+ for status, status_result in result_on_statuses.items():
108
+ if response.status_code == status:
109
+ res = status_result
110
+ break
111
+ elif status is default and not is_ok:
112
+ res = status_result
113
+ is_res_default = True
114
+ break
115
+
116
+
117
+ # If result is not defined, get it from response
118
+ if res is to_be_defined:
91
119
  if "application/json" in response.headers['Content-Type'] and len(response.content) > 0:
92
120
  res = response.json()
93
121
  elif response.headers['Content-Type'].startswith('text'):
@@ -96,8 +124,7 @@ class RestClient(Object):
96
124
  res = response.content
97
125
 
98
126
  # Verify status
99
- is_ok = isinstance(status_ok, list) and response.status_code in status_ok or response.status_code == status_ok
100
- if not is_ok:
127
+ if not is_ok and not is_res_default:
101
128
  raise FunctionalException(f"[{self.name}] Request failed with status {response.status_code} (expected success status: {status_ok}) on error: {res}")
102
129
 
103
130
  return res
@@ -115,7 +142,7 @@ class RestClient(Object):
115
142
  raise TechnicalException(f"[{self.name}] Failed to process {method} '{url}' with arguments {r_kwargs}") from exc
116
143
 
117
144
  if Tools.do_log(logger, logging.TRACE): # @UndefinedVariable
118
- logger.trace(f"[{self.name}] {method} on url '{url}' => {Tools.represent_object(res, 4)}")
145
+ logger.trace(f"[{self.name}] {method} on url '{url}' => {Tools.represent_object(res, 4)}", msg_size_limit=None)
119
146
  elif Tools.do_log(logger, self.request_log_level):
120
147
  logger.log(self.request_log_level, f"[{self.name}] {method} on url '{url}' => {Tools.represent_object(res, 4, max_level=1)}")
121
148
  return res
@@ -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_system.system.global_system import GlobalSystem
20
21
 
21
22
  logger = logging.getLogger(__name__)
22
23
 
@@ -42,26 +43,33 @@ def step_impl(context, var_name):
42
43
  here = os.path.abspath(os.path.dirname(__file__))
43
44
  django_project_path = os.path.normpath(os.path.join(here, "..", "..", "..", "..", "..", "..", "..", "tests", "behave", "test_holado", "tools", "django", "api_rest"))
44
45
 
46
+ if 8000 in GlobalSystem.get_used_ports():
47
+ port = GlobalSystem.get_first_available_anonymous_port()
48
+ else:
49
+ port = 8000
50
+ __get_variable_manager().register_variable("__INTERNAL_REST_SERVER_PORT__", port)
51
+
45
52
  execute_steps(u"""
46
53
  Given {var_name} = new Django server
47
54
  | Name | Value |
48
55
  | 'name' | 'REST server for holado tests' |
49
56
  | 'django_project_path' | '{django_project_path}' |
50
- | 'port' | 8000 |
57
+ | 'port' | {port} |
51
58
  When start (Django server: {var_name})
52
- """.format(var_name=var_name, django_project_path=django_project_path))
59
+ """.format(var_name=var_name, django_project_path=django_project_path, port=port))
53
60
 
54
61
 
55
62
 
56
63
  @Given(r"(?P<var_name>{Variable}) = new internal REST client")
57
64
  def step_impl(context, var_name):
58
65
  var_name = StepTools.evaluate_variable_name(var_name)
66
+ port = __get_variable_manager().get_variable_value("__INTERNAL_REST_SERVER_PORT__")
59
67
  execute_steps(u"""
60
68
  Given {var_name} = new REST client
61
- | Name | Value |
62
- | 'url' | 'http://localhost:8000' |
63
- | 'headers.Content-Type' | 'application/json' |
64
- | 'authentication.user' | ('admin', 'admin') |
65
- """.format(var_name=var_name))
69
+ | Name | Value |
70
+ | 'url' | 'http://localhost:{port}' |
71
+ | 'headers.Content-Type' | 'application/json' |
72
+ | 'authentication.user' | ('admin', 'admin') |
73
+ """.format(var_name=var_name, port=port))
66
74
 
67
75
 
@@ -14,6 +14,8 @@
14
14
  from holado.common.handlers.object import DeleteableObject
15
15
  import os
16
16
  from typing import AnyStr, List
17
+ from holado_python.standard_library.typing import Typing
18
+ from holado_core.common.exceptions.technical_exception import TechnicalException
17
19
 
18
20
 
19
21
  class File(DeleteableObject):
@@ -33,7 +35,15 @@ class File(DeleteableObject):
33
35
 
34
36
  def _delete_object(self):
35
37
  self.close()
36
-
38
+
39
+ def __enter__(self):
40
+ if self.__file is None:
41
+ self.open()
42
+ return self
43
+
44
+ def __exit__(self, exc_type, exc_val, exc_tb):
45
+ self.close()
46
+
37
47
  @property
38
48
  def path(self):
39
49
  return self.__path
@@ -74,3 +84,36 @@ class File(DeleteableObject):
74
84
  def readlines(self, hint: int = -1) -> List[AnyStr]:
75
85
  return self.internal_file.readlines(hint)
76
86
 
87
+
88
+
89
+ @classmethod
90
+ def get_file_content(cls, path, is_text_file=True):
91
+ mode = 'rt' if is_text_file else 'rb'
92
+ with File(path, mode=mode) as file:
93
+ res = file.read()
94
+ return res
95
+
96
+ @classmethod
97
+ def get_file_content_in_base64(cls, path):
98
+ import base64
99
+
100
+ with File(path, mode="rb") as fin:
101
+ content = fin.read()
102
+ res = base64.b64encode(content)
103
+
104
+ return res
105
+
106
+ @classmethod
107
+ def create_file_with_content(cls, path, content):
108
+ if isinstance(content, str):
109
+ with File(path, mode='wt') as fout:
110
+ fout.write(content)
111
+ elif isinstance(content, bytes):
112
+ with File(path, mode='wb') as fout:
113
+ fout.write(content)
114
+ else:
115
+ raise TechnicalException(f"Unexpected content type {Typing.get_object_class_fullname(content)} (allowed types: str, bytes)")
116
+
117
+
118
+
119
+
@@ -171,7 +171,7 @@ class GlobalSystem(object):
171
171
  if cls.get_os_type() == OSTypes.Linux:
172
172
  cmd = "netstat -tunlep | grep LISTEN | awk '{print $4}' | awk '{gsub(\".*:\",\"\");print}'"
173
173
  result = cls.execute_command(cmd, do_log_output=False, do_raise_on_stderr=False)
174
- res = [Converter.to_integer(v) for v in result.output.split('\n') if len(v) > 0]
174
+ res = {Converter.to_integer(v) for v in result.output.split('\n') if len(v) > 0}
175
175
  return res
176
176
  else:
177
177
  raise NotImplementedError(f"Not implemented for OS type '{cls.get_os_type().name}'")
@@ -88,8 +88,7 @@ def step_impl(context, var_name, path):
88
88
  open_kwargs = ValueTableConverter.convert_name_value_table_2_dict(table)
89
89
 
90
90
  __get_path_manager().makedirs(path)
91
- res = File(path)
92
- res.open(**open_kwargs)
91
+ res = File(path, **open_kwargs)
93
92
 
94
93
  __get_variable_manager().register_variable(var_name, res)
95
94
 
@@ -125,9 +124,7 @@ def step_impl(context, var_name, is_text_file_str, path): # @DuplicatedSignatur
125
124
  is_text_file = is_text_file_str is not None
126
125
  path = StepTools.evaluate_scenario_parameter(path)
127
126
 
128
- mode = 'rt' if is_text_file else 'rb'
129
- with open(path, mode) as fin:
130
- res = fin.read()
127
+ res = File.get_file_content(path, is_text_file)
131
128
 
132
129
  __get_variable_manager().register_variable(var_name, res)
133
130
 
@@ -136,9 +133,7 @@ def step_impl(context, var_name, path): # @DuplicatedSignature
136
133
  var_name = StepTools.evaluate_variable_name(var_name)
137
134
  path = StepTools.evaluate_scenario_parameter(path)
138
135
 
139
- with open(path, "rb") as fin:
140
- content = fin.read()
141
- res = base64.b64encode(content)
136
+ res = File.get_file_content_in_base64(path)
142
137
 
143
138
  __get_variable_manager().register_variable(var_name, res)
144
139
 
@@ -147,7 +142,7 @@ def step_impl(context, var_name, path): # @DuplicatedSignature
147
142
  var_name = StepTools.evaluate_variable_name(var_name)
148
143
  path = StepTools.evaluate_scenario_parameter(path)
149
144
 
150
- with open(path, "r") as fin:
145
+ with File(path, mode="r") as fin:
151
146
  lines = fin.readlines()
152
147
  res = list(map(lambda x: x.strip('\n'), lines))
153
148
 
@@ -192,14 +187,7 @@ def step_impl(context, var_name, path_name, content):
192
187
  file_path = os.path.join(dest_path, filename)
193
188
  __get_path_manager().makedirs(file_path)
194
189
 
195
- if isinstance(content, str):
196
- with open(file_path, 'wt') as fout:
197
- fout.write(content)
198
- elif isinstance(content, bytes):
199
- with open(file_path, 'wb') as fout:
200
- fout.write(content)
201
- else:
202
- raise TechnicalException(f"Unexpected content type {Typing.get_object_class_fullname(content)} (allowed types: string, bytes)")
190
+ File.create_file_with_content(file_path, content)
203
191
 
204
192
  __get_variable_manager().register_variable(var_name, file_path)
205
193
 
@@ -104,16 +104,24 @@ class YAMLClient(Object):
104
104
 
105
105
  # Update file
106
106
  dst_data = self.load_file(file_path)
107
- self.update_data(dst_data, data, update_type)
107
+ if dst_data is None:
108
+ dst_data = data
109
+ else:
110
+ self.update_data(dst_data, data, update_type)
108
111
  self.save_in_file(file_path, dst_data, **kwargs) # Note: as file already exists, it is not needed to pass parameters mode, user and group
109
112
 
110
113
  def update_string(self, text, data, update_type=UpdateType.AddOrUpdate, **kwargs):
111
114
  dst_data = self.load_string(text)
112
- self.update_data(dst_data, data, update_type)
115
+ if dst_data is None:
116
+ dst_data = data
117
+ else:
118
+ self.update_data(dst_data, data, update_type)
113
119
  res = self.save_in_string(dst_data, **kwargs)
114
120
  return res
115
121
 
116
122
  def update_data(self, dst, src, update_type=UpdateType.AddOrUpdate):
123
+ if dst is None:
124
+ raise TechnicalException("Destination data cannot be None")
117
125
  if isinstance(src, str):
118
126
  src = self.load_string(src)
119
127
 
File without changes