argus-alm 0.12.0b1__tar.gz → 0.12.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/PKG-INFO +1 -1
  2. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/controller/testrun_api.py +52 -0
  3. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/plugins/core.py +4 -0
  4. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/plugins/generic/model.py +1 -0
  5. argus_alm-0.12.2/argus/backend/service/jenkins_service.py +63 -0
  6. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/service/stats.py +1 -0
  7. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/client/driver_matrix_tests/client.py +2 -2
  8. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/pyproject.toml +1 -1
  9. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/LICENSE +0 -0
  10. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/README.md +0 -0
  11. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/__init__.py +0 -0
  12. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/.gitkeep +0 -0
  13. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/__init__.py +0 -0
  14. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/cli.py +0 -0
  15. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/controller/__init__.py +0 -0
  16. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/controller/admin.py +0 -0
  17. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/controller/admin_api.py +0 -0
  18. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/controller/api.py +0 -0
  19. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/controller/auth.py +0 -0
  20. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/controller/client_api.py +0 -0
  21. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/controller/main.py +0 -0
  22. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/controller/notification_api.py +0 -0
  23. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/controller/notifications.py +0 -0
  24. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/controller/team.py +0 -0
  25. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/controller/team_ui.py +0 -0
  26. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/db.py +0 -0
  27. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/error_handlers.py +0 -0
  28. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/events/event_processors.py +0 -0
  29. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/models/__init__.py +0 -0
  30. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/models/web.py +0 -0
  31. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/plugins/__init__.py +0 -0
  32. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/plugins/driver_matrix_tests/controller.py +0 -0
  33. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/plugins/driver_matrix_tests/model.py +0 -0
  34. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/plugins/driver_matrix_tests/plugin.py +0 -0
  35. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/plugins/driver_matrix_tests/raw_types.py +0 -0
  36. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/plugins/driver_matrix_tests/service.py +0 -0
  37. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/plugins/driver_matrix_tests/udt.py +0 -0
  38. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/plugins/generic/plugin.py +0 -0
  39. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/plugins/generic/types.py +0 -0
  40. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/plugins/loader.py +0 -0
  41. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/plugins/sct/controller.py +0 -0
  42. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/plugins/sct/plugin.py +0 -0
  43. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/plugins/sct/resource_setup.py +0 -0
  44. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/plugins/sct/service.py +0 -0
  45. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/plugins/sct/testrun.py +0 -0
  46. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/plugins/sct/types.py +0 -0
  47. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/plugins/sct/udt.py +0 -0
  48. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/plugins/sirenada/model.py +0 -0
  49. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/plugins/sirenada/plugin.py +0 -0
  50. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/plugins/sirenada/types.py +0 -0
  51. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/service/admin.py +0 -0
  52. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/service/argus_service.py +0 -0
  53. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/service/build_system_monitor.py +0 -0
  54. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/service/client_service.py +0 -0
  55. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/service/event_service.py +0 -0
  56. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/service/notification_manager.py +0 -0
  57. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/service/release_manager.py +0 -0
  58. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/service/team_manager_service.py +0 -0
  59. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/service/testrun.py +0 -0
  60. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/service/user.py +0 -0
  61. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/template_filters.py +0 -0
  62. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/util/common.py +0 -0
  63. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/util/config.py +0 -0
  64. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/util/encoders.py +0 -0
  65. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/util/enums.py +0 -0
  66. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/util/logsetup.py +0 -0
  67. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/util/module_loaders.py +0 -0
  68. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/backend/util/send_email.py +0 -0
  69. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/client/__init__.py +0 -0
  70. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/client/base.py +0 -0
  71. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/client/generic/cli.py +0 -0
  72. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/client/generic/client.py +0 -0
  73. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/client/sct/client.py +0 -0
  74. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/client/sct/types.py +0 -0
  75. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/client/sirenada/client.py +0 -0
  76. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/db/.gitkeep +0 -0
  77. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/db/argus_json.py +0 -0
  78. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/db/cloud_types.py +0 -0
  79. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/db/config.py +0 -0
  80. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/db/db_types.py +0 -0
  81. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/db/interface.py +0 -0
  82. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/db/testrun.py +0 -0
  83. {argus_alm-0.12.0b1 → argus_alm-0.12.2}/argus/db/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: argus-alm
