argus-alm 0.10.2__py3-none-any.whl → 0.11.0__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.
@@ -122,6 +122,24 @@ class PluginModelBase(Model):
122
122
 
123
123
  return list(rows)
124
124
 
125
+ @classmethod
126
+ def get_run_meta_by_build_id(cls, build_id: str, limit: int = 10):
127
+ cluster = ScyllaCluster.get()
128
+ query = cluster.prepare("SELECT id, test_id, group_id, release_id, status, start_time, build_job_url, build_id, "
129
+ f"assignee, end_time, investigation_status, heartbeat FROM {cls.table_name()} WHERE build_id = ? LIMIT ?")
130
+ rows = cluster.session.execute(query=query, parameters=(build_id, limit))
131
+
132
+ return list(rows)
133
+
134
+ @classmethod
135
+ def get_run_meta_by_run_id(cls, run_id: UUID | str):
136
+ cluster = ScyllaCluster.get()
137
+ query = cluster.prepare("SELECT id, test_id, group_id, release_id, status, start_time, build_job_url, build_id, "
138
+ f"assignee, end_time, investigation_status, heartbeat FROM {cls.table_name()} WHERE id = ?")
139
+ rows = cluster.session.execute(query=query, parameters=(run_id,))
140
+
141
+ return list(rows)
142
+
125
143
  @classmethod
126
144
  def load_test_run(cls, run_id: UUID) -> 'PluginModelBase':
127
145
  raise NotImplementedError()
@@ -45,7 +45,7 @@ class SCTTestRunSubmissionRequest():
45
45
 
46
46
 
47
47
  class SCTTestRun(PluginModelBase):
48
- __table_name__ = "test_runs_v8"
48
+ __table_name__ = "sct_test_run"
49
49
  _plugin_name = "scylla-cluster-tests"
50
50
 
51
51
  # Test Details
