testit-python-commons 3.3.2__tar.gz → 3.4.1__tar.gz
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.
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/PKG-INFO +11 -2
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/setup.py +1 -1
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/app_properties.py +12 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/client/api_client.py +206 -20
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/client/converter.py +25 -2
- testit_python_commons-3.4.1/src/testit_python_commons/models/fixture.py +24 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/services/__init__.py +2 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/services/adapter_manager.py +34 -7
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/services/adapter_manager_configuration.py +8 -8
- testit_python_commons-3.4.1/src/testit_python_commons/services/fixture_manager.py +60 -0
- testit_python_commons-3.4.1/src/testit_python_commons/services/fixture_storage.py +40 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/services/plugin_manager.py +12 -1
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/services/utils.py +8 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons.egg-info/PKG-INFO +11 -2
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons.egg-info/SOURCES.txt +3 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/README.md +0 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/setup.cfg +0 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit.py +0 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/__init__.py +0 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/client/__init__.py +0 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/client/client_configuration.py +0 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/decorators.py +0 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/dynamic_methods.py +0 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/models/__init__.py +0 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/models/adapter_mode.py +0 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/models/link.py +0 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/models/link_type.py +0 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/models/outcome_type.py +0 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/models/step_result.py +0 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/models/test_result.py +0 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/models/test_result_with_all_fixture_step_results_model.py +0 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/services/logger.py +0 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/services/retry.py +0 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/services/step_manager.py +0 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/services/step_result_storage.py +0 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/step.py +0 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons.egg-info/dependency_links.txt +0 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons.egg-info/requires.txt +0 -0
- {testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: testit-python-commons
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.4.1
|
|
4
4
|
Summary: Python commons for Test IT
|
|
5
5
|
Home-page: https://github.com/testit-tms/adapters-python/
|
|
6
6
|
Author: Integration team
|
|
@@ -17,6 +17,15 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
Requires-Dist: pluggy
|
|
19
19
|
Requires-Dist: testit-api-client==5.0.0
|
|
20
|
+
Dynamic: author
|
|
21
|
+
Dynamic: author-email
|
|
22
|
+
Dynamic: classifier
|
|
23
|
+
Dynamic: description
|
|
24
|
+
Dynamic: description-content-type
|
|
25
|
+
Dynamic: home-page
|
|
26
|
+
Dynamic: license
|
|
27
|
+
Dynamic: requires-dist
|
|
28
|
+
Dynamic: summary
|
|
20
29
|
|
|
21
30
|
# How to enable debug logging?
|
|
22
31
|
1. Add in **connection_config.ini** file from the root directory of the project:
|
|
@@ -113,6 +113,10 @@ class AppProperties:
|
|
|
113
113
|
option.set_automatic_updation_links_to_test_cases):
|
|
114
114
|
cli_properties['automaticupdationlinkstotestcases'] = option.set_automatic_updation_links_to_test_cases
|
|
115
115
|
|
|
116
|
+
if hasattr(option, 'set_import_realtime') and cls.__check_property_value(
|
|
117
|
+
option.set_import_realtime):
|
|
118
|
+
cli_properties['importrealtime'] = option.set_import_realtime
|
|
119
|
+
|
|
116
120
|
return cli_properties
|
|
117
121
|
|
|
118
122
|
@classmethod
|
|
@@ -165,6 +169,11 @@ class AppProperties:
|
|
|
165
169
|
env_properties['automaticupdationlinkstotestcases'] = os.environ.get(
|
|
166
170
|
f'{cls.__env_prefix}_AUTOMATIC_UPDATION_LINKS_TO_TEST_CASES')
|
|
167
171
|
|
|
172
|
+
if f'{cls.__env_prefix}_IMPORT_REALTIME' in os.environ.keys() and cls.__check_property_value(
|
|
173
|
+
os.environ.get(f'{cls.__env_prefix}_IMPORT_REALTIME')):
|
|
174
|
+
env_properties['importrealtime'] = os.environ.get(
|
|
175
|
+
f'{cls.__env_prefix}_IMPORT_REALTIME')
|
|
176
|
+
|
|
168
177
|
return env_properties
|
|
169
178
|
|
|
170
179
|
@classmethod
|
|
@@ -226,6 +235,9 @@ class AppProperties:
|
|
|
226
235
|
if not cls.__check_property_value(properties.get('automaticupdationlinkstotestcases')):
|
|
227
236
|
properties['automaticupdationlinkstotestcases'] = 'false'
|
|
228
237
|
|
|
238
|
+
if not cls.__check_property_value(properties.get('importrealtime')):
|
|
239
|
+
properties['importrealtime'] = 'true'
|
|
240
|
+
|
|
229
241
|
@staticmethod
|
|
230
242
|
def __search_in_environ(var_name: str):
|
|
231
243
|
if re.fullmatch(r'{[a-zA-Z_]\w*}', var_name) and var_name[1:-1] in os.environ:
|
|
@@ -4,10 +4,14 @@ import typing
|
|
|
4
4
|
from datetime import datetime
|
|
5
5
|
|
|
6
6
|
from testit_api_client import ApiClient, Configuration
|
|
7
|
-
from testit_api_client.api import AttachmentsApi, AutoTestsApi, TestRunsApi, TestResultsApi
|
|
7
|
+
from testit_api_client.api import AttachmentsApi, AutoTestsApi, TestRunsApi, TestResultsApi, WorkItemsApi
|
|
8
8
|
from testit_api_client.models import (
|
|
9
|
+
AutoTestModel,
|
|
10
|
+
AutoTestPostModel,
|
|
11
|
+
AutoTestPutModel,
|
|
9
12
|
AttachmentPutModel,
|
|
10
|
-
|
|
13
|
+
AutoTestResultsForTestRunModel,
|
|
14
|
+
TestResultResponse,
|
|
11
15
|
WorkItemIdModel,
|
|
12
16
|
WorkItemIdentifierModel
|
|
13
17
|
)
|
|
@@ -15,13 +19,13 @@ from testit_api_client.models import (
|
|
|
15
19
|
from testit_python_commons.client.client_configuration import ClientConfiguration
|
|
16
20
|
from testit_python_commons.client.converter import Converter
|
|
17
21
|
from testit_python_commons.models.test_result import TestResult
|
|
18
|
-
from testit_python_commons.models.test_result_with_all_fixture_step_results_model import \
|
|
19
|
-
TestResultWithAllFixtureStepResults
|
|
20
22
|
from testit_python_commons.services.logger import adapter_logger
|
|
21
23
|
from testit_python_commons.services.retry import retry
|
|
22
24
|
|
|
23
25
|
|
|
24
26
|
class ApiClientWorker:
|
|
27
|
+
__max_tests_for_write = 100
|
|
28
|
+
|
|
25
29
|
def __init__(self, config: ClientConfiguration):
|
|
26
30
|
api_client_config = self.__get_api_client_configuration(
|
|
27
31
|
url=config.get_url(),
|
|
@@ -33,6 +37,7 @@ class ApiClientWorker:
|
|
|
33
37
|
self.__autotest_api = AutoTestsApi(api_client=api_client)
|
|
34
38
|
self.__attachments_api = AttachmentsApi(api_client=api_client)
|
|
35
39
|
self.__test_results_api = TestResultsApi(api_client=api_client)
|
|
40
|
+
self.__work_items_api = WorkItemsApi(api_client=api_client)
|
|
36
41
|
self.__config = config
|
|
37
42
|
|
|
38
43
|
@staticmethod
|
|
@@ -86,16 +91,175 @@ class ApiClientWorker:
|
|
|
86
91
|
autotests = self.__autotest_api.api_v2_auto_tests_search_post(autotests_select_model=model)
|
|
87
92
|
|
|
88
93
|
if autotests:
|
|
89
|
-
self.__update_test(test_result, autotests[0]
|
|
90
|
-
|
|
91
|
-
autotest_global_id = autotests[0].id
|
|
94
|
+
self.__update_test(test_result, autotests[0])
|
|
92
95
|
else:
|
|
93
|
-
|
|
96
|
+
self.__create_test(test_result)
|
|
97
|
+
|
|
98
|
+
return self.__load_test_result(test_result)
|
|
99
|
+
|
|
100
|
+
@adapter_logger
|
|
101
|
+
def write_tests(self, test_results: typing.List[TestResult], fixture_containers: dict):
|
|
102
|
+
autotests_for_create = []
|
|
103
|
+
autotests_for_update = []
|
|
104
|
+
results_for_autotests_being_created = []
|
|
105
|
+
results_for_autotests_being_updated = []
|
|
106
|
+
|
|
107
|
+
for test_result in test_results:
|
|
108
|
+
test_result = self.__add_fixtures_to_test_result(test_result, fixture_containers)
|
|
109
|
+
|
|
110
|
+
model = Converter.project_id_and_external_id_to_auto_tests_search_post_request(
|
|
111
|
+
self.__config.get_project_id(),
|
|
112
|
+
test_result.get_external_id())
|
|
113
|
+
|
|
114
|
+
test_result_model = Converter.test_result_to_testrun_result_post_model(
|
|
115
|
+
test_result,
|
|
116
|
+
self.__config.get_configuration_id())
|
|
117
|
+
|
|
118
|
+
autotests = self.__autotest_api.api_v2_auto_tests_search_post(autotests_select_model=model)
|
|
119
|
+
|
|
120
|
+
if autotests:
|
|
121
|
+
autotest_for_update = self.__prepare_to_update_autotest(test_result, autotests[0])
|
|
122
|
+
|
|
123
|
+
autotests_for_update.append(autotest_for_update)
|
|
124
|
+
results_for_autotests_being_updated.append(test_result_model)
|
|
125
|
+
|
|
126
|
+
if len(autotests_for_update) >= self.__max_tests_for_write:
|
|
127
|
+
self.__update_tests(autotests_for_update)
|
|
128
|
+
self.__load_test_results(results_for_autotests_being_updated)
|
|
129
|
+
|
|
130
|
+
autotests_for_update.clear()
|
|
131
|
+
results_for_autotests_being_updated.clear()
|
|
132
|
+
else:
|
|
133
|
+
autotest_for_create = self.__prepare_to_create_autotest(test_result)
|
|
134
|
+
|
|
135
|
+
autotests_for_create.append(autotest_for_create)
|
|
136
|
+
results_for_autotests_being_created.append(test_result_model)
|
|
137
|
+
|
|
138
|
+
if len(autotests_for_create) >= self.__max_tests_for_write:
|
|
139
|
+
self.__create_tests(autotests_for_create)
|
|
140
|
+
self.__load_test_results(results_for_autotests_being_created)
|
|
141
|
+
|
|
142
|
+
autotests_for_create.clear()
|
|
143
|
+
results_for_autotests_being_created.clear()
|
|
144
|
+
|
|
145
|
+
if len(autotests_for_update) > 0:
|
|
146
|
+
self.__update_tests(autotests_for_update)
|
|
147
|
+
self.__load_test_results(results_for_autotests_being_updated)
|
|
148
|
+
|
|
149
|
+
autotests_for_update.clear()
|
|
150
|
+
results_for_autotests_being_updated.clear()
|
|
151
|
+
|
|
152
|
+
if len(autotests_for_create) > 0:
|
|
153
|
+
self.__create_tests(autotests_for_create)
|
|
154
|
+
self.__load_test_results(results_for_autotests_being_created)
|
|
155
|
+
|
|
156
|
+
autotests_for_create.clear()
|
|
157
|
+
results_for_autotests_being_created.clear()
|
|
158
|
+
|
|
159
|
+
@adapter_logger
|
|
160
|
+
def __prepare_to_create_autotest(self, test_result: TestResult) -> AutoTestPostModel:
|
|
161
|
+
logging.debug('Preparing to create the auto test ', test_result.get_external_id())
|
|
162
|
+
|
|
163
|
+
model = Converter.test_result_to_autotest_post_model(
|
|
164
|
+
test_result,
|
|
165
|
+
self.__config.get_project_id())
|
|
166
|
+
model.work_item_ids_for_link_with_auto_test = self.__get_work_item_uuids_for_link_with_auto_test(
|
|
167
|
+
test_result.get_work_item_ids())
|
|
168
|
+
|
|
169
|
+
return model
|
|
170
|
+
|
|
171
|
+
@adapter_logger
|
|
172
|
+
def __prepare_to_update_autotest(
|
|
173
|
+
self,
|
|
174
|
+
test_result: TestResult,
|
|
175
|
+
autotest: AutoTestModel) -> AutoTestPutModel:
|
|
176
|
+
logging.debug('Preparing to update the auto test ', test_result.get_external_id())
|
|
177
|
+
|
|
178
|
+
model = Converter.test_result_to_autotest_put_model(
|
|
179
|
+
test_result,
|
|
180
|
+
self.__config.get_project_id())
|
|
181
|
+
model.is_flaky = autotest.is_flaky
|
|
182
|
+
model.work_item_ids_for_link_with_auto_test = self.__get_work_item_uuids_for_link_with_auto_test(
|
|
183
|
+
test_result.get_work_item_ids(),
|
|
184
|
+
str(autotest.global_id))
|
|
185
|
+
|
|
186
|
+
return model
|
|
187
|
+
|
|
188
|
+
@staticmethod
|
|
189
|
+
@adapter_logger
|
|
190
|
+
def __add_fixtures_to_test_result(
|
|
191
|
+
test_result: TestResult,
|
|
192
|
+
fixtures_containers: dict) -> TestResult:
|
|
193
|
+
setup_results = []
|
|
194
|
+
teardown_results = []
|
|
195
|
+
|
|
196
|
+
for uuid, fixtures_container in fixtures_containers.items():
|
|
197
|
+
if test_result.get_external_id() in fixtures_container.external_ids:
|
|
198
|
+
if fixtures_container.befores:
|
|
199
|
+
setup_results += fixtures_container.befores[0].steps
|
|
200
|
+
|
|
201
|
+
if fixtures_container.afters:
|
|
202
|
+
teardown_results = fixtures_container.afters[0].steps + teardown_results
|
|
203
|
+
|
|
204
|
+
test_result.set_setup_results(setup_results)
|
|
205
|
+
test_result.set_teardown_results(teardown_results)
|
|
206
|
+
|
|
207
|
+
return test_result
|
|
208
|
+
|
|
209
|
+
@adapter_logger
|
|
210
|
+
def __get_work_item_uuids_for_link_with_auto_test(
|
|
211
|
+
self,
|
|
212
|
+
work_item_ids: list,
|
|
213
|
+
autotest_global_id: str = None) -> list:
|
|
214
|
+
linked_work_items = []
|
|
94
215
|
|
|
95
216
|
if autotest_global_id:
|
|
96
|
-
self.
|
|
217
|
+
linked_work_items = self.__get_work_items_linked_to_autotest(autotest_global_id)
|
|
97
218
|
|
|
98
|
-
|
|
219
|
+
work_item_uuids = self.__prepare_list_of_work_item_uuids(linked_work_items, work_item_ids)
|
|
220
|
+
|
|
221
|
+
return work_item_uuids
|
|
222
|
+
|
|
223
|
+
@adapter_logger
|
|
224
|
+
def __prepare_list_of_work_item_uuids(
|
|
225
|
+
self,
|
|
226
|
+
linked_work_items: list,
|
|
227
|
+
work_item_ids: list) -> list:
|
|
228
|
+
work_item_uuids = []
|
|
229
|
+
|
|
230
|
+
for linked_work_item in linked_work_items:
|
|
231
|
+
linked_work_item_id = str(linked_work_item.global_id)
|
|
232
|
+
linked_work_item_uuid = linked_work_item.id
|
|
233
|
+
|
|
234
|
+
if linked_work_item_id in work_item_ids:
|
|
235
|
+
work_item_ids.remove(linked_work_item_id)
|
|
236
|
+
work_item_uuids.append(linked_work_item_uuid)
|
|
237
|
+
|
|
238
|
+
continue
|
|
239
|
+
|
|
240
|
+
if self.__config.get_automatic_updation_links_to_test_cases() != 'true':
|
|
241
|
+
work_item_uuids.append(linked_work_item_uuid)
|
|
242
|
+
|
|
243
|
+
for work_item_id in work_item_ids:
|
|
244
|
+
work_item_uuid = self.__get_work_item_uuid_by_work_item_id(work_item_id)
|
|
245
|
+
|
|
246
|
+
if work_item_uuid:
|
|
247
|
+
work_item_uuids.append(work_item_uuid)
|
|
248
|
+
|
|
249
|
+
return work_item_uuids
|
|
250
|
+
|
|
251
|
+
@adapter_logger
|
|
252
|
+
def __get_work_item_uuid_by_work_item_id(self, work_item_id: str) -> str or None:
|
|
253
|
+
logging.debug('Getting workitem by id ' + work_item_id)
|
|
254
|
+
|
|
255
|
+
try:
|
|
256
|
+
work_item = self.__work_items_api.get_work_item_by_id(id=work_item_id)
|
|
257
|
+
|
|
258
|
+
logging.debug(f'Got workitem {work_item}')
|
|
259
|
+
|
|
260
|
+
return work_item.id
|
|
261
|
+
except Exception as exc:
|
|
262
|
+
logging.error(f'Getting workitem by id {work_item_id} status: {exc}')
|
|
99
263
|
|
|
100
264
|
@adapter_logger
|
|
101
265
|
def __get_work_items_linked_to_autotest(self, autotest_global_id: str) -> typing.List[WorkItemIdentifierModel]:
|
|
@@ -123,9 +287,7 @@ class ApiClientWorker:
|
|
|
123
287
|
def __create_test(self, test_result: TestResult) -> str:
|
|
124
288
|
logging.debug(f'Autotest "{test_result.get_autotest_name()}" was not found')
|
|
125
289
|
|
|
126
|
-
model =
|
|
127
|
-
test_result,
|
|
128
|
-
self.__config.get_project_id())
|
|
290
|
+
model = self.__prepare_to_create_autotest(test_result)
|
|
129
291
|
|
|
130
292
|
autotest_response = self.__autotest_api.create_auto_test(auto_test_post_model=model)
|
|
131
293
|
|
|
@@ -134,18 +296,31 @@ class ApiClientWorker:
|
|
|
134
296
|
return autotest_response.id
|
|
135
297
|
|
|
136
298
|
@adapter_logger
|
|
137
|
-
def
|
|
299
|
+
def __create_tests(self, autotests_for_create: typing.List[AutoTestPostModel]):
|
|
300
|
+
logging.debug(f'Creating autotests: "{autotests_for_create}')
|
|
301
|
+
|
|
302
|
+
self.__autotest_api.create_multiple(auto_test_post_model=autotests_for_create)
|
|
303
|
+
|
|
304
|
+
logging.debug(f'Autotests were created')
|
|
305
|
+
|
|
306
|
+
@adapter_logger
|
|
307
|
+
def __update_test(self, test_result: TestResult, autotest: AutoTestModel):
|
|
138
308
|
logging.debug(f'Autotest "{test_result.get_autotest_name()}" was found')
|
|
139
309
|
|
|
140
|
-
model =
|
|
141
|
-
test_result,
|
|
142
|
-
self.__config.get_project_id())
|
|
143
|
-
model.is_flaky = is_flaky
|
|
310
|
+
model = self.__prepare_to_update_autotest(test_result, autotest)
|
|
144
311
|
|
|
145
312
|
self.__autotest_api.update_auto_test(auto_test_put_model=model)
|
|
146
313
|
|
|
147
314
|
logging.debug(f'Autotest "{test_result.get_autotest_name()}" was updated')
|
|
148
315
|
|
|
316
|
+
@adapter_logger
|
|
317
|
+
def __update_tests(self, autotests_for_update: typing.List[AutoTestPutModel]):
|
|
318
|
+
logging.debug(f'Updating autotests: {autotests_for_update}')
|
|
319
|
+
|
|
320
|
+
self.__autotest_api.update_multiple(auto_test_put_model=autotests_for_update)
|
|
321
|
+
|
|
322
|
+
logging.debug(f'Autotests were updated')
|
|
323
|
+
|
|
149
324
|
@adapter_logger
|
|
150
325
|
@retry
|
|
151
326
|
def __unlink_test_to_work_item(self, autotest_global_id: str, work_item_id: str):
|
|
@@ -180,11 +355,22 @@ class ApiClientWorker:
|
|
|
180
355
|
return Converter.get_test_result_id_from_testrun_result_post_response(response)
|
|
181
356
|
|
|
182
357
|
@adapter_logger
|
|
183
|
-
def
|
|
358
|
+
def __load_test_results(self, test_results: typing.List[AutoTestResultsForTestRunModel]):
|
|
359
|
+
logging.debug(f'Loading test results: {test_results}')
|
|
360
|
+
|
|
361
|
+
self.__test_run_api.set_auto_test_results_for_test_run(
|
|
362
|
+
id=self.__config.get_test_run_id(),
|
|
363
|
+
auto_test_results_for_test_run_model=test_results)
|
|
364
|
+
|
|
365
|
+
@adapter_logger
|
|
366
|
+
def get_test_result_by_id(self, test_result_id: str) -> TestResultResponse:
|
|
184
367
|
return self.__test_results_api.api_v2_test_results_id_get(id=test_result_id)
|
|
185
368
|
|
|
186
369
|
@adapter_logger
|
|
187
|
-
def update_test_results(self,
|
|
370
|
+
def update_test_results(self, fixtures_containers: dict, test_result_ids: dict):
|
|
371
|
+
test_results = Converter.fixtures_containers_to_test_results_with_all_fixture_step_results(
|
|
372
|
+
fixtures_containers, test_result_ids)
|
|
373
|
+
|
|
188
374
|
for test_result in test_results:
|
|
189
375
|
model = Converter.convert_test_result_model_to_test_results_id_put_request(
|
|
190
376
|
self.get_test_result_by_id(test_result.get_test_result_id()))
|
|
@@ -17,7 +17,7 @@ from testit_api_client.models import (
|
|
|
17
17
|
SearchAutoTestsQueryIncludesModel,
|
|
18
18
|
AutotestsSelectModel,
|
|
19
19
|
TestResultUpdateV2Request,
|
|
20
|
-
|
|
20
|
+
TestResultResponse,
|
|
21
21
|
TestResultV2GetModel,
|
|
22
22
|
AttachmentModel,
|
|
23
23
|
AttachmentUpdateRequest
|
|
@@ -179,7 +179,7 @@ class Converter:
|
|
|
179
179
|
@adapter_logger
|
|
180
180
|
def convert_test_result_model_to_test_results_id_put_request(
|
|
181
181
|
cls,
|
|
182
|
-
test_result:
|
|
182
|
+
test_result: TestResultResponse) -> TestResultUpdateV2Request:
|
|
183
183
|
return TestResultUpdateV2Request(
|
|
184
184
|
failure_class_ids=test_result.failure_class_ids,
|
|
185
185
|
outcome=test_result.outcome,
|
|
@@ -331,6 +331,29 @@ class Converter:
|
|
|
331
331
|
|
|
332
332
|
return autotest_model_step_results
|
|
333
333
|
|
|
334
|
+
@staticmethod
|
|
335
|
+
@adapter_logger
|
|
336
|
+
def fixtures_containers_to_test_results_with_all_fixture_step_results(
|
|
337
|
+
fixtures_containers: dict,
|
|
338
|
+
test_result_ids: dict) -> typing.List[TestResultWithAllFixtureStepResults]:
|
|
339
|
+
test_results_with_all_fixture_step_results = []
|
|
340
|
+
|
|
341
|
+
for external_id, test_result_id in test_result_ids.items():
|
|
342
|
+
test_result_with_all_fixture_step_results = TestResultWithAllFixtureStepResults(test_result_id)
|
|
343
|
+
|
|
344
|
+
for uuid, fixtures_container in fixtures_containers.items():
|
|
345
|
+
if external_id in fixtures_container.external_ids:
|
|
346
|
+
if fixtures_container.befores:
|
|
347
|
+
test_result_with_all_fixture_step_results.set_setup_results(fixtures_container.befores[0].steps)
|
|
348
|
+
|
|
349
|
+
if fixtures_container.afters:
|
|
350
|
+
test_result_with_all_fixture_step_results.set_teardown_results(
|
|
351
|
+
fixtures_container.afters[0].steps)
|
|
352
|
+
|
|
353
|
+
test_results_with_all_fixture_step_results.append(test_result_with_all_fixture_step_results)
|
|
354
|
+
|
|
355
|
+
return test_results_with_all_fixture_step_results
|
|
356
|
+
|
|
334
357
|
@classmethod
|
|
335
358
|
@adapter_logger
|
|
336
359
|
def step_results_to_auto_test_step_result_update_request(
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from attr import attrs, attrib
|
|
2
|
+
from attr import Factory
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@attrs
|
|
6
|
+
class FixtureResult:
|
|
7
|
+
title = attrib(default=None)
|
|
8
|
+
outcome = attrib(default=None)
|
|
9
|
+
description = attrib(default=None)
|
|
10
|
+
message = attrib(default=None)
|
|
11
|
+
stacktrace = attrib(default=None)
|
|
12
|
+
steps = attrib(default=None)
|
|
13
|
+
attachments = attrib(default=Factory(list))
|
|
14
|
+
parameters = attrib(default=Factory(list))
|
|
15
|
+
start = attrib(default=None)
|
|
16
|
+
stop = attrib(default=None)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@attrs
|
|
20
|
+
class FixturesContainer:
|
|
21
|
+
uuid = attrib(default=None)
|
|
22
|
+
external_ids = attrib(default=Factory(list))
|
|
23
|
+
befores = attrib(default=Factory(list))
|
|
24
|
+
afters = attrib(default=Factory(list))
|
|
@@ -2,6 +2,7 @@ from pluggy import HookimplMarker
|
|
|
2
2
|
|
|
3
3
|
from testit_python_commons.services.adapter_manager import AdapterManager
|
|
4
4
|
from testit_python_commons.services.plugin_manager import TmsPluginManager
|
|
5
|
+
from testit_python_commons.services.fixture_manager import FixtureManager
|
|
5
6
|
from testit_python_commons.services.step_manager import StepManager
|
|
6
7
|
from testit_python_commons.services.utils import Utils
|
|
7
8
|
|
|
@@ -10,6 +11,7 @@ hookimpl = HookimplMarker("testit")
|
|
|
10
11
|
__all__ = [
|
|
11
12
|
'AdapterManager',
|
|
12
13
|
'TmsPluginManager',
|
|
14
|
+
'FixtureManager',
|
|
13
15
|
'StepManager',
|
|
14
16
|
'Utils',
|
|
15
17
|
'hookimpl'
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import os
|
|
2
|
-
import typing
|
|
3
2
|
import uuid
|
|
4
3
|
|
|
5
4
|
from testit_python_commons.client.api_client import ApiClientWorker
|
|
6
5
|
from testit_python_commons.client.client_configuration import ClientConfiguration
|
|
7
6
|
from testit_python_commons.models.adapter_mode import AdapterMode
|
|
8
7
|
from testit_python_commons.models.test_result import TestResult
|
|
9
|
-
from testit_python_commons.
|
|
8
|
+
from testit_python_commons.services.fixture_manager import FixtureManager
|
|
10
9
|
from testit_python_commons.services.adapter_manager_configuration import AdapterManagerConfiguration
|
|
11
10
|
from testit_python_commons.services.logger import adapter_logger
|
|
12
11
|
from testit_python_commons.services.utils import Utils
|
|
@@ -16,9 +15,13 @@ class AdapterManager:
|
|
|
16
15
|
def __init__(
|
|
17
16
|
self,
|
|
18
17
|
adapter_configuration: AdapterManagerConfiguration,
|
|
19
|
-
client_configuration: ClientConfiguration
|
|
18
|
+
client_configuration: ClientConfiguration,
|
|
19
|
+
fixture_manager: FixtureManager):
|
|
20
20
|
self.__config = adapter_configuration
|
|
21
21
|
self.__api_client = ApiClientWorker(client_configuration)
|
|
22
|
+
self.__fixture_manager = fixture_manager
|
|
23
|
+
self.__test_result_map = {}
|
|
24
|
+
self.__test_results = []
|
|
22
25
|
|
|
23
26
|
@adapter_logger
|
|
24
27
|
def set_test_run_id(self, test_run_id: str):
|
|
@@ -40,15 +43,39 @@ class AdapterManager:
|
|
|
40
43
|
return
|
|
41
44
|
|
|
42
45
|
@adapter_logger
|
|
43
|
-
def write_test(self, test_result: TestResult)
|
|
46
|
+
def write_test(self, test_result: TestResult):
|
|
47
|
+
if self.__config.should_import_realtime():
|
|
48
|
+
self.__write_test_realtime(test_result)
|
|
49
|
+
|
|
50
|
+
return
|
|
51
|
+
|
|
52
|
+
self.__test_results.append(test_result)
|
|
53
|
+
|
|
54
|
+
@adapter_logger
|
|
55
|
+
def __write_test_realtime(self, test_result: TestResult):
|
|
44
56
|
test_result.set_automatic_creation_test_cases(
|
|
45
57
|
self.__config.should_automatic_creation_test_cases())
|
|
46
58
|
|
|
47
|
-
|
|
59
|
+
self.__test_result_map[test_result.get_external_id()] = self.__api_client.write_test(test_result)
|
|
48
60
|
|
|
49
61
|
@adapter_logger
|
|
50
|
-
def
|
|
51
|
-
self.
|
|
62
|
+
def write_tests(self):
|
|
63
|
+
if self.__config.should_import_realtime():
|
|
64
|
+
self.__load_setup_and_teardown_step_results()
|
|
65
|
+
|
|
66
|
+
return
|
|
67
|
+
|
|
68
|
+
self.__write_tests_after_all()
|
|
69
|
+
|
|
70
|
+
@adapter_logger
|
|
71
|
+
def __load_setup_and_teardown_step_results(self):
|
|
72
|
+
self.__api_client.update_test_results(self.__fixture_manager.get_all_items(), self.__test_result_map)
|
|
73
|
+
|
|
74
|
+
@adapter_logger
|
|
75
|
+
def __write_tests_after_all(self):
|
|
76
|
+
fixtures = self.__fixture_manager.get_all_items()
|
|
77
|
+
|
|
78
|
+
self.__api_client.write_tests(self.__test_results, fixtures)
|
|
52
79
|
|
|
53
80
|
@adapter_logger
|
|
54
81
|
def load_attachments(self, attach_paths: list or tuple):
|
|
@@ -11,13 +11,9 @@ class AdapterManagerConfiguration:
|
|
|
11
11
|
self.__test_run_id = Utils.uuid_check(app_properties.get('testrunid'))
|
|
12
12
|
|
|
13
13
|
self.__adapter_mode = app_properties.get('adaptermode', AdapterMode.USE_FILTER)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
if __automatic_creation_test_cases and __automatic_creation_test_cases == 'true':
|
|
18
|
-
self.__automatic_creation_test_cases = True
|
|
19
|
-
else:
|
|
20
|
-
self.__automatic_creation_test_cases = False
|
|
14
|
+
self.__automatic_creation_test_cases = Utils.convert_value_str_to_bool(
|
|
15
|
+
app_properties.get('automaticcreationtestcases'))
|
|
16
|
+
self.__import_realtime = Utils.convert_value_str_to_bool(app_properties.get('importrealtime'))
|
|
21
17
|
|
|
22
18
|
@adapter_logger
|
|
23
19
|
def get_test_run_id(self):
|
|
@@ -32,5 +28,9 @@ class AdapterManagerConfiguration:
|
|
|
32
28
|
return self.__adapter_mode
|
|
33
29
|
|
|
34
30
|
@adapter_logger
|
|
35
|
-
def should_automatic_creation_test_cases(self):
|
|
31
|
+
def should_automatic_creation_test_cases(self) -> bool:
|
|
36
32
|
return self.__automatic_creation_test_cases
|
|
33
|
+
|
|
34
|
+
@adapter_logger
|
|
35
|
+
def should_import_realtime(self) -> bool:
|
|
36
|
+
return self.__import_realtime
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
from testit_python_commons.services.fixture_storage import ThreadContextFixtures
|
|
2
|
+
from testit_python_commons.models.step_result import StepResult
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class FixtureManager:
|
|
6
|
+
def __init__(self):
|
|
7
|
+
self._items = ThreadContextFixtures()
|
|
8
|
+
self._orphan_items = []
|
|
9
|
+
|
|
10
|
+
def _update_item(self, uuid, **kwargs):
|
|
11
|
+
item = self._items[uuid] if uuid else self._items[next(reversed(self._items))]
|
|
12
|
+
for name, value in kwargs.items():
|
|
13
|
+
attr = getattr(item, name)
|
|
14
|
+
if isinstance(attr, list):
|
|
15
|
+
attr.append(value)
|
|
16
|
+
else:
|
|
17
|
+
setattr(item, name, value)
|
|
18
|
+
|
|
19
|
+
def _last_executable(self):
|
|
20
|
+
for _uuid in reversed(self._items):
|
|
21
|
+
if isinstance(self._items[_uuid], StepResult):
|
|
22
|
+
return _uuid
|
|
23
|
+
|
|
24
|
+
def get_item(self, uuid):
|
|
25
|
+
return self._items.get(uuid)
|
|
26
|
+
|
|
27
|
+
def get_last_item(self, item_type=None):
|
|
28
|
+
for _uuid in reversed(self._items):
|
|
29
|
+
if item_type is None:
|
|
30
|
+
return self._items.get(_uuid)
|
|
31
|
+
if type(self._items[_uuid]) == item_type:
|
|
32
|
+
return self._items.get(_uuid)
|
|
33
|
+
|
|
34
|
+
def start_group(self, uuid, group):
|
|
35
|
+
self._items[uuid] = group
|
|
36
|
+
|
|
37
|
+
def stop_group(self, uuid, **kwargs):
|
|
38
|
+
self._update_item(uuid, **kwargs)
|
|
39
|
+
|
|
40
|
+
def update_group(self, uuid, **kwargs):
|
|
41
|
+
self._update_item(uuid, **kwargs)
|
|
42
|
+
|
|
43
|
+
def start_before_fixture(self, parent_uuid, uuid, fixture):
|
|
44
|
+
self._items.get(parent_uuid).befores.append(fixture)
|
|
45
|
+
self._items[uuid] = fixture
|
|
46
|
+
|
|
47
|
+
def stop_before_fixture(self, uuid, **kwargs):
|
|
48
|
+
self._update_item(uuid, **kwargs)
|
|
49
|
+
self._items.pop(uuid)
|
|
50
|
+
|
|
51
|
+
def start_after_fixture(self, parent_uuid, uuid, fixture):
|
|
52
|
+
self._items.get(parent_uuid).afters.append(fixture)
|
|
53
|
+
self._items[uuid] = fixture
|
|
54
|
+
|
|
55
|
+
def stop_after_fixture(self, uuid, **kwargs):
|
|
56
|
+
self._update_item(uuid, **kwargs)
|
|
57
|
+
self._items.pop(uuid)
|
|
58
|
+
|
|
59
|
+
def get_all_items(self):
|
|
60
|
+
return self._items.get_all()
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import threading
|
|
2
|
+
from collections import OrderedDict, defaultdict
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class ThreadContextFixtures:
|
|
6
|
+
_thread_context = defaultdict(OrderedDict)
|
|
7
|
+
_init_thread: threading.Thread
|
|
8
|
+
|
|
9
|
+
@property
|
|
10
|
+
def thread_context(self):
|
|
11
|
+
context = self._thread_context[threading.current_thread()]
|
|
12
|
+
if not context and threading.current_thread() is not self._init_thread:
|
|
13
|
+
uuid, last_item = next(reversed(self._thread_context[self._init_thread].items()))
|
|
14
|
+
context[uuid] = last_item
|
|
15
|
+
return context
|
|
16
|
+
|
|
17
|
+
def __init__(self, *args, **kwargs):
|
|
18
|
+
self._init_thread = threading.current_thread()
|
|
19
|
+
super().__init__(*args, **kwargs)
|
|
20
|
+
|
|
21
|
+
def __setitem__(self, key, value):
|
|
22
|
+
self.thread_context.__setitem__(key, value)
|
|
23
|
+
|
|
24
|
+
def __getitem__(self, item):
|
|
25
|
+
return self.thread_context.__getitem__(item)
|
|
26
|
+
|
|
27
|
+
def __iter__(self):
|
|
28
|
+
return self.thread_context.__iter__()
|
|
29
|
+
|
|
30
|
+
def __reversed__(self):
|
|
31
|
+
return self.thread_context.__reversed__()
|
|
32
|
+
|
|
33
|
+
def get(self, key):
|
|
34
|
+
return self.thread_context.get(key)
|
|
35
|
+
|
|
36
|
+
def pop(self, key):
|
|
37
|
+
return self.thread_context.pop(key)
|
|
38
|
+
|
|
39
|
+
def get_all(self):
|
|
40
|
+
return dict(self.thread_context.items())
|
|
@@ -9,6 +9,7 @@ from testit_python_commons.app_properties import AppProperties
|
|
|
9
9
|
class TmsPluginManager:
|
|
10
10
|
__plugin_manager = None
|
|
11
11
|
__adapter_manager = None
|
|
12
|
+
__fixture_manager = None
|
|
12
13
|
__step_manager = None
|
|
13
14
|
__logger = None
|
|
14
15
|
|
|
@@ -32,11 +33,21 @@ class TmsPluginManager:
|
|
|
32
33
|
|
|
33
34
|
client_configuration = ClientConfiguration(app_properties)
|
|
34
35
|
adapter_configuration = AdapterManagerConfiguration(app_properties)
|
|
36
|
+
fixture_manager = cls.get_fixture_manager()
|
|
35
37
|
|
|
36
|
-
cls.__adapter_manager = AdapterManager(adapter_configuration, client_configuration)
|
|
38
|
+
cls.__adapter_manager = AdapterManager(adapter_configuration, client_configuration, fixture_manager)
|
|
37
39
|
|
|
38
40
|
return cls.__adapter_manager
|
|
39
41
|
|
|
42
|
+
@classmethod
|
|
43
|
+
def get_fixture_manager(cls):
|
|
44
|
+
if cls.__fixture_manager is None:
|
|
45
|
+
from testit_python_commons.services.fixture_manager import FixtureManager
|
|
46
|
+
|
|
47
|
+
cls.__fixture_manager = FixtureManager()
|
|
48
|
+
|
|
49
|
+
return cls.__fixture_manager
|
|
50
|
+
|
|
40
51
|
@classmethod
|
|
41
52
|
def get_step_manager(cls) -> StepManager:
|
|
42
53
|
if cls.__step_manager is None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: testit-python-commons
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.4.1
|
|
4
4
|
Summary: Python commons for Test IT
|
|
5
5
|
Home-page: https://github.com/testit-tms/adapters-python/
|
|
6
6
|
Author: Integration team
|
|
@@ -17,6 +17,15 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
Requires-Dist: pluggy
|
|
19
19
|
Requires-Dist: testit-api-client==5.0.0
|
|
20
|
+
Dynamic: author
|
|
21
|
+
Dynamic: author-email
|
|
22
|
+
Dynamic: classifier
|
|
23
|
+
Dynamic: description
|
|
24
|
+
Dynamic: description-content-type
|
|
25
|
+
Dynamic: home-page
|
|
26
|
+
Dynamic: license
|
|
27
|
+
Dynamic: requires-dist
|
|
28
|
+
Dynamic: summary
|
|
20
29
|
|
|
21
30
|
# How to enable debug logging?
|
|
22
31
|
1. Add in **connection_config.ini** file from the root directory of the project:
|
|
@@ -17,6 +17,7 @@ src/testit_python_commons/client/client_configuration.py
|
|
|
17
17
|
src/testit_python_commons/client/converter.py
|
|
18
18
|
src/testit_python_commons/models/__init__.py
|
|
19
19
|
src/testit_python_commons/models/adapter_mode.py
|
|
20
|
+
src/testit_python_commons/models/fixture.py
|
|
20
21
|
src/testit_python_commons/models/link.py
|
|
21
22
|
src/testit_python_commons/models/link_type.py
|
|
22
23
|
src/testit_python_commons/models/outcome_type.py
|
|
@@ -26,6 +27,8 @@ src/testit_python_commons/models/test_result_with_all_fixture_step_results_model
|
|
|
26
27
|
src/testit_python_commons/services/__init__.py
|
|
27
28
|
src/testit_python_commons/services/adapter_manager.py
|
|
28
29
|
src/testit_python_commons/services/adapter_manager_configuration.py
|
|
30
|
+
src/testit_python_commons/services/fixture_manager.py
|
|
31
|
+
src/testit_python_commons/services/fixture_storage.py
|
|
29
32
|
src/testit_python_commons/services/logger.py
|
|
30
33
|
src/testit_python_commons/services/plugin_manager.py
|
|
31
34
|
src/testit_python_commons/services/retry.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/decorators.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/models/link.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{testit_python_commons-3.3.2 → testit_python_commons-3.4.1}/src/testit_python_commons/step.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|