3
- Version: 0.12.0b1
3
+ Version: 0.12.2
4
4
  Summary: Argus
5
5
  Home-page: https://github.com/scylladb/argus
6
6
  License: Apache-2.0
@@ -6,6 +6,7 @@ from flask import (
6
6
  )
7
7
 
8
8
  from argus.backend.error_handlers import handle_api_exception
9
+ from argus.backend.service.jenkins_service import JenkinsService
9
10
  from argus.backend.service.testrun import TestRunService
10
11
  from argus.backend.service.user import api_login_required
11
12
  from argus.backend.util.common import get_payload
@@ -285,3 +286,54 @@ def ignore_jobs():
285
286
  "affectedJobs": result
286
287
  }
287
288
  }
289
+
290
+
291
+ @bp.route("/jenkins/params", methods=["POST"])
292
+ @api_login_required
293
+ def get_jenkins_job_params():
294
+
295
+ payload = get_payload(request)
296
+ service = JenkinsService()
297
+
298
+ result = service.retrieve_job_parameters(build_id=payload["buildId"], build_number=payload["buildNumber"])
299
+
300
+ return {
301
+ "status": "ok",
302
+ "response": {
303
+ "parameters": result
304
+ }
305
+ }
306
+
307
+
308
+ @bp.route("/jenkins/build", methods=["POST"])
309
+ @api_login_required
310
+ def build_jenkins_job():
311
+
312
+ payload = get_payload(request)
313
+ service = JenkinsService()
314
+
315
+ result = service.build_job(build_id=payload["buildId"], params=payload["parameters"])
316
+
317
+ return {
318
+ "status": "ok",
319
+ "response": {
320
+ "queueItem": result
321
+ }
322
+ }
323
+
324
+
325
+ @bp.route("/jenkins/queue_info")
326
+ @api_login_required
327
+ def get_queue_info():
328
+ queue_item = request.args.get("queueItem")
329
+ if not queue_item:
330
+ raise Exception("No queueItem provided")
331
+ service = JenkinsService()
332
+ result = service.get_queue_info(int(queue_item))
333
+
334
+ return {
335
+ "status": "ok",
336
+ "response": {
337
+ "queueItem": result
338
+ }
339
+ }
@@ -38,6 +38,7 @@ class PluginModelBase(Model):
38
38
  heartbeat = columns.Integer(default=lambda: int(time()))
39
39
  end_time = columns.DateTime(default=lambda: datetime.utcfromtimestamp(0))
40
40
  build_job_url = columns.Text()
41
+ product_version = columns.Text(index=True)
41
42
 
42
43
  # Test Logs Collection
43
44
  logs = columns.List(value_type=columns.Tuple(columns.Text(), columns.Text()))
@@ -180,6 +181,9 @@ class PluginModelBase(Model):
180
181
  def submit_product_version(self, version: str):
181
182
  raise NotImplementedError()
182
183
 
184
+ def set_product_version(self, version: str):
185
+ self.product_version = version
186
+
183
187
  def submit_logs(self, logs: list[dict]):
184
188
  raise NotImplementedError()
185
189
 
@@ -38,6 +38,7 @@ class GenericRun(PluginModelBase):
38
38
 
39
39
  def submit_product_version(self, version: str):
40
40
  self.scylla_version = version
41
+ self.set_product_version(version)
41
42
 
42
43
  @classmethod
43
44
  def load_test_run(cls, run_id: UUID) -> 'GenericRun':
