argus-alm 0.12.4b2__py3-none-any.whl → 0.12.5__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/client/base.py CHANGED
@@ -7,6 +7,7 @@ from uuid import UUID
7
7
  import requests
8
8
 
9
9
  from argus.backend.util.enums import TestStatus
10
+ from argus.client.generic_result import GenericResultTable
10
11
  from argus.client.sct.types import LogLink
11
12
 
12
13
  JSON = dict[str, Any] | list[Any] | int | str | float | bool | Type[None]
@@ -28,6 +29,8 @@ class ArgusClient:
28
29
  SET_STATUS = "/testrun/$type/$id/set_status"
29
30
  SET_PRODUCT_VERSION = "/testrun/$type/$id/update_product_version"
30
31
  SUBMIT_LOGS = "/testrun/$type/$id/logs/submit"
32
+ SUBMIT_RESULTS = "/testrun/$type/$id/submit_results"
33
+ FETCH_RESULTS = "/testrun/$type/$id/fetch_results"
31
34
  FINALIZE = "/testrun/$type/$id/finalize"
32
35
 
33
36
  def __init__(self, auth_token: str, base_url: str, api_version="v1") -> None:
@@ -190,3 +193,16 @@ class ArgusClient:
190
193
  }
191
194
  )
192
195
  self.check_response(response)
196
+
197
+ def submit_results(self, result: GenericResultTable) -> None:
198
+ response = self.post(
199
+ endpoint=self.Routes.SUBMIT_RESULTS,
200
+ location_params={"type": self.test_type, "id": str(self.run_id)},
201
+ body={
202
+ **self.generic_body,
203
+ "run_id": str(self.run_id),
204
+ ** result.as_dict(),
205
+ }
206
+ )
207
+ self.check_response(response)
208
+
@@ -1,77 +1,214 @@
1
+ from functools import reduce
2
+ from datetime import datetime
3
+ from typing import TypedDict, Literal
4
+ import re
5
+ import logging
1
6
  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
+
2
12
  from argus.backend.util.enums import TestStatus
3
13
  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
+ }
4
68
 
5
69
 
6
70
  class ArgusDriverMatrixClient(ArgusClient):
7
71
  test_type = "driver-matrix-tests"
8
- schema_version: None = "v2"
72
+ schema_version: None = "v1"
9
73
 
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"
74
+ TEST_ADAPTERS = {
75
+ "java": java_driver_matrix_adapter,
76
+ "cpp": cpp_driver_matrix_adapter,
77
+ "python": python_driver_matrix_adapter,
78
+ "gocql": gocql_driver_matrix_adapter,
79
+ }
14
80
 
15
81
  def __init__(self, run_id: UUID, auth_token: str, base_url: str, api_version="v1") -> None:
16
82
  super().__init__(auth_token, base_url, api_version)
17
83
  self.run_id = run_id
18
84
 
19
- def submit_driver_matrix_run(self, job_name: str, job_url: str) -> None:
20
- response = super().submit_run(run_type=self.test_type, run_body={
21
- "run_id": str(self.run_id),
22
- "job_name": job_name,
23
- "job_url": job_url
24
- })
85
+ def parse_build_environment(self, env_path: str) -> dict[str, str]:
86
+ with open(Path(env_path), mode="rt", encoding="utf-8") as env_file:
87
+ raw_env = env_file.read()
25
88
 
26
- self.check_response(response)
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()
27
96
 
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)
97
+ return result
44
98
 
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)
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
61
139
 
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,
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")))
73
172
  }
74
- )
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:
204
+ response = super().submit_run(run_type=self.test_type, run_body={
205
+ "run_id": str(self.run_id),
206
+ "job_name": job_name,
207
+ "job_url": job_url,
208
+ "test_environment": test_environment,
209
+ "matrix_results": results
210
+ })
211
+
75
212
  self.check_response(response)
76
213
 
77
214
  def set_matrix_status(self, status: TestStatus):