@@ -0,0 +1,113 @@
1
+ from datetime import datetime
2
+ from uuid import UUID, uuid4
3
+ from cassandra.cqlengine import columns
4
+ from cassandra.cqlengine.usertype import UserType
5
+ from cassandra.cqlengine.models import Model
6
+ from argus.backend.db import ScyllaCluster
7
+ from argus.backend.models.web import ArgusRelease
8
+ from argus.backend.plugins.core import PluginModelBase
9
+ from argus.backend.plugins.sirenada.types import RawSirenadaRequest, SirenadaPluginException
10
+ from argus.backend.util.enums import TestStatus
11
+
12
+
13
+ class SirenadaTest(UserType):
14
+ test_name = columns.Text()
15
+ class_name = columns.Text()
16
+ file_name = columns.Text()
17
+ browser_type = columns.Text()
18
+ cluster_type = columns.Text()
19
+ status = columns.Text()
20
+ duration = columns.Float()
21
+ message = columns.Text()
22
+ start_time = columns.DateTime()
23
+ stack_trace = columns.Text()
24
+ screenshot_file = columns.Text()
25
+ s3_folder_id = columns.Text()
26
+ requests_file = columns.Text()
27
+ sirenada_test_id = columns.Text()
28
+ sirenada_user = columns.Text()
29
+ sirenada_password = columns.Text()
30
+
31
+
32
+
33
+ class SirenadaRun(PluginModelBase):
34
+ _plugin_name = "sirenada"
35
+ __table_name__ = "sirenada_run"
36
+ logs = columns.Map(key_type=columns.Text(), value_type=columns.Text())
37
+ # TODO: Legacy field name, should be renamed to product_version and abstracted
38
+ scylla_version = columns.Text()
39
+ region = columns.Text()
40
+ sirenada_test_ids = columns.List(value_type=columns.Text())
41
+ s3_folder_ids = columns.List(value_type=columns.Tuple(columns.Text(), columns.Text()))
42
+ browsers = columns.List(value_type=columns.Text())
43
+ clusters = columns.List(value_type=columns.Text())
44
+ sct_test_id = columns.UUID()
45
+ results = columns.List(value_type=columns.UserDefinedType(user_type=SirenadaTest))
46
+
47
+ @classmethod
48
+ def _stats_query(cls) -> str:
49
+ return ("SELECT id, test_id, group_id, release_id, status, start_time, build_job_url, build_id, "
50
+ f"assignee, end_time, investigation_status, heartbeat, scylla_version FROM {cls.table_name()} WHERE release_id = ?")
51
+
52
+ @classmethod
53
+ def get_distinct_product_versions(cls, release: ArgusRelease, cluster: ScyllaCluster = None) -> list[str]:
54
+ if not cluster:
55
+ cluster = ScyllaCluster.get()
56
+ statement = cluster.prepare(f"SELECT scylla_version FROM {cls.table_name()} WHERE release_id = ?")
57
+ rows = cluster.session.execute(query=statement, parameters=(release.id,))
58
+ unique_versions = {r["scylla_version"] for r in rows if r["scylla_version"]}
59
+
60
+ return sorted(list(unique_versions), reverse=True)
61
+
62
+ def submit_product_version(self, version: str):
63
+ self.scylla_version = version
64
+
65
+ def submit_logs(self, logs: dict[str, str]):
66
+ raise SirenadaPluginException("Log submission is not supported for Sirenada")
67
+
68
+ def finish_run(self):
69
+ raise SirenadaPluginException("Sirenada runs do not need finalization")
70
+
71
+ @classmethod
72
+ def load_test_run(cls, run_id: UUID) -> 'SirenadaRun':
73
+ return cls.get(id=run_id)
74
+
75
+ @classmethod
76
+ def submit_run(cls, request_data: RawSirenadaRequest) -> 'SirenadaRun':
77
+ try:
78
+ run = cls.get(id=UUID(request_data["run_id"]))
79
+ except cls.DoesNotExist:
80
+ run = cls()
81
+ run.id = request_data["run_id"]
82
+ run.build_id = request_data["build_id"]
83
+ run.start_time = datetime.utcnow()
84
+ run.assign_categories()
85
+ run.build_job_url = request_data["build_job_url"]
86
+ run.region = request_data["region"]
87
+ run.status = TestStatus.PASSED.value
88
+ try:
89
+ run.assignee = run.get_scheduled_assignee()
90
+ except Model.DoesNotExist:
91
+ run.assignee = None
92
+
93
+ for raw_case in request_data["results"]:
94
+ case = SirenadaTest(**raw_case)
95
+ if case.status in ["failed", "error"] and run.status not in [TestStatus.FAILED.value, TestStatus.ABORTED.value]:
96
+ run.status = TestStatus.FAILED.value
97
+ run.results.append(case)
98
+
99
+ if case.sirenada_test_id not in run.sirenada_test_ids:
100
+ run.sirenada_test_ids.append(case.sirenada_test_id)
101
+
102
+ if case.browser_type not in run.browsers:
103
+ run.browsers.append(case.browser_type)
104
+
105
+ if case.cluster_type not in run.clusters:
106
+ run.clusters.append(case.cluster_type)
107
+
108
+ if (case.s3_folder_id, case.sirenada_test_id) not in run.s3_folder_ids and case.s3_folder_id:
109
+ run.s3_folder_ids.append((case.s3_folder_id, case.sirenada_test_id))
110
+
111
+ run.save()
112
+
113
+ return run
@@ -0,0 +1,17 @@
1
+ from flask import Blueprint
2
+
3
+ from argus.backend.plugins.core import PluginInfoBase, PluginModelBase
4
+ from argus.backend.plugins.sirenada.model import SirenadaRun, SirenadaTest
5
+
6
+
7
+ class PluginInfo(PluginInfoBase):
8
+ # pylint: disable=too-few-public-methods
9
+ name: str = "sirenada"
10
+ model: PluginModelBase = SirenadaRun
11
+ controller: Blueprint = None
12
+ all_models = [
13
+ SirenadaRun
14
+ ]
15
+ all_types = [
16
+ SirenadaTest
17
+ ]
@@ -0,0 +1,35 @@
1
+ from typing import TypedDict
2
+
3
+
4
+ class RawSirenadaTestCase(TypedDict):
5
+ test_name: str
6
+ class_name: str
7
+ file_name: str
8
+ browser_type: str
9
+ cluster_type: str
10
+ status: str
11
+ duration: float
12
+ message: str
13
+ start_time: str
14
+ stack_trace: str
15
+ screenshot_file: str
16
+ s3_folder_id: str
17
+ requests_file: str
18
+ sirenada_test_id: str
19
+ sirenada_user: str
20
+ sirenada_password: str
21
+
22
+
23
+ class RawSirenadaRequest(TypedDict):
24
+ build_id: str
25
+ build_job_url: str
26
+ run_id: str # UUID
27
+ region: list[str]
28
+ browsers: list[str]
29
+ clusters: list[str]
30
+ sct_test_id: str
31
+ results: list[RawSirenadaTestCase]
32
+
33
+
34
+ class SirenadaPluginException(Exception):
35
+ pass
@@ -3,6 +3,7 @@ import logging
3
3
  from datetime import datetime
