argus-alm 0.12.5__py3-none-any.whl → 0.12.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.
- argus/backend/controller/admin_api.py +67 -2
- argus/backend/controller/api.py +18 -1
- argus/backend/controller/auth.py +15 -13
- argus/backend/controller/client_api.py +10 -5
- argus/backend/controller/main.py +1 -0
- argus/backend/controller/testrun_api.py +2 -1
- argus/backend/models/result.py +40 -6
- 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 +9 -3
- argus/backend/service/argus_service.py +15 -5
- argus/backend/service/build_system_monitor.py +3 -3
- argus/backend/service/client_service.py +22 -4
- argus/backend/service/jenkins_service.py +3 -1
- argus/backend/service/results_service.py +201 -0
- argus/backend/service/testrun.py +2 -19
- 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/client/generic_result.py +10 -5
- {argus_alm-0.12.5.dist-info → argus_alm-0.12.8.dist-info}/METADATA +1 -1
- {argus_alm-0.12.5.dist-info → argus_alm-0.12.8.dist-info}/RECORD +33 -31
- {argus_alm-0.12.5.dist-info → argus_alm-0.12.8.dist-info}/entry_points.txt +1 -0
- {argus_alm-0.12.5.dist-info → argus_alm-0.12.8.dist-info}/LICENSE +0 -0
- {argus_alm-0.12.5.dist-info → argus_alm-0.12.8.dist-info}/WHEEL +0 -0
argus/client/base.py
CHANGED
|
@@ -24,6 +24,7 @@ class ArgusClient:
|
|
|
24
24
|
class Routes():
|
|
25
25
|
# pylint: disable=too-few-public-methods
|
|
26
26
|
SUBMIT = "/testrun/$type/submit"
|
|
27
|
+
GET = "/testrun/$type/$id/get"
|
|
27
28
|
HEARTBEAT = "/testrun/$type/$id/heartbeat"
|
|
28
29
|
GET_STATUS = "/testrun/$type/$id/get_status"
|
|
29
30
|
SET_STATUS = "/testrun/$type/$id/set_status"
|
|
@@ -125,7 +126,23 @@ class ArgusClient:
|
|
|
125
126
|
**self.generic_body,
|
|
126
127
|
**run_body
|
|
127
128
|
})
|
|
128
|
-
|
|
129
|
+
|
|
130
|
+
def get_run(self, run_type: str = None, run_id: UUID | str = None) -> requests.Response:
|
|
131
|
+
|
|
132
|
+
if not run_type and hasattr(self, "test_type"):
|
|
133
|
+
run_type = self.test_type
|
|
134
|
+
|
|
135
|
+
if not run_id and hasattr(self, "run_id"):
|
|
136
|
+
run_id = self.run_id
|
|
137
|
+
|
|
138
|
+
if not (run_type and run_id):
|
|
139
|
+
raise ValueError("run_type and run_id must be set in func params or object attributes")
|
|
140
|
+
|
|
141
|
+
response = self.get(endpoint=self.Routes.GET, location_params={"type": run_type, "id": run_id })
|
|
142
|
+
self.check_response(response)
|
|
143
|
+
|
|
144
|
+
return response.json()["response"]
|
|
145
|
+
|
|
129
146
|
def get_status(self, run_type: str = None, run_id: UUID = None) -> TestStatus:
|
|
130
147
|
if not run_type and hasattr(self, "test_type"):
|
|
131
148
|
run_type = self.test_type
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
import json
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
import click
|
|
5
|
+
import logging
|
|
6
|
+
from argus.backend.util.enums import TestStatus
|
|
7
|
+
|
|
8
|
+
from argus.client.driver_matrix_tests.client import ArgusDriverMatrixClient
|
|
9
|
+
|
|
10
|
+
LOGGER = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@click.group
|
|
14
|
+
def cli():
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _submit_driver_result_internal(api_key: str, base_url: str, run_id: str, metadata_path: str):
|
|
19
|
+
metadata = json.loads(Path(metadata_path).read_text(encoding="utf-8"))
|
|
20
|
+
LOGGER.info("Submitting results for %s [%s/%s] to Argus...", run_id, metadata["driver_name"], metadata["driver_type"])
|
|
21
|
+
raw_xml = (Path(metadata_path).parent / metadata["junit_result"]).read_bytes()
|
|
22
|
+
client = ArgusDriverMatrixClient(run_id=run_id, auth_token=api_key, base_url=base_url)
|
|
23
|
+
client.submit_driver_result(driver_name=metadata["driver_name"], driver_type=metadata["driver_type"], raw_junit_data=base64.encodebytes(raw_xml))
|
|
24
|
+
LOGGER.info("Done.")
|
|
25
|
+
|
|
26
|
+
def _submit_driver_failure_internal(api_key: str, base_url: str, run_id: str, metadata_path: str):
|
|
27
|
+
metadata = json.loads(Path(metadata_path).read_text(encoding="utf-8"))
|
|
28
|
+
LOGGER.info("Submitting failure for %s [%s/%s] to Argus...", run_id, metadata["driver_name"], metadata["driver_type"])
|
|
29
|
+
client = ArgusDriverMatrixClient(run_id=run_id, auth_token=api_key, base_url=base_url)
|
|
30
|
+
client.submit_driver_failure(driver_name=metadata["driver_name"], driver_type=metadata["driver_type"], failure_reason=metadata["failure_reason"])
|
|
31
|
+
LOGGER.info("Done.")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@click.command("submit-run")
|
|
35
|
+
@click.option("--api-key", help="Argus API key for authorization", required=True)
|
|
36
|
+
@click.option("--base-url", default="https://argus.scylladb.com", help="Base URL for argus instance")
|
|
37
|
+
@click.option("--id", "run_id", required=True, help="UUID (v4 or v1) unique to the job")
|
|
38
|
+
@click.option("--build-id", required=True, help="Unique job identifier in the build system, e.g. scylla-master/group/job for jenkins (The full path)")
|
|
39
|
+
@click.option("--build-url", required=True, help="Job URL in the build system")
|
|
40
|
+
def submit_driver_matrix_run(api_key: str, base_url: str, run_id: str, build_id: str, build_url: str):
|
|
41
|
+
LOGGER.info("Submitting %s (%s) to Argus...", build_id, run_id)
|
|
42
|
+
client = ArgusDriverMatrixClient(run_id=run_id, auth_token=api_key, base_url=base_url)
|
|
43
|
+
client.submit_driver_matrix_run(job_name=build_id, job_url=build_url)
|
|
44
|
+
LOGGER.info("Done.")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@click.command("submit-driver")
|
|
48
|
+
@click.option("--api-key", help="Argus API key for authorization", required=True)
|
|
49
|
+
@click.option("--base-url", default="https://argus.scylladb.com", help="Base URL for argus instance")
|
|
50
|
+
@click.option("--id", "run_id", required=True, help="UUID (v4 or v1) unique to the job")
|
|
51
|
+
@click.option("--metadata-path", required=True, help="Path to the metadata .json file that contains path to junit xml and other required information")
|
|
52
|
+
def submit_driver_result(api_key: str, base_url: str, run_id: str, metadata_path: str):
|
|
53
|
+
_submit_driver_result_internal(api_key=api_key, base_url=base_url, run_id=run_id, metadata_path=metadata_path)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@click.command("fail-driver")
|
|
57
|
+
@click.option("--api-key", help="Argus API key for authorization", required=True)
|
|
58
|
+
@click.option("--base-url", default="https://argus.scylladb.com", help="Base URL for argus instance")
|
|
59
|
+
@click.option("--id", "run_id", required=True, help="UUID (v4 or v1) unique to the job")
|
|
60
|
+
@click.option("--metadata-path", required=True, help="Path to the metadata .json file that contains path to junit xml and other required information")
|
|
61
|
+
def submit_driver_failure(api_key: str, base_url: str, run_id: str, metadata_path: str):
|
|
62
|
+
_submit_driver_failure_internal(api_key=api_key, base_url=base_url, run_id=run_id, metadata_path=metadata_path)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@click.command("submit-or-fail-driver")
|
|
66
|
+
@click.option("--api-key", help="Argus API key for authorization", required=True)
|
|
67
|
+
@click.option("--base-url", default="https://argus.scylladb.com", help="Base URL for argus instance")
|
|
68
|
+
@click.option("--id", "run_id", required=True, help="UUID (v4 or v1) unique to the job")
|
|
69
|
+
@click.option("--metadata-path", required=True, help="Path to the metadata .json file that contains path to junit xml and other required information")
|
|
70
|
+
def submit_or_fail_driver(api_key: str, base_url: str, run_id: str, metadata_path: str):
|
|
71
|
+
metadata = json.loads(Path(metadata_path).read_text(encoding="utf-8"))
|
|
72
|
+
if metadata.get("failure_reason"):
|
|
73
|
+
_submit_driver_failure_internal(api_key=api_key, base_url=base_url, run_id=run_id, metadata_path=metadata_path)
|
|
74
|
+
else:
|
|
75
|
+
_submit_driver_result_internal(api_key=api_key, base_url=base_url, run_id=run_id, metadata_path=metadata_path)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@click.command("submit-env")
|
|
79
|
+
@click.option("--api-key", help="Argus API key for authorization", required=True)
|
|
80
|
+
@click.option("--base-url", default="https://argus.scylladb.com", help="Base URL for argus instance")
|
|
81
|
+
@click.option("--id", "run_id", required=True, help="UUID (v4 or v1) unique to the job")
|
|
82
|
+
@click.option("--env-path", required=True, help="Path to the Build-00.txt file that contains environment information about Scylla")
|
|
83
|
+
def submit_driver_env(api_key: str, base_url: str, run_id: str, env_path: str):
|
|
84
|
+
LOGGER.info("Submitting environment for run %s to Argus...", run_id)
|
|
85
|
+
raw_env = Path(env_path).read_text()
|
|
86
|
+
client = ArgusDriverMatrixClient(run_id=run_id, auth_token=api_key, base_url=base_url)
|
|
87
|
+
client.submit_env(raw_env)
|
|
88
|
+
LOGGER.info("Done.")
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@click.command("finish-run")
|
|
92
|
+
@click.option("--api-key", help="Argus API key for authorization", required=True)
|
|
93
|
+
@click.option("--base-url", default="https://argus.scylladb.com", help="Base URL for argus instance")
|
|
94
|
+
@click.option("--id", "run_id", required=True, help="UUID (v4 or v1) unique to the job")
|
|
95
|
+
@click.option("--status", required=True, help="Resulting job status")
|
|
96
|
+
def finish_driver_matrix_run(api_key: str, base_url: str, run_id: str, status: str):
|
|
97
|
+
client = ArgusDriverMatrixClient(run_id=run_id, auth_token=api_key, base_url=base_url)
|
|
98
|
+
client.finalize_run(run_type=ArgusDriverMatrixClient.test_type, run_id=run_id, body={"status": TestStatus(status)})
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
cli.add_command(submit_driver_matrix_run)
|
|
102
|
+
cli.add_command(submit_driver_result)
|
|
103
|
+
cli.add_command(submit_or_fail_driver)
|
|
104
|
+
cli.add_command(submit_driver_failure)
|
|
105
|
+
cli.add_command(submit_driver_env)
|
|
106
|
+
cli.add_command(finish_driver_matrix_run)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
if __name__ == "__main__":
|
|
110
|
+
cli()
|
|
@@ -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)
|
argus/client/generic_result.py
CHANGED
|
@@ -7,6 +7,7 @@ class Status(Enum):
|
|
|
7
7
|
PASS = auto()
|
|
8
8
|
WARNING = auto()
|
|
9
9
|
ERROR = auto()
|
|
10
|
+
UNSET = auto()
|
|
10
11
|
|
|
11
12
|
def __str__(self):
|
|
12
13
|
return self.name
|
|
@@ -16,6 +17,7 @@ class ResultType(Enum):
|
|
|
16
17
|
INTEGER = auto()
|
|
17
18
|
FLOAT = auto()
|
|
18
19
|
DURATION = auto()
|
|
20
|
+
TEXT = auto()
|
|
19
21
|
|
|
20
22
|
def __str__(self):
|
|
21
23
|
return self.name
|
|
@@ -44,7 +46,7 @@ class ResultTableMeta(type):
|
|
|
44
46
|
cls_instance.name = meta.name
|
|
45
47
|
cls_instance.description = meta.description
|
|
46
48
|
cls_instance.columns = meta.Columns
|
|
47
|
-
cls_instance.
|
|
49
|
+
cls_instance.column_types = {column.name: column.type for column in cls_instance.columns}
|
|
48
50
|
cls_instance.rows = []
|
|
49
51
|
return cls_instance
|
|
50
52
|
|
|
@@ -57,12 +59,13 @@ class Cell:
|
|
|
57
59
|
status: Status
|
|
58
60
|
|
|
59
61
|
def as_dict(self) -> dict:
|
|
60
|
-
|
|
62
|
+
cell = {"value_text": self.value} if isinstance(self.value, str) else {"value": self.value}
|
|
63
|
+
cell.update({
|
|
61
64
|
"column": self.column,
|
|
62
65
|
"row": self.row,
|
|
63
|
-
"value": self.value,
|
|
64
66
|
"status": str(self.status)
|
|
65
|
-
}
|
|
67
|
+
})
|
|
68
|
+
return cell
|
|
66
69
|
|
|
67
70
|
|
|
68
71
|
@dataclass
|
|
@@ -94,6 +97,8 @@ class GenericResultTable(metaclass=ResultTableMeta):
|
|
|
94
97
|
}
|
|
95
98
|
|
|
96
99
|
def add_result(self, column: str, row: str, value: Union[int, float, str], status: Status):
|
|
97
|
-
if column not in self.
|
|
100
|
+
if column not in self.column_types:
|
|
98
101
|
raise ValueError(f"Column {column} not found in the table")
|
|
102
|
+
if isinstance(value, str) and self.column_types[column] != ResultType.TEXT:
|
|
103
|
+
raise ValueError(f"Column {column} is not of type TEXT")
|
|
99
104
|
self.results.append(Cell(column=column, row=row, value=value, status=status))
|
|
@@ -4,31 +4,31 @@ 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=722KPfrclfxHHf7eUai-ZRv9L-3ehs6FGHr5Qs6AsIU,14827
|
|
9
|
+
argus/backend/controller/auth.py,sha256=rGKgqqjfiZOnoOEpthg5JTd1BuotcEk0S95z_USrgN4,2291
|
|
10
|
+
argus/backend/controller/client_api.py,sha256=ZUVDnaO9b6OesEVvYlqegnkx50vnwCAq8aCNCFPk3JA,3574
|
|
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
|
|
15
15
|
argus/backend/controller/team_ui.py,sha256=B7N1_Kzl6Rac8BV3FbKj55pGAS_dht47rYhAi94PC8A,589
|
|
16
|
-
argus/backend/controller/testrun_api.py,sha256=
|
|
16
|
+
argus/backend/controller/testrun_api.py,sha256=MCcVmbfNuyODCVbxF8TfcvVu9sMT0xO1UzS4VgumQiM,12638
|
|
17
17
|
argus/backend/controller/view_api.py,sha256=rI7LwcS7keK37nYx76D9StFV_rLHcNkHan8OhFgBrhM,4106
|
|
18
18
|
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=H2VOIWiQgkSHtFVK7piwlsEFML4qLOjhhuIFSXVJPjs,3182
|
|
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,39 +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=XV7aCK88nSw-SN5R_8rGpoOoQBDUUUm6YwmJQfI8P8k,10537
|
|
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=4u4kAl5aeeScQhhUQdkXqwjje-YWrjTLpzSljKVXDAQ,3965
|
|
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=GYvP5x-zLHFwxLFzx8QxX2CNSNUJDf0mYu5k2Q5TcD8,7495
|
|
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=Erhc4iDh1VwjUDIW5YmggQ98HjB7j5UolQy1uU2SHT8,21534
|
|
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
|
-
argus/client/generic_result.py,sha256=
|
|
74
|
+
argus/client/generic_result.py,sha256=yjNH_YwIx7oJWcegWWI-gd8yvnMrpLnJNpoAu9aBNjg,2962
|
|
73
75
|
argus/client/generic_result_old.py,sha256=Oi15Gu8WbXK_WruF0IU-Fokr-I1k8mzg1MpHbmpt50M,4662
|
|
74
76
|
argus/client/sct/client.py,sha256=DtRA0Ra3ycUcedDYfZZW1jER0nc8vdYHaY6DT0te4x0,11341
|
|
75
77
|
argus/client/sct/types.py,sha256=VLgVe7qPmJtCLqtPnuX8N8kMKZq-iY3SKz68nvU6nJ4,371
|
|
@@ -82,8 +84,8 @@ argus/db/db_types.py,sha256=iLbmrUaDzrBw0kDCnvW0FSZ9-kNc3uQY-fsbIPymV4E,3612
|
|
|
82
84
|
argus/db/interface.py,sha256=HroyA1Yijz5cXLdYbxorHCEu0GH9VeMMqB36IHTlcew,17146
|
|
83
85
|
argus/db/testrun.py,sha256=0YG7FIH5FLQeNlYULxC6rhhyru2rziSMe3qKtYzTBnc,26014
|
|
84
86
|
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.
|
|
87
|
+
argus_alm-0.12.8.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
88
|
+
argus_alm-0.12.8.dist-info/METADATA,sha256=Z5AqERaHlu2VBQSdQockV34Pn76P6nV5AEsjIjHQbSo,3508
|
|
89
|
+
argus_alm-0.12.8.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
90
|
+
argus_alm-0.12.8.dist-info/entry_points.txt,sha256=pcYW8nxZuDaymxE8tn86K0dq8eEodUdiS0sSvwEQ_zU,137
|
|
91
|
+
argus_alm-0.12.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|