@@ -0,0 +1,63 @@
1
+ from typing import Any, TypedDict
2
+ import xml.etree.ElementTree as ET
3
+ import jenkins
4
+ import logging
5
+
6
+ from flask import current_app, g
7
+
8
+ LOGGER = logging.getLogger(__name__)
9
+
10
+
11
+ class Parameter(TypedDict):
12
+ _class: str
13
+ name: str
14
+ description: str
15
+ value: Any
16
+
17
+
18
+ class JenkinsService:
19
+ RESERVED_PARAMETER_NAME = "requested_by_user"
20
+
21
+ def __init__(self) -> None:
22
+ self._jenkins = jenkins.Jenkins(url=current_app.config["JENKINS_URL"],
23
+ username=current_app.config["JENKINS_USER"],
24
+ password=current_app.config["JENKINS_API_TOKEN"])
25
+
26
+ def retrieve_job_parameters(self, build_id: str, build_number: int) -> list[Parameter]:
27
+ job_info = self._jenkins.get_build_info(name=build_id, number=build_number)
28
+ raw_config = self._jenkins.get_job_config(name=build_id)
29
+ config = ET.fromstring(raw_config)
30
+ parameter_defs = config.find("*//parameterDefinitions")
31
+ if parameter_defs:
32
+ descriptions = {
33
+ define.findtext("name"): f"{define.findtext('description', '')}" + f" (default: <span class=\"fw-bold\">{define.findtext('defaultValue')}</span>)" if define.findtext('defaultValue') else ""
34
+ for define in parameter_defs.iterfind("hudson.model.StringParameterDefinition")
35
+ }
36
+ else:
37
+ descriptions = {}
38
+ params = next(a for a in job_info["actions"] if a.get("_class", "#NONE") == "hudson.model.ParametersAction")["parameters"]
39
+ params = [param for param in params if param["name"] != self.RESERVED_PARAMETER_NAME]
40
+ for idx, param in enumerate(params):
41
+ params[idx]["description"] = descriptions.get(param["name"], "")
42
+
43
+ return params
44
+
45
+ def build_job(self, build_id: str, params: dict, user_override: str = None):
46
+ queue_number = self._jenkins.build_job(build_id, {
47
+ **params,
48
+ self.RESERVED_PARAMETER_NAME: g.user.username if not user_override else user_override
49
+ })
50
+ return queue_number
51
+
52
+ def get_queue_info(self, queue_item: int):
53
+ build_info = self._jenkins.get_queue_item(queue_item)
54
+ LOGGER.info("%s", build_info)
55
+ executable = build_info.get("executable")
56
+ if executable:
57
+ return executable
58
+ else:
59
+ return {
60
+ "why": build_info["why"],
61
+ "inQueueSince": build_info["inQueueSince"],
62
+ "taskUrl": build_info["task"]["url"],
63
+ }
@@ -33,6 +33,7 @@ class TestRunStatRow(TypedDict):
33
33
  class ComparableTestStatus:
34
34
  PRIORITY_MAP = {
35
35
  TestStatus.FAILED: 10,
36
+ TestStatus.TEST_ERROR: 10,
36
37
  TestStatus.ABORTED: 9,
37
38
  TestStatus.RUNNING: 8,
38
39
  TestStatus.CREATED: 7,
@@ -110,8 +110,8 @@ class ArgusDriverMatrixClient(ArgusClient):
110
110
  raw_cases.append({
111
111
  "name": case.attrib["name"],
112
112
  "status": status,
113
- "time": float(case.attrib["time"]),
114
- "classname": case.attrib["classname"],
113
+ "time": float(case.attrib.get("time", 0.0)),
114
+ "classname": case.attrib.get("classname", ""),
115
115
  "message": message,
116
116
  })
117
117
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "argus-alm"
3
- version = "0.12.0b1"
3
+ version = "0.12.2"
4
4
  description = "Argus"
5
5
  authors = ["Alexey Kartashov <alexey.kartashov@scylladb.com>"]
6
6
  license = "Apache-2.0"
File without changes
File without changes