4
4
  from typing import TypedDict
5
5
  from uuid import UUID
6
+
6
7
  from argus.backend.plugins.loader import all_plugin_models
7
8
  from argus.backend.util.common import get_build_number
8
9
  from argus.backend.util.enums import TestStatus, TestInvestigationStatus
@@ -92,16 +93,28 @@ class ReleaseStats:
92
93
  self.all_tests = []
93
94
 
94
95
  def to_dict(self) -> dict:
96
+ converted_groups = {str(group.group.id): group.to_dict() for group in self.groups}
97
+ aggregated_investigation_status = {}
98
+ for group in converted_groups.values():
99
+ for investigation_status in TestInvestigationStatus:
100
+ current_status = aggregated_investigation_status.get(investigation_status.value, {})
101
+ result = {
102
+ status.value: current_status.get(status.value, 0) + group.get(investigation_status.value, {}).get(status, 0)
103
+ for status in TestStatus
104
+ }
105
+ aggregated_investigation_status[investigation_status.value] = result
106
+
95
107
  return {
96
108
  "release": dict(self.release.items()),
97
- "groups": {str(group.group.id): group.to_dict() for group in self.groups},
109
+ "groups": converted_groups,
98
110
  "total": self.total_tests,
99
111
  **self.status_map,
100
112
  "disabled": not self.release.enabled,
101
113
  "perpetual": self.release.perpetual,
102
114
  "lastStatus": self.last_investigation_status,
103
115
  "lastInvestigationStatus": self.last_investigation_status,
104
- "hasBugReport": self.has_bug_report
116
+ "hasBugReport": self.has_bug_report,
117
+ **aggregated_investigation_status
105
118
  }
106
119
 
107
120
  def collect(self, rows: list[TestRunStatRow], limited=False, force=False) -> None:
@@ -144,6 +157,15 @@ class GroupStats:
144
157
  self.tests: list[TestStats] = []
145
158
 
146
159
  def to_dict(self) -> dict:
160
+ converted_tests = {str(test.test.id): test.to_dict() for test in self.tests}
161
+ investigation_progress = {}
162
+ for test in converted_tests.values():
163
+ progress_for_status = investigation_progress.get(test["investigation_status"], {})
164
+ status_count = progress_for_status.get(test["status"], 0)
165
+ status_count += 1
166
+ progress_for_status[test["status"]] = status_count
167
+ investigation_progress[test["investigation_status"]] = progress_for_status
168
+
147
169
  return {
148
170
  "group": dict(self.group.items()),
149
171
  "total": self.total_tests,
@@ -151,7 +173,8 @@ class GroupStats:
151
173
  "lastStatus": self.last_status,
152
174
  "lastInvestigationStatus": self.last_investigation_status,
153
175
  "disabled": self.disabled,
154
- "tests": {str(test.test.id): test.to_dict() for test in self.tests}
176
+ "tests": converted_tests,
177
+ **investigation_progress
155
178
  }
156
179
 
157
180
  def collect(self, limited=False):
@@ -68,14 +68,14 @@ class TestRunService:
68
68
  if not plugin:
69
69
  return []
70
70
 
71
- last_runs: list[PluginModelBase] = list(plugin.model.filter(build_id=test.build_system_id).limit(limit).all())
72
- last_runs_ids = [run.id for run in last_runs]
71
+ last_runs: list[dict] = plugin.model.get_run_meta_by_build_id(build_id=test.build_system_id, limit=limit)
72
+ last_runs_ids = [run["id"] for run in last_runs]
73
73
  for added_run in additional_runs:
74
74
  if added_run not in last_runs_ids:
75
- last_runs.append(plugin.model.get(id=added_run))
75
+ last_runs.extend(plugin.model.get_run_meta_by_run_id(run_id=added_run))
76
76
 
77
77
  for row in last_runs:
78
- setattr(row, "build_number", get_build_number(build_job_url=row.build_job_url))
78
+ row["build_number"] = get_build_number(build_job_url=row["build_job_url"])
79
79
 
