holado 0.2.8__py3-none-any.whl → 0.4.0__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/undefined.py +7 -1
- {holado-0.2.8.dist-info → holado-0.4.0.dist-info}/METADATA +4 -1
- {holado-0.2.8.dist-info → holado-0.4.0.dist-info}/RECORD +108 -101
- holado_ais/ais/ais_messages.py +97 -6
- holado_ais/tests/behave/steps/ais/ais_manager_steps.py +1 -1
- holado_ais/tests/behave/steps/ais/ais_messages_steps.py +45 -6
- holado_binary/ipc/bit_series.py +3 -3
- holado_binary/tests/behave/steps/ipc/binary_steps.py +1 -1
- holado_binary/tests/behave/steps/ipc/bit_series_steps.py +4 -3
- holado_context/tests/behave/steps/private/common/context_steps.py +1 -1
- holado_core/common/resource/persisted_data_manager.py +13 -16
- holado_core/common/resource/resource_manager.py +10 -10
- holado_core/common/tables/converters/table_converter.py +47 -9
- holado_core/common/tables/table_manager.py +6 -7
- holado_core/common/tables/table_with_header.py +6 -0
- holado_core/tests/behave/steps/common/common_steps.py +2 -1
- holado_core/tests/behave/steps/common/config_steps.py +1 -1
- holado_core/tests/behave/steps/common/resource_steps.py +1 -1
- holado_core/tests/behave/steps/common/tables_steps.py +18 -2
- holado_data/data/generator/generator_manager.py +39 -0
- holado_data/tests/behave/steps/data/generator_steps.py +1 -1
- holado_data/tests/behave/steps/tools/utils_steps.py +1 -2
- holado_db/tests/behave/steps/tools/db/db_client_steps.py +1 -1
- holado_db/tests/behave/steps/tools/db/postgresql_client_steps.py +1 -1
- holado_db/tests/behave/steps/tools/db/sqlite_client_steps.py +1 -1
- holado_db/tools/db/clients/base/db_client.py +81 -28
- holado_db/tools/db/clients/postgresql/postgresql_client.py +17 -7
- holado_db/tools/db/query/base/query_builder.py +58 -7
- holado_db/tools/db/query/pypika/pypika_query_builder.py +73 -21
- holado_docker/tests/behave/steps/tools/docker_steps.py +1 -1
- holado_grpc/tests/behave/steps/api/grpc_client_steps.py +1 -1
- holado_grpc/tests/behave/steps/private/api/grpc_steps.py +1 -1
- holado_json/tests/behave/steps/ipc/json_steps.py +1 -1
- holado_keycloak/tests/behave/steps/tools/keycloak_client_steps.py +1 -1
- holado_multitask/tests/behave/steps/multiprocessing_steps.py +1 -1
- holado_multitask/tests/behave/steps/multithreading_steps.py +1 -1
- holado_protobuf/ipc/protobuf/types/google/protobuf.py +1 -1
- holado_protobuf/tests/behave/steps/ipc/protobuf_steps.py +1 -1
- holado_python/common/tools/datetime.py +31 -12
- holado_python/standard_library/socket/blocking_socket.py +37 -24
- holado_python/standard_library/socket/message_socket.py +11 -3
- holado_python/standard_library/socket/non_blocking_socket.py +24 -24
- holado_python/standard_library/socket/socket.py +132 -19
- holado_python/standard_library/ssl/resources/certificates/NOTES.txt +1 -1
- holado_python/standard_library/ssl/resources/certificates/rootCACert.pem +24 -0
- holado_python/standard_library/ssl/resources/certificates/tcpbin.crt +21 -0
- holado_python/standard_library/ssl/resources/certificates/tcpbin.key +28 -0
- holado_python/standard_library/ssl/ssl.py +138 -21
- holado_python/tests/behave/steps/convert_steps.py +1 -1
- holado_python/tests/behave/steps/iterable_steps.py +1 -1
- holado_python/tests/behave/steps/standard_library/csv_steps.py +1 -1
- holado_python/tests/behave/steps/standard_library/datetime_steps.py +1 -1
- holado_python/tests/behave/steps/standard_library/hashlib_steps.py +2 -2
- holado_python/tests/behave/steps/standard_library/multiprocessing_steps.py +1 -1
- holado_python/tests/behave/steps/standard_library/queue_steps.py +1 -1
- holado_python/tests/behave/steps/standard_library/socket_steps.py +132 -18
- holado_python/tests/behave/steps/standard_library/ssl_steps.py +87 -16
- holado_rabbitmq/tests/behave/steps/tools/rabbitmq_client_steps.py +48 -20
- holado_rabbitmq/tests/behave/steps/tools/rabbitmq_server_steps.py +1 -1
- holado_rabbitmq/tools/rabbitmq/rabbitmq_client.py +19 -13
- holado_rabbitmq/tools/rabbitmq/rabbitmq_manager.py +2 -29
- holado_redis/tests/behave/steps/tools/redis_client_steps.py +1 -1
- holado_rest/api/rest/rest_client.py +18 -1
- holado_rest/api/rest/rest_manager.py +5 -0
- holado_rest/tests/behave/steps/api/rest_client_steps.py +52 -11
- holado_rest/tests/behave/steps/private/api/rest_steps.py +1 -1
- holado_s3/tests/behave/steps/private/tools/s3_steps.py +1 -1
- holado_s3/tests/behave/steps/tools/s3_client_steps.py +1 -1
- holado_s3/tests/behave/steps/tools/s3_server_steps.py +1 -1
- holado_scripting/tests/behave/steps/common/tools/variable_convert_steps.py +3 -2
- holado_scripting/tests/behave/steps/common/tools/variable_new_steps.py +1 -1
- holado_scripting/tests/behave/steps/common/tools/variable_steps.py +1 -1
- holado_scripting/tests/behave/steps/common/tools/variable_verify_steps.py +1 -1
- holado_scripting/tests/behave/steps/scenario/function_steps.py +1 -1
- holado_scripting/tests/behave/steps/scenario/if_steps.py +1 -1
- holado_scripting/tests/behave/steps/scenario/loop_steps.py +1 -1
- holado_sftp/tests/behave/steps/private/tools/sftp_steps.py +1 -1
- holado_sftp/tests/behave/steps/tools/sftp_client_steps.py +1 -1
- holado_sftp/tests/behave/steps/tools/sftp_server_steps.py +1 -1
- holado_swagger/tests/behave/steps/swagger_hub/mockserver_steps.py +1 -1
- holado_system/system/command/command.py +14 -9
- holado_system/tests/behave/steps/system/commands_steps.py +1 -1
- holado_system/tests/behave/steps/system/file_steps.py +1 -1
- holado_system/tests/behave/steps/system/system_steps.py +1 -1
- holado_test/scenario/step_tools.py +1 -1
- holado_test/scenario/tester_tools.py +6 -3
- holado_test/tests/behave/steps/scenario/exception_steps.py +1 -1
- holado_test/tests/behave/steps/scenario/scenario_steps.py +1 -1
- holado_test/tests/behave/steps/scenario/tester_steps.py +4 -4
- holado_value/common/tables/converters/value_table_converter.py +52 -8
- holado_value/common/tables/value_table_manager.py +0 -10
- holado_ws/tests/behave/steps/api/web_service_steps.py +1 -1
- holado_yaml/tests/behave/steps/yaml_steps.py +1 -1
- holado_yaml/yaml/yaml_manager.py +2 -2
- test_holado/features/NonReg/common/tables/table.feature +30 -24
- test_holado/features/NonReg/holado_ais/ais_message-bitarray_to_nmea.feature +1 -1
- 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_with_ssl.feature → socket/local_echo_server/socket_with_tls_and_verify.feature} +53 -30
- 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.feature → socket/local_echo_server/socket_without_tls.feature} +2 -2
- 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/tools/RabbitMQ.feature +9 -9
- test_holado/features/NonReg/tools/RabbitMQ_steps.feature +8 -8
- test_holado/logging.conf +5 -3
- holado_core/common/transport/__init__.py +0 -0
- holado_core/common/transport/crc.py +0 -40
- {holado-0.2.8.dist-info → holado-0.4.0.dist-info}/WHEEL +0 -0
- {holado-0.2.8.dist-info → holado-0.4.0.dist-info}/licenses/LICENSE +0 -0
holado_ais/ais/ais_messages.py
CHANGED
|
@@ -22,6 +22,7 @@ from holado_binary.ipc.binary import Binary
|
|
|
22
22
|
from holado_core.common.tools.tools import Tools
|
|
23
23
|
from holado_python.standard_library.typing import Typing
|
|
24
24
|
import copy
|
|
25
|
+
from holado_core.common.exceptions.functional_exception import FunctionalException
|
|
25
26
|
|
|
26
27
|
logger = logging.getLogger(__name__)
|
|
27
28
|
|
|
@@ -46,6 +47,9 @@ class AISMessages(object):
|
|
|
46
47
|
def is_available(cls):
|
|
47
48
|
return with_pyais
|
|
48
49
|
|
|
50
|
+
###########################################################################
|
|
51
|
+
# Methods depending to pyais
|
|
52
|
+
###########################################################################
|
|
49
53
|
if with_pyais:
|
|
50
54
|
|
|
51
55
|
def __init__(self):
|
|
@@ -172,12 +176,6 @@ class AISMessages(object):
|
|
|
172
176
|
|
|
173
177
|
return res
|
|
174
178
|
|
|
175
|
-
def __new_tag_block_group_id(self):
|
|
176
|
-
self.__tag_block_group_id += 1
|
|
177
|
-
if self.__tag_block_group_id > 9999:
|
|
178
|
-
self.__tag_block_group_id = 0
|
|
179
|
-
return self.__tag_block_group_id
|
|
180
|
-
|
|
181
179
|
def convert_message_to_binary_str(self, msg):
|
|
182
180
|
return msg.to_bitarray().to01()
|
|
183
181
|
|
|
@@ -201,4 +199,97 @@ class AISMessages(object):
|
|
|
201
199
|
return res
|
|
202
200
|
|
|
203
201
|
|
|
202
|
+
|
|
203
|
+
###########################################################################
|
|
204
|
+
# Methods independent of pyais
|
|
205
|
+
###########################################################################
|
|
206
|
+
|
|
207
|
+
def __new_tag_block_group_id(self):
|
|
208
|
+
self.__tag_block_group_id += 1
|
|
209
|
+
if self.__tag_block_group_id > 9999:
|
|
210
|
+
self.__tag_block_group_id = 0
|
|
211
|
+
return self.__tag_block_group_id
|
|
212
|
+
|
|
213
|
+
def split_raw_to_sentences(self, ais_raw):
|
|
214
|
+
if isinstance(ais_raw, str):
|
|
215
|
+
split_char = '\n'
|
|
216
|
+
elif isinstance(ais_raw, bytes):
|
|
217
|
+
split_char = b'\n'
|
|
218
|
+
else:
|
|
219
|
+
raise FunctionalException(f"Raw must by of type str or bytes (obtained type: {Typing.get_object_class_fullname(ais_raw)})")
|
|
220
|
+
|
|
221
|
+
res = ais_raw.split(split_char)
|
|
222
|
+
|
|
223
|
+
return res
|
|
224
|
+
|
|
225
|
+
def split_sentence_to_tab_block_and_message(self, ais_sentence):
|
|
226
|
+
if isinstance(ais_sentence, str):
|
|
227
|
+
split_char = '\\'
|
|
228
|
+
elif isinstance(ais_sentence, bytes):
|
|
229
|
+
split_char = b'\\'
|
|
230
|
+
else:
|
|
231
|
+
raise FunctionalException(f"Sentence must by of type str or bytes (obtained type: {Typing.get_object_class_fullname(ais_sentence)})")
|
|
232
|
+
|
|
233
|
+
res = ais_sentence.split(split_char)
|
|
234
|
+
if len(res) > 1:
|
|
235
|
+
# Remove part before first '\'
|
|
236
|
+
del res[0]
|
|
237
|
+
else:
|
|
238
|
+
# Tag block is not present, insert it as None
|
|
239
|
+
res.insert(0, None)
|
|
240
|
+
|
|
241
|
+
return res
|
|
242
|
+
|
|
243
|
+
def convert_tag_block_to_dict(self, tag_block):
|
|
244
|
+
if isinstance(tag_block, str):
|
|
245
|
+
checksum_delimiter = '*'
|
|
246
|
+
param_delimiter = ','
|
|
247
|
+
name_delimiter = ':'
|
|
248
|
+
elif isinstance(tag_block, bytes):
|
|
249
|
+
checksum_delimiter = b'*'
|
|
250
|
+
param_delimiter = b','
|
|
251
|
+
name_delimiter = b':'
|
|
252
|
+
else:
|
|
253
|
+
raise FunctionalException(f"Tag Block must by of type str or bytes (obtained type: {Typing.get_object_class_fullname(tag_block)})")
|
|
254
|
+
|
|
255
|
+
# Remove checksum
|
|
256
|
+
try:
|
|
257
|
+
chk_index = tag_block.index(checksum_delimiter)
|
|
258
|
+
except:
|
|
259
|
+
chk_index = None
|
|
260
|
+
tb_str = tag_block[:chk_index] if chk_index else tag_block
|
|
261
|
+
|
|
262
|
+
# Split parameters
|
|
263
|
+
tb_list = tb_str.split(param_delimiter)
|
|
264
|
+
|
|
265
|
+
# Extract parameter names and values
|
|
266
|
+
param_list = [e.split(name_delimiter) for e in tb_list]
|
|
267
|
+
res = {p[0]:p[1] for p in param_list}
|
|
268
|
+
|
|
269
|
+
return res
|
|
270
|
+
|
|
271
|
+
def split_message_to_fields(self, ais_message):
|
|
272
|
+
split_char = self.__get_fields_delimiter_for_message(ais_message)
|
|
273
|
+
res = ais_message.split(split_char)
|
|
274
|
+
return res
|
|
275
|
+
|
|
276
|
+
def __get_fields_delimiter_for_message(self, ais_message):
|
|
277
|
+
if isinstance(ais_message, str):
|
|
278
|
+
return ','
|
|
279
|
+
elif isinstance(ais_message, bytes):
|
|
280
|
+
return b','
|
|
281
|
+
else:
|
|
282
|
+
raise FunctionalException(f"Message must by of type str or bytes (obtained type: {Typing.get_object_class_fullname(ais_message)})")
|
|
283
|
+
|
|
284
|
+
def replace_message_id_in_message(self, ais_message, replacement_id):
|
|
285
|
+
if type(ais_message) != type(replacement_id):
|
|
286
|
+
raise FunctionalException(f"Replacement ID must of same type than message ({Typing.get_object_class_fullname(ais_message)})")
|
|
287
|
+
|
|
288
|
+
fields = self.split_message_to_fields(ais_message)
|
|
289
|
+
fields[3] = replacement_id
|
|
290
|
+
|
|
291
|
+
split_char = self.__get_fields_delimiter_for_message(ais_message)
|
|
292
|
+
return split_char.join(fields)
|
|
293
|
+
|
|
294
|
+
|
|
204
295
|
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
from holado_test.scenario.step_tools import StepTools
|
|
17
17
|
from holado.common.context.session_context import SessionContext
|
|
18
18
|
import logging
|
|
19
|
-
from holado_test.behave.behave import *
|
|
19
|
+
from holado_test.behave.behave import * # @UnusedWildImport
|
|
20
20
|
|
|
21
21
|
logger = logging.getLogger(__name__)
|
|
22
22
|
|
|
@@ -18,7 +18,7 @@ from holado.common.context.session_context import SessionContext
|
|
|
18
18
|
import logging
|
|
19
19
|
from holado_test.behave.scenario.behave_step_tools import BehaveStepTools
|
|
20
20
|
from holado_ais.ais.ais_messages import AISMessages
|
|
21
|
-
from holado_test.behave.behave import *
|
|
21
|
+
from holado_test.behave.behave import * # @UnusedWildImport
|
|
22
22
|
from holado_ais.ais.enums import AISMessageType
|
|
23
23
|
from holado_core.common.tools.string_tools import StrTools
|
|
24
24
|
from holado_value.common.tables.converters.value_table_converter import ValueTableConverter
|
|
@@ -152,7 +152,7 @@ if AISMessages.is_available():
|
|
|
152
152
|
|
|
153
153
|
__get_variable_manager().register_variable(var_name, res)
|
|
154
154
|
|
|
155
|
-
@Step(r"(?P<var_name>{Variable}) = decode AIS
|
|
155
|
+
@Step(r"(?P<var_name>{Variable}) = decode NMEA AIS message (?P<encoded_ais_message>{Str})(?P<dictionnary_str> as dictionnary)?")
|
|
156
156
|
def step_impl(context, var_name, encoded_ais_message, dictionnary_str):
|
|
157
157
|
var_name = StepTools.evaluate_variable_name(var_name)
|
|
158
158
|
encoded_ais_message = StepTools.evaluate_scenario_parameter(encoded_ais_message)
|
|
@@ -167,15 +167,54 @@ if AISMessages.is_available():
|
|
|
167
167
|
|
|
168
168
|
__get_variable_manager().register_variable(var_name, res)
|
|
169
169
|
|
|
170
|
-
|
|
171
|
-
|
|
170
|
+
#TODO EKL: rename step
|
|
171
|
+
@Given(r"(?P<var_name>{Variable}) = split NMEA AIS message (?P<ais_message>{Bytes}|{Str}) to fields")
|
|
172
|
+
def step_impl(context, var_name, ais_message):
|
|
172
173
|
var_name = StepTools.evaluate_variable_name(var_name)
|
|
173
|
-
|
|
174
|
+
ais_message = StepTools.evaluate_scenario_parameter(ais_message)
|
|
174
175
|
|
|
175
|
-
res =
|
|
176
|
+
res = __get_ais_messages().split_message_to_fields(ais_message)
|
|
177
|
+
|
|
178
|
+
__get_variable_manager().register_variable(var_name, res)
|
|
179
|
+
|
|
180
|
+
@Given(r"(?P<var_name>{Variable}) = split (?P<ais_raw>{Bytes}|{Str}) to NMEA AIS sentences")
|
|
181
|
+
def step_impl(context, var_name, ais_raw):
|
|
182
|
+
var_name = StepTools.evaluate_variable_name(var_name)
|
|
183
|
+
ais_raw = StepTools.evaluate_scenario_parameter(ais_raw)
|
|
184
|
+
|
|
185
|
+
res = __get_ais_messages().split_raw_to_sentences(ais_raw)
|
|
176
186
|
|
|
177
187
|
__get_variable_manager().register_variable(var_name, res)
|
|
178
188
|
|
|
189
|
+
@Given(r"(?P<tb_var_name>{Variable}), (?P<msg_var_name>{Variable}) = split NMEA AIS sentence (?P<ais_sentence>{Bytes}|{Str}) to tag block and message")
|
|
190
|
+
def step_impl(context, tb_var_name, msg_var_name, ais_sentence):
|
|
191
|
+
tb_var_name = StepTools.evaluate_variable_name(tb_var_name)
|
|
192
|
+
msg_var_name = StepTools.evaluate_variable_name(msg_var_name)
|
|
193
|
+
ais_sentence = StepTools.evaluate_scenario_parameter(ais_sentence)
|
|
194
|
+
|
|
195
|
+
tb, msg = __get_ais_messages().split_sentence_to_tab_block_and_message(ais_sentence)
|
|
196
|
+
|
|
197
|
+
__get_variable_manager().register_variable(tb_var_name, tb)
|
|
198
|
+
__get_variable_manager().register_variable(msg_var_name, msg)
|
|
199
|
+
|
|
200
|
+
@Given(r"(?P<var_name>{Variable}) = split NMEA AIS Tag Block (?P<tag_block>{Bytes}|{Str}) to dict")
|
|
201
|
+
def step_impl(context, var_name, tag_block):
|
|
202
|
+
var_name = StepTools.evaluate_variable_name(var_name)
|
|
203
|
+
tag_block = StepTools.evaluate_scenario_parameter(tag_block)
|
|
204
|
+
|
|
205
|
+
res = __get_ais_messages().convert_tag_block_to_dict(tag_block)
|
|
206
|
+
|
|
207
|
+
__get_variable_manager().register_variable(var_name, res)
|
|
208
|
+
|
|
209
|
+
@Given(r"(?P<var_name>{Variable}) = NMEA AIS message (?P<ais_message>{Bytes}|{Str}) with message ID replaced by (?P<replacement_id>{Bytes}|{Str})")
|
|
210
|
+
def step_impl(context, var_name, ais_message, replacement_id):
|
|
211
|
+
var_name = StepTools.evaluate_variable_name(var_name)
|
|
212
|
+
ais_message = StepTools.evaluate_scenario_parameter(ais_message)
|
|
213
|
+
replacement_id = StepTools.evaluate_scenario_parameter(replacement_id)
|
|
214
|
+
|
|
215
|
+
res = __get_ais_messages().replace_message_id_in_message(ais_message, replacement_id)
|
|
216
|
+
|
|
217
|
+
__get_variable_manager().register_variable(var_name, res)
|
|
179
218
|
|
|
180
219
|
|
|
181
220
|
|
holado_binary/ipc/bit_series.py
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
import logging
|
|
15
15
|
from holado_core.common.tables.table_with_header import TableWithHeader
|
|
16
16
|
from holado_core.common.exceptions.technical_exception import TechnicalException
|
|
17
|
-
from typing import NamedTuple
|
|
17
|
+
from typing import NamedTuple, Iterable
|
|
18
18
|
from holado_core.common.tables.table_row import TableRow
|
|
19
19
|
from holado_core.common.exceptions.functional_exception import FunctionalException
|
|
20
20
|
from holado_binary.ipc.binary import Binary
|
|
@@ -82,8 +82,8 @@ class BitSeries():
|
|
|
82
82
|
Parameter "bit_sections_list" is an iterable of "bit_section".
|
|
83
83
|
"""
|
|
84
84
|
if bit_sections_list is not None:
|
|
85
|
-
if not isinstance(bit_sections_list,
|
|
86
|
-
raise TechnicalException(f"Parameter 'bit_sections_list' has to be
|
|
85
|
+
if not isinstance(bit_sections_list, Iterable):
|
|
86
|
+
raise TechnicalException(f"Parameter 'bit_sections_list' has to be an iterable (obtained type: {Typing.get_object_class_fullname(bit_sections_list)})")
|
|
87
87
|
for bit_section in bit_sections_list:
|
|
88
88
|
self.add_bit_section(bit_section=bit_section)
|
|
89
89
|
return
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
#################################################
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
from holado_test.behave.behave import *
|
|
16
|
+
from holado_test.behave.behave import * # @UnusedWildImport
|
|
17
17
|
from holado_test.scenario.step_tools import StepTools
|
|
18
18
|
import logging
|
|
19
19
|
from holado_binary.ipc.binary import Binary
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
#################################################
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
from holado_test.behave.behave import *
|
|
16
|
+
from holado_test.behave.behave import * # @UnusedWildImport
|
|
17
17
|
from holado_value.common.tables.value_table_manager import ValueTableManager
|
|
18
18
|
from holado_test.scenario.step_tools import StepTools
|
|
19
19
|
from holado_binary.ipc.bit_series import BitSeries
|
|
@@ -25,6 +25,7 @@ from holado_core.common.tables.comparators.table_with_header_comparator import T
|
|
|
25
25
|
from holado_test.behave.scenario.behave_step_tools import BehaveStepTools
|
|
26
26
|
from holado.common.context.session_context import SessionContext
|
|
27
27
|
from holado_core.common.exceptions.functional_exception import FunctionalException
|
|
28
|
+
from holado_value.common.tables.converters.value_table_converter import ValueTableConverter
|
|
28
29
|
|
|
29
30
|
logger = logging.getLogger(__name__)
|
|
30
31
|
|
|
@@ -52,7 +53,7 @@ def step_impl(context, var_name):
|
|
|
52
53
|
table = BehaveStepTools.convert_step_table_2_value_table_with_header(context.table)
|
|
53
54
|
|
|
54
55
|
__verify_table_is_bit_series_table(table)
|
|
55
|
-
bs = BitSeries(bit_sections_list =
|
|
56
|
+
bs = BitSeries(bit_sections_list = ValueTableConverter.convert_table_2_list_of_tuples(table, as_generator=True))
|
|
56
57
|
|
|
57
58
|
__get_variable_manager().register_variable(var_name, bs)
|
|
58
59
|
|
|
@@ -93,7 +94,7 @@ def step_impl(context, hex_str):
|
|
|
93
94
|
# Build a table representing the bit series in hexadecimal string
|
|
94
95
|
declare_table = copy.copy(expected_table)
|
|
95
96
|
declare_table.remove_column(name="Value")
|
|
96
|
-
bs = BitSeries(bit_sections_list=
|
|
97
|
+
bs = BitSeries(bit_sections_list=ValueTableConverter.convert_table_2_list_of_tuples(declare_table, as_generator=True))
|
|
97
98
|
bs.from_hex(hex_str)
|
|
98
99
|
obtained_table = bit_series.convert_bit_series_to_table(bs)
|
|
99
100
|
|
|
@@ -55,23 +55,20 @@ class PersistedDataManager():
|
|
|
55
55
|
if not self.__resource_manager.has_data_table(self.__table_name, db_name=self.__db_name):
|
|
56
56
|
raise TechnicalException(f"Failed to create table '{self.__table_name}' in DB '{self.__db_name}'")
|
|
57
57
|
|
|
58
|
-
def has_persisted_data(self, filter_data):
|
|
59
|
-
return self.__resource_manager.has_persisted_data(self.__table_name, filter_data, db_name=self.__db_name)
|
|
58
|
+
def has_persisted_data(self, filter_data=None, filter_compare_data=None):
|
|
59
|
+
return self.__resource_manager.has_persisted_data(self.__table_name, where_data=filter_data, where_compare_data=filter_compare_data, db_name=self.__db_name)
|
|
60
60
|
|
|
61
|
-
def get_persisted_datas(self, filter_data):
|
|
61
|
+
def get_persisted_datas(self, filter_data=None, filter_compare_data=None, as_generator=False):
|
|
62
62
|
"""
|
|
63
63
|
Note: Whereas 'data' is already a plural, a 's' is added in method name to be coherent with other method names
|
|
64
64
|
"""
|
|
65
|
-
|
|
66
|
-
if res is not None:
|
|
67
|
-
res = TableConverter.convert_table_with_header_to_dict_list(res)
|
|
68
|
-
return res
|
|
65
|
+
return self.__resource_manager.get_persisted_data(self.__table_name, where_data=filter_data, where_compare_data=filter_compare_data, db_name=self.__db_name, result_as_dict_list=True, as_generator=as_generator)
|
|
69
66
|
|
|
70
|
-
def get_persisted_data(self, filter_data):
|
|
67
|
+
def get_persisted_data(self, filter_data=None, filter_compare_data=None):
|
|
71
68
|
"""
|
|
72
69
|
Note: Whereas 'datum' should be the right word in method name since method returns only one datum, method is named with 'data' in its usual singular meaning for most people.
|
|
73
70
|
"""
|
|
74
|
-
data = self.get_persisted_datas(filter_data)
|
|
71
|
+
data = self.get_persisted_datas(filter_data=filter_data, filter_compare_data=filter_compare_data)
|
|
75
72
|
if len(data) > 1:
|
|
76
73
|
raise TechnicalException(f"Too many ({len(data)}) {self.__data_name} found for filter {filter_data}.")
|
|
77
74
|
elif len(data) == 1:
|
|
@@ -79,13 +76,13 @@ class PersistedDataManager():
|
|
|
79
76
|
else:
|
|
80
77
|
return None
|
|
81
78
|
|
|
82
|
-
def count_persisted_data(self, filter_data):
|
|
83
|
-
return self.__resource_manager.count_persisted_data(self.__table_name, filter_data, db_name=self.__db_name)
|
|
79
|
+
def count_persisted_data(self, filter_data=None, filter_compare_data=None):
|
|
80
|
+
return self.__resource_manager.count_persisted_data(self.__table_name, where_data=filter_data, where_compare_data=filter_compare_data, db_name=self.__db_name)
|
|
84
81
|
|
|
85
|
-
def update_persisted_data(self, data,
|
|
82
|
+
def update_persisted_data(self, data, filter_data=None, filter_compare_data=None):
|
|
86
83
|
if Tools.do_log(logger, logging.DEBUG):
|
|
87
|
-
logger.debug(f"Update persisted {self.__data_name} for {
|
|
88
|
-
self.__resource_manager.update_persisted_data(self.__table_name, data,
|
|
84
|
+
logger.debug(f"Update persisted {self.__data_name} for {filter_data} and {filter_compare_data}: {data}")
|
|
85
|
+
self.__resource_manager.update_persisted_data(self.__table_name, data, where_data=filter_data, where_compare_data=filter_compare_data, db_name=self.__db_name)
|
|
89
86
|
|
|
90
87
|
def add_persisted_data(self, data, persisted_filter_data=None):
|
|
91
88
|
if Tools.do_log(logger, logging.DEBUG):
|
|
@@ -102,12 +99,12 @@ class PersistedDataManager():
|
|
|
102
99
|
has_persisted_data = persisted_data is not None
|
|
103
100
|
|
|
104
101
|
if has_persisted_data:
|
|
105
|
-
self.update_persisted_data(data, persisted_filter_data)
|
|
102
|
+
self.update_persisted_data(data, filter_data=persisted_filter_data)
|
|
106
103
|
else:
|
|
107
104
|
self.add_persisted_data(data, persisted_filter_data)
|
|
108
105
|
|
|
109
106
|
def delete_persisted_data(self, filter_data):
|
|
110
|
-
self.__resource_manager.delete_persisted_data(self.__table_name, filter_data, db_name=self.__db_name)
|
|
107
|
+
self.__resource_manager.delete_persisted_data(self.__table_name, where_data=filter_data, db_name=self.__db_name)
|
|
111
108
|
|
|
112
109
|
|
|
113
110
|
|
|
@@ -112,32 +112,32 @@ class ResourceManager():
|
|
|
112
112
|
sql = result[0][0].content
|
|
113
113
|
return sql == create_sql
|
|
114
114
|
|
|
115
|
-
def count_persisted_data(self, table_name,
|
|
115
|
+
def count_persisted_data(self, table_name, where_data: dict=None, where_compare_data: list=None, db_name="default"):
|
|
116
116
|
client = self.get_persistent_db_client(db_name)
|
|
117
|
-
result = client.select(table_name, where_data=
|
|
117
|
+
result = client.select(table_name, where_data=where_data, where_compare_data=where_compare_data, sql_return="count(*)")
|
|
118
118
|
if Tools.do_log(logger, logging.DEBUG):
|
|
119
119
|
logger.debug(f"result: {Tools.represent_object(result)}")
|
|
120
120
|
return result[0][0].content
|
|
121
121
|
|
|
122
|
-
def has_persisted_data(self, table_name,
|
|
123
|
-
count = self.count_persisted_data(table_name,
|
|
122
|
+
def has_persisted_data(self, table_name, where_data: dict=None, where_compare_data: list=None, db_name="default"):
|
|
123
|
+
count = self.count_persisted_data(table_name, where_data=where_data, where_compare_data=where_compare_data, db_name=db_name)
|
|
124
124
|
return count > 0
|
|
125
125
|
|
|
126
|
-
def get_persisted_data(self, table_name,
|
|
126
|
+
def get_persisted_data(self, table_name, where_data: dict=None, where_compare_data: list=None, db_name="default", result_as_dict_list=False, as_generator=False):
|
|
127
127
|
client = self.get_persistent_db_client(db_name)
|
|
128
|
-
result = client.select(table_name, where_data=
|
|
128
|
+
result = client.select(table_name, where_data=where_data, where_compare_data=where_compare_data, result_as_dict_list=result_as_dict_list, as_generator=as_generator)
|
|
129
129
|
return result
|
|
130
130
|
|
|
131
131
|
def add_persisted_data(self, table_name, data: dict, db_name="default", do_commit=True):
|
|
132
132
|
client = self.get_persistent_db_client(db_name)
|
|
133
133
|
client.insert(table_name, data, do_commit=do_commit)
|
|
134
134
|
|
|
135
|
-
def update_persisted_data(self, table_name, data: dict, where_data: dict, db_name="default", do_commit=True):
|
|
135
|
+
def update_persisted_data(self, table_name, data: dict, where_data: dict=None, where_compare_data: list=None, db_name="default", do_commit=True):
|
|
136
136
|
client = self.get_persistent_db_client(db_name)
|
|
137
|
-
result = client.update(table_name, data=data, where_data=where_data, do_commit=do_commit)
|
|
137
|
+
result = client.update(table_name, data=data, where_data=where_data, where_compare_data=where_compare_data, do_commit=do_commit)
|
|
138
138
|
return result
|
|
139
139
|
|
|
140
|
-
def delete_persisted_data(self, table_name,
|
|
140
|
+
def delete_persisted_data(self, table_name, where_data: dict=None, where_compare_data: list=None, db_name="default", do_commit=True):
|
|
141
141
|
client = self.get_persistent_db_client(db_name)
|
|
142
|
-
client.delete(table_name,
|
|
142
|
+
client.delete(table_name, where_data=where_data, where_compare_data=where_compare_data, do_commit=do_commit)
|
|
143
143
|
|
|
@@ -21,6 +21,7 @@ from holado_core.common.tables.table_manager import TableManager
|
|
|
21
21
|
from holado_core.common.exceptions.functional_exception import FunctionalException
|
|
22
22
|
import re
|
|
23
23
|
from holado_core.common.tools.tools import Tools
|
|
24
|
+
from holado_data.data.generator.base import BaseGenerator
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
logger = logging.getLogger(__name__)
|
|
@@ -31,7 +32,7 @@ class TableConverter(object):
|
|
|
31
32
|
|
|
32
33
|
@classmethod
|
|
33
34
|
def convert_table_with_header_to_dict(cls, table):
|
|
34
|
-
res_list = cls.convert_table_with_header_to_dict_list(table)
|
|
35
|
+
res_list = cls.convert_table_with_header_to_dict_list(table, as_generator=False)
|
|
35
36
|
if len(res_list) == 0:
|
|
36
37
|
return None
|
|
37
38
|
elif len(res_list) == 1:
|
|
@@ -40,15 +41,52 @@ class TableConverter(object):
|
|
|
40
41
|
raise TechnicalException(f"Failed to convert table to dict, since table has more than one row.")
|
|
41
42
|
|
|
42
43
|
@classmethod
|
|
43
|
-
def convert_table_with_header_to_dict_list(cls, table):
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
def convert_table_with_header_to_dict_list(cls, table, as_generator=False):
|
|
45
|
+
if as_generator:
|
|
46
|
+
class TableWithHeader2DictGenerator(BaseGenerator):
|
|
47
|
+
def __init__(self, table):
|
|
48
|
+
super().__init__(name="table with header to dict generator")
|
|
49
|
+
self.__table = table
|
|
50
|
+
self.__index_by_name = table.get_column_indexes_by_string_content()
|
|
51
|
+
self.__table_rows_iter = iter(self.__table.rows)
|
|
52
|
+
|
|
53
|
+
def __next__(self):
|
|
54
|
+
row = next(self.__table_rows_iter)
|
|
55
|
+
return {name: row.get_cell(index).content for name, index in self.__index_by_name.items()}
|
|
50
56
|
|
|
51
|
-
|
|
57
|
+
return TableWithHeader2DictGenerator(table)
|
|
58
|
+
else:
|
|
59
|
+
# index_by_name = table.get_column_indexes_by_string_content()
|
|
60
|
+
#
|
|
61
|
+
# res = []
|
|
62
|
+
# for row in table.rows:
|
|
63
|
+
# new_dict = {name: row.get_cell(index).content for name, index in index_by_name.items()}
|
|
64
|
+
# res.append(new_dict)
|
|
65
|
+
#
|
|
66
|
+
# return res
|
|
67
|
+
gen = cls.convert_table_with_header_to_dict_list(table, as_generator=True)
|
|
68
|
+
return [e for e in gen]
|
|
69
|
+
|
|
70
|
+
@classmethod
|
|
71
|
+
def convert_table_2_list_of_tuples(cls, table, as_generator=False):
|
|
72
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
73
|
+
logger.debug("Converting table to a list of tuples...")
|
|
74
|
+
if as_generator:
|
|
75
|
+
class Table2TupleGenerator(BaseGenerator):
|
|
76
|
+
def __init__(self, table):
|
|
77
|
+
super().__init__(name="table with header to dict generator")
|
|
78
|
+
self.__table = table
|
|
79
|
+
self.__table_rows_iter = iter(self.__table.rows)
|
|
80
|
+
|
|
81
|
+
def __next__(self):
|
|
82
|
+
row = next(self.__table_rows_iter)
|
|
83
|
+
return tuple((cell.content for cell in row.cells))
|
|
84
|
+
|
|
85
|
+
return Table2TupleGenerator(table)
|
|
86
|
+
else:
|
|
87
|
+
# return [tuple((cell.content for cell in row.cells)) for row in table.rows]
|
|
88
|
+
gen = cls.convert_table_2_list_of_tuples(table, as_generator=True)
|
|
89
|
+
return [e for e in gen]
|
|
52
90
|
|
|
53
91
|
@classmethod
|
|
54
92
|
def convert_dict_list_to_table_with_header(cls, dict_list):
|
|
@@ -40,6 +40,7 @@ class TableManager(object):
|
|
|
40
40
|
def is_table_with_header(cls, table):
|
|
41
41
|
return isinstance(table, TableWithHeader)
|
|
42
42
|
|
|
43
|
+
#TODO: move in TableConverter
|
|
43
44
|
@classmethod
|
|
44
45
|
def convert_object_attributes_2_name_value_table(cls, obj):
|
|
45
46
|
if Tools.do_log(logger, logging.DEBUG):
|
|
@@ -59,6 +60,7 @@ class TableManager(object):
|
|
|
59
60
|
|
|
60
61
|
return res
|
|
61
62
|
|
|
63
|
+
#TODO: move in TableConverter
|
|
62
64
|
@classmethod
|
|
63
65
|
def convert_list_2_column_table(cls, el_list):
|
|
64
66
|
if Tools.do_log(logger, logging.DEBUG):
|
|
@@ -72,6 +74,7 @@ class TableManager(object):
|
|
|
72
74
|
|
|
73
75
|
return res
|
|
74
76
|
|
|
77
|
+
#TODO: move in TableConverter
|
|
75
78
|
@classmethod
|
|
76
79
|
def convert_object_list_2_table_with_attributes_as_column(cls, list_obj):
|
|
77
80
|
if Tools.do_log(logger, logging.DEBUG):
|
|
@@ -98,6 +101,7 @@ class TableManager(object):
|
|
|
98
101
|
|
|
99
102
|
return res
|
|
100
103
|
|
|
104
|
+
#TODO: move in TableConverter
|
|
101
105
|
@classmethod
|
|
102
106
|
def convert_object_list_2_column_table(cls, list_obj):
|
|
103
107
|
if Tools.do_log(logger, logging.DEBUG):
|
|
@@ -111,6 +115,7 @@ class TableManager(object):
|
|
|
111
115
|
return res
|
|
112
116
|
|
|
113
117
|
|
|
118
|
+
#TODO: move in TableConverter
|
|
114
119
|
@classmethod
|
|
115
120
|
def convert_dict_2_name_value_table(cls, obj):
|
|
116
121
|
if Tools.do_log(logger, logging.DEBUG):
|
|
@@ -125,6 +130,7 @@ class TableManager(object):
|
|
|
125
130
|
|
|
126
131
|
return res
|
|
127
132
|
|
|
133
|
+
#TODO: move in TableConverter
|
|
128
134
|
@classmethod
|
|
129
135
|
def convert_dict_2_table_with_keys_as_column(cls, obj):
|
|
130
136
|
if Tools.do_log(logger, logging.DEBUG):
|
|
@@ -138,13 +144,6 @@ class TableManager(object):
|
|
|
138
144
|
|
|
139
145
|
return res
|
|
140
146
|
|
|
141
|
-
@classmethod
|
|
142
|
-
def convert_table_2_list_of_tuples(cls, table):
|
|
143
|
-
if Tools.do_log(logger, logging.DEBUG):
|
|
144
|
-
logger.debug("Converting table to a list of tuples...")
|
|
145
|
-
return [tuple((cell.content for cell in row.cells)) for row in table.rows]
|
|
146
|
-
|
|
147
|
-
|
|
148
147
|
@classmethod
|
|
149
148
|
def compare_tables(cls, table_1, table_2, compare_params_table, reorder_columns_table_1=True, reorder_columns_table_2=True, raise_exception=True):
|
|
150
149
|
compared_tables, columns_compare_methods, compared_columns, expected_table_columns = cls._extract_compared_data(table_1, table_2, compare_params_table, reorder_columns_table_1, reorder_columns_table_2)
|
|
@@ -53,6 +53,12 @@ class TableWithHeader(Table):
|
|
|
53
53
|
|
|
54
54
|
return res
|
|
55
55
|
|
|
56
|
+
def set_header(self, row=None, cells=None, cells_content=None):
|
|
57
|
+
if row is not None:
|
|
58
|
+
self.header = row
|
|
59
|
+
else:
|
|
60
|
+
self.header = TableRow(cells=cells, cells_content=cells_content)
|
|
61
|
+
|
|
56
62
|
def add_row(self, row=None, cells=None, cells_content=None, contents_by_colname: dict =None, **kwargs):
|
|
57
63
|
# Manage super call
|
|
58
64
|
if contents_by_colname is None:
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
from holado_test.scenario.step_tools import StepTools
|
|
17
17
|
from holado.common.context.session_context import SessionContext
|
|
18
18
|
from holado_core.common.exceptions.functional_exception import FunctionalException
|
|
19
|
-
from holado_test.behave.behave import *
|
|
19
|
+
from holado_test.behave.behave import * # @UnusedWildImport
|
|
20
20
|
import time
|
|
21
21
|
import logging
|
|
22
22
|
import re
|
|
@@ -109,6 +109,7 @@ def step_impl(context, then_step, then_after_steps, accepted, timeout, polling):
|
|
|
109
109
|
|
|
110
110
|
redo = StepRedo(then_step, before_steps)
|
|
111
111
|
redo.with_accepted_time(accepted).with_timeout(timeout).polling_every(polling)
|
|
112
|
+
redo.ignoring(VerifyException)
|
|
112
113
|
redo.execute()
|
|
113
114
|
|
|
114
115
|
@Then(r"(?P<value>{Str}) matches pattern (?P<pattern_str>{RawStr})")
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
from holado.common.context.session_context import SessionContext
|
|
17
|
-
from holado_test.behave.behave import *
|
|
17
|
+
from holado_test.behave.behave import * # @UnusedWildImport
|
|
18
18
|
import logging
|
|
19
19
|
from holado_test.scenario.step_tools import StepTools
|
|
20
20
|
import os
|
|
@@ -38,6 +38,7 @@ from holado_test.behave.scenario.behave_step_tools import BehaveStepTools
|
|
|
38
38
|
from holado_value.common.tables.converters.value_table_converter import ValueTableConverter
|
|
39
39
|
from holado_python.standard_library.typing import Typing
|
|
40
40
|
from holado_value.common.tables.value_table_manager import ValueTableManager
|
|
41
|
+
from holado_core.common.tables.converters.table_converter import TableConverter
|
|
41
42
|
|
|
42
43
|
logger = logging.getLogger(__name__)
|
|
43
44
|
|
|
@@ -111,6 +112,21 @@ def step_impl(context, var_name, obj_str):
|
|
|
111
112
|
|
|
112
113
|
__get_variable_manager().register_variable(var_name, table)
|
|
113
114
|
|
|
115
|
+
@Step(r"(?P<var_name>{Variable}) = convert table with header (?P<table>{Variable}) to list of dictionary(?: \((?P<as_generator_str>as generator)\))?")
|
|
116
|
+
def step_impl(context, var_name, table, as_generator_str):
|
|
117
|
+
var_name = StepTools.evaluate_variable_name(var_name)
|
|
118
|
+
table = StepTools.evaluate_scenario_parameter(table)
|
|
119
|
+
as_generator = as_generator_str is not None
|
|
120
|
+
if not TableManager.is_table_with_header(table):
|
|
121
|
+
raise TechnicalException(f"Table must be a table with header (obtained type: {Typing.get_object_class_fullname(table)})")
|
|
122
|
+
|
|
123
|
+
if ValueTableManager.is_value_table(table):
|
|
124
|
+
res = ValueTableConverter.convert_table_with_header_to_dict_list(table, as_generator=as_generator)
|
|
125
|
+
else:
|
|
126
|
+
res = TableConverter.convert_table_with_header_to_dict_list(table, as_generator=as_generator)
|
|
127
|
+
|
|
128
|
+
__get_variable_manager().register_variable(var_name, res)
|
|
129
|
+
|
|
114
130
|
@Step(r'(?P<var_name>{Variable}) = convert object (?P<obj_str>{Variable}) to name/value table')
|
|
115
131
|
def step_impl(context, var_name, obj_str):
|
|
116
132
|
var_name = StepTools.evaluate_variable_name(var_name)
|
|
@@ -257,7 +273,7 @@ def step_impl(context, var_name, table_varname):
|
|
|
257
273
|
table_new_columns = BehaveStepTools.convert_step_table_2_value_table_with_header(context.table, do_eval_once=False)
|
|
258
274
|
|
|
259
275
|
res_table = copy.copy(table)
|
|
260
|
-
is_res_value_table =
|
|
276
|
+
is_res_value_table = ValueTableManager.is_value_table(res_table)
|
|
261
277
|
|
|
262
278
|
res_col_indexes = res_table.get_column_indexes_by_string_content()
|
|
263
279
|
|
|
@@ -293,7 +309,7 @@ def step_impl(context, var_name, table_varname):
|
|
|
293
309
|
table_new_rows = BehaveStepTools.convert_step_table_2_value_table_with_header(context.table)
|
|
294
310
|
|
|
295
311
|
res_table = copy.copy(table)
|
|
296
|
-
is_res_value_table =
|
|
312
|
+
is_res_value_table = ValueTableManager.is_value_table(res_table)
|
|
297
313
|
|
|
298
314
|
# Verify tables headers
|
|
299
315
|
header_comp = StringTableRowComparator()
|