utf-queue-client 1.18.0a0__tar.gz → 1.19.0__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.
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/.idea/.gitignore +0 -2
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/.idea/utf_queue_client_python.iml +1 -3
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/Jenkinsfile +2 -3
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/PKG-INFO +1 -1
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/pyproject.toml +1 -1
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/sonar-project.properties +1 -1
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test/Dockerfile.script_test +1 -1
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test/conftest.py +22 -19
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test/test_amqp_connections.py +1 -1
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test/test_models.py +5 -1
- utf_queue_client-1.19.0/test/test_xray_data_producer.py +65 -0
- utf_queue_client-1.19.0/tools/build_dist.bat +14 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/clients/data_lake_data_producer.py +2 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/clients/http_producer.py +2 -2
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/clients/opentelemetry_data_producer.py +2 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/clients/sqa_test_result_producer.py +4 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/clients/test_rail_data_producer.py +2 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/clients/ubai_artifact_upload_request_producer.py +2 -0
- utf_queue_client-1.19.0/utf_queue_client/clients/xray_data_producer.py +95 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/models/schemas/utf_queue_models/models/python/generated_models.py +24 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/models/schemas/utf_queue_models/models/python/generated_models_pydantic_v1.py +80 -2
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/models/schemas/utf_queue_models/models/python/generated_models_pydantic_v2.py +80 -2
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/models/schemas/utf_queue_models/schema/queue_message.json +254 -1
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/scripts/__init__.py +0 -2
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client.egg-info/PKG-INFO +1 -1
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client.egg-info/SOURCES.txt +2 -0
- utf_queue_client-1.18.0a0/tools/build_dist.bat +0 -12
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/.gitignore +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/.gitmodules +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/.idea/modules.xml +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/.idea/vcs.xml +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/.pre-commit-config.yaml +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/README.md +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/examples/example_async_consumer.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/requirements.txt +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/setup.cfg +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test/.gitattributes +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test/pytest.ini +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test/script_test.groovy +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test/stopwatch.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test/test.hex +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test/test_async_consumer.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test/test_connection_retry.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test/test_data_lake_data_producer.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test/test_http_producer.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test/test_opentelemetry_data_producer.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test/test_publish_release_info.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test/test_publish_test_results.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test/test_rail_data_producer_tests.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test/test_sqa_test_result_producer.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test/test_ubai_copy.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test/test_ubai_search.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test/test_ubai_update_retention.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test/test_ubai_upload.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test/test_utils.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test-requirements-pydantic-v1.txt +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/test-requirements.txt +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/tools/setup_venv.bat +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/tools/silabs-net.pem +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/tools/silabs.pem +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/tools/update_schema.bat +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/tools/upload_to_nexus.bat +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/tools/upload_to_pypi.bat +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/tools/upload_to_testpypi.bat +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/tox.ini +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/__init__.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/clients/__init__.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/clients/async_consumer.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/clients/base_producer.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/exceptions/__init__.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/models/__init__.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/models/base_model.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/models/model_factory.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/models/schemas/__init__.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/models/schemas/utf_queue_models/models/python/__init__.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/scripts/publish_release_info_cli.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/scripts/publish_test_results_cli.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/scripts/ubai_copy_cli.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/scripts/ubai_search_cli.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/scripts/ubai_update_retention_cli.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/scripts/ubai_upload_cli.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/utils/__init__.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/utils/queue_metrics_exporter.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/utils/queue_span_exporter.py +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client.egg-info/dependency_links.txt +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client.egg-info/entry_points.txt +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client.egg-info/requires.txt +0 -0
- {utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client.egg-info/top_level.txt +0 -0
|
@@ -2,11 +2,9 @@
|
|
|
2
2
|
<module type="PYTHON_MODULE" version="4">
|
|
3
3
|
<component name="NewModuleRootManager">
|
|
4
4
|
<content url="file://$MODULE_DIR$">
|
|
5
|
-
<excludeFolder url="file://$MODULE_DIR$/.idea/copilot/chatSessions" />
|
|
6
5
|
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
|
7
|
-
<excludeFolder url="file://$MODULE_DIR$/venv2" />
|
|
8
6
|
</content>
|
|
9
|
-
<orderEntry type="
|
|
7
|
+
<orderEntry type="inheritedJdk" />
|
|
10
8
|
<orderEntry type="sourceFolder" forTests="false" />
|
|
11
9
|
</component>
|
|
12
10
|
<component name="PyDocumentationSettings">
|
|
@@ -25,7 +25,6 @@ pipeline {
|
|
|
25
25
|
TEST_RESULTS_DIR = 'test/test_results'
|
|
26
26
|
OTEL_EXPORTER_OTLP_ENDPOINT = "https://otel-collector-http.silabs.net"
|
|
27
27
|
OTEL_EXPORTER_OTLP_PROTOCOL = "http/protobuf"
|
|
28
|
-
OTEL_EXPORTER_OTLP_CERTIFICATE = "/usr/share/ca-certificates/vault/vault-ca-prod.crt"
|
|
29
28
|
UTF_QUEUE_VIRTUAL_HOST = "testing"
|
|
30
29
|
OTEL_SERVICE_NAME = "utf-queue-client-tests"
|
|
31
30
|
PYENV_VERSION = "3.9"
|
|
@@ -122,11 +121,11 @@ pipeline {
|
|
|
122
121
|
python3 -m venv venv
|
|
123
122
|
fi
|
|
124
123
|
. venv/bin/activate
|
|
125
|
-
pip3 install wheel && pip3 install -r test-requirements.txt
|
|
124
|
+
pip3 install wheel && pip3 install -r test-requirements.txt build
|
|
126
125
|
rm -rf build
|
|
127
126
|
rm -rf dist
|
|
128
127
|
rm -rf utf_queue_client.egg-info
|
|
129
|
-
python3
|
|
128
|
+
python3 -m build
|
|
130
129
|
|
|
131
130
|
twine upload dist/*
|
|
132
131
|
'''
|
|
@@ -2,7 +2,7 @@ sonar.projectKey=utf:queue-client-python
|
|
|
2
2
|
sonar.projectName=utf-queue-client-python
|
|
3
3
|
sonar.sources=utf_queue_client
|
|
4
4
|
sonar.tests=./test
|
|
5
|
-
sonar.exclusions=utf_queue_client/models/schemas/utf_queue_models/models
|
|
5
|
+
sonar.exclusions=utf_queue_client/models/schemas/utf_queue_models/models/**
|
|
6
6
|
sonar.coverage.exclusions=test/**
|
|
7
7
|
sonar.python.coverage.reportPaths=test/test_results/coverage.xml
|
|
8
8
|
sonar.python.xunit.reportPath=test/test_results/junit*.xml
|
|
@@ -7,7 +7,6 @@ from urllib import parse
|
|
|
7
7
|
|
|
8
8
|
import ndjson
|
|
9
9
|
import pytest
|
|
10
|
-
import requests
|
|
11
10
|
from otel_extensions_pytest import TelemetryOptions, instrumented_fixture
|
|
12
11
|
from stopwatch import Stopwatch
|
|
13
12
|
|
|
@@ -19,6 +18,9 @@ from utf_queue_client.models import (
|
|
|
19
18
|
)
|
|
20
19
|
from utf_queue_client.models.schemas.utf_queue_models.models.python.generated_models import (
|
|
21
20
|
TestRailResult,
|
|
21
|
+
XrayImportTestExecution,
|
|
22
|
+
XrayInfo,
|
|
23
|
+
XrayTestExecUpdate,
|
|
22
24
|
)
|
|
23
25
|
|
|
24
26
|
pytest_plugins = ("otel_extensions",)
|
|
@@ -35,24 +37,6 @@ def pytest_addoption(parser, pluginmanager):
|
|
|
35
37
|
if options.OTEL_EXPORTER_OTLP_ENDPOINT is None:
|
|
36
38
|
options.OTEL_EXPORTER_OTLP_ENDPOINT = "https://otel-collector-http.silabs.net/"
|
|
37
39
|
options.OTEL_EXPORTER_OTLP_PROTOCOL = "http/protobuf"
|
|
38
|
-
cert_bundle = os.path.join(os.path.dirname(__file__), "silabs-net.pem")
|
|
39
|
-
options.OTEL_EXPORTER_OTLP_CERTIFICATE = cert_bundle
|
|
40
|
-
if not os.path.exists(cert_bundle):
|
|
41
|
-
with open(cert_bundle, "wb") as bundle:
|
|
42
|
-
r = requests.get(
|
|
43
|
-
"https://vault.dev.silabs.net:443/v1/pki/ca/pem", verify=False
|
|
44
|
-
)
|
|
45
|
-
cert_file = os.path.join(os.path.dirname(__file__), "vault-ca-dev.crt")
|
|
46
|
-
with open(cert_file, "wb") as f:
|
|
47
|
-
f.write(r.content)
|
|
48
|
-
bundle.write(r.content + b"\n")
|
|
49
|
-
r = requests.get(
|
|
50
|
-
"https://vault.silabs.net:443/v1/pki/ca/pem", verify=False
|
|
51
|
-
)
|
|
52
|
-
cert_file = os.path.join(os.path.dirname(__file__), "vault-ca.crt")
|
|
53
|
-
with open(cert_file, "wb") as f:
|
|
54
|
-
f.write(r.content)
|
|
55
|
-
bundle.write(r.content)
|
|
56
40
|
|
|
57
41
|
|
|
58
42
|
@pytest.fixture()
|
|
@@ -157,6 +141,25 @@ def test_rail_add_test_result():
|
|
|
157
141
|
)
|
|
158
142
|
|
|
159
143
|
|
|
144
|
+
@pytest.fixture()
|
|
145
|
+
def xray_import_test_execution_data():
|
|
146
|
+
yield XrayImportTestExecution(
|
|
147
|
+
test_execution_key="DUMMY_EXEC",
|
|
148
|
+
add_tests_to_plan=True,
|
|
149
|
+
info=XrayInfo(project="DUMMY", test_plan_key="DUMMY_PLAN"),
|
|
150
|
+
tests=[
|
|
151
|
+
XrayTestExecUpdate(
|
|
152
|
+
comment="",
|
|
153
|
+
executed_by="test",
|
|
154
|
+
finish="2025-02-11T07:39:25+00:00",
|
|
155
|
+
start="2025-02-11T07:39:23+00:00",
|
|
156
|
+
status="PASS",
|
|
157
|
+
test_key="TC1234567890",
|
|
158
|
+
)
|
|
159
|
+
],
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
|
|
160
163
|
@pytest.fixture()
|
|
161
164
|
def data_lake_tenant_key():
|
|
162
165
|
return "dummy_key"
|
|
@@ -37,7 +37,7 @@ def test_producer(queue_server, username, password):
|
|
|
37
37
|
params = pika.URLParameters(p.url)
|
|
38
38
|
logger.info(f"stack timeout: {params.stack_timeout}")
|
|
39
39
|
begin = time.time()
|
|
40
|
-
for _ in range(0,
|
|
40
|
+
for _ in range(0, 3):
|
|
41
41
|
logger.info(f"{queue_server}: declaring queue...")
|
|
42
42
|
start = time.time()
|
|
43
43
|
p.queue_declare("default", durable=True)
|
|
@@ -112,14 +112,18 @@ def test_deserialize_queue_message_v1(artifact_upload_request):
|
|
|
112
112
|
_ = ArtifactUploadRequest(payload)
|
|
113
113
|
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
@pytest.mark.parametrize("messageId", [None, "12345678910"])
|
|
116
|
+
def test_deserialize_queue_message_v2(artifact_upload_request, messageId):
|
|
116
117
|
message = {
|
|
117
118
|
"payload": artifact_upload_request.as_dict(),
|
|
118
119
|
"recordType": "ARTIFACT_UPLOAD_REQUEST",
|
|
119
120
|
"tenantKey": "12345678",
|
|
120
121
|
"recordTimestamp": "2022-03-10T18:50:05Z",
|
|
121
122
|
}
|
|
123
|
+
if messageId:
|
|
124
|
+
message["messageId"] = messageId
|
|
122
125
|
queue_message = QueueMessage(message)
|
|
126
|
+
assert queue_message.messageId == messageId
|
|
123
127
|
if queue_message.recordType == "ARTIFACT_UPLOAD_REQUEST":
|
|
124
128
|
payload = queue_message.payload.as_dict()
|
|
125
129
|
_ = ArtifactUploadRequest(payload)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from unittest.mock import MagicMock
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
from utf_queue_client.clients.xray_data_producer import (
|
|
6
|
+
DummyXrayDataProducer,
|
|
7
|
+
LocalXrayDataProducer,
|
|
8
|
+
XrayDataProducer,
|
|
9
|
+
XrayDataProducerFactory,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def test_xray_data_producer_empty_url():
|
|
14
|
+
with pytest.raises(RuntimeError):
|
|
15
|
+
_ = XrayDataProducer()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def test_xray_data_producer_create_connect_error(mocker):
|
|
19
|
+
mock_class = mocker.patch(
|
|
20
|
+
"utf_queue_client.clients.xray_data_producer.LocalXrayDataProducer"
|
|
21
|
+
)
|
|
22
|
+
mock_instance = MagicMock()
|
|
23
|
+
mock_class.return_value = mock_instance
|
|
24
|
+
mock_class.side_effect = ConnectionError("failing for test")
|
|
25
|
+
with pytest.raises(ConnectionError):
|
|
26
|
+
_ = XrayDataProducerFactory.create_producer()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_dummy_producer(xray_import_test_execution_data):
|
|
30
|
+
producer = DummyXrayDataProducer()
|
|
31
|
+
producer.publish_test_execution(xray_import_test_execution_data)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test_local_xray_producer(xray_import_test_execution_data, mocker):
|
|
35
|
+
mocker.patch(
|
|
36
|
+
"utf_queue_client.clients.base_producer.BlockingProducer.__init__",
|
|
37
|
+
return_value=None,
|
|
38
|
+
)
|
|
39
|
+
mocker.patch(
|
|
40
|
+
"utf_queue_client.clients.base_producer.BlockingProducer.queue_declare"
|
|
41
|
+
)
|
|
42
|
+
mock_producer_publish = mocker.patch(
|
|
43
|
+
"utf_queue_client.clients.base_producer.BlockingProducer.publish"
|
|
44
|
+
)
|
|
45
|
+
producer = LocalXrayDataProducer()
|
|
46
|
+
producer.producer_app_id = "DUMMY"
|
|
47
|
+
producer.publish_test_execution(xray_import_test_execution_data)
|
|
48
|
+
assert mock_producer_publish.called
|
|
49
|
+
kwargs = mock_producer_publish.call_args.kwargs
|
|
50
|
+
payload = kwargs.get("payload")
|
|
51
|
+
assert payload.get("recordSubType") == "IMPORT_TEST_EXECUTION"
|
|
52
|
+
assert payload.get("tenantKey") == "DUMMY"
|
|
53
|
+
payload_data = payload.get("payload")
|
|
54
|
+
assert payload_data.get("test_execution_key") == "DUMMY_EXEC"
|
|
55
|
+
assert payload_data.get("add_tests_to_plan") is True
|
|
56
|
+
assert payload_data.get("info").get("project") == "DUMMY"
|
|
57
|
+
assert payload_data.get("info").get("test_plan_key") == "DUMMY_PLAN"
|
|
58
|
+
assert len(payload_data.get("tests")) == 1
|
|
59
|
+
test = payload_data.get("tests")[0]
|
|
60
|
+
assert test.get("comment") == ""
|
|
61
|
+
assert test.get("executed_by") == "test"
|
|
62
|
+
assert test.get("finish") == "2025-02-11T07:39:25+00:00"
|
|
63
|
+
assert test.get("start") == "2025-02-11T07:39:23+00:00"
|
|
64
|
+
assert test.get("status") == "PASS"
|
|
65
|
+
assert test.get("test_key") == "TC1234567890"
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
setlocal
|
|
2
|
+
call %~dp0setup_venv.bat
|
|
3
|
+
|
|
4
|
+
pushd ..
|
|
5
|
+
|
|
6
|
+
rd /s /q build
|
|
7
|
+
rd /s /q dist
|
|
8
|
+
rd /s /q utf_queue_client.egg-info
|
|
9
|
+
|
|
10
|
+
pip install wheel
|
|
11
|
+
pip install -r test-requirements.txt --index-url https://artifactory.silabs.net/artifactory/api/pypi/infrasw-python-virtual/simple
|
|
12
|
+
python -m build
|
|
13
|
+
|
|
14
|
+
popd
|
|
@@ -6,6 +6,7 @@ from datetime import datetime
|
|
|
6
6
|
from io import BytesIO
|
|
7
7
|
from socket import gethostname
|
|
8
8
|
from typing import List, Optional, Tuple, Union
|
|
9
|
+
from uuid import uuid4
|
|
9
10
|
|
|
10
11
|
import ndjson
|
|
11
12
|
from otel_extensions import instrumented
|
|
@@ -89,6 +90,7 @@ class DataLakeDataProducer:
|
|
|
89
90
|
recordType="DATALAKE_DATA",
|
|
90
91
|
tenantKey=self.tenant_key,
|
|
91
92
|
recordTimestamp=datetime.now().isoformat(),
|
|
93
|
+
messageId=str(uuid4()),
|
|
92
94
|
)
|
|
93
95
|
self.__client.publish(
|
|
94
96
|
exchange="",
|
{utf_queue_client-1.18.0a0 → utf_queue_client-1.19.0}/utf_queue_client/clients/http_producer.py
RENAMED
|
@@ -187,7 +187,7 @@ class CompositeHTTPProducer(Loggable):
|
|
|
187
187
|
for index, producer in enumerate(self.producers):
|
|
188
188
|
if index:
|
|
189
189
|
self.logger.warning(
|
|
190
|
-
f"Failed to execute queue_declare for host {self.producers[index-1].hostname}, retrying with {producer.hostname}..."
|
|
190
|
+
f"Failed to execute queue_declare for host {self.producers[index - 1].hostname}, retrying with {producer.hostname}..."
|
|
191
191
|
)
|
|
192
192
|
try:
|
|
193
193
|
return producer.queue_declare(queue, **kwargs)
|
|
@@ -200,7 +200,7 @@ class CompositeHTTPProducer(Loggable):
|
|
|
200
200
|
for index, producer in enumerate(self.producers):
|
|
201
201
|
if index:
|
|
202
202
|
self.logger.warning(
|
|
203
|
-
f"Failed to execute publish for host {self.producers[index-1].hostname}, retrying with {producer.hostname}..."
|
|
203
|
+
f"Failed to execute publish for host {self.producers[index - 1].hostname}, retrying with {producer.hostname}..."
|
|
204
204
|
)
|
|
205
205
|
try:
|
|
206
206
|
return producer.publish(exchange, routing_key, payload, persistent)
|
|
@@ -2,6 +2,7 @@ import base64
|
|
|
2
2
|
from datetime import datetime
|
|
3
3
|
from socket import gethostname
|
|
4
4
|
from typing import Optional
|
|
5
|
+
from uuid import uuid4
|
|
5
6
|
|
|
6
7
|
from ..models import QueueMessage, TelemetryData
|
|
7
8
|
from .base_producer import BlockingProducer
|
|
@@ -34,6 +35,7 @@ class OpenTelemetryDataProducer:
|
|
|
34
35
|
recordType="OPENTELEMETRY_DATA",
|
|
35
36
|
tenantKey=self.producer_app_id,
|
|
36
37
|
recordTimestamp=datetime.now().isoformat(),
|
|
38
|
+
messageId=str(uuid4()),
|
|
37
39
|
)
|
|
38
40
|
self.__client.publish(
|
|
39
41
|
exchange="",
|
|
@@ -4,6 +4,7 @@ from abc import ABC, abstractmethod
|
|
|
4
4
|
from datetime import datetime
|
|
5
5
|
from socket import gethostname
|
|
6
6
|
from typing import Optional
|
|
7
|
+
from uuid import uuid4
|
|
7
8
|
|
|
8
9
|
from otel_extensions import instrumented
|
|
9
10
|
|
|
@@ -75,6 +76,7 @@ class SqaTestResultProducer(BaseSqaTestResultProducer):
|
|
|
75
76
|
recordSubType="TEST_RESULT",
|
|
76
77
|
tenantKey=self.producer_app_id,
|
|
77
78
|
recordTimestamp=datetime.now().isoformat(),
|
|
79
|
+
messageId=str(uuid4()),
|
|
78
80
|
)
|
|
79
81
|
self._publish_message(queue_message)
|
|
80
82
|
|
|
@@ -86,6 +88,7 @@ class SqaTestResultProducer(BaseSqaTestResultProducer):
|
|
|
86
88
|
recordSubType=subtype,
|
|
87
89
|
tenantKey=self.producer_app_id,
|
|
88
90
|
recordTimestamp=datetime.now().isoformat(),
|
|
91
|
+
messageId=str(uuid4()),
|
|
89
92
|
)
|
|
90
93
|
self._publish_message(queue_message)
|
|
91
94
|
|
|
@@ -108,6 +111,7 @@ class SqaTestResultProducer(BaseSqaTestResultProducer):
|
|
|
108
111
|
recordSubType="BUILD_RESULT",
|
|
109
112
|
tenantKey=self.producer_app_id,
|
|
110
113
|
recordTimestamp=datetime.now().isoformat(),
|
|
114
|
+
messageId=str(uuid4()),
|
|
111
115
|
)
|
|
112
116
|
self._publish_message(queue_message)
|
|
113
117
|
|
|
@@ -3,6 +3,7 @@ from abc import ABC, abstractmethod
|
|
|
3
3
|
from datetime import datetime
|
|
4
4
|
from socket import gethostname
|
|
5
5
|
from typing import Optional
|
|
6
|
+
from uuid import uuid4
|
|
6
7
|
|
|
7
8
|
from otel_extensions import instrumented
|
|
8
9
|
|
|
@@ -50,6 +51,7 @@ class TestRailDataProducer(BaseTestRailDataProducer):
|
|
|
50
51
|
recordSubType="TEST_RESULT",
|
|
51
52
|
tenantKey=self.producer_app_id,
|
|
52
53
|
recordTimestamp=datetime.now().isoformat(),
|
|
54
|
+
messageId=str(uuid4()),
|
|
53
55
|
)
|
|
54
56
|
self.__producer_client.publish(
|
|
55
57
|
exchange="",
|
|
@@ -4,6 +4,7 @@ import os.path
|
|
|
4
4
|
from datetime import datetime
|
|
5
5
|
from socket import gethostname
|
|
6
6
|
from typing import Optional
|
|
7
|
+
from uuid import uuid4
|
|
7
8
|
|
|
8
9
|
from otel_extensions import instrumented
|
|
9
10
|
from ubai_client.apis import ArtifactApi
|
|
@@ -68,6 +69,7 @@ class UbaiArtifactUploadRequestProducer:
|
|
|
68
69
|
recordType="ARTIFACT_UPLOAD_REQUEST",
|
|
69
70
|
tenantKey=self.producer_app_id,
|
|
70
71
|
recordTimestamp=datetime.now().isoformat(),
|
|
72
|
+
messageId=str(uuid4()),
|
|
71
73
|
)
|
|
72
74
|
|
|
73
75
|
self.__client.publish(
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from abc import ABC, abstractmethod
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from socket import gethostname
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
from otel_extensions import instrumented
|
|
8
|
+
|
|
9
|
+
from ..models import QueueMessage, XrayImportTestExecution
|
|
10
|
+
from . import Loggable
|
|
11
|
+
from .base_producer import BlockingProducer as AMQPBlockingProducer
|
|
12
|
+
from .base_producer import ConnectionError
|
|
13
|
+
from .http_producer import CompositeHTTPProducer
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"XrayDataProducer",
|
|
17
|
+
"LocalXrayDataProducer",
|
|
18
|
+
"ConnectionError",
|
|
19
|
+
"XrayDataProducerFactory",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class BaseXrayDataProducer(ABC):
|
|
24
|
+
@abstractmethod
|
|
25
|
+
def publish_test_execution(self, import_test_exec: dict):
|
|
26
|
+
"""publish a test execution object"""
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class XrayDataProducer(BaseXrayDataProducer):
|
|
30
|
+
RECORD_TYPE = "XRAY_EVENT"
|
|
31
|
+
|
|
32
|
+
def __init__(
|
|
33
|
+
self,
|
|
34
|
+
url=None,
|
|
35
|
+
producer_app_id: str = None,
|
|
36
|
+
producer_class: Optional[type] = None,
|
|
37
|
+
):
|
|
38
|
+
if producer_class is None:
|
|
39
|
+
producer_class = AMQPBlockingProducer
|
|
40
|
+
self.queue_name = "default"
|
|
41
|
+
self.__producer_client = producer_class(url, producer_app_id)
|
|
42
|
+
self.__producer_client.queue_declare(queue=self.queue_name, durable=True)
|
|
43
|
+
self.producer_app_id = producer_app_id
|
|
44
|
+
|
|
45
|
+
@instrumented
|
|
46
|
+
def publish_test_execution(self, import_test_exec: XrayImportTestExecution):
|
|
47
|
+
queue_message = QueueMessage(
|
|
48
|
+
payload=import_test_exec,
|
|
49
|
+
recordType=self.RECORD_TYPE,
|
|
50
|
+
recordSubType="IMPORT_TEST_EXECUTION",
|
|
51
|
+
tenantKey=self.producer_app_id,
|
|
52
|
+
recordTimestamp=datetime.now().isoformat(),
|
|
53
|
+
)
|
|
54
|
+
self.__producer_client.publish(
|
|
55
|
+
exchange="",
|
|
56
|
+
routing_key=self.queue_name,
|
|
57
|
+
payload=queue_message.as_dict(),
|
|
58
|
+
persistent=True,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class DummyXrayDataProducer(BaseXrayDataProducer):
|
|
63
|
+
def publish_test_execution(self, import_test_exec: XrayImportTestExecution):
|
|
64
|
+
# noqa
|
|
65
|
+
pass
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class LocalXrayDataProducer(XrayDataProducer):
|
|
69
|
+
def __init__(self):
|
|
70
|
+
super().__init__(
|
|
71
|
+
"amqp://guest:guest@localhost:5672/%2f",
|
|
72
|
+
os.environ.get(
|
|
73
|
+
"UTF_PRODUCER_APP_ID", f"LocalXrayDataProducer at {gethostname()}"
|
|
74
|
+
),
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class XrayDataProducerFactory(Loggable):
|
|
79
|
+
@classmethod
|
|
80
|
+
def create_producer(cls, raise_on_connection_error=False):
|
|
81
|
+
try:
|
|
82
|
+
queue_server_url = os.environ.get("UTF_QUEUE_SERVER_URL")
|
|
83
|
+
if queue_server_url is not None:
|
|
84
|
+
return XrayDataProducer(
|
|
85
|
+
url=queue_server_url,
|
|
86
|
+
producer_app_id=os.environ.get("UTF_PRODUCER_APP_ID"),
|
|
87
|
+
producer_class=CompositeHTTPProducer,
|
|
88
|
+
)
|
|
89
|
+
else:
|
|
90
|
+
return LocalXrayDataProducer()
|
|
91
|
+
except ConnectionError as e:
|
|
92
|
+
cls.logger.warning(f"Unable to connect to queue server: {repr(e)}")
|
|
93
|
+
if raise_on_connection_error:
|
|
94
|
+
raise
|
|
95
|
+
return DummyXrayDataProducer()
|
|
@@ -18,6 +18,14 @@ if IS_PYDANTIC_V1:
|
|
|
18
18
|
from .generated_models_pydantic_v1 import ExceptionEvent
|
|
19
19
|
from .generated_models_pydantic_v1 import TestRailResult
|
|
20
20
|
from .generated_models_pydantic_v1 import TestResultCustomProps
|
|
21
|
+
from .generated_models_pydantic_v1 import XrayInfo
|
|
22
|
+
from .generated_models_pydantic_v1 import XrayStep
|
|
23
|
+
from .generated_models_pydantic_v1 import XrayParameter
|
|
24
|
+
from .generated_models_pydantic_v1 import XrayCustomField
|
|
25
|
+
from .generated_models_pydantic_v1 import XrayIteration
|
|
26
|
+
from .generated_models_pydantic_v1 import XrayTestInfo
|
|
27
|
+
from .generated_models_pydantic_v1 import XrayTestExecUpdate
|
|
28
|
+
from .generated_models_pydantic_v1 import XrayImportTestExecution
|
|
21
29
|
else:
|
|
22
30
|
from .generated_models_pydantic_v2 import QueueMessage
|
|
23
31
|
from .generated_models_pydantic_v2 import QueueMessageV1
|
|
@@ -34,6 +42,14 @@ else:
|
|
|
34
42
|
from .generated_models_pydantic_v2 import ExceptionEvent
|
|
35
43
|
from .generated_models_pydantic_v2 import TestRailResult
|
|
36
44
|
from .generated_models_pydantic_v2 import TestResultCustomProps
|
|
45
|
+
from .generated_models_pydantic_v2 import XrayInfo
|
|
46
|
+
from .generated_models_pydantic_v2 import XrayStep
|
|
47
|
+
from .generated_models_pydantic_v2 import XrayParameter
|
|
48
|
+
from .generated_models_pydantic_v2 import XrayCustomField
|
|
49
|
+
from .generated_models_pydantic_v2 import XrayIteration
|
|
50
|
+
from .generated_models_pydantic_v2 import XrayTestInfo
|
|
51
|
+
from .generated_models_pydantic_v2 import XrayTestExecUpdate
|
|
52
|
+
from .generated_models_pydantic_v2 import XrayImportTestExecution
|
|
37
53
|
|
|
38
54
|
__all__ = [
|
|
39
55
|
"QueueMessage",
|
|
@@ -51,4 +67,12 @@ __all__ = [
|
|
|
51
67
|
"ExceptionEvent",
|
|
52
68
|
"TestRailResult",
|
|
53
69
|
"TestResultCustomProps",
|
|
70
|
+
"XrayInfo",
|
|
71
|
+
"XrayStep",
|
|
72
|
+
"XrayParameter",
|
|
73
|
+
"XrayCustomField",
|
|
74
|
+
"XrayIteration",
|
|
75
|
+
"XrayTestInfo",
|
|
76
|
+
"XrayTestExecUpdate",
|
|
77
|
+
"XrayImportTestExecution",
|
|
54
78
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# generated by datamodel-codegen:
|
|
2
2
|
# filename: queue_message.json
|
|
3
|
-
# timestamp: 2025-
|
|
3
|
+
# timestamp: 2025-03-05T15:14:50+00:00
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
@@ -223,6 +223,76 @@ class TestResultCustomProps(BaseModel):
|
|
|
223
223
|
extra = Extra.allow
|
|
224
224
|
|
|
225
225
|
|
|
226
|
+
class XrayInfo(BaseModel):
|
|
227
|
+
project: Optional[str] = None
|
|
228
|
+
summary: Optional[str] = None
|
|
229
|
+
description: Optional[str] = None
|
|
230
|
+
version: Optional[str] = None
|
|
231
|
+
revision: Optional[str] = None
|
|
232
|
+
user: Optional[str] = None
|
|
233
|
+
start_date: Optional[str] = None
|
|
234
|
+
finish_date: Optional[str] = None
|
|
235
|
+
test_plan_key: Optional[str] = None
|
|
236
|
+
test_environments: Optional[List[str]] = None
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
class XrayStep(BaseModel):
|
|
240
|
+
action: str
|
|
241
|
+
data: str
|
|
242
|
+
result: str
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
class XrayParameter(BaseModel):
|
|
246
|
+
name: str
|
|
247
|
+
value: str
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
class XrayCustomField(BaseModel):
|
|
251
|
+
name: str
|
|
252
|
+
id: Optional[int] = None
|
|
253
|
+
value: str
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
class XrayIteration(BaseModel):
|
|
257
|
+
name: Optional[str] = None
|
|
258
|
+
id: Optional[int] = None
|
|
259
|
+
parameters: List[XrayParameter]
|
|
260
|
+
status: Literal["ABORTED", "EXECUTING", "FAIL", "PASS", "TODO"]
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
class XrayTestInfo(BaseModel):
|
|
264
|
+
project_key: str
|
|
265
|
+
summary: Optional[str] = None
|
|
266
|
+
description: Optional[str] = None
|
|
267
|
+
test_type: Optional[str] = None
|
|
268
|
+
requirement_keys: Optional[List[str]] = None
|
|
269
|
+
labels: Optional[List[str]] = None
|
|
270
|
+
steps: Optional[List[XrayStep]] = None
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
class XrayTestExecUpdate(BaseModel):
|
|
274
|
+
test_key: str
|
|
275
|
+
status: Literal["ABORTED", "EXECUTING", "FAIL", "PASS", "TODO"]
|
|
276
|
+
test_info: Optional[XrayTestInfo] = None
|
|
277
|
+
test_version: Optional[str] = None
|
|
278
|
+
start: Optional[str] = None
|
|
279
|
+
finish: Optional[str] = None
|
|
280
|
+
comment: Optional[str] = None
|
|
281
|
+
executed_by: Optional[str] = None
|
|
282
|
+
assignee: Optional[str] = None
|
|
283
|
+
steps: Optional[List[XrayStep]] = None
|
|
284
|
+
iterations: Optional[List[XrayIteration]] = None
|
|
285
|
+
custom_fields: Optional[List[XrayCustomField]] = None
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
class XrayImportTestExecution(BaseModel):
|
|
289
|
+
test_execution_key: str
|
|
290
|
+
tests: List[XrayTestExecUpdate]
|
|
291
|
+
test_map_field_name: Optional[str] = None
|
|
292
|
+
info: Optional[XrayInfo] = None
|
|
293
|
+
add_tests_to_plan: Optional[bool] = None
|
|
294
|
+
|
|
295
|
+
|
|
226
296
|
class QueueMessage(BaseModel):
|
|
227
297
|
recordType: Literal[
|
|
228
298
|
"ARTIFACT_UPLOAD_REQUEST",
|
|
@@ -232,9 +302,16 @@ class QueueMessage(BaseModel):
|
|
|
232
302
|
"OPENTELEMETRY_DATA",
|
|
233
303
|
"TEST_RAIL_EVENT",
|
|
234
304
|
"UTF_TEST_EVENT",
|
|
305
|
+
"XRAY_EVENT",
|
|
235
306
|
] = Field(..., description="Type of record")
|
|
236
307
|
recordSubType: Optional[
|
|
237
|
-
Literal[
|
|
308
|
+
Literal[
|
|
309
|
+
"BUILD_RESULT",
|
|
310
|
+
"IMPORT_TEST_EXECUTION",
|
|
311
|
+
"SESSION_START",
|
|
312
|
+
"SESSION_STOP",
|
|
313
|
+
"TEST_RESULT",
|
|
314
|
+
]
|
|
238
315
|
] = Field(
|
|
239
316
|
None,
|
|
240
317
|
description="Subtype of record. Not all types have a subtype, but it is required when they have one.",
|
|
@@ -251,6 +328,7 @@ class QueueMessage(BaseModel):
|
|
|
251
328
|
...,
|
|
252
329
|
description="Record Payload.\nThis is flexible to allow different fields for different record types and DB tables",
|
|
253
330
|
)
|
|
331
|
+
messageId: Optional[str] = Field(None, description="Unique client-generated UUID")
|
|
254
332
|
|
|
255
333
|
|
|
256
334
|
class QueueMessageV1(BaseModel):
|