80
80
  return last_runs
81
81
 
@@ -391,7 +391,7 @@ class TestRunService:
391
391
  response = []
392
392
  for issue in all_issues:
393
393
  runs = runs_by_issue.get(issue, [])
394
- runs.append(issue.run_id)
394
+ runs.append({"test_id": issue.test_id, "run_id": issue.run_id})
395
395
  runs_by_issue[issue] = runs
396
396
 
397
397
  for issue, runs in runs_by_issue.items():
@@ -0,0 +1,151 @@
1
+ import json
2
+ import logging
3
+ from glob import glob, escape
4
+ from pathlib import Path
5
+ from typing import TypedDict
6
+ from xml.etree import ElementTree
7
+
8
+ from argus.backend.plugins.sirenada.types import RawSirenadaRequest, RawSirenadaTestCase
9
+
10
+ from argus.client.base import ArgusClient
11
+
12
+
13
+ LOGGER = logging.getLogger(__name__)
14
+
15
+ class SirenadaEnv(TypedDict):
16
+ SIRENADA_JOB_ID: str
17
+ SIRENADA_BROWSER: str
18
+ SIRENADA_REGION: str
19
+ SIRENADA_CLUSTER: str
20
+ WORKSPACE: str
21
+ BUILD_NUMBER: str
22
+ BUILD_URL: str
23
+ JOB_NAME: str
24
+
25
+
26
+ class TestCredentials(TypedDict):
27
+ SIRENADA_TEST_ID: str
28
+ SIRENADA_USER_NAME: str
29
+ SIRENADA_USER_PASS: str
30
+ SIRENADA_OTP_SECRET: str
31
+ ClusterID: str
32
+ region: str
33
+
34
+ class ArgusSirenadaClient(ArgusClient):
35
+ test_type = "sirenada"
36
+ schema_version: None = "v1"
37
+ _junit_xml_filename = "junit_results.xml"
38
+ _credentials_filename = "test_credentials.json"
39
+ _bucket_url_template = "https://sirenada-results.s3.us-east-1.amazonaws.com/{s3_id}/{test_results_dir}/{filename}"
40
+ TEST_TAG_MAPPING = {
41
+ "failure": "failed",
42
+ "error": "aborted",
43
+ "skipped": "skipped"
44
+ }
45
+
46
+ def __init__(self, auth_token: str, base_url: str, api_version="v1") -> None:
47
+ self.results_path: Path | None = None
48
+ super().__init__(auth_token, base_url, api_version)
49
+
50
+ def _verify_required_files_exist(self, results_path: Path):
51
+ assert (results_path / self._junit_xml_filename).exists(), "Missing jUnit XML results file!"
52
+ assert (results_path / self._credentials_filename).exists(), "Missing test credentials file!"
53
+
54
+ @staticmethod
55
+ def _verify_env(env: SirenadaEnv):
56
+ for key in SirenadaEnv.__annotations__.keys():
57
+ assert env.get(key), f"Missing required key {key} in the environment"
58
+
59
+ def _set_files_for_failed_test(self, test_case: RawSirenadaTestCase):
60
+ test_results_dir = f"sirenada-{test_case['sirenada_test_id']}"
61
+ results_dir: Path = self.results_path / test_results_dir
62
+
63
+ just_class_name = test_case.get("class_name").split(".")[-1]
64
+ requests_pattern = f"{just_class_name}-{test_case.get('test_name')}.requests.json"
65
+ screenshot_pattern = f"{just_class_name}-{escape(test_case.get('test_name'))}-*.png"
66
+
67
+ if not results_dir.exists():
68
+ return
69
+
70
+ if not (s3_bucket_id_path := (results_dir / "s3_id")).exists():
71
+ return
72
+
73
+ with open(s3_bucket_id_path, "rt") as s3_id_file:
74
+ test_case["s3_folder_id"] = s3_id_file.read().strip()
75
+
76
+ test_case["requests_file"] = self._bucket_url_template.format(
77
+ s3_id=test_case.get("s3_folder_id"),
78
+ test_results_dir=test_results_dir,
79
+ filename=requests_pattern,
80
+ )
81
+
82
+ screenshots = glob(pathname=screenshot_pattern, root_dir=results_dir)
83
+ if len(screenshots) > 0:
84
+ test_case["screenshot_file"] = self._bucket_url_template.format(
85
+ s3_id=test_case.get("s3_folder_id"),
86
+ test_results_dir=test_results_dir,
87
+ filename=screenshots[0],
88
+ )
89
+
90
+ def _set_case_status(self, raw_case: RawSirenadaTestCase, junit_case: ElementTree.Element):
91
+ subelements = list(junit_case.iter())
92
+ if len(subelements) == 2:
93
+ status_node = subelements[1]
94
+ raw_case["status"] = self.TEST_TAG_MAPPING.get(status_node.tag, "failed")
95
+ raw_case["message"] = status_node.get("message", "#NO_MESSAGE")
96
+ raw_case["stack_trace"] = status_node.text
97
+ self._set_files_for_failed_test(raw_case)
98
+ else:
99
+ raw_case["status"] = "passed"
100
+
101
+ def _parse_junit_results(self, junit_xml: Path, credentials: TestCredentials, env: SirenadaEnv) -> list[RawSirenadaTestCase]:
102
+ etree = ElementTree.parse(source=junit_xml)
103
+ cases = list(etree.iter("testcase"))
104
+ assert len(cases) > 0, "No test cases found in test results XML."
105
+
106
+ parsed_cases: list[RawSirenadaTestCase] = []
107
+ for case in cases:
108
+ raw_case: RawSirenadaTestCase = {}
109
+ raw_case["class_name"] = case.get("classname", "#NO_CLASSNAME")
110
+ raw_case["file_name"] = case.get("file", "#NO_FILE")
111
+ raw_case["test_name"] = case.get("name", "#NO_TEST_NAME")
112
+ raw_case["browser_type"] = env.get("SIRENADA_BROWSER")
113
+ raw_case["cluster_type"] = env.get("SIRENADA_CLUSTER")
114
+ raw_case["duration"] = float(case.attrib.get("time", "0.0"))
115
+ raw_case["sirenada_test_id"] = credentials.get("SIRENADA_TEST_ID")
116
+ raw_case["sirenada_user"] = credentials.get("SIRENADA_USER_NAME")
117
+ raw_case["sirenada_password"] = credentials.get("SIRENADA_USER_PASS")
118
+ self._set_case_status(raw_case, case)
119
+ parsed_cases.append(raw_case)
120
+
121
+ return parsed_cases
122
+
123
+ @staticmethod
124
+ def _read_credentials(credentials_path: Path) -> TestCredentials:
125
+ with open(credentials_path, "rt") as creds_file:
126
+ credentials: TestCredentials = json.load(creds_file)
127
+
128
+ assert credentials.get("SIRENADA_TEST_ID"), "Credentials are missing required field: SIRENADA_TEST_ID"
129
+ return credentials
130
+
131
+ def submit_sirenada_run(self, env: SirenadaEnv, test_results_path: Path):
132
+ self.results_path = test_results_path
133
+ try:
134
+ self._verify_env(env)
135
+ self._verify_required_files_exist(self.results_path)
136
+ except AssertionError as exc:
137
+ LOGGER.critical("%s", exc.args[0])
138
+ raise exc
139
+
140
+ credentials = self._read_credentials(self.results_path / self._credentials_filename)
141
+ results = self._parse_junit_results(junit_xml=self.results_path / self._junit_xml_filename, credentials=credentials, env=env)
142
+ request_body: RawSirenadaRequest = {}
143
+
144
+ request_body["run_id"] = env.get("SIRENADA_JOB_ID")
145
+ request_body["build_id"] = env.get("JOB_NAME")
146
+ request_body["build_job_url"] = env.get("BUILD_URL")
147
+ request_body["region"] = env.get("SIRENADA_REGION")
148
+ request_body["results"] = results
149
+
150
+ response = self.submit_run(run_type=self.test_type, run_body=request_body)
151
+ self.check_response(response)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: argus-alm
3
- Version: 0.10.2
3
+ Version: 0.11.0
4
4
  Summary: Argus
