testit-python-commons 4.2.8__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.
Files changed (71) hide show
  1. api_client_syncstorage/__init__.py +27 -0
  2. api_client_syncstorage/api/__init__.py +3 -0
  3. api_client_syncstorage/api/completion_api.py +302 -0
  4. api_client_syncstorage/api/health_api.py +158 -0
  5. api_client_syncstorage/api/system_api.py +158 -0
  6. api_client_syncstorage/api/test_results_api.py +182 -0
  7. api_client_syncstorage/api/workers_api.py +308 -0
  8. api_client_syncstorage/api_client.py +898 -0
  9. api_client_syncstorage/apis/__init__.py +21 -0
  10. api_client_syncstorage/configuration.py +450 -0
  11. api_client_syncstorage/exceptions.py +158 -0
  12. api_client_syncstorage/model/__init__.py +5 -0
  13. api_client_syncstorage/model/completion_response.py +267 -0
  14. api_client_syncstorage/model/health_status_response.py +267 -0
  15. api_client_syncstorage/model/register_request.py +275 -0
  16. api_client_syncstorage/model/register_response.py +279 -0
  17. api_client_syncstorage/model/set_worker_status_request.py +271 -0
  18. api_client_syncstorage/model/set_worker_status_response.py +267 -0
  19. api_client_syncstorage/model/shutdown_response.py +267 -0
  20. api_client_syncstorage/model/test_result_cut_api_model.py +279 -0
  21. api_client_syncstorage/model/test_result_save_response.py +267 -0
  22. api_client_syncstorage/model_utils.py +2058 -0
  23. api_client_syncstorage/models/__init__.py +20 -0
  24. api_client_syncstorage/rest.py +356 -0
  25. testit.py +69 -0
  26. testit_python_commons/__init__.py +0 -0
  27. testit_python_commons/app_properties.py +257 -0
  28. testit_python_commons/client/__init__.py +9 -0
  29. testit_python_commons/client/api_client.py +560 -0
  30. testit_python_commons/client/client_configuration.py +74 -0
  31. testit_python_commons/client/converter.py +618 -0
  32. testit_python_commons/client/helpers/__init__.py +0 -0
  33. testit_python_commons/client/helpers/bulk_autotest_helper.py +246 -0
  34. testit_python_commons/client/helpers/threads_manager.py +86 -0
  35. testit_python_commons/client/models/__init__.py +8 -0
  36. testit_python_commons/client/models/threads_for_create_and_result.py +35 -0
  37. testit_python_commons/client/models/threads_for_update_and_result.py +45 -0
  38. testit_python_commons/configurations/__init__.py +0 -0
  39. testit_python_commons/configurations/properties_names.py +51 -0
  40. testit_python_commons/decorators.py +221 -0
  41. testit_python_commons/dynamic_methods.py +237 -0
  42. testit_python_commons/models/__init__.py +5 -0
  43. testit_python_commons/models/adapter_mode.py +4 -0
  44. testit_python_commons/models/fixture.py +24 -0
  45. testit_python_commons/models/link.py +53 -0
  46. testit_python_commons/models/link_type.py +10 -0
  47. testit_python_commons/models/outcome_type.py +5 -0
  48. testit_python_commons/models/status_type.py +6 -0
  49. testit_python_commons/models/step_result.py +90 -0
  50. testit_python_commons/models/test_result.py +297 -0
  51. testit_python_commons/models/test_result_with_all_fixture_step_results_model.py +28 -0
  52. testit_python_commons/services/__init__.py +41 -0
  53. testit_python_commons/services/adapter_manager.py +318 -0
  54. testit_python_commons/services/adapter_manager_configuration.py +42 -0
  55. testit_python_commons/services/fixture_manager.py +60 -0
  56. testit_python_commons/services/fixture_storage.py +40 -0
  57. testit_python_commons/services/logger.py +32 -0
  58. testit_python_commons/services/plugin_manager.py +101 -0
  59. testit_python_commons/services/retry.py +92 -0
  60. testit_python_commons/services/step_manager.py +36 -0
  61. testit_python_commons/services/step_result_storage.py +26 -0
  62. testit_python_commons/services/sync_storage/__init__.py +9 -0
  63. testit_python_commons/services/sync_storage/sync_storage_runner.py +589 -0
  64. testit_python_commons/services/utils.py +132 -0
  65. testit_python_commons/step.py +101 -0
  66. testit_python_commons/utils/__init__.py +3 -0
  67. testit_python_commons/utils/html_escape_utils.py +219 -0
  68. testit_python_commons-4.2.8.dist-info/METADATA +52 -0
  69. testit_python_commons-4.2.8.dist-info/RECORD +71 -0
  70. testit_python_commons-4.2.8.dist-info/WHEEL +5 -0
  71. testit_python_commons-4.2.8.dist-info/top_level.txt +3 -0