@@ -0,0 +1,99 @@
1
+ from dataclasses import dataclass, field
2
+ from enum import Enum, auto
3
+ from typing import Union
4
+
5
+
6
+ class Status(Enum):
7
+ PASS = auto()
8
+ WARNING = auto()
9
+ ERROR = auto()
10
+
11
+ def __str__(self):
12
+ return self.name
13
+
14
+
15
+ class ResultType(Enum):
16
+ INTEGER = auto()
17
+ FLOAT = auto()
18
+ DURATION = auto()
19
+
20
+ def __str__(self):
21
+ return self.name
22
+
23
+
24
+ @dataclass
25
+ class ColumnMetadata:
26
+ name: str
27
+ unit: str
28
+ type: ResultType
29
+
30
+ def as_dict(self) -> dict:
31
+ return {
32
+ "name": self.name,
33
+ "unit": self.unit,
34
+ "type": str(self.type)
35
+ }
36
+
37
+
38
+ class ResultTableMeta(type):
39
+ def __new__(cls, name, bases, dct):
40
+ cls_instance = super().__new__(cls, name, bases, dct)
41
+ meta = dct.get('Meta')
42
+
43
+ if meta:
44
+ cls_instance.name = meta.name
45
+ cls_instance.description = meta.description
46
+ cls_instance.columns = meta.Columns
47
+ cls_instance.column_names = {column.name for column in cls_instance.columns}
48
+ cls_instance.rows = []
49
+ return cls_instance
50
+
51
+
52
+ @dataclass
53
+ class Cell:
54
+ column: str
55
+ row: str
56
+ value: Union[int, float, str]
57
+ status: Status
58
+
59
+ def as_dict(self) -> dict:
60
+ return {
61
+ "column": self.column,
62
+ "row": self.row,
63
+ "value": self.value,
64
+ "status": str(self.status)
65
+ }
66
+
67
+
68
+ @dataclass
69
+ class GenericResultTable(metaclass=ResultTableMeta):
70
+ """
71
+ Base class for all Generic Result Tables in Argus. Use it as a base class for your result table.
72
+ """
73
+ sut_timestamp: int = 0 # automatic timestamp based on SUT version. Works only with SCT and refers to Scylla version.
74
+ sut_details: str = ""
75
+ results: list[Cell] = field(default_factory=list)
76
+
77
+ def as_dict(self) -> dict:
78
+ rows = []
79
+ for result in self.results:
80
+ if result.row not in rows:
81
+ rows.append(result.row)
82
+
83
+ meta_info = {
84
+ "name": self.name,
85
+ "description": self.description,
86
+ "columns_meta": [column.as_dict() for column in self.columns],
87
+ "rows_meta": rows
88
+ }
89
+ return {
90
+ "meta": meta_info,
91
+ "sut_timestamp": self.sut_timestamp,
92
+ "sut_details": self.sut_details,
93
+ "results": [result.as_dict() for result in self.results]
94
+ }
95
+
96
+ def add_result(self, column: str, row: str, value: Union[int, float, str], status: Status):
97
+ if column not in self.column_names:
98
+ raise ValueError(f"Column {column} not found in the table")
99
+ self.results.append(Cell(column=column, row=row, value=value, status=status))
@@ -0,0 +1,143 @@
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)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: argus-alm
3
- Version: 0.12.4b2
3
+ Version: 0.12.5
4
4
  Summary: Argus
5
5
  Home-page: https://github.com/scylladb/argus
6
6
  License: Apache-2.0
@@ -7,27 +7,28 @@ argus/backend/controller/admin.py,sha256=2z29RX7ZQO_VTklSKH9RrEj-Ag2SsvyOaIzWDKr
7
7
  argus/backend/controller/admin_api.py,sha256=I2eQbU5f5rlQeL7eI4t9mRoxM3SJ5O-6fqLsHf0wcEU,6975
8
8
  argus/backend/controller/api.py,sha256=HvjpR4ug5NXiTdBlrFTBeq57YQ5Vl_jca-IT35sAuas,14203
9
9
  argus/backend/controller/auth.py,sha256=nwF_5uZLxPOCLm2ljLyw2OxGur6fmPM7WAAoGJLI_kk,2030