5
5
  Home-page: https://github.com/scylladb/argus
6
6
  License: Apache-2.0
@@ -10,9 +10,8 @@ Requires-Python: >=3.10,<4.0
10
10
  Classifier: License :: OSI Approved :: Apache Software License
11
11
  Classifier: Programming Language :: Python :: 3
12
12
  Classifier: Programming Language :: Python :: 3.10
13
- Requires-Dist: PyYAML (>=5.4.1,<6.0.0)
14
- Requires-Dist: pydantic (>=1.8.2,<2.0.0)
15
- Requires-Dist: scylla-driver (>=3.24.8,<4.0.0)
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Requires-Dist: requests (>=2.26.0,<3.0.0)
16
15
  Project-URL: Repository, https://github.com/scylladb/argus
17
16
  Description-Content-Type: text/markdown
18
17
 
@@ -20,7 +20,7 @@ argus/backend/events/event_processors.py,sha256=-GKSE4xNFXtjwR9QuRpWbfA_ixarMrGa
20
20
  argus/backend/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
21
  argus/backend/models/web.py,sha256=imXIbp9VSEywzB4hh5uQXf_PlL4wN11XLyalnISbHwU,12069
22
22
  argus/backend/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
- argus/backend/plugins/core.py,sha256=dPSls0ghXbUz2iTSQhTWJHnYKEp8HBCuFUrz0H6vWDI,5604
23
+ argus/backend/plugins/core.py,sha256=VnlCFdWDBYMWi7R-e5Cb-cG3JWFNOlA94Zq98VDsaQQ,6562
24
24
  argus/backend/plugins/driver_matrix_tests/controller.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
