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.
- api_client_syncstorage/__init__.py +27 -0
- api_client_syncstorage/api/__init__.py +3 -0
- api_client_syncstorage/api/completion_api.py +302 -0
- api_client_syncstorage/api/health_api.py +158 -0
- api_client_syncstorage/api/system_api.py +158 -0
- api_client_syncstorage/api/test_results_api.py +182 -0
- api_client_syncstorage/api/workers_api.py +308 -0
- api_client_syncstorage/api_client.py +898 -0
- api_client_syncstorage/apis/__init__.py +21 -0
- api_client_syncstorage/configuration.py +450 -0
- api_client_syncstorage/exceptions.py +158 -0
- api_client_syncstorage/model/__init__.py +5 -0
- api_client_syncstorage/model/completion_response.py +267 -0
- api_client_syncstorage/model/health_status_response.py +267 -0
- api_client_syncstorage/model/register_request.py +275 -0
- api_client_syncstorage/model/register_response.py +279 -0
- api_client_syncstorage/model/set_worker_status_request.py +271 -0
- api_client_syncstorage/model/set_worker_status_response.py +267 -0
- api_client_syncstorage/model/shutdown_response.py +267 -0
- api_client_syncstorage/model/test_result_cut_api_model.py +279 -0
- api_client_syncstorage/model/test_result_save_response.py +267 -0
- api_client_syncstorage/model_utils.py +2058 -0
- api_client_syncstorage/models/__init__.py +20 -0
- api_client_syncstorage/rest.py +356 -0
- testit.py +69 -0
- testit_python_commons/__init__.py +0 -0
- testit_python_commons/app_properties.py +257 -0
- testit_python_commons/client/__init__.py +9 -0
- testit_python_commons/client/api_client.py +560 -0
- testit_python_commons/client/client_configuration.py +74 -0
- testit_python_commons/client/converter.py +618 -0
- testit_python_commons/client/helpers/__init__.py +0 -0
- testit_python_commons/client/helpers/bulk_autotest_helper.py +246 -0
- testit_python_commons/client/helpers/threads_manager.py +86 -0
- testit_python_commons/client/models/__init__.py +8 -0
- testit_python_commons/client/models/threads_for_create_and_result.py +35 -0
- testit_python_commons/client/models/threads_for_update_and_result.py +45 -0
- testit_python_commons/configurations/__init__.py +0 -0
- testit_python_commons/configurations/properties_names.py +51 -0
- testit_python_commons/decorators.py +221 -0
- testit_python_commons/dynamic_methods.py +237 -0
- testit_python_commons/models/__init__.py +5 -0
- testit_python_commons/models/adapter_mode.py +4 -0
- testit_python_commons/models/fixture.py +24 -0
- testit_python_commons/models/link.py +53 -0
- testit_python_commons/models/link_type.py +10 -0
- testit_python_commons/models/outcome_type.py +5 -0
- testit_python_commons/models/status_type.py +6 -0
- testit_python_commons/models/step_result.py +90 -0
- testit_python_commons/models/test_result.py +297 -0
- testit_python_commons/models/test_result_with_all_fixture_step_results_model.py +28 -0
- testit_python_commons/services/__init__.py +41 -0
- testit_python_commons/services/adapter_manager.py +318 -0
- testit_python_commons/services/adapter_manager_configuration.py +42 -0
- testit_python_commons/services/fixture_manager.py +60 -0
- testit_python_commons/services/fixture_storage.py +40 -0
- testit_python_commons/services/logger.py +32 -0
- testit_python_commons/services/plugin_manager.py +101 -0
- testit_python_commons/services/retry.py +92 -0
- testit_python_commons/services/step_manager.py +36 -0
- testit_python_commons/services/step_result_storage.py +26 -0
- testit_python_commons/services/sync_storage/__init__.py +9 -0
- testit_python_commons/services/sync_storage/sync_storage_runner.py +589 -0
- testit_python_commons/services/utils.py +132 -0
- testit_python_commons/step.py +101 -0
- testit_python_commons/utils/__init__.py +3 -0
- testit_python_commons/utils/html_escape_utils.py +219 -0
- testit_python_commons-4.2.8.dist-info/METADATA +52 -0
- testit_python_commons-4.2.8.dist-info/RECORD +71 -0
- testit_python_commons-4.2.8.dist-info/WHEEL +5 -0
- testit_python_commons-4.2.8.dist-info/top_level.txt +3 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# flake8: noqa
|
|
2
|
+
|
|
3
|
+
# import all models into this package
|
|
4
|
+
# if you have many models here with many references from one model to another this may
|
|
5
|
+
# raise a RecursionError
|
|
6
|
+
# to avoid this, import only the models that you directly need like:
|
|
7
|
+
# from api_client_syncstorage.model.pet import Pet
|
|
8
|
+
# or import this package, but before doing it, use:
|
|
9
|
+
# import sys
|
|
10
|
+
# sys.setrecursionlimit(n)
|
|
11
|
+
|
|
12
|
+
from api_client_syncstorage.model.completion_response import CompletionResponse
|
|
13
|
+
from api_client_syncstorage.model.health_status_response import HealthStatusResponse
|
|
14
|
+
from api_client_syncstorage.model.register_request import RegisterRequest
|
|
15
|
+
from api_client_syncstorage.model.register_response import RegisterResponse
|
|
16
|
+
from api_client_syncstorage.model.set_worker_status_request import SetWorkerStatusRequest
|
|
17
|
+
from api_client_syncstorage.model.set_worker_status_response import SetWorkerStatusResponse
|
|
18
|
+
from api_client_syncstorage.model.shutdown_response import ShutdownResponse
|
|
19
|
+
from api_client_syncstorage.model.test_result_cut_api_model import TestResultCutApiModel
|
|
20
|
+
from api_client_syncstorage.model.test_result_save_response import TestResultSaveResponse
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Sync Storage Service API
|
|
3
|
+
|
|
4
|
+
This is a sync storage service for coordinating test workers. # noqa: E501
|
|
5
|
+
|
|
6
|
+
The version of the OpenAPI document: 1.0
|
|
7
|
+
Generated by: https://openapi-generator.tech
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
import io
|
|
12
|
+
import json
|
|
13
|
+
import logging
|
|
14
|
+
import re
|
|
15
|
+
import ssl
|
|
16
|
+
from urllib.parse import urlencode
|
|
17
|
+
from urllib.parse import urlparse
|
|
18
|
+
from urllib.request import proxy_bypass_environment
|
|
19
|
+
import urllib3
|
|
20
|
+
import ipaddress
|
|
21
|
+
|
|
22
|
+
from api_client_syncstorage.exceptions import ApiException, UnauthorizedException, ForbiddenException, NotFoundException, ServiceException, ApiValueError
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
logger = logging.getLogger(__name__)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class RESTResponse(io.IOBase):
|
|
29
|
+
|
|
30
|
+
def __init__(self, resp):
|
|
31
|
+
self.urllib3_response = resp
|
|
32
|
+
self.status = resp.status
|
|
33
|
+
self.reason = resp.reason
|
|
34
|
+
self.data = resp.data
|
|
35
|
+
|
|
36
|
+
def getheaders(self):
|
|
37
|
+
"""Returns a dictionary of the response headers."""
|
|
38
|
+
return self.urllib3_response.getheaders()
|
|
39
|
+
|
|
40
|
+
def getheader(self, name, default=None):
|
|
41
|
+
"""Returns a given response header."""
|
|
42
|
+
return self.urllib3_response.getheader(name, default)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class RESTClientObject(object):
|
|
46
|
+
|
|
47
|
+
def __init__(self, configuration, pools_size=4, maxsize=None):
|
|
48
|
+
# urllib3.PoolManager will pass all kw parameters to connectionpool
|
|
49
|
+
# https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/poolmanager.py#L75 # noqa: E501
|
|
50
|
+
# https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/connectionpool.py#L680 # noqa: E501
|
|
51
|
+
# maxsize is the number of requests to host that are allowed in parallel # noqa: E501
|
|
52
|
+
# Custom SSL certificates and client certificates: http://urllib3.readthedocs.io/en/latest/advanced-usage.html # noqa: E501
|
|
53
|
+
|
|
54
|
+
# cert_reqs
|
|
55
|
+
if configuration.verify_ssl:
|
|
56
|
+
cert_reqs = ssl.CERT_REQUIRED
|
|
57
|
+
else:
|
|
58
|
+
cert_reqs = ssl.CERT_NONE
|
|
59
|
+
|
|
60
|
+
addition_pool_args = {}
|
|
61
|
+
if configuration.assert_hostname is not None:
|
|
62
|
+
addition_pool_args['assert_hostname'] = configuration.assert_hostname # noqa: E501
|
|
63
|
+
|
|
64
|
+
if configuration.retries is not None:
|
|
65
|
+
addition_pool_args['retries'] = configuration.retries
|
|
66
|
+
|
|
67
|
+
if configuration.tls_server_name:
|
|
68
|
+
addition_pool_args['server_hostname'] = configuration.tls_server_name
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
if configuration.socket_options is not None:
|
|
72
|
+
addition_pool_args['socket_options'] = configuration.socket_options
|
|
73
|
+
|
|
74
|
+
if maxsize is None:
|
|
75
|
+
if configuration.connection_pool_maxsize is not None:
|
|
76
|
+
maxsize = configuration.connection_pool_maxsize
|
|
77
|
+
else:
|
|
78
|
+
maxsize = 4
|
|
79
|
+
|
|
80
|
+
# https pool manager
|
|
81
|
+
if configuration.proxy and not should_bypass_proxies(
|
|
82
|
+
configuration.host, no_proxy=configuration.no_proxy or ''):
|
|
83
|
+
self.pool_manager = urllib3.ProxyManager(
|
|
84
|
+
num_pools=pools_size,
|
|
85
|
+
maxsize=maxsize,
|
|
86
|
+
cert_reqs=cert_reqs,
|
|
87
|
+
ca_certs=configuration.ssl_ca_cert,
|
|
88
|
+
cert_file=configuration.cert_file,
|
|
89
|
+
key_file=configuration.key_file,
|
|
90
|
+
proxy_url=configuration.proxy,
|
|
91
|
+
proxy_headers=configuration.proxy_headers,
|
|
92
|
+
**addition_pool_args
|
|
93
|
+
)
|
|
94
|
+
else:
|
|
95
|
+
self.pool_manager = urllib3.PoolManager(
|
|
96
|
+
num_pools=pools_size,
|
|
97
|
+
maxsize=maxsize,
|
|
98
|
+
cert_reqs=cert_reqs,
|
|
99
|
+
ca_certs=configuration.ssl_ca_cert,
|
|
100
|
+
cert_file=configuration.cert_file,
|
|
101
|
+
key_file=configuration.key_file,
|
|
102
|
+
**addition_pool_args
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
def request(self, method, url, query_params=None, headers=None,
|
|
106
|
+
body=None, post_params=None, _preload_content=True,
|
|
107
|
+
_request_timeout=None):
|
|
108
|
+
"""Perform requests.
|
|
109
|
+
|
|
110
|
+
:param method: http request method
|
|
111
|
+
:param url: http request url
|
|
112
|
+
:param query_params: query parameters in the url
|
|
113
|
+
:param headers: http request headers
|
|
114
|
+
:param body: request json body, for `application/json`
|
|
115
|
+
:param post_params: request post parameters,
|
|
116
|
+
`application/x-www-form-urlencoded`
|
|
117
|
+
and `multipart/form-data`
|
|
118
|
+
:param _preload_content: if False, the urllib3.HTTPResponse object will
|
|
119
|
+
be returned without reading/decoding response
|
|
120
|
+
data. Default is True.
|
|
121
|
+
:param _request_timeout: timeout setting for this request. If one
|
|
122
|
+
number provided, it will be total request
|
|
123
|
+
timeout. It can also be a pair (tuple) of
|
|
124
|
+
(connection, read) timeouts.
|
|
125
|
+
"""
|
|
126
|
+
method = method.upper()
|
|
127
|
+
assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT',
|
|
128
|
+
'PATCH', 'OPTIONS']
|
|
129
|
+
|
|
130
|
+
if post_params and body:
|
|
131
|
+
raise ApiValueError(
|
|
132
|
+
"body parameter cannot be used with post_params parameter."
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
post_params = post_params or {}
|
|
136
|
+
headers = headers or {}
|
|
137
|
+
|
|
138
|
+
timeout = None
|
|
139
|
+
if _request_timeout:
|
|
140
|
+
if isinstance(_request_timeout, (int, float)): # noqa: E501,F821
|
|
141
|
+
timeout = urllib3.Timeout(total=_request_timeout)
|
|
142
|
+
elif (isinstance(_request_timeout, tuple) and
|
|
143
|
+
len(_request_timeout) == 2):
|
|
144
|
+
timeout = urllib3.Timeout(
|
|
145
|
+
connect=_request_timeout[0], read=_request_timeout[1])
|
|
146
|
+
|
|
147
|
+
try:
|
|
148
|
+
# For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE`
|
|
149
|
+
if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']:
|
|
150
|
+
# Only set a default Content-Type for POST, PUT, PATCH and OPTIONS requests
|
|
151
|
+
if (method != 'DELETE') and ('Content-Type' not in headers):
|
|
152
|
+
headers['Content-Type'] = 'application/json'
|
|
153
|
+
if query_params:
|
|
154
|
+
url += '?' + urlencode(query_params)
|
|
155
|
+
if ('Content-Type' not in headers) or (re.search('json',
|
|
156
|
+
headers['Content-Type'], re.IGNORECASE)):
|
|
157
|
+
request_body = None
|
|
158
|
+
if body is not None:
|
|
159
|
+
request_body = json.dumps(body)
|
|
160
|
+
r = self.pool_manager.request(
|
|
161
|
+
method, url,
|
|
162
|
+
body=request_body,
|
|
163
|
+
preload_content=_preload_content,
|
|
164
|
+
timeout=timeout,
|
|
165
|
+
headers=headers)
|
|
166
|
+
elif headers['Content-Type'] == 'application/x-www-form-urlencoded': # noqa: E501
|
|
167
|
+
r = self.pool_manager.request(
|
|
168
|
+
method, url,
|
|
169
|
+
fields=post_params,
|
|
170
|
+
encode_multipart=False,
|
|
171
|
+
preload_content=_preload_content,
|
|
172
|
+
timeout=timeout,
|
|
173
|
+
headers=headers)
|
|
174
|
+
elif headers['Content-Type'] == 'multipart/form-data':
|
|
175
|
+
# must del headers['Content-Type'], or the correct
|
|
176
|
+
# Content-Type which generated by urllib3 will be
|
|
177
|
+
# overwritten.
|
|
178
|
+
del headers['Content-Type']
|
|
179
|
+
r = self.pool_manager.request(
|
|
180
|
+
method, url,
|
|
181
|
+
fields=post_params,
|
|
182
|
+
encode_multipart=True,
|
|
183
|
+
preload_content=_preload_content,
|
|
184
|
+
timeout=timeout,
|
|
185
|
+
headers=headers)
|
|
186
|
+
# Pass a `string` parameter directly in the body to support
|
|
187
|
+
# other content types than Json when `body` argument is
|
|
188
|
+
# provided in serialized form
|
|
189
|
+
elif isinstance(body, str) or isinstance(body, bytes):
|
|
190
|
+
request_body = body
|
|
191
|
+
r = self.pool_manager.request(
|
|
192
|
+
method, url,
|
|
193
|
+
body=request_body,
|
|
194
|
+
preload_content=_preload_content,
|
|
195
|
+
timeout=timeout,
|
|
196
|
+
headers=headers)
|
|
197
|
+
else:
|
|
198
|
+
# Cannot generate the request from given parameters
|
|
199
|
+
msg = """Cannot prepare a request message for provided
|
|
200
|
+
arguments. Please check that your arguments match
|
|
201
|
+
declared content type."""
|
|
202
|
+
raise ApiException(status=0, reason=msg)
|
|
203
|
+
# For `GET`, `HEAD`
|
|
204
|
+
else:
|
|
205
|
+
r = self.pool_manager.request(method, url,
|
|
206
|
+
fields=query_params,
|
|
207
|
+
preload_content=_preload_content,
|
|
208
|
+
timeout=timeout,
|
|
209
|
+
headers=headers)
|
|
210
|
+
except urllib3.exceptions.SSLError as e:
|
|
211
|
+
msg = "{0}\n{1}".format(type(e).__name__, str(e))
|
|
212
|
+
raise ApiException(status=0, reason=msg)
|
|
213
|
+
|
|
214
|
+
if _preload_content:
|
|
215
|
+
r = RESTResponse(r)
|
|
216
|
+
|
|
217
|
+
# log response body
|
|
218
|
+
logger.debug("response body: %s", r.data)
|
|
219
|
+
|
|
220
|
+
if not 200 <= r.status <= 299:
|
|
221
|
+
if r.status == 401:
|
|
222
|
+
raise UnauthorizedException(http_resp=r)
|
|
223
|
+
|
|
224
|
+
if r.status == 403:
|
|
225
|
+
raise ForbiddenException(http_resp=r)
|
|
226
|
+
|
|
227
|
+
if r.status == 404:
|
|
228
|
+
raise NotFoundException(http_resp=r)
|
|
229
|
+
|
|
230
|
+
if 500 <= r.status <= 599:
|
|
231
|
+
raise ServiceException(http_resp=r)
|
|
232
|
+
|
|
233
|
+
raise ApiException(http_resp=r)
|
|
234
|
+
|
|
235
|
+
return r
|
|
236
|
+
|
|
237
|
+
def GET(self, url, headers=None, query_params=None, _preload_content=True,
|
|
238
|
+
_request_timeout=None):
|
|
239
|
+
return self.request("GET", url,
|
|
240
|
+
headers=headers,
|
|
241
|
+
_preload_content=_preload_content,
|
|
242
|
+
_request_timeout=_request_timeout,
|
|
243
|
+
query_params=query_params)
|
|
244
|
+
|
|
245
|
+
def HEAD(self, url, headers=None, query_params=None, _preload_content=True,
|
|
246
|
+
_request_timeout=None):
|
|
247
|
+
return self.request("HEAD", url,
|
|
248
|
+
headers=headers,
|
|
249
|
+
_preload_content=_preload_content,
|
|
250
|
+
_request_timeout=_request_timeout,
|
|
251
|
+
query_params=query_params)
|
|
252
|
+
|
|
253
|
+
def OPTIONS(self, url, headers=None, query_params=None, post_params=None,
|
|
254
|
+
body=None, _preload_content=True, _request_timeout=None):
|
|
255
|
+
return self.request("OPTIONS", url,
|
|
256
|
+
headers=headers,
|
|
257
|
+
query_params=query_params,
|
|
258
|
+
post_params=post_params,
|
|
259
|
+
_preload_content=_preload_content,
|
|
260
|
+
_request_timeout=_request_timeout,
|
|
261
|
+
body=body)
|
|
262
|
+
|
|
263
|
+
def DELETE(self, url, headers=None, query_params=None, body=None,
|
|
264
|
+
_preload_content=True, _request_timeout=None):
|
|
265
|
+
return self.request("DELETE", url,
|
|
266
|
+
headers=headers,
|
|
267
|
+
query_params=query_params,
|
|
268
|
+
_preload_content=_preload_content,
|
|
269
|
+
_request_timeout=_request_timeout,
|
|
270
|
+
body=body)
|
|
271
|
+
|
|
272
|
+
def POST(self, url, headers=None, query_params=None, post_params=None,
|
|
273
|
+
body=None, _preload_content=True, _request_timeout=None):
|
|
274
|
+
return self.request("POST", url,
|
|
275
|
+
headers=headers,
|
|
276
|
+
query_params=query_params,
|
|
277
|
+
post_params=post_params,
|
|
278
|
+
_preload_content=_preload_content,
|
|
279
|
+
_request_timeout=_request_timeout,
|
|
280
|
+
body=body)
|
|
281
|
+
|
|
282
|
+
def PUT(self, url, headers=None, query_params=None, post_params=None,
|
|
283
|
+
body=None, _preload_content=True, _request_timeout=None):
|
|
284
|
+
return self.request("PUT", url,
|
|
285
|
+
headers=headers,
|
|
286
|
+
query_params=query_params,
|
|
287
|
+
post_params=post_params,
|
|
288
|
+
_preload_content=_preload_content,
|
|
289
|
+
_request_timeout=_request_timeout,
|
|
290
|
+
body=body)
|
|
291
|
+
|
|
292
|
+
def PATCH(self, url, headers=None, query_params=None, post_params=None,
|
|
293
|
+
body=None, _preload_content=True, _request_timeout=None):
|
|
294
|
+
return self.request("PATCH", url,
|
|
295
|
+
headers=headers,
|
|
296
|
+
query_params=query_params,
|
|
297
|
+
post_params=post_params,
|
|
298
|
+
_preload_content=_preload_content,
|
|
299
|
+
_request_timeout=_request_timeout,
|
|
300
|
+
body=body)
|
|
301
|
+
|
|
302
|
+
# end of class RESTClientObject
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
def is_ipv4(target):
|
|
306
|
+
""" Test if IPv4 address or not
|
|
307
|
+
"""
|
|
308
|
+
try:
|
|
309
|
+
chk = ipaddress.IPv4Address(target)
|
|
310
|
+
return True
|
|
311
|
+
except ipaddress.AddressValueError:
|
|
312
|
+
return False
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
def in_ipv4net(target, net):
|
|
316
|
+
""" Test if target belongs to given IPv4 network
|
|
317
|
+
"""
|
|
318
|
+
try:
|
|
319
|
+
nw = ipaddress.IPv4Network(net)
|
|
320
|
+
ip = ipaddress.IPv4Address(target)
|
|
321
|
+
if ip in nw:
|
|
322
|
+
return True
|
|
323
|
+
return False
|
|
324
|
+
except ipaddress.AddressValueError:
|
|
325
|
+
return False
|
|
326
|
+
except ipaddress.NetmaskValueError:
|
|
327
|
+
return False
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
def should_bypass_proxies(url, no_proxy=None):
|
|
331
|
+
""" Yet another requests.should_bypass_proxies
|
|
332
|
+
Test if proxies should not be used for a particular url.
|
|
333
|
+
"""
|
|
334
|
+
|
|
335
|
+
parsed = urlparse(url)
|
|
336
|
+
|
|
337
|
+
# special cases
|
|
338
|
+
if parsed.hostname in [None, '']:
|
|
339
|
+
return True
|
|
340
|
+
|
|
341
|
+
# special cases
|
|
342
|
+
if no_proxy in [None, '']:
|
|
343
|
+
return False
|
|
344
|
+
if no_proxy == '*':
|
|
345
|
+
return True
|
|
346
|
+
|
|
347
|
+
no_proxy = no_proxy.lower().replace(' ', '');
|
|
348
|
+
entries = (
|
|
349
|
+
host for host in no_proxy.split(',') if host
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
if is_ipv4(parsed.hostname):
|
|
353
|
+
for item in entries:
|
|
354
|
+
if in_ipv4net(parsed.hostname, item):
|
|
355
|
+
return True
|
|
356
|
+
return proxy_bypass_environment(parsed.hostname, {'no': no_proxy})
|
testit.py
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
from testit_python_commons.decorators import (
|
|
2
|
+
className,
|
|
3
|
+
description,
|
|
4
|
+
displayName,
|
|
5
|
+
externalID,
|
|
6
|
+
externalId,
|
|
7
|
+
labels,
|
|
8
|
+
tags,
|
|
9
|
+
link,
|
|
10
|
+
links,
|
|
11
|
+
nameSpace,
|
|
12
|
+
title,
|
|
13
|
+
workItemID,
|
|
14
|
+
workItemIds
|
|
15
|
+
)
|
|
16
|
+
from testit_python_commons.dynamic_methods import (
|
|
17
|
+
addAttachments,
|
|
18
|
+
addLink,
|
|
19
|
+
addLinks,
|
|
20
|
+
addMessage,
|
|
21
|
+
addWorkItemIds,
|
|
22
|
+
addDisplayName,
|
|
23
|
+
addNameSpace,
|
|
24
|
+
addClassName,
|
|
25
|
+
addExternalId,
|
|
26
|
+
addTitle,
|
|
27
|
+
addDescription,
|
|
28
|
+
addLabels,
|
|
29
|
+
addTags,
|
|
30
|
+
addParameter,
|
|
31
|
+
attachments,
|
|
32
|
+
message
|
|
33
|
+
)
|
|
34
|
+
from testit_python_commons.models import LinkType
|
|
35
|
+
from testit_python_commons.step import step
|
|
36
|
+
|
|
37
|
+
__all__ = [
|
|
38
|
+
'externalID',
|
|
39
|
+
'externalId',
|
|
40
|
+
'displayName',
|
|
41
|
+
'nameSpace',
|
|
42
|
+
'className',
|
|
43
|
+
'workItemID',
|
|
44
|
+
'workItemIds',
|
|
45
|
+
'title',
|
|
46
|
+
'description',
|
|
47
|
+
'labels',
|
|
48
|
+
'tags',
|
|
49
|
+
'link',
|
|
50
|
+
'links',
|
|
51
|
+
'addLink',
|
|
52
|
+
'addLinks',
|
|
53
|
+
'attachments',
|
|
54
|
+
'addAttachments',
|
|
55
|
+
'message',
|
|
56
|
+
'addMessage',
|
|
57
|
+
'addWorkItemIds',
|
|
58
|
+
'addDisplayName',
|
|
59
|
+
'addNameSpace',
|
|
60
|
+
'addClassName',
|
|
61
|
+
'addExternalId',
|
|
62
|
+
'addTitle',
|
|
63
|
+
'addDescription',
|
|
64
|
+
'addLabels',
|
|
65
|
+
'addTags',
|
|
66
|
+
'addParameter',
|
|
67
|
+
'step',
|
|
68
|
+
'LinkType'
|
|
69
|
+
]
|
|
File without changes
|