10
- argus/backend/controller/client_api.py,sha256=SM6HRlnoguxkPrqHzm42b5JsoQ2b8-1hTtfLWe832hc,3007
10
+ argus/backend/controller/client_api.py,sha256=AsPkZVjvogEVbNnhqVftvVX-1MACmzJuULAoUj_95bw,3366
11
11
  argus/backend/controller/main.py,sha256=gYA0pqUBlLhpedkOetUX0V82qfe489frOEHPEtM-iHQ,8992
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=92VI_FngMxr9SpKMhlEdSzambvbL4dpMtfx26Z3_Eso,12264
16
+ argus/backend/controller/testrun_api.py,sha256=nJZz2VhyNUWMyHdOmnK-BbxT7ifMLrMPZl8qh9tjVpM,12571
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/web.py,sha256=nl9sCOaPT53UKcZwguQB1DVm523Scgw7d2Rs4xaC9x4,12943
22
+ argus/backend/models/result.py,sha256=jkdwC7bP_KOysAnfB6YcgKIFX_9Tya9Hpe_Zw-YU3x8,1319
23
+ argus/backend/models/web.py,sha256=4K1Gj70nugmuW3sv0Sv5M_sVSmEhfJgxRE670qChGzo,13095
23
24
  argus/backend/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
- argus/backend/plugins/core.py,sha256=kMp2zrEcgAZP0D4yw_dzY5uD8DcC19CoZ_E7urH0f0k,8608
25
- argus/backend/plugins/driver_matrix_tests/controller.py,sha256=GdPpProzsVXQw8A4h2IS8inUPdr_Q4IN93i6ocOThS8,2213
26
- argus/backend/plugins/driver_matrix_tests/model.py,sha256=Wqot8rOYqroYV7cn60ltlarnuIuYrL2qyrk13NwLeT4,15419
25
+ argus/backend/plugins/core.py,sha256=p5VZ3OJPWf3IUzNZbVKW7pG5iysrtTvOCFX3C1HMU0Y,8678
26
+ argus/backend/plugins/driver_matrix_tests/controller.py,sha256=9Q6QCripzM528SGsQnYupM6k7HW7hUzkNyjJFiXXfEw,739
27
+ argus/backend/plugins/driver_matrix_tests/model.py,sha256=8iq9YqHcSSur2N4nZtD6Fn-07F5NN7uVxAu5rauCzUA,7025
27
28
  argus/backend/plugins/driver_matrix_tests/plugin.py,sha256=72ESU7s8C6ovVMfJTlYwtaokdvRp_HJF1_czm1UMhKg,745
28
- argus/backend/plugins/driver_matrix_tests/raw_types.py,sha256=KwbwsvS52RzOZb7_PT7kkYkChNzRH-MpKoO_eeZNDIk,1153
29
- argus/backend/plugins/driver_matrix_tests/service.py,sha256=98m6IyPsbenq0O-EtGaW0tiQVuM2yGX41xNCO3icmnc,2524
30
- argus/backend/plugins/driver_matrix_tests/udt.py,sha256=WRtnJU1dZcLXZJQgfU0mgjNzK_DyVhNgLTzr-aXX8K8,1394
29
+ argus/backend/plugins/driver_matrix_tests/raw_types.py,sha256=A108HCnv5q0RHfNRhUJrTpRy3fG7sPxr9Sk4gfsbooU,600
30
+ argus/backend/plugins/driver_matrix_tests/service.py,sha256=dxb8VGTJLIyVqVrZ4RtzCXgnmS2qg2RAGhcp_SARt9I,1737
31
+ argus/backend/plugins/driver_matrix_tests/udt.py,sha256=6lydzF3AQHm3GR5bKEDu1xLPYsLaBL3o-wu9NpabbqA,1134
31
32
  argus/backend/plugins/generic/model.py,sha256=QLVO7QhGr38Hz0VO-BlDYF7LhRX7Pl049vw4W_VMT8o,3302
32
33
  argus/backend/plugins/generic/plugin.py,sha256=5URbQVUCizrk-KZqb6I0P_8nLUekjYh-Js7ZLKVoBAA,407
33
34
  argus/backend/plugins/generic/types.py,sha256=jlZUcQ7r153ziyl3ZJmix7AzL2G1aX9N_z-4Kw9trWc,267
@@ -36,7 +37,7 @@ argus/backend/plugins/sct/controller.py,sha256=NF11JLoUJ13whghlxRrVex9rLMgFtlkcz
36
37
  argus/backend/plugins/sct/plugin.py,sha256=_sOMcXLoFfeG9jwj_t48C4IFvY87juK8ApR6tfSw6q4,1007
37
38
  argus/backend/plugins/sct/resource_setup.py,sha256=hwfAOu-oKOH42tjtzJhiqwq_MtUE9_HevoFyql8JKqY,10120