25
  argus/backend/plugins/driver_matrix_tests/model.py,sha256=DObVIfN8NXLrqdhmx-kPkS0rLvlL_B0eEwlUPXqN8Cs,4748
26
26
  argus/backend/plugins/driver_matrix_tests/plugin.py,sha256=NZN6lpHFpNuBkv2D_gGHh03402z0qlOeCWjgZXRs2c4,637
@@ -31,17 +31,20 @@ argus/backend/plugins/sct/controller.py,sha256=psm08pLQQCTTKP8xGdCe6YQS_AQoOBbR1
31
31
  argus/backend/plugins/sct/plugin.py,sha256=-ezQ7brAdgQ_YJpZiCaVBNuzP91FtBiKWf_IXy70xgg,902
32
32
  argus/backend/plugins/sct/resource_setup.py,sha256=hwfAOu-oKOH42tjtzJhiqwq_MtUE9_HevoFyql8JKqY,10120
33
33
  argus/backend/plugins/sct/service.py,sha256=YIyPtiHY0VMW9n6icVWeM7z9OF3WcLNQ7LJZCpF8akE,8723
34
- argus/backend/plugins/sct/testrun.py,sha256=5MCNT-ZKmYf9ATObV0YBxLVb5L3NaLbRp3R95mCaum0,6556
34
+ argus/backend/plugins/sct/testrun.py,sha256=Amj2-Wg2go2hd8EJc1upuGnff_RhpD4c3KXIoORJQGg,6556
35
35
  argus/backend/plugins/sct/udt.py,sha256=j1Q7sidzYXxP8ELkkaT-YeJqhe7qixNU9tbNuzLQ5_8,2420
36
+ argus/backend/plugins/sirenada/model.py,sha256=hZZvpUBp8Ch-hWVGjT_ua3xxhQicEIUK6NLGQGhAkts,4639
37
+ argus/backend/plugins/sirenada/plugin.py,sha256=AlQAakwy3u-OqAqqK3RonUR5oDm-JoiwBUDUF3YEVP4,447
38
+ argus/backend/plugins/sirenada/types.py,sha256=Gm3XMK9YJoozVaeM9XE7n8iRxA6PKBrS23Mo2vJfdLs,697
36
39
  argus/backend/service/admin.py,sha256=_VnWl3CkZBOAie_pPbd9sbXZUpBf2SApyNoFZLfB_QI,637
37
40
  argus/backend/service/argus_service.py,sha256=hF_-d6dNyHBx_KO-RjH-a7MK8T3cjLI2cR5XoHBObKc,24865
38
41
  argus/backend/service/build_system_monitor.py,sha256=ODxU2LxqJPOqU0r0sDSkxk73ZXjlaYngsJeXg4m-O5c,6586
39
42
  argus/backend/service/client_service.py,sha256=wvR0PY5nCwKmIXuxrR_kNtY4WR8SLvRk6SOnxVU1myI,2109
40
43
  argus/backend/service/notification_manager.py,sha256=h00Ej_-hH9H7pq0wah_1TH8dnpPyPNsgVJNO1rwJi7o,7011