@@ -0,0 +1,257 @@
1
+ import configparser
2
+ import logging
3
+ import os
4
+ import warnings
5
+ import uuid
6
+ import re
7
+ from urllib.parse import urlparse
8
+ import tomli
9
+
10
+ from testit_python_commons.models.adapter_mode import AdapterMode
11
+ from testit_python_commons.configurations.properties_names import PropertiesNames, ENV_TO_PROPERTY, OPTION_TO_PROPERTY
12
+
13
+
14
+ class AppProperties:
15
+ __toml_extension = '.toml'
16
+ __ini_extension = '.ini'
17
+ __project_metadata_file = 'pyproject' + __toml_extension
18
+ __tms_config_file = 'connection_config' + __ini_extension
19
+ __properties_file = __tms_config_file
20
+ __available_extensions = [__toml_extension, __ini_extension]
21
+
22
+ ENV_CONFIG_FILE = 'TMS_CONFIG_FILE'
23
+ __config_section_name = 'testit'
24
+ __debug_section_name = 'debug'
25
+
26
+ @staticmethod
27
+ def load_properties(option=None):
28
+ properties = AppProperties.load_file_properties(
29
+ option.set_config_file if hasattr(option, 'set_config_file') else None)
30
+
31
+ AppProperties.__check_token_property(properties)
32
+
33
+ properties.update(AppProperties.load_env_properties())
34
+
35
+ if option:
36
+ properties.update(AppProperties.load_cli_properties(option))
37
+
38
+ AppProperties.__check_properties(properties)
39
+
40
+ return properties
41
+
42
+ @classmethod
43
+ def load_file_properties(cls, cli_file_path: str = None):
44
+ if os.path.isfile(cls.__project_metadata_file):
45
+ # https://peps.python.org/pep-0621/
46
+ cls.__properties_file = cls.__project_metadata_file
47
+
48
+ path = os.path.abspath('')
49
+ root = path[:path.index(os.sep)]
50
+
51
+ while not os.path.isfile(
52
+ path + os.sep + cls.__tms_config_file) and path != root:
53
+ path = path[:path.rindex(os.sep)]
54
+
55
+ path = path + os.sep + cls.__tms_config_file
56
+
57
+ if os.path.isfile(path):
58
+ cls.__properties_file = cls.__tms_config_file
59
+
60
+ if os.environ.get(cls.ENV_CONFIG_FILE):
61
+ cls.__properties_file = cls.__tms_config_file
62
+ path = os.environ.get(cls.ENV_CONFIG_FILE)
63
+
64
+ if cli_file_path:
65
+ cls.__properties_file = cls.__tms_config_file
66
+ path = cli_file_path
67
+
68
+ _, extension = os.path.splitext(cls.__properties_file)
69
+ if extension not in cls.__available_extensions:
70
+ raise FileNotFoundError(
71
+ f'{cls.__properties_file} is not a valid file ({_, extension}). Available extensions: {cls.__available_extensions}'
72
+ )
73
+
74
+ if extension == cls.__toml_extension:
75
+ toml_properties = cls.__load_file_properties_from_toml()
76
+ if toml_properties is not None:
77
+ return toml_properties
78
+
79
+ return cls.__load_file_properties_from_ini(path)
80
+
81
+ @classmethod
82
+ def load_cli_properties(cls, option):
83
+ # Формируем словарь `cli_properties` с помощью генератора
84
+ return {
85
+ prop: getattr(option, option_attr)
86
+ for option_attr, prop in OPTION_TO_PROPERTY.items()
87
+ if hasattr(option, option_attr) and cls.__check_property_value(getattr(option, option_attr))
88
+ }
89
+
90
+ @classmethod
91
+ def map_env_to_properties(cls) -> dict:
92
+ env_properties = {}
93
+ for env_key, property_name in ENV_TO_PROPERTY.items():
94
+ if env_key in os.environ and cls.__check_property_value(os.environ.get(env_key)):
95
+ env_properties[property_name] = os.environ.get(env_key)
96
+ return env_properties
97
+
98
+ @classmethod
99
+ def load_env_properties(cls):
100
+ env_properties = cls.map_env_to_properties()
101
+ return env_properties
102
+
103
+ @classmethod
104
+ def __check_properties(cls, properties: dict):
105
+ adapter_mode = properties.get(PropertiesNames.ADAPTER_MODE)
106
+
107
+ if adapter_mode == AdapterMode.NEW_TEST_RUN:
108
+ try:
109
+ uuid.UUID(str(properties.get(PropertiesNames.TEST_RUN_ID)))
110
+ logging.warning('Adapter mode "2" is enabled. Config should not contains test run id!')
111
+ properties[PropertiesNames.TEST_RUN_ID] = None
112
+ except ValueError:
113
+ pass
114
+
115
+ elif adapter_mode in (
116
+ AdapterMode.RUN_ALL_TESTS,
117
+ AdapterMode.USE_FILTER,
118
+ None):
119
+ try:
120
+ uuid.UUID(str(properties.get(PropertiesNames.TEST_RUN_ID)))
121
+ except ValueError:
122
+ logging.error(f'Adapter mode "{adapter_mode if adapter_mode else "0"}" is enabled. '
123
+ f'The test run ID is needed, but it was not found!')
124
+ raise SystemExit
125
+ else:
126
+ logging.error(f'Unknown adapter mode "{adapter_mode}"!')
127
+ raise SystemExit
128
+
129
+ try:
130
+ uuid.UUID(str(properties.get(PropertiesNames.PROJECT_ID)))
131
+ except ValueError:
132
+ logging.error('Project ID was not found!')
133
+ raise SystemExit
134
+
135
+ try:
136
+ url = urlparse(properties.get(PropertiesNames.URL))
137
+ if not all([url.scheme, url.netloc]):
138
+ raise AttributeError
139
+ except AttributeError:
140
+ logging.error('URL is invalid!')
141
+ raise SystemExit
142
+
143
+ if not cls.__check_property_value(properties.get(PropertiesNames.PRIVATE_TOKEN)):
144
+ logging.error('Private token was not found!')
145
+ raise SystemExit
146
+
147
+ try:
148
+ uuid.UUID(str(properties.get(PropertiesNames.CONFIGURATION_ID)))
149
+ except ValueError:
150
+ logging.error('Configuration ID was not found!')
151
+ raise SystemExit
152
+
153
+ if not cls.__check_property_value(properties.get(PropertiesNames.CERT_VALIDATION)):
154
+ properties[PropertiesNames.CERT_VALIDATION] = 'true'
155
+
156
+ if not cls.__check_property_value(properties.get(PropertiesNames.AUTOMATIC_CREATION_TEST_CASES)):
157
+ properties[PropertiesNames.AUTOMATIC_CREATION_TEST_CASES] = 'false'
158
+
159
+ if not cls.__check_property_value(properties.get(PropertiesNames.AUTOMATIC_UPDATION_LINKS_TO_TEST_CASES)):
160
+ properties[PropertiesNames.AUTOMATIC_UPDATION_LINKS_TO_TEST_CASES] = 'false'
161
+
162
+ if not cls.__check_property_value(properties.get(PropertiesNames.IMPORT_REALTIME)):
163
+ # import realtime false by default
164
+ properties[PropertiesNames.IMPORT_REALTIME] = 'false'
165
+
166
+ if not cls.__check_property_value(properties.get(PropertiesNames.SYNC_STORAGE_PORT)):
167
+ # import realtime false by default
168
+ properties[PropertiesNames.SYNC_STORAGE_PORT] = '49152'
169
+
170
+ if not cls.__check_property_value(properties.get(PropertiesNames.LEGACY_WORKFLOW)):
171
+ properties[PropertiesNames.LEGACY_WORKFLOW] = 'false'
172
+
173
+ @classmethod
174
+ def __load_file_properties_from_toml(cls):
175
+ properties = {}
176
+
177
+ with open(cls.__project_metadata_file, "rb+") as file:
178
+ toml_dict = tomli.load(file)
179
+
180
+ if not cls.__check_toml_section(toml_dict, cls.__config_section_name):
181
+ logging.warning(
182
+ f'Config section "[{cls.__config_section_name}]" in "{cls.__properties_file}" was not found. '
183
+ f'Skipping "{cls.__properties_file}" and continuing with other sources (ini/env/cli).'
184
+ )
185
+ return None
186
+
187
+ config_section = toml_dict.get(cls.__config_section_name)
188
+
189
+ for key, value in config_section.items():
190
+ properties[key.lower()] = cls.__search_in_environ(str(value))
191
+
192
+ if cls.__check_toml_section(toml_dict, cls.__debug_section_name):
193
+ debug_section = toml_dict.get(cls.__debug_section_name)
194
+
195
+ for key, value in debug_section.items():
196
+ if key == PropertiesNames.TMS_PROXY:
197
+ properties[PropertiesNames.TMS_PROXY] = cls.__search_in_environ(str(value))
198
+
199
+ if key == '__dev':
200
+ properties['logs'] = cls.__search_in_environ(str(value)).lower()
201
+
202
+ return properties
203
+
204
+ @classmethod
205
+ def __load_file_properties_from_ini(cls, path: str) -> dict:
206
+ properties = {}
207
+ parser = configparser.RawConfigParser()
208
+
209
+ parser.read(path, encoding="utf-8")
210
+
211
+ if parser.has_section(cls.__config_section_name):
212
+ for key, value in parser.items(cls.__config_section_name):
213
+ properties[key] = cls.__search_in_environ(value)
214
+
215
+ if parser.has_section('debug'):
216
+ if parser.has_option('debug', PropertiesNames.TMS_PROXY):
217
+ properties[PropertiesNames.TMS_PROXY] = cls.__search_in_environ(
218
+ parser.get('debug', PropertiesNames.TMS_PROXY))
219
+
220
+ if parser.has_option('debug', '__dev'):
221
+ properties['logs'] = cls.__search_in_environ(
222
+ parser.get('debug', '__dev')).lower()
223
+
224
+ return properties
225
+
226
+ @staticmethod
227
+ def __search_in_environ(var_name: str):
228
+ if re.fullmatch(r'{[a-zA-Z_]\w*}', var_name) and var_name[1:-1] in os.environ:
229
+ return os.environ[var_name[1:-1]]
230
+
231
+ return var_name
232
+
233
+ @staticmethod
234
+ def __check_property_value(value: str):
235
+ if value is not None and value != "":
236
+ return True
237
+
238
+ return False
239
+
240
+ @staticmethod
241
+ def __check_toml_section(toml_dict: dict, section_name: str) -> bool:
242
+ if section_name not in toml_dict.keys():
243
+ return False
244
+ if not type(toml_dict.get(section_name)) is dict:
245
+ return False
246
+
247
+ return True
248
+
249
+ @staticmethod
250
+ def __check_token_property(properties: dict):
251
+ if PropertiesNames.PRIVATE_TOKEN in properties:
252
+ warnings.warn(
253
+ 'The configuration file specifies a private token. It is not safe.'
254
+ ' Use TMS_PRIVATE_TOKEN environment variable',
255
+ category=Warning,
256
+ stacklevel=2)
257
+ warnings.simplefilter('default', Warning)
@@ -0,0 +1,9 @@
1
+ from testit_python_commons.client.api_client import (
2
+ ApiClientWorker,
3
+ ClientConfiguration
4
+ )
5
+
6
+ __all__ = [
7
+ 'ApiClientWorker',
8
+ 'ClientConfiguration'
9
+ ]