38
39
  argus/backend/plugins/sct/service.py,sha256=ygAL85BkyyovJ1xHktlCQJdJS8CrerJZ_Tbr3EXqsg4,22021
39
- argus/backend/plugins/sct/testrun.py,sha256=NopC3Gnzf2m65S_E4DedAlgnbFvyaMQH5aLJip6ZPrE,9660
40
+ argus/backend/plugins/sct/testrun.py,sha256=u0jDFVMo1v4w0_IXRp3BzIjgDIScre20fd3bCLzZl-c,10166
40
41
  argus/backend/plugins/sct/types.py,sha256=Gw1y4iqYguqNqTh_GopLDFho8vuGaOGuK7fjaHYhAOQ,1326
41
42
  argus/backend/plugins/sct/udt.py,sha256=V_x8_yw8rV7Q_QRBYayqtTNsPdZvjzOxWpRhXP1XAzs,3119
42
43
  argus/backend/plugins/sirenada/model.py,sha256=KVnI75BacuBryc5lR_Aai-mEOs7CB9xxhb7J-YRU3bc,4705
@@ -45,14 +46,14 @@ argus/backend/plugins/sirenada/types.py,sha256=Gm3XMK9YJoozVaeM9XE7n8iRxA6PKBrS2
45
46
  argus/backend/service/admin.py,sha256=_VnWl3CkZBOAie_pPbd9sbXZUpBf2SApyNoFZLfB_QI,637
46
47
  argus/backend/service/argus_service.py,sha256=d1NrCQmcE_1NmkV761dheBL43Vk0n-oP0S4IZtQzJUQ,28832
47
48
  argus/backend/service/build_system_monitor.py,sha256=E8Ro1HBMfktxqcCHLPuXwzohkdgrls7pYro-VSG_CMs,8248
48
- argus/backend/service/client_service.py,sha256=CS5esppd9s-SgUYE-HVLkfz-MrN8zxPouf9e4VlPV_M,2326
49
+ argus/backend/service/client_service.py,sha256=shcDLlCxHNUBuYxE8sjkAPfzqLict-BDllCVlUm8mFs,3273
49
50
  argus/backend/service/event_service.py,sha256=iYeqxN2QCYTjYB1WPPv4BEFLXG0Oz3TvskkaK4v9pVY,654
50
51
  argus/backend/service/jenkins_service.py,sha256=PKmu44kAEWl-Dw7f8gXkKhwRkV4yWy-B4CmFxv7c6-8,9685
51
52
  argus/backend/service/notification_manager.py,sha256=h00Ej_-hH9H7pq0wah_1TH8dnpPyPNsgVJNO1rwJi7o,7011
52
53
  argus/backend/service/release_manager.py,sha256=d1J6llBb4aKgFPrsPTPYpV9NnGx772jeORZjs-ojYGE,7771
53
54
  argus/backend/service/stats.py,sha256=-V94A8EUlQBvwG53oJTL4U1EzR4vciEF7Niu-efTL6Y,22713
54
55
  argus/backend/service/team_manager_service.py,sha256=zY5dvy3ffvQbJuXBvlWKE5dS5LQ3ss6tkFE-cwFZsdw,3010
55
- argus/backend/service/testrun.py,sha256=ZM0D38IQpbrmia1GlCfLK02ZLwp_pbpUuQPN8BwibAw,21432
56
+ argus/backend/service/testrun.py,sha256=RmkjdcaKiFguYwIw3g6tFZHIIw5NdVefqXkhdYc4vDw,22310
56
57
  argus/backend/service/user.py,sha256=N3t43rgKMnSsPXU5R9bigEEGbPjYrc6MsJtof3z7kDE,9027
57
58
  argus/backend/service/views.py,sha256=amkyOQgHSP3YEDqiFHAhOiNzNCLk2sLkruTB2_IagDQ,11244
58
59
  argus/backend/template_filters.py,sha256=04PHl0DiN4PBHQ82HMAmTfww09fGMXcYy-I5BU_b1s4,682
@@ -64,11 +65,12 @@ argus/backend/util/logsetup.py,sha256=XWyFLC1_J5G8NcR7oC9l-Pf02ybAvEZR95y5LoY4W4
64
65
  argus/backend/util/module_loaders.py,sha256=AcIlX-VRmUQ2THFKT8DLefLSE62Eub2hCxIosg3WgE0,698