41
44
  argus/backend/service/release_manager.py,sha256=v2yg45oWBpK_uwqkHtJHPTPbe21_cJu3skmzeaChVhw,6259
42
- argus/backend/service/stats.py,sha256=hL4ca5ETZI0PKsfMeQuB0ZQD-usQL4SExBXA5N7b5ZI,11110
45
+ argus/backend/service/stats.py,sha256=R8krmGi2RsOBSV3ZHDS9crkXSogiPqSnDE2LRYy3APs,12274
43
46
  argus/backend/service/team_manager_service.py,sha256=zY5dvy3ffvQbJuXBvlWKE5dS5LQ3ss6tkFE-cwFZsdw,3010
44
- argus/backend/service/testrun.py,sha256=tBpmyjochlqvJsAk_StlvmSHTyBqidZ21RPAzJ7QqlI,17829
47
+ argus/backend/service/testrun.py,sha256=wCHowQoD_PkTdpyXLQ1EXxkU_pfvgpaDde5xOUD5Fn8,17883
45
48
  argus/backend/service/user.py,sha256=uvhOOvMgrYJHV1I6RH3P-h1d--TlO55uvum8eOpHyxQ,8858
46
49
  argus/backend/template_filters.py,sha256=hD8eDyBYp-X6JVoyQhM-TWYv3MuyorAv0Emz728iGcU,523
47
50
  argus/backend/util/common.py,sha256=fmE9cKnJ1CX_Cz4Mw1d_M-T-jwPh8DkKr_fLAx8LY9M,1458
@@ -56,6 +59,7 @@ argus/client/base.py,sha256=q0awF6GX4Ufi-3IjfBTYvh4dZAfBQCqimEKcSxlvMmg,5972
56
59
  argus/client/driver_matrix_tests/client.py,sha256=pnyE2YSSyBJ9XZjG-z_hEaKQJV7oP6hFaxDqUjxVY5o,7585
57
60
  argus/client/sct/client.py,sha256=mc44QXDwxgXAY51yO0ui9w9V_tNgt4-M_yq__8fvnXQ,8217
58
61
  argus/client/sct/types.py,sha256=VLgVe7qPmJtCLqtPnuX8N8kMKZq-iY3SKz68nvU6nJ4,371
62
+ argus/client/sirenada/client.py,sha256=jpvvHsRf5VSQKSmnamvK054ZlVXHM6w8UXDiUhFEF0A,6222
59
63
  argus/db/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
64
  argus/db/argus_json.py,sha256=zwu7yug0_oUmt5TbcvIQ58uC1PxloEOj5udqoPJn6jQ,391
61
65
  argus/db/cloud_types.py,sha256=KXk6bzFrcIH_0b9L7m9CYiU1YkEeL7ZDpHqH-XKONsY,3702
@@ -64,7 +68,7 @@ argus/db/db_types.py,sha256=iLbmrUaDzrBw0kDCnvW0FSZ9-kNc3uQY-fsbIPymV4E,3612
64
68
  argus/db/interface.py,sha256=HroyA1Yijz5cXLdYbxorHCEu0GH9VeMMqB36IHTlcew,17146
65
69
  argus/db/testrun.py,sha256=0YG7FIH5FLQeNlYULxC6rhhyru2rziSMe3qKtYzTBnc,26014
66
70
  argus/db/utils.py,sha256=YAWsuLjUScSgKgdaL5aF4Sgr13gqH29Mb5cLctX4V_w,337
67
- argus_alm-0.10.2.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
68
- argus_alm-0.10.2.dist-info/WHEEL,sha256=FWzWAvOOsDP6aqtZj_z3pIhVEk8S9F03Xwafa0tLqIY,90
69
- argus_alm-0.10.2.dist-info/METADATA,sha256=pJE21_j1amyGihPVJEI227h9sex5iY9pM9_MxP7xGm8,6858
70
- argus_alm-0.10.2.dist-info/RECORD,,
71
+ argus_alm-0.11.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
72
+ argus_alm-0.11.0.dist-info/METADATA,sha256=Hima5dK6luGSWBfNFa4S2PTLPhsMspRh_w24VlHR1L4,6824
73
+ argus_alm-0.11.0.dist-info/WHEEL,sha256=vVCvjcmxuUltf8cYhJ0sJMRDLr1XsPuxEId8YDzbyCY,88
74
+ argus_alm-0.11.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.1.0b2
2
+ Generator: poetry-core 1.4.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any