argus-alm 0.12.5__py3-none-any.whl → 0.12.7__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.
- argus/backend/controller/admin_api.py +67 -2
- argus/backend/controller/api.py +14 -0
- argus/backend/controller/auth.py +15 -13
- argus/backend/controller/client_api.py +9 -0
- argus/backend/controller/main.py +1 -0
- argus/backend/models/result.py +22 -0
- argus/backend/plugins/core.py +3 -3
- argus/backend/plugins/driver_matrix_tests/controller.py +39 -0
- argus/backend/plugins/driver_matrix_tests/model.py +248 -2
- argus/backend/plugins/driver_matrix_tests/raw_types.py +27 -0
- argus/backend/plugins/driver_matrix_tests/service.py +18 -0
- argus/backend/plugins/driver_matrix_tests/udt.py +14 -13
- argus/backend/plugins/sct/testrun.py +2 -0
- argus/backend/service/argus_service.py +15 -5
- argus/backend/service/build_system_monitor.py +3 -3
- argus/backend/service/client_service.py +13 -1
- argus/backend/service/jenkins_service.py +3 -1
- argus/backend/service/results_service.py +140 -0
- argus/backend/service/testrun.py +13 -8
- argus/backend/service/user.py +61 -4
- argus/backend/service/views.py +3 -3
- argus/backend/util/config.py +3 -1
- argus/backend/util/encoders.py +17 -0
- argus/client/base.py +18 -1
- argus/client/driver_matrix_tests/cli.py +110 -0
- argus/client/driver_matrix_tests/client.py +56 -193
- {argus_alm-0.12.5.dist-info → argus_alm-0.12.7.dist-info}/METADATA +1 -1
- {argus_alm-0.12.5.dist-info → argus_alm-0.12.7.dist-info}/RECORD +31 -30
- {argus_alm-0.12.5.dist-info → argus_alm-0.12.7.dist-info}/WHEEL +1 -1
- {argus_alm-0.12.5.dist-info → argus_alm-0.12.7.dist-info}/entry_points.txt +1 -0
- argus/client/generic_result_old.py +0 -143
- {argus_alm-0.12.5.dist-info → argus_alm-0.12.7.dist-info}/LICENSE +0 -0
|
@@ -1,216 +1,79 @@
|
|
|
1
|
-
from functools import reduce
|
|
2
|
-
from datetime import datetime
|
|
3
|
-
from typing import TypedDict, Literal
|
|
4
|
-
import re
|
|
5
|
-
import logging
|
|
6
1
|
from uuid import UUID
|
|
7
|
-
from pathlib import Path
|
|
8
|
-
from pprint import pformat
|
|
9
|
-
from glob import glob
|
|
10
|
-
from xml.etree import ElementTree
|
|
11
|
-
|
|
12
2
|
from argus.backend.util.enums import TestStatus
|
|
13
3
|
from argus.client.base import ArgusClient
|
|
14
|
-
from argus.backend.plugins.driver_matrix_tests.raw_types import RawMatrixTestResult, RawMatrixTestCase
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
LOGGER = logging.getLogger(__name__)
|
|
18
|
-
|
|
19
|
-
TestTypeType = Literal['java', 'cpp', 'python', 'gocql']
|
|
20
|
-
|
|
21
|
-
class AdaptedXUnitData(TypedDict):
|
|
22
|
-
timestamp: str
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def python_driver_matrix_adapter(xml: ElementTree.ElementTree) -> AdaptedXUnitData:
|
|
26
|
-
testsuites = list(xml.getroot().iter("testsuite"))
|
|
27
|
-
|
|
28
|
-
return {
|
|
29
|
-
"timestamp": testsuites[0].attrib.get("timestamp"),
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def java_driver_matrix_adapter(xml: ElementTree.ElementTree) -> AdaptedXUnitData:
|
|
34
|
-
testsuites = xml.getroot()
|
|
35
|
-
ts_now = datetime.utcnow().timestamp()
|
|
36
|
-
try:
|
|
37
|
-
time_taken = float(testsuites.attrib.get("time"))
|
|
38
|
-
except ValueError:
|
|
39
|
-
time_taken = 0.0
|
|
40
|
-
|
|
41
|
-
timestamp = datetime.utcfromtimestamp(ts_now - time_taken).isoformat()
|
|
42
|
-
|
|
43
|
-
return {
|
|
44
|
-
"timestamp": timestamp,
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def cpp_driver_matrix_adapter(xml: ElementTree.ElementTree) -> AdaptedXUnitData:
|
|
49
|
-
testsuites = xml.getroot()
|
|
50
|
-
|
|
51
|
-
return {
|
|
52
|
-
"timestamp": testsuites.attrib.get("timestamp"),
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
def gocql_driver_matrix_adapter(xml: ElementTree.ElementTree) -> AdaptedXUnitData:
|
|
57
|
-
testsuites = list(xml.getroot().iter("testsuite"))
|
|
58
|
-
|
|
59
|
-
return {
|
|
60
|
-
"timestamp": testsuites[0].attrib.get("timestamp"),
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def generic_adapter(xml: ElementTree.ElementTree) -> AdaptedXUnitData:
|
|
65
|
-
return {
|
|
66
|
-
"timestamp": datetime.utcnow().isoformat()
|
|
67
|
-
}
|
|
68
4
|
|
|
69
5
|
|
|
70
6
|
class ArgusDriverMatrixClient(ArgusClient):
|
|
71
7
|
test_type = "driver-matrix-tests"
|
|
72
|
-
schema_version: None = "
|
|
8
|
+
schema_version: None = "v2"
|
|
73
9
|
|
|
74
|
-
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
"gocql": gocql_driver_matrix_adapter,
|
|
79
|
-
}
|
|
10
|
+
class Routes(ArgusClient.Routes):
|
|
11
|
+
SUBMIT_DRIVER_RESULT = "/driver_matrix/result/submit"
|
|
12
|
+
SUBMIT_DRIVER_FAILURE = "/driver_matrix/result/fail"
|
|
13
|
+
SUBMIT_ENV = "/driver_matrix/env/submit"
|
|
80
14
|
|
|
81
15
|
def __init__(self, run_id: UUID, auth_token: str, base_url: str, api_version="v1") -> None:
|
|
82
16
|
super().__init__(auth_token, base_url, api_version)
|
|
83
17
|
self.run_id = run_id
|
|
84
18
|
|
|
85
|
-
def
|
|
86
|
-
with open(Path(env_path), mode="rt", encoding="utf-8") as env_file:
|
|
87
|
-
raw_env = env_file.read()
|
|
88
|
-
|
|
89
|
-
result = {}
|
|
90
|
-
for line in raw_env.split("\n"):
|
|
91
|
-
if not line:
|
|
92
|
-
continue
|
|
93
|
-
LOGGER.debug("ENV: %s", line)
|
|
94
|
-
key, val = line.split(": ")
|
|
95
|
-
result[key] = val.strip()
|
|
96
|
-
|
|
97
|
-
return result
|
|
98
|
-
|
|
99
|
-
def get_test_cases(self, cases: list[ElementTree.Element]) -> list[RawMatrixTestCase]:
|
|
100
|
-
raw_cases = []
|
|
101
|
-
for case in cases:
|
|
102
|
-
children = list(case.findall("./*"))
|
|
103
|
-
if len(children) > 0:
|
|
104
|
-
status = children[0].tag
|
|
105
|
-
message = f"{children[0].attrib.get('message', 'no-message')} ({children[0].attrib.get('type', 'no-type')})"
|
|
106
|
-
else:
|
|
107
|
-
status = "passed"
|
|
108
|
-
message = ""
|
|
109
|
-
|
|
110
|
-
raw_cases.append({
|
|
111
|
-
"name": case.attrib["name"],
|
|
112
|
-
"status": status,
|
|
113
|
-
"time": float(case.attrib.get("time", 0.0)),
|
|
114
|
-
"classname": case.attrib.get("classname", ""),
|
|
115
|
-
"message": message,
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
return raw_cases
|
|
119
|
-
|
|
120
|
-
def get_driver_info(self, xml_name: str, test_type: TestTypeType) -> dict[str, str]:
|
|
121
|
-
if test_type == "cpp":
|
|
122
|
-
filename_re = r"TEST-(?P<driver_name>[\w]*)-(?P<version>[\d\.]*)\.xml"
|
|
123
|
-
else:
|
|
124
|
-
filename_re = r"(?P<name>[\w]*)\.(?P<driver_name>[\w]*)\.(?P<proto>v\d)\.(?P<version>[\d\.]*)\.xml"
|
|
125
|
-
|
|
126
|
-
match = re.match(filename_re, xml_name)
|
|
127
|
-
|
|
128
|
-
return match.groupdict() if match else {}
|
|
129
|
-
|
|
130
|
-
def get_passed_count(self, suite_attribs: dict[str, str]) -> int:
|
|
131
|
-
if (pass_count := suite_attribs.get("passed")):
|
|
132
|
-
return int(pass_count)
|
|
133
|
-
total = int(suite_attribs.get("tests", 0))
|
|
134
|
-
errors = int(suite_attribs.get("errors", 0))
|
|
135
|
-
skipped = int(suite_attribs.get("skipped", 0))
|
|
136
|
-
failures = int(suite_attribs.get("failures", 0))
|
|
137
|
-
|
|
138
|
-
return total - errors - skipped - failures
|
|
139
|
-
|
|
140
|
-
def parse_result_xml(self, xml_path: Path, test_type: TestTypeType) -> RawMatrixTestResult:
|
|
141
|
-
with xml_path.open(mode="rt", encoding="utf-8") as xml_file:
|
|
142
|
-
xml = ElementTree.parse(source=xml_file)
|
|
143
|
-
LOGGER.info("%s", pformat(xml))
|
|
144
|
-
testsuites = xml.getroot()
|
|
145
|
-
adapted_data = self.TEST_ADAPTERS.get(test_type, generic_adapter)(xml)
|
|
146
|
-
|
|
147
|
-
driver_info = self.get_driver_info(xml_path.name, test_type)
|
|
148
|
-
test_collection = {
|
|
149
|
-
"timestamp": adapted_data["timestamp"],
|
|
150
|
-
"name": xml_path.stem,
|
|
151
|
-
"driver_name": driver_info.get("driver_name"),
|
|
152
|
-
"tests": 0,
|
|
153
|
-
"failures": 0,
|
|
154
|
-
"errors": 0,
|
|
155
|
-
"disabled": 0,
|
|
156
|
-
"skipped": 0,
|
|
157
|
-
"passed": 0,
|
|
158
|
-
"time": 0.0,
|
|
159
|
-
}
|
|
160
|
-
all_suites = []
|
|
161
|
-
for suite in testsuites.iter("testsuite"):
|
|
162
|
-
raw_suite = {
|
|
163
|
-
"name": suite.attrib["name"],
|
|
164
|
-
"tests": int(suite.attrib.get("tests", 0)),
|
|
165
|
-
"failures": int(suite.attrib.get("failures", 0)),
|
|
166
|
-
"disabled": int(0),
|
|
167
|
-
"passed": self.get_passed_count(suite.attrib),
|
|
168
|
-
"skipped": int(suite.attrib.get("skipped", 0)),
|
|
169
|
-
"errors": int(suite.attrib.get("errors", 0)),
|
|
170
|
-
"time": float(suite.attrib["time"]),
|
|
171
|
-
"cases": self.get_test_cases(list(suite.iter("testcase")))
|
|
172
|
-
}
|
|
173
|
-
all_suites.append(raw_suite)
|
|
174
|
-
test_collection["tests"] += raw_suite["tests"]
|
|
175
|
-
test_collection["failures"] += raw_suite["failures"]
|
|
176
|
-
test_collection["errors"] += raw_suite["errors"]
|
|
177
|
-
test_collection["disabled"] += raw_suite["disabled"]
|
|
178
|
-
test_collection["skipped"] += raw_suite["skipped"]
|
|
179
|
-
test_collection["passed"] += raw_suite["passed"]
|
|
180
|
-
test_collection["time"] += raw_suite["time"]
|
|
181
|
-
|
|
182
|
-
return {
|
|
183
|
-
**test_collection,
|
|
184
|
-
"suites": all_suites
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
def get_results(self, result_path: str, test_type: TestTypeType) -> list[RawMatrixTestResult]:
|
|
188
|
-
xmls = glob(f"{result_path}/**/*.xml", recursive=True)
|
|
189
|
-
LOGGER.info("Will use following XMLs: %s", pformat(xmls))
|
|
190
|
-
results = []
|
|
191
|
-
for xml in xmls:
|
|
192
|
-
result = self.parse_result_xml(Path(xml), test_type)
|
|
193
|
-
results.append(result)
|
|
194
|
-
return results
|
|
195
|
-
|
|
196
|
-
def submit(self, build_id: str, build_url: str, env_path: str, result_path: str, test_type: TestTypeType):
|
|
197
|
-
env = self.parse_build_environment(env_path)
|
|
198
|
-
results = self.get_results(result_path, test_type)
|
|
199
|
-
|
|
200
|
-
self.submit_driver_matrix_run(job_name=build_id, job_url=build_url, test_environment=env, results=results)
|
|
201
|
-
|
|
202
|
-
def submit_driver_matrix_run(self, job_name: str, job_url: str,
|
|
203
|
-
results: list[RawMatrixTestResult], test_environment: dict[str, str]) -> None:
|
|
19
|
+
def submit_driver_matrix_run(self, job_name: str, job_url: str) -> None:
|
|
204
20
|
response = super().submit_run(run_type=self.test_type, run_body={
|
|
205
21
|
"run_id": str(self.run_id),
|
|
206
22
|
"job_name": job_name,
|
|
207
|
-
"job_url": job_url
|
|
208
|
-
"test_environment": test_environment,
|
|
209
|
-
"matrix_results": results
|
|
23
|
+
"job_url": job_url
|
|
210
24
|
})
|
|
211
25
|
|
|
212
26
|
self.check_response(response)
|
|
213
27
|
|
|
28
|
+
def submit_driver_result(self, driver_name: str, driver_type: str, raw_junit_data: bytes):
|
|
29
|
+
"""
|
|
30
|
+
Submit results of a single driver run
|
|
31
|
+
"""
|
|
32
|
+
response = self.post(
|
|
33
|
+
endpoint=self.Routes.SUBMIT_DRIVER_RESULT,
|
|
34
|
+
location_params={},
|
|
35
|
+
body={
|
|
36
|
+
**self.generic_body,
|
|
37
|
+
"run_id": str(self.run_id),
|
|
38
|
+
"driver_name": driver_name,
|
|
39
|
+
"driver_type": driver_type,
|
|
40
|
+
"raw_xml": str(raw_junit_data, encoding="utf-8"),
|
|
41
|
+
}
|
|
42
|
+
)
|
|
43
|
+
self.check_response(response)
|
|
44
|
+
|
|
45
|
+
def submit_driver_failure(self, driver_name: str, driver_type: str, failure_reason: str):
|
|
46
|
+
"""
|
|
47
|
+
Submit a failure to run of a specific driver test
|
|
48
|
+
"""
|
|
49
|
+
response = self.post(
|
|
50
|
+
endpoint=self.Routes.SUBMIT_DRIVER_FAILURE,
|
|
51
|
+
location_params={},
|
|
52
|
+
body={
|
|
53
|
+
**self.generic_body,
|
|
54
|
+
"run_id": str(self.run_id),
|
|
55
|
+
"driver_name": driver_name,
|
|
56
|
+
"driver_type": driver_type,
|
|
57
|
+
"failure_reason": failure_reason,
|
|
58
|
+
}
|
|
59
|
+
)
|
|
60
|
+
self.check_response(response)
|
|
61
|
+
|
|
62
|
+
def submit_env(self, env_info: str):
|
|
63
|
+
"""
|
|
64
|
+
Submit env-info file (Build-00.txt)
|
|
65
|
+
"""
|
|
66
|
+
response = self.post(
|
|
67
|
+
endpoint=self.Routes.SUBMIT_ENV,
|
|
68
|
+
location_params={},
|
|
69
|
+
body={
|
|
70
|
+
**self.generic_body,
|
|
71
|
+
"run_id": str(self.run_id),
|
|
72
|
+
"raw_env": env_info,
|
|
73
|
+
}
|
|
74
|
+
)
|
|
75
|
+
self.check_response(response)
|
|
76
|
+
|
|
214
77
|
def set_matrix_status(self, status: TestStatus):
|
|
215
78
|
response = super().set_status(run_type=self.test_type, run_id=self.run_id, new_status=status)
|
|
216
79
|
self.check_response(response)
|
|
@@ -4,11 +4,11 @@ argus/backend/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
4
4
|
argus/backend/cli.py,sha256=fWSS1m0mhQeCwfH58Qfs4Cicxc95IKi9vwmQn3SUYs0,1346
|
|
5
5
|
argus/backend/controller/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
argus/backend/controller/admin.py,sha256=2z29RX7ZQO_VTklSKH9RrEj-Ag2SsvyOaIzWDKr0ahQ,575
|
|
7
|
-
argus/backend/controller/admin_api.py,sha256=
|
|
8
|
-
argus/backend/controller/api.py,sha256=
|
|
9
|
-
argus/backend/controller/auth.py,sha256=
|
|
10
|
-
argus/backend/controller/client_api.py,sha256=
|
|
11
|
-
argus/backend/controller/main.py,sha256=
|
|
7
|
+
argus/backend/controller/admin_api.py,sha256=lj5g6rdoKN9X13H9hXmKYx_-9tftt6HSftiNFLCr_kY,8567
|
|
8
|
+
argus/backend/controller/api.py,sha256=3TmNyrQXG4AfsHBAGFpUcDemaOlU_ePyx1S6qZsVABs,14613
|
|
9
|
+
argus/backend/controller/auth.py,sha256=rGKgqqjfiZOnoOEpthg5JTd1BuotcEk0S95z_USrgN4,2291
|
|
10
|
+
argus/backend/controller/client_api.py,sha256=IKDIX4rVZgSp5g35ptR1Yx00bAWXm0aRGt6vAroDV74,3646
|
|
11
|
+
argus/backend/controller/main.py,sha256=EXrwvGq2TyebT8a54Ojkxq-o5_QOhm0w51M53G0h_n0,9060
|
|
12
12
|
argus/backend/controller/notification_api.py,sha256=wz7V4nE6Mxclpq78P8gNnCyeQ7xA9BBJjZ-dPhLLd2I,1964
|
|
13
13
|
argus/backend/controller/notifications.py,sha256=zMSJln72BGU6Q_nQvJesMnuvJ57Ucbov4M2ZI-37Bxo,290
|
|
14
14
|
argus/backend/controller/team.py,sha256=G6LdIBaYgfG0Qr4RhNQ53MZVdh4wcuotsIIpFwhTJ3w,3101
|
|
@@ -19,16 +19,16 @@ argus/backend/db.py,sha256=bBiraYD05Qex28yZHjSP1bRlcMsc6oTYGt792zXmaHo,4101
|
|
|
19
19
|
argus/backend/error_handlers.py,sha256=IEjz7Vzfldv1PTOeHrpRWmRsgBrHtAW0PXHUJZDovAE,480
|
|
20
20
|
argus/backend/events/event_processors.py,sha256=bsmBayiXvlGn3aqiT2z9WgwnVBRtn2cRqkgn4pLodck,1291
|
|
21
21
|
argus/backend/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
-
argus/backend/models/result.py,sha256=
|
|
22
|
+
argus/backend/models/result.py,sha256=WNB7nfjLBRwbvWcGW8Y1Co4gWYYwvFeHZb9CW5mw1PM,2216
|
|
23
23
|
argus/backend/models/web.py,sha256=4K1Gj70nugmuW3sv0Sv5M_sVSmEhfJgxRE670qChGzo,13095
|
|
24
24
|
argus/backend/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
|
-
argus/backend/plugins/core.py,sha256=
|
|
26
|
-
argus/backend/plugins/driver_matrix_tests/controller.py,sha256=
|
|
27
|
-
argus/backend/plugins/driver_matrix_tests/model.py,sha256=
|
|
25
|
+
argus/backend/plugins/core.py,sha256=UsrK8oWyhpDSLEcnqAQsEqYVUIX0eCQB862Em7GMQLo,8690
|
|
26
|
+
argus/backend/plugins/driver_matrix_tests/controller.py,sha256=GdPpProzsVXQw8A4h2IS8inUPdr_Q4IN93i6ocOThS8,2213
|
|
27
|
+
argus/backend/plugins/driver_matrix_tests/model.py,sha256=Wqot8rOYqroYV7cn60ltlarnuIuYrL2qyrk13NwLeT4,15419
|
|
28
28
|
argus/backend/plugins/driver_matrix_tests/plugin.py,sha256=72ESU7s8C6ovVMfJTlYwtaokdvRp_HJF1_czm1UMhKg,745
|
|
29
|
-
argus/backend/plugins/driver_matrix_tests/raw_types.py,sha256=
|
|
30
|
-
argus/backend/plugins/driver_matrix_tests/service.py,sha256=
|
|
31
|
-
argus/backend/plugins/driver_matrix_tests/udt.py,sha256=
|
|
29
|
+
argus/backend/plugins/driver_matrix_tests/raw_types.py,sha256=KwbwsvS52RzOZb7_PT7kkYkChNzRH-MpKoO_eeZNDIk,1153
|
|
30
|
+
argus/backend/plugins/driver_matrix_tests/service.py,sha256=98m6IyPsbenq0O-EtGaW0tiQVuM2yGX41xNCO3icmnc,2524
|
|
31
|
+
argus/backend/plugins/driver_matrix_tests/udt.py,sha256=WRtnJU1dZcLXZJQgfU0mgjNzK_DyVhNgLTzr-aXX8K8,1394
|
|
32
32
|
argus/backend/plugins/generic/model.py,sha256=QLVO7QhGr38Hz0VO-BlDYF7LhRX7Pl049vw4W_VMT8o,3302
|
|
33
33
|
argus/backend/plugins/generic/plugin.py,sha256=5URbQVUCizrk-KZqb6I0P_8nLUekjYh-Js7ZLKVoBAA,407
|
|
34
34
|
argus/backend/plugins/generic/types.py,sha256=jlZUcQ7r153ziyl3ZJmix7AzL2G1aX9N_z-4Kw9trWc,267
|
|
@@ -37,40 +37,41 @@ argus/backend/plugins/sct/controller.py,sha256=NF11JLoUJ13whghlxRrVex9rLMgFtlkcz
|
|
|
37
37
|
argus/backend/plugins/sct/plugin.py,sha256=_sOMcXLoFfeG9jwj_t48C4IFvY87juK8ApR6tfSw6q4,1007
|
|
38
38
|
argus/backend/plugins/sct/resource_setup.py,sha256=hwfAOu-oKOH42tjtzJhiqwq_MtUE9_HevoFyql8JKqY,10120
|
|
39
39
|
argus/backend/plugins/sct/service.py,sha256=ygAL85BkyyovJ1xHktlCQJdJS8CrerJZ_Tbr3EXqsg4,22021
|
|
40
|
-
argus/backend/plugins/sct/testrun.py,sha256=
|
|
40
|
+
argus/backend/plugins/sct/testrun.py,sha256=vd44G99mqdR4mAb4hEou48xZN5r1OTg8QTVaawGx9p8,10264
|
|
41
41
|
argus/backend/plugins/sct/types.py,sha256=Gw1y4iqYguqNqTh_GopLDFho8vuGaOGuK7fjaHYhAOQ,1326
|
|
42
42
|
argus/backend/plugins/sct/udt.py,sha256=V_x8_yw8rV7Q_QRBYayqtTNsPdZvjzOxWpRhXP1XAzs,3119
|
|
43
43
|
argus/backend/plugins/sirenada/model.py,sha256=KVnI75BacuBryc5lR_Aai-mEOs7CB9xxhb7J-YRU3bc,4705
|
|
44
44
|
argus/backend/plugins/sirenada/plugin.py,sha256=AlQAakwy3u-OqAqqK3RonUR5oDm-JoiwBUDUF3YEVP4,447
|
|
45
45
|
argus/backend/plugins/sirenada/types.py,sha256=Gm3XMK9YJoozVaeM9XE7n8iRxA6PKBrS23Mo2vJfdLs,697
|
|
46
46
|
argus/backend/service/admin.py,sha256=_VnWl3CkZBOAie_pPbd9sbXZUpBf2SApyNoFZLfB_QI,637
|
|
47
|
-
argus/backend/service/argus_service.py,sha256=
|
|
48
|
-
argus/backend/service/build_system_monitor.py,sha256=
|
|
49
|
-
argus/backend/service/client_service.py,sha256=
|
|
47
|
+
argus/backend/service/argus_service.py,sha256=YF6El9CyIelePDrCydVn4K82sd7CzCoZNmcvn2ZeR9I,29266
|
|
48
|
+
argus/backend/service/build_system_monitor.py,sha256=QB7RfMMuA2VJ4oUAOAqLxOwxqaQE52_4ZhsASVcoXkU,8296
|
|
49
|
+
argus/backend/service/client_service.py,sha256=wcL_Yv_6Q5P4JnvrBMFA_SGVwZqTdK0tjj8q_yt_MAk,3726
|
|
50
50
|
argus/backend/service/event_service.py,sha256=iYeqxN2QCYTjYB1WPPv4BEFLXG0Oz3TvskkaK4v9pVY,654
|
|
51
|
-
argus/backend/service/jenkins_service.py,sha256=
|
|
51
|
+
argus/backend/service/jenkins_service.py,sha256=njomagkliIWKisR9FmhKKqZ8y9NijyJ3hUQe23gl2U4,9878
|
|
52
52
|
argus/backend/service/notification_manager.py,sha256=h00Ej_-hH9H7pq0wah_1TH8dnpPyPNsgVJNO1rwJi7o,7011
|
|
53
53
|
argus/backend/service/release_manager.py,sha256=d1J6llBb4aKgFPrsPTPYpV9NnGx772jeORZjs-ojYGE,7771
|
|
54
|
+
argus/backend/service/results_service.py,sha256=t2IW05avpl1bl8TJDjGo_bt0gswwoM-4vOnnekGCVAc,4528
|
|
54
55
|
argus/backend/service/stats.py,sha256=-V94A8EUlQBvwG53oJTL4U1EzR4vciEF7Niu-efTL6Y,22713
|
|
55
56
|
argus/backend/service/team_manager_service.py,sha256=zY5dvy3ffvQbJuXBvlWKE5dS5LQ3ss6tkFE-cwFZsdw,3010
|
|
56
|
-
argus/backend/service/testrun.py,sha256=
|
|
57
|
-
argus/backend/service/user.py,sha256=
|
|
58
|
-
argus/backend/service/views.py,sha256=
|
|
57
|
+
argus/backend/service/testrun.py,sha256=fPME2Eq02rKobL_QxFwR2jXn5bG_RSS4EN1UVMzRRPY,22735
|
|
58
|
+
argus/backend/service/user.py,sha256=DC8fII7mElWGB-pMGyn4uzaJHIbmxzh_ZWf2POmlBkU,10936
|
|
59
|
+
argus/backend/service/views.py,sha256=gUzwQv3fasGh0hRvivCr64XooQhG3c1V1KcxgMjC2qM,11292
|
|
59
60
|
argus/backend/template_filters.py,sha256=04PHl0DiN4PBHQ82HMAmTfww09fGMXcYy-I5BU_b1s4,682
|
|
60
61
|
argus/backend/util/common.py,sha256=vLMit9ZBBN8S4-dw32LIhjtaEOX_5hwWneHILS_SNBg,1723
|
|
61
|
-
argus/backend/util/config.py,sha256=
|
|
62
|
-
argus/backend/util/encoders.py,sha256=
|
|
62
|
+
argus/backend/util/config.py,sha256=1HpHm8Du6yz61gwAE1vR6uwuHCStaSerirbEhBLnDws,927
|
|
63
|
+
argus/backend/util/encoders.py,sha256=5AfJbs2V3gOOg5LtFLZAtBqlnSdX8HHITT7r9Wu-law,1129
|
|
63
64
|
argus/backend/util/enums.py,sha256=EhTQrgedlEz5sDYJ1gFnE2eC2nc1neQCRgzOgssQvWY,749
|
|
64
65
|
argus/backend/util/logsetup.py,sha256=XWyFLC1_J5G8NcR7oC9l-Pf02ybAvEZR95y5LoY4W48,2438
|
|
65
66
|
argus/backend/util/module_loaders.py,sha256=AcIlX-VRmUQ2THFKT8DLefLSE62Eub2hCxIosg3WgE0,698
|
|
66
67
|
argus/backend/util/send_email.py,sha256=Bb2Hta7WlBCvDKga0_WPFWgxWJEfKpectOGypgf9xzo,3217
|
|
67
68
|
argus/client/__init__.py,sha256=bO9_j5_jK5kvTHR46KEZ0Y-p0li7CBW8QSd-K5Ez4vA,42
|
|
68
|
-
argus/client/base.py,sha256=
|
|
69
|
-
argus/client/driver_matrix_tests/
|
|
69
|
+
argus/client/base.py,sha256=ihSNHlcpChYafooUHnzFI8aYqIkk4fD_qVF4iYIDbQ8,7994
|
|
70
|
+
argus/client/driver_matrix_tests/cli.py,sha256=PIK4IyA4qku7jCnJ8A0i59DeVl1jvMWYukeMOqUQ0jM,6346
|
|
71
|
+
argus/client/driver_matrix_tests/client.py,sha256=UPryBku2rg6IV2wKKDkclXHnH3r6EYwWdds65wLC-KU,2748
|
|
70
72
|
argus/client/generic/cli.py,sha256=IJkgEZ5VOAeqp5SlLM13Y5m8e34Cqnyz8WkfeKoN7so,2208
|
|
71
73
|
argus/client/generic/client.py,sha256=l4PDjDy65Mm2OI9ZLSnyd8_2i4Ei1Pp9yRt3bRX8s2Y,1114
|
|
72
74
|
argus/client/generic_result.py,sha256=Xg3MwwulHH7dGk_pwwbVOm4cHzV4qbfHaFD0VteFVHI,2666
|
|
73
|
-
argus/client/generic_result_old.py,sha256=Oi15Gu8WbXK_WruF0IU-Fokr-I1k8mzg1MpHbmpt50M,4662
|
|
74
75
|
argus/client/sct/client.py,sha256=DtRA0Ra3ycUcedDYfZZW1jER0nc8vdYHaY6DT0te4x0,11341
|
|
75
76
|
argus/client/sct/types.py,sha256=VLgVe7qPmJtCLqtPnuX8N8kMKZq-iY3SKz68nvU6nJ4,371
|
|
76
77
|
argus/client/sirenada/client.py,sha256=ilcyLXJb-0gKbmb9WSPr-Yvldh73joGBhRDoilQoSJ4,6220
|
|
@@ -82,8 +83,8 @@ argus/db/db_types.py,sha256=iLbmrUaDzrBw0kDCnvW0FSZ9-kNc3uQY-fsbIPymV4E,3612
|
|
|
82
83
|
argus/db/interface.py,sha256=HroyA1Yijz5cXLdYbxorHCEu0GH9VeMMqB36IHTlcew,17146
|
|
83
84
|
argus/db/testrun.py,sha256=0YG7FIH5FLQeNlYULxC6rhhyru2rziSMe3qKtYzTBnc,26014
|
|
84
85
|
argus/db/utils.py,sha256=YAWsuLjUScSgKgdaL5aF4Sgr13gqH29Mb5cLctX4V_w,337
|
|
85
|
-
argus_alm-0.12.
|
|
86
|
-
argus_alm-0.12.
|
|
87
|
-
argus_alm-0.12.
|
|
88
|
-
argus_alm-0.12.
|
|
89
|
-
argus_alm-0.12.
|
|
86
|
+
argus_alm-0.12.7.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
87
|
+
argus_alm-0.12.7.dist-info/METADATA,sha256=5mRLCu-5qnJwLHJmwc3yBlZaBqr_ihdnXb2vo_yiqjs,3508
|
|
88
|
+
argus_alm-0.12.7.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
|
89
|
+
argus_alm-0.12.7.dist-info/entry_points.txt,sha256=pcYW8nxZuDaymxE8tn86K0dq8eEodUdiS0sSvwEQ_zU,137
|
|
90
|
+
argus_alm-0.12.7.dist-info/RECORD,,
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
from dataclasses import dataclass, field, asdict
|
|
2
|
-
from typing import Dict, List, Tuple, Union, Type
|
|
3
|
-
from uuid import UUID
|
|
4
|
-
from enum import Enum
|
|
5
|
-
import json
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class Status(Enum):
|
|
10
|
-
PASS = 1
|
|
11
|
-
WARNING = 2
|
|
12
|
-
ERROR = 3
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class ResultType(Enum):
|
|
16
|
-
INTEGER = int
|
|
17
|
-
FLOAT = float
|
|
18
|
-
TEXT = str
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
@dataclass
|
|
22
|
-
class ColumnMetadata:
|
|
23
|
-
id: int
|
|
24
|
-
unit: str
|
|
25
|
-
type: ResultType
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
@dataclass
|
|
29
|
-
class Result:
|
|
30
|
-
value: Union[int, float, str]
|
|
31
|
-
status: Status
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
class ResultTableMeta(type):
|
|
35
|
-
def __new__(cls, name, bases, dct):
|
|
36
|
-
cls_instance = super().__new__(cls, name, bases, dct)
|
|
37
|
-
meta = dct.get('Meta')
|
|
38
|
-
|
|
39
|
-
if meta:
|
|
40
|
-
cls_instance.table_name = meta.table_name
|
|
41
|
-
cls_instance.columns_map = {col_name: ColumnMetadata(id=col_id, unit=unit, type=result_type)
|
|
42
|
-
for col_name, (col_id, unit, result_type) in meta.Columns.items()}
|
|
43
|
-
cls_instance.rows_map = {row_name: row_id
|
|
44
|
-
for row_name, row_id in meta.Rows.items()}
|
|
45
|
-
return cls_instance
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
class Row:
|
|
49
|
-
def __init__(self, columns_map: Dict[str, ColumnMetadata]):
|
|
50
|
-
self.columns_map = columns_map
|
|
51
|
-
self.data: Dict[str, Result] = {}
|
|
52
|
-
|
|
53
|
-
def __getitem__(self, column_name: str) -> Result:
|
|
54
|
-
return self.data[column_name]
|
|
55
|
-
|
|
56
|
-
def __setitem__(self, column_name: str, result: Result):
|
|
57
|
-
if column_name not in self.columns_map:
|
|
58
|
-
raise ValueError(f"Column name '{column_name}' not found in columns_map.")
|
|
59
|
-
column_metadata = self.columns_map[column_name]
|
|
60
|
-
if not isinstance(result.value, column_metadata.type.value):
|
|
61
|
-
raise ValueError(f"Value {result.value} for column '{column_name}' is not of type {column_metadata.type.name}")
|
|
62
|
-
self.data[column_name] = result
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
@dataclass
|
|
66
|
-
class BaseResultTable(metaclass=ResultTableMeta):
|
|
67
|
-
results: Dict[str, Row] = field(default_factory=dict)
|
|
68
|
-
|
|
69
|
-
def as_dict(self) -> dict:
|
|
70
|
-
results_list = []
|
|
71
|
-
for row_name, row in self.results.items():
|
|
72
|
-
row_id = self.rows_map.get(row_name)
|
|
73
|
-
for column_name, result in row.data.items():
|
|
74
|
-
column_metadata = self.columns_map.get(column_name)
|
|
75
|
-
results_list.append({
|
|
76
|
-
"column_id": column_metadata.id,
|
|
77
|
-
"row_id": row_id,
|
|
78
|
-
"result": result.value,
|
|
79
|
-
"status": result.status.value
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
meta_info = {
|
|
83
|
-
"table_name": self.table_name,
|
|
84
|
-
"columns": {name: {"id": meta.id, "unit": meta.unit, "type": meta.type.name} for name, meta in self.columns_map.items()},
|
|
85
|
-
"rows": self.rows_map
|
|
86
|
-
}
|
|
87
|
-
return {
|
|
88
|
-
"meta": meta_info,
|
|
89
|
-
"results": results_list
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
def to_json(self) -> str:
|
|
93
|
-
dict_result = self.as_dict()
|
|
94
|
-
return json.dumps(dict_result, default=str)
|
|
95
|
-
|
|
96
|
-
def __getitem__(self, row_name: str) -> Row:
|
|
97
|
-
if row_name not in self.rows_map:
|
|
98
|
-
raise ValueError(f"Row name '{row_name}' not found in rows_map.")
|
|
99
|
-
if row_name not in self.results:
|
|
100
|
-
self.results[row_name] = Row(self.columns_map)
|
|
101
|
-
return self.results[row_name]
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
# Example of a specific result table with its own metadata
|
|
105
|
-
class LatencyResultTable(BaseResultTable):
|
|
106
|
-
class Meta:
|
|
107
|
-
table_name = "latency_percentile_write"
|
|
108
|
-
Columns = {
|
|
109
|
-
"latency": (1, "ms", ResultType.FLOAT),
|
|
110
|
-
"op_rate": (2, "ops", ResultType.INTEGER)
|
|
111
|
-
}
|
|
112
|
-
Rows = {
|
|
113
|
-
"mean": 1,
|
|
114
|
-
"p99": 2
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
# Client code example
|
|
119
|
-
if __name__ == "__main__":
|
|
120
|
-
class LatencyResultTable(BaseResultTable):
|
|
121
|
-
class Meta:
|
|
122
|
-
table_name = "latency_percentile_write"
|
|
123
|
-
Columns = {
|
|
124
|
-
"latency": (1, "ms", ResultType.FLOAT),
|
|
125
|
-
"op_rate": (2, "ops", ResultType.INTEGER)
|
|
126
|
-
}
|
|
127
|
-
Rows = {
|
|
128
|
-
"mean": 1,
|
|
129
|
-
"p99": 2
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
result_table = LatencyResultTable()
|
|
133
|
-
|
|
134
|
-
result_table["mean"]["latency"] = Result(value=1.1, status=Status.WARNING)
|
|
135
|
-
result_table["mean"]["op_rate"] = Result(value=59988, status=Status.ERROR)
|
|
136
|
-
result_table["p99"]["latency"] = Result(value=2.7, status=Status.PASS)
|
|
137
|
-
result_table["p99"]["op_rate"] = Result(value=59988, status=Status.WARNING)
|
|
138
|
-
|
|
139
|
-
from argus.client.sct.client import ArgusSCTClient
|
|
140
|
-
|
|
141
|
-
run_id = UUID("24e09748-bba4-47fd-a615-bf7ea2c425eb")
|
|
142
|
-
client = ArgusSCTClient(run_id, auth_token="UO+2GXL9XqSgcVJijWk5WnbPXPit5ot5nfkLAHAr7SaqROfSCWycabpp/wxyY8+I", base_url="http://localhost:5000")
|
|
143
|
-
client.submit_results(result_table)
|
|
File without changes
|