65
66
  argus/backend/util/send_email.py,sha256=Bb2Hta7WlBCvDKga0_WPFWgxWJEfKpectOGypgf9xzo,3217
66
67
  argus/client/__init__.py,sha256=bO9_j5_jK5kvTHR46KEZ0Y-p0li7CBW8QSd-K5Ez4vA,42
67
- argus/client/base.py,sha256=-R-BINTolY06lUQLOLGlsWzza4fBdtLBW-4V3NT64vg,6755
68
- argus/client/driver_matrix_tests/cli.py,sha256=PIK4IyA4qku7jCnJ8A0i59DeVl1jvMWYukeMOqUQ0jM,6346
69
- argus/client/driver_matrix_tests/client.py,sha256=UPryBku2rg6IV2wKKDkclXHnH3r6EYwWdds65wLC-KU,2748
68
+ argus/client/base.py,sha256=etjUxHIlbGNTrvPtvFQYKFYGazuo7avnP8Z__NI6ZyE,7358
69
+ argus/client/driver_matrix_tests/client.py,sha256=ekuTkEZbcVqhg6DAC6PvGuC9bXuu4DSOjk96vcLzmuQ,7817
70
70
  argus/client/generic/cli.py,sha256=IJkgEZ5VOAeqp5SlLM13Y5m8e34Cqnyz8WkfeKoN7so,2208
71
71
  argus/client/generic/client.py,sha256=l4PDjDy65Mm2OI9ZLSnyd8_2i4Ei1Pp9yRt3bRX8s2Y,1114
72
+ argus/client/generic_result.py,sha256=Xg3MwwulHH7dGk_pwwbVOm4cHzV4qbfHaFD0VteFVHI,2666
73
+ argus/client/generic_result_old.py,sha256=Oi15Gu8WbXK_WruF0IU-Fokr-I1k8mzg1MpHbmpt50M,4662
72
74
  argus/client/sct/client.py,sha256=DtRA0Ra3ycUcedDYfZZW1jER0nc8vdYHaY6DT0te4x0,11341
73
75
  argus/client/sct/types.py,sha256=VLgVe7qPmJtCLqtPnuX8N8kMKZq-iY3SKz68nvU6nJ4,371
74
76
  argus/client/sirenada/client.py,sha256=ilcyLXJb-0gKbmb9WSPr-Yvldh73joGBhRDoilQoSJ4,6220
@@ -80,8 +82,8 @@ argus/db/db_types.py,sha256=iLbmrUaDzrBw0kDCnvW0FSZ9-kNc3uQY-fsbIPymV4E,3612
80
82
  argus/db/interface.py,sha256=HroyA1Yijz5cXLdYbxorHCEu0GH9VeMMqB36IHTlcew,17146
81
83
  argus/db/testrun.py,sha256=0YG7FIH5FLQeNlYULxC6rhhyru2rziSMe3qKtYzTBnc,26014
82
84
  argus/db/utils.py,sha256=YAWsuLjUScSgKgdaL5aF4Sgr13gqH29Mb5cLctX4V_w,337
83
- argus_alm-0.12.4b2.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
84
- argus_alm-0.12.4b2.dist-info/METADATA,sha256=bF-azdmr9Fwi30Aj_jt1znGiMdXenmDqAUMC0TeV1hA,3510
85
- argus_alm-0.12.4b2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
86
- argus_alm-0.12.4b2.dist-info/entry_points.txt,sha256=pcYW8nxZuDaymxE8tn86K0dq8eEodUdiS0sSvwEQ_zU,137
87
- argus_alm-0.12.4b2.dist-info/RECORD,,
85
+ argus_alm-0.12.5.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
86
+ argus_alm-0.12.5.dist-info/METADATA,sha256=IaMdyKUclP6Zdzy58_4wulhMbGQIOblEXaMnGAKcEa8,3508
87
+ argus_alm-0.12.5.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
88
+ argus_alm-0.12.5.dist-info/entry_points.txt,sha256=zEqrAK95P8AAhKbwO4lgrQzKBWqCzHH9zlUPCaCVHoQ,69
89
+ argus_alm-0.12.5.dist-info/RECORD,,
@@ -1,4 +1,3 @@
1
1
  [console_scripts]
2
2
  argus-client-generic=argus.client.generic.cli:cli
3
- argus-driver-matrix-client=argus.client.driver_matrix_tests.cli:cli
4
3