argus-alm 0.12.10__py3-none-any.whl → 0.13.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.
Files changed (92) hide show
  1. argus/client/base.py +1 -1
  2. argus/client/driver_matrix_tests/cli.py +2 -2
  3. argus/client/driver_matrix_tests/client.py +1 -1
  4. argus/client/generic/cli.py +2 -2
  5. argus/client/sct/client.py +3 -3
  6. argus/client/sirenada/client.py +1 -1
  7. {argus_alm-0.12.10.dist-info → argus_alm-0.13.0.dist-info}/METADATA +2 -4
  8. argus_alm-0.13.0.dist-info/RECORD +20 -0
  9. argus/backend/.gitkeep +0 -0
  10. argus/backend/cli.py +0 -41
  11. argus/backend/controller/__init__.py +0 -0
  12. argus/backend/controller/admin.py +0 -20
  13. argus/backend/controller/admin_api.py +0 -354
  14. argus/backend/controller/api.py +0 -529
  15. argus/backend/controller/auth.py +0 -67
  16. argus/backend/controller/client_api.py +0 -108
  17. argus/backend/controller/main.py +0 -274
  18. argus/backend/controller/notification_api.py +0 -72
  19. argus/backend/controller/notifications.py +0 -13
  20. argus/backend/controller/team.py +0 -126
  21. argus/backend/controller/team_ui.py +0 -18
  22. argus/backend/controller/testrun_api.py +0 -482
  23. argus/backend/controller/view_api.py +0 -162
  24. argus/backend/db.py +0 -100
  25. argus/backend/error_handlers.py +0 -21
  26. argus/backend/events/event_processors.py +0 -34
  27. argus/backend/models/__init__.py +0 -0
  28. argus/backend/models/result.py +0 -138
  29. argus/backend/models/web.py +0 -389
  30. argus/backend/plugins/__init__.py +0 -0
  31. argus/backend/plugins/core.py +0 -225
  32. argus/backend/plugins/driver_matrix_tests/controller.py +0 -63
  33. argus/backend/plugins/driver_matrix_tests/model.py +0 -421
  34. argus/backend/plugins/driver_matrix_tests/plugin.py +0 -22
  35. argus/backend/plugins/driver_matrix_tests/raw_types.py +0 -62
  36. argus/backend/plugins/driver_matrix_tests/service.py +0 -60
  37. argus/backend/plugins/driver_matrix_tests/udt.py +0 -42
  38. argus/backend/plugins/generic/model.py +0 -79
  39. argus/backend/plugins/generic/plugin.py +0 -16
  40. argus/backend/plugins/generic/types.py +0 -13
  41. argus/backend/plugins/loader.py +0 -40
  42. argus/backend/plugins/sct/controller.py +0 -185
  43. argus/backend/plugins/sct/plugin.py +0 -38
  44. argus/backend/plugins/sct/resource_setup.py +0 -178
  45. argus/backend/plugins/sct/service.py +0 -491
  46. argus/backend/plugins/sct/testrun.py +0 -272
  47. argus/backend/plugins/sct/udt.py +0 -101
  48. argus/backend/plugins/sirenada/model.py +0 -113
  49. argus/backend/plugins/sirenada/plugin.py +0 -17
  50. argus/backend/service/admin.py +0 -27
  51. argus/backend/service/argus_service.py +0 -688
  52. argus/backend/service/build_system_monitor.py +0 -188
  53. argus/backend/service/client_service.py +0 -122
  54. argus/backend/service/event_service.py +0 -18
  55. argus/backend/service/jenkins_service.py +0 -240
  56. argus/backend/service/notification_manager.py +0 -150
  57. argus/backend/service/release_manager.py +0 -230
  58. argus/backend/service/results_service.py +0 -317
  59. argus/backend/service/stats.py +0 -540
  60. argus/backend/service/team_manager_service.py +0 -83
  61. argus/backend/service/testrun.py +0 -559
  62. argus/backend/service/user.py +0 -307
  63. argus/backend/service/views.py +0 -258
  64. argus/backend/template_filters.py +0 -27
  65. argus/backend/tests/__init__.py +0 -0
  66. argus/backend/tests/argus_web.test.yaml +0 -39
  67. argus/backend/tests/conftest.py +0 -44
  68. argus/backend/tests/results_service/__init__.py +0 -0
  69. argus/backend/tests/results_service/test_best_results.py +0 -70
  70. argus/backend/util/common.py +0 -65
  71. argus/backend/util/config.py +0 -38
  72. argus/backend/util/encoders.py +0 -41
  73. argus/backend/util/logsetup.py +0 -81
  74. argus/backend/util/module_loaders.py +0 -30
  75. argus/backend/util/send_email.py +0 -91
  76. argus/client/generic_result_old.py +0 -143
  77. argus/db/.gitkeep +0 -0
  78. argus/db/argus_json.py +0 -14
  79. argus/db/cloud_types.py +0 -125
  80. argus/db/config.py +0 -135
  81. argus/db/db_types.py +0 -139
  82. argus/db/interface.py +0 -370
  83. argus/db/testrun.py +0 -740
  84. argus/db/utils.py +0 -15
  85. argus_alm-0.12.10.dist-info/RECORD +0 -96
  86. /argus/{backend → common}/__init__.py +0 -0
  87. /argus/{backend/util → common}/enums.py +0 -0
  88. /argus/{backend/plugins/sct/types.py → common/sct_types.py} +0 -0
  89. /argus/{backend/plugins/sirenada/types.py → common/sirenada_types.py} +0 -0
  90. {argus_alm-0.12.10.dist-info → argus_alm-0.13.0.dist-info}/LICENSE +0 -0
  91. {argus_alm-0.12.10.dist-info → argus_alm-0.13.0.dist-info}/WHEEL +0 -0
  92. {argus_alm-0.12.10.dist-info → argus_alm-0.13.0.dist-info}/entry_points.txt +0 -0
@@ -1,70 +0,0 @@
1
- import logging
2
- import uuid
3
- from dataclasses import asdict
4
- from typing import Optional, Dict
5
-
6
- from _pytest.fixtures import fixture
7
-
8
- from argus.backend.plugins.sct.testrun import SCTTestRunSubmissionRequest
9
- from argus.client.generic_result import GenericResultTable, ColumnMetadata, ResultType, ValidationRule
10
-
11
- LOGGER = logging.getLogger(__name__)
12
-
13
- @fixture(autouse=True, scope='session')
14
- def release(release_manager_service):
15
- return release_manager_service.create_release("best_results", "best_results", False)
16
-
17
-
18
- @fixture(autouse=True, scope='session')
19
- def group(release_manager_service, release):
20
- return release_manager_service.create_group("br_group", "best_results", build_system_id="best_results", release_id=str(release.id))
21
-
22
- def get_fake_test_run(
23
- schema_version: str = "1.0.0",
24
- run_id: str = str(uuid.uuid4()),
25
- job_name: str = "default_job_name",
26
- job_url: str = "http://example.com",
27
- started_by: str = "default_user",
28
- commit_id: str = "default_commit_id",
29
- sct_config: dict | None = None,
30
- origin_url: str | None = None,
31
- branch_name: str | None = "main",
32
- runner_public_ip: str | None = None,
33
- runner_private_ip: str | None = None
34
- ) -> tuple[str, dict]:
35
- return "scylla-cluster-tests", asdict(SCTTestRunSubmissionRequest(
36
- schema_version=schema_version,
37
- run_id=run_id,
38
- job_name=job_name,
39
- job_url=job_url,
40
- started_by=started_by,
41
- commit_id=commit_id,
42
- sct_config=sct_config,
43
- origin_url=origin_url,
44
- branch_name=branch_name,
45
- runner_public_ip=runner_public_ip,
46
- runner_private_ip=runner_private_ip
47
- ))
48
-
49
- class SampleTable(GenericResultTable):
50
- class Meta:
51
- name = "Test Table Name"
52
- description = "Test Table Description"
53
- Columns = [ColumnMetadata(name="float col name", unit="ms", type=ResultType.FLOAT, higher_is_better=False),
54
- ColumnMetadata(name="int col name", unit="ms", type=ResultType.INTEGER, higher_is_better=False),
55
- ColumnMetadata(name="duration col name", unit="s", type=ResultType.DURATION, higher_is_better=False),
56
- ColumnMetadata(name="non tracked col name", unit="", type=ResultType.FLOAT),
57
- ColumnMetadata(name="text col name", unit="", type=ResultType.TEXT),
58
- ]
59
- ValidationRules = {"float col name": ValidationRule(best_abs=4),
60
- "int col name": ValidationRule(best_pct=50, best_abs=5),
61
- "duration col name": ValidationRule(fixed_limit=590)
62
- }
63
-
64
- def test_argus_tracks_best_result(release_manager_service, client_service, release, group):
65
- test = release_manager_service.create_test('track_best_result', 'track_best_result', 'track_best_result', 'track_best_result',
66
- group_id=str(group.id), release_id=str(release.id), plugin_name='sct')
67
- print(test)
68
- LOGGER.warning(f"available plugins: {client_service.PLUGINS}")
69
- client_service.submit_run(*get_fake_test_run())
70
- assert test
@@ -1,65 +0,0 @@
1
- from itertools import islice
2
- import logging
3
- from typing import Callable, Iterable
4
- from uuid import UUID
5
-
6
- from flask import Request, Response, g
7
-
8
- from argus.backend.models.web import User
9
-
10
-
11
- LOGGER = logging.getLogger(__name__)
12
- FlaskView = Callable[..., Response]
13
-
14
-
15
- def first(iterable, value, key: Callable = None, predicate: Callable = None):
16
- for elem in iterable:
17
- if predicate and predicate(elem, value):
18
- return elem
19
- elif key and key(elem) == value:
20
- return elem
21
- elif elem == value:
22
- return elem
23
- return None
24
-
25
-
26
- def chunk(iterable: Iterable, slice_size = 90):
27
- it = iter(iterable)
28
- return iter(lambda: list(islice(it, slice_size)), [])
29
-
30
-
31
- def check_scheduled_test(test, group, testname):
32
- return testname in (f"{group}/{test}", test)
33
-
34
-
35
- def strip_html_tags(text: str):
36
- return text.replace("<", "&lt;").replace(">", "&gt;")
37
-
38
-
39
- def convert_str_list_to_uuid(lst: list[str]) -> list[UUID]:
40
- return [UUID(s) for s in lst]
41
-
42
-
43
- def get_payload(client_request: Request) -> dict:
44
- if not client_request.is_json:
45
- raise Exception(
46
- "Content-Type mismatch, expected application/json, got:",
47
- client_request.content_type
48
- )
49
- request_payload = client_request.get_json()
50
-
51
- return request_payload
52
-
53
-
54
- def current_user() -> User:
55
- return g.user
56
-
57
-
58
- def get_build_number(build_job_url: str) -> int | None:
59
- build_number = build_job_url.rstrip("/").split("/")[-1] if build_job_url else -1
60
- if build_number:
61
- try:
62
- return int(build_number)
63
- except ValueError:
64
- LOGGER.error("Error parsing build number from %s: got %s as build_number", build_job_url, build_number)
65
- return None
@@ -1,38 +0,0 @@
1
- import logging
2
- from pathlib import Path
3
-
4
- import yaml
5
-
6
-
7
- LOGGER = logging.getLogger(__name__)
8
-
9
-
10
- class Config:
11
- CONFIG = None
12
- CONFIG_PATHS = [
13
- Path(__file__).parents[3] / "config" / "argus_web.yaml",
14
- Path("argus_web.yaml"),
15
- Path("../config/argus_web.yaml"),
16
-
17
- ]
18
-
19
- @classmethod
20
- def locate_argus_web_config(cls) -> Path:
21
- for config in cls.CONFIG_PATHS:
22
- if config.exists():
23
- return config
24
- else:
25
- LOGGER.debug("Tried %s as config, not found.", config)
26
-
27
- raise Exception("Failed to locate web application config file!")
28
-
29
- @classmethod
30
- def load_yaml_config(cls) -> dict:
31
- if cls.CONFIG:
32
- return cls.CONFIG
33
- path = cls.locate_argus_web_config()
34
- with open(path, "rt", encoding="utf-8") as file:
35
- config = yaml.safe_load(file)
36
-
37
- cls.CONFIG = config
38
- return config
@@ -1,41 +0,0 @@
1
- from datetime import datetime
2
- import logging
3
- from json.encoder import JSONEncoder
4
- from uuid import UUID
5
-
6
- from flask.json.provider import DefaultJSONProvider
7
- import cassandra.cqlengine.usertype as ut
8
- import cassandra.cqlengine.models as m
9
-
10
-
11
- LOGGER = logging.getLogger(__name__)
12
-
13
- class ArgusJSONEncoder(JSONEncoder):
14
- def default(self, o):
15
- match o:
16
- case UUID():
17
- return str(o)
18
- case ut.UserType():
19
- return dict(o.items())
20
- case m.Model():
21
- return dict(o.items())
22
- case datetime():
23
- return o.strftime("%Y-%m-%dT%H:%M:%SZ")
24
- case _:
25
- return super().default(o)
26
-
27
-
28
- class ArgusJSONProvider(DefaultJSONProvider):
29
-
30
- def default(self, o):
31
- match o:
32
- case UUID():
33
- return str(o)
34
- case ut.UserType():
35
- return dict(o.items())
36
- case m.Model():
37
- return dict(o.items())
38
- case datetime():
39
- return o.strftime("%Y-%m-%dT%H:%M:%SZ")
40
- case _:
41
- return super().default(o)
@@ -1,81 +0,0 @@
1
- import logging
2
- from logging.config import dictConfig
3
- from flask import has_request_context, request
4
-
5
- # pylint: disable=line-too-long
6
- LOG_FORMAT_REQUEST = "[%(levelcolor)s%(levelname)s%(colorreset)s] %(grey)s<%(remote_addr)s - %(url)s - %(endpoint)s>%(colorreset)s - %(module)s::%(funcName)s - %(message)s"
7
-
8
-
9
- class ArgusRequestLogFormatter(logging.Formatter):
10
- yellow = "\x1b[33;20m"
11
- red = "\x1b[31;20m"
12
- blue = "\x1b[34;20m"
13
- bold_red = "\x1b[31;1m"
14
- reset = "\x1b[0m"
15
- grey = "\x1b[38;2;200;200;200m"
16
- color_map = {
17
- logging.DEBUG: grey,
18
- logging.INFO: blue,
19
- logging.WARNING: yellow,
20
- logging.ERROR: red,
21
- logging.CRITICAL: bold_red
22
- }
23
-
24
- def format(self, record: logging.LogRecord) -> str:
25
- record.grey = self.grey
26
- record.colorreset = self.reset
27
- record.levelcolor = self.color_map.get(record.levelno, self.grey)
28
- if has_request_context():
29
- record.url = request.url
30
- record.remote_addr = request.remote_addr
31
- record.endpoint = request.endpoint
32
- else:
33
- record.url = ''
34
- record.remote_addr = ''
35
- record.endpoint = ''
36
- return super().format(record)
37
-
38
-
39
- def setup_application_logging(log_level=logging.INFO):
40
- dictConfig({
41
- 'version': 1,
42
- 'formatters': {
43
- 'request': {
44
- 'class': f"{__name__}.{ArgusRequestLogFormatter.__name__}",
45
- 'format': LOG_FORMAT_REQUEST,
46
- }
47
- },
48
- 'handlers': {
49
- 'main': {
50
- 'class': 'logging.StreamHandler',
51
- 'stream': 'ext://sys.stderr',
52
- 'formatter': 'request'
53
- }
54
- },
55
- 'loggers': {
56
- 'cassandra': {
57
- 'level': log_level,
58
- 'handlers': ['main']
59
- },
60
- 'argus': {
61
- 'level': log_level,
62
- 'handlers': ['main']
63
- },
64
- 'argus_backend': {
65
- 'level': log_level,
66
- 'handlers': ['main']
67
- },
68
- 'werkzeug': {
69
- 'level': log_level,
70
- 'handlers': ['main']
71
- },
72
- 'uwsgi': {
73
- 'level': log_level,
74
- 'handlers': ['main']
75
- },
76
- '__main__': {
77
- 'level': log_level,
78
- 'handlers': ['main']
79
- },
80
- }
81
- })
@@ -1,30 +0,0 @@
1
- import sys
2
- from functools import wraps
3
- from typing import Callable
4
-
5
-
6
- def is_filter(filter_name: str) -> Callable:
7
- def outer_wrapper(func):
8
- func.is_filter = True
9
- func.filter_name = filter_name
10
-
11
- @wraps(func)
12
- def wrapper(*args, **kwargs):
13
- return func(*args, **kwargs)
14
-
15
- return wrapper
16
-
17
- return outer_wrapper
18
-
19
-
20
- def export_functions(module_name: str, attr: str) -> list[Callable]:
21
- module = sys.modules[module_name]
22
- funcs = []
23
-
24
- for member in dir(module):
25
- export = getattr(module, member)
26
- applicable_export = getattr(export, attr, False)
27
- if applicable_export:
28
- funcs.append(export)
29
-
30
- return funcs
@@ -1,91 +0,0 @@
1
- import smtplib
2
- from typing import List, Set
3
- from smtplib import SMTPException
4
-
5
- from email.mime.multipart import MIMEMultipart
6
- from email.mime.text import MIMEText
7
- from flask import current_app
8
- from flask import render_template
9
-
10
- class Email:
11
- # pylint: disable=too-many-instance-attributes
12
- """
13
- Responsible for sending emails
14
- """
15
- _attachments_size_limit = 10485760 # 10Mb = 20 * 1024 * 1024
16
- _body_size_limit = 26214400 # 25Mb = 20 * 1024 * 1024
17
-
18
- def __init__(self, init_connection=True):
19
- self.sender: str = ""
20
- self._password: str = ""
21
- self._user: str = ""
22
- self._server_host: str = ""
23
- self._server_port: int = 0
24
- self._connection: smtplib.SMTP | None = None
25
- self._retrieve_credentials()
26
- if init_connection:
27
- self._connect()
28
-
29
- def _retrieve_credentials(self):
30
- self.sender = current_app.config["EMAIL_SENDER"]
31
- self._password = current_app.config["EMAIL_SENDER_PASS"]
32
- self._user = current_app.config["EMAIL_SENDER_USER"]
33
- self._server_host = current_app.config["EMAIL_SERVER"]
34
- self._server_port = int(current_app.config["EMAIL_SERVER_PORT"])
35
-
36
- def _connect(self):
37
- try:
38
- self._connection = smtplib.SMTP(host=self._server_host, port=self._server_port)
39
- self._connection.ehlo()
40
- self._connection.starttls()
41
- self._connection.login(user=self._user, password=self._password)
42
- except SMTPException as details:
43
- current_app.logger.error("Failed to initialize smtp session %s", details)
44
-
45
- def _is_connection_open(self):
46
- if not self._connection:
47
- return False
48
- try:
49
- status, _ = self._connection.noop()
50
- except SMTPException:
51
- status = -1
52
-
53
- return True if status == 250 else False
54
-
55
- def _prepare_email(self, subject:str,
56
- content: str,
57
- recipients: List[str],
58
- html: bool = True): # pylint: disable=too-many-arguments
59
- msg = MIMEMultipart()
60
- msg['subject'] = subject
61
- msg['from'] = self.sender
62
- assert recipients, "No recipients provided"
63
- msg['to'] = ','.join(recipients)
64
- if html:
65
- text_part = MIMEText(content, "html")
66
- else:
67
- text_part = MIMEText(content, "plain")
68
- msg.attach(text_part)
69
- email = msg.as_string()
70
- return email
71
-
72
- def send(self, subject, content, recipients, html=True): # pylint: disable=too-many-arguments
73
- """
74
- :param subject: text
75
- :param content: text/html
76
- :param recipients: iterable, list of recipients
77
- :param html: True/False
78
- :param files: paths of the files that will be attached to the email
79
- :return:
80
- """
81
- email = self._prepare_email(subject, content, recipients, html)
82
- self._send_email(recipients, email)
83
-
84
- def _send_email(self, recipients, email):
85
- if not self._is_connection_open():
86
- self._connect()
87
- self._connection.sendmail(self.sender, recipients, email)
88
-
89
- def __del__(self):
90
- if self._connection:
91
- self._connection.quit()
@@ -1,143 +0,0 @@
1
- from dataclasses import dataclass, field, asdict
2
- from typing import Dict, List, Tuple, Union, Type
3
- from uuid import UUID
4
- from enum import Enum
5
- import json
6
-
7
-
8
-
9
- class Status(Enum):
10
- PASS = 1
11
- WARNING = 2
12
- ERROR = 3
13
-
14
-
15
- class ResultType(Enum):
16
- INTEGER = int
17
- FLOAT = float
18
- TEXT = str
19
-
20
-
21
- @dataclass
22
- class ColumnMetadata:
23
- id: int
24
- unit: str
25
- type: ResultType
26
-
27
-
28
- @dataclass
29
- class Result:
30
- value: Union[int, float, str]
31
- status: Status
32
-
33
-
34
- class ResultTableMeta(type):
35
- def __new__(cls, name, bases, dct):
36
- cls_instance = super().__new__(cls, name, bases, dct)
37
- meta = dct.get('Meta')
38
-
39
- if meta:
40
- cls_instance.table_name = meta.table_name
41
- cls_instance.columns_map = {col_name: ColumnMetadata(id=col_id, unit=unit, type=result_type)
42
- for col_name, (col_id, unit, result_type) in meta.Columns.items()}
43
- cls_instance.rows_map = {row_name: row_id
44
- for row_name, row_id in meta.Rows.items()}
45
- return cls_instance
46
-
47
-
48
- class Row:
49
- def __init__(self, columns_map: Dict[str, ColumnMetadata]):
50
- self.columns_map = columns_map
51
- self.data: Dict[str, Result] = {}
52
-
53
- def __getitem__(self, column_name: str) -> Result:
54
- return self.data[column_name]
55
-
56
- def __setitem__(self, column_name: str, result: Result):
57
- if column_name not in self.columns_map:
58
- raise ValueError(f"Column name '{column_name}' not found in columns_map.")
59
- column_metadata = self.columns_map[column_name]
60
- if not isinstance(result.value, column_metadata.type.value):
61
- raise ValueError(f"Value {result.value} for column '{column_name}' is not of type {column_metadata.type.name}")
62
- self.data[column_name] = result
63
-
64
-
65
- @dataclass
66
- class BaseResultTable(metaclass=ResultTableMeta):
67
- results: Dict[str, Row] = field(default_factory=dict)
68
-
69
- def as_dict(self) -> dict:
70
- results_list = []
71
- for row_name, row in self.results.items():
72
- row_id = self.rows_map.get(row_name)
73
- for column_name, result in row.data.items():
74
- column_metadata = self.columns_map.get(column_name)
75
- results_list.append({
76
- "column_id": column_metadata.id,
77
- "row_id": row_id,
78
- "result": result.value,
79
- "status": result.status.value
80
- })
81
-
82
- meta_info = {
83
- "table_name": self.table_name,
84
- "columns": {name: {"id": meta.id, "unit": meta.unit, "type": meta.type.name} for name, meta in self.columns_map.items()},
85
- "rows": self.rows_map
86
- }
87
- return {
88
- "meta": meta_info,
89
- "results": results_list
90
- }
91
-
92
- def to_json(self) -> str:
93
- dict_result = self.as_dict()
94
- return json.dumps(dict_result, default=str)
95
-
96
- def __getitem__(self, row_name: str) -> Row:
97
- if row_name not in self.rows_map:
98
- raise ValueError(f"Row name '{row_name}' not found in rows_map.")
99
- if row_name not in self.results:
100
- self.results[row_name] = Row(self.columns_map)
101
- return self.results[row_name]
102
-
103
-
104
- # Example of a specific result table with its own metadata
105
- class LatencyResultTable(BaseResultTable):
106
- class Meta:
107
- table_name = "latency_percentile_write"
108
- Columns = {
109
- "latency": (1, "ms", ResultType.FLOAT),
110
- "op_rate": (2, "ops", ResultType.INTEGER)
111
- }
112
- Rows = {
113
- "mean": 1,
114
- "p99": 2
115
- }
116
-
117
-
118
- # Client code example
119
- if __name__ == "__main__":
120
- class LatencyResultTable(BaseResultTable):
121
- class Meta:
122
- table_name = "latency_percentile_write"
123
- Columns = {
124
- "latency": (1, "ms", ResultType.FLOAT),
125
- "op_rate": (2, "ops", ResultType.INTEGER)
126
- }
127
- Rows = {
128
- "mean": 1,
129
- "p99": 2
130
- }
131
-
132
- result_table = LatencyResultTable()
133
-
134
- result_table["mean"]["latency"] = Result(value=1.1, status=Status.WARNING)
135
- result_table["mean"]["op_rate"] = Result(value=59988, status=Status.ERROR)
136
- result_table["p99"]["latency"] = Result(value=2.7, status=Status.PASS)
137
- result_table["p99"]["op_rate"] = Result(value=59988, status=Status.WARNING)
138
-
139
- from argus.client.sct.client import ArgusSCTClient
140
-
141
- run_id = UUID("24e09748-bba4-47fd-a615-bf7ea2c425eb")
142
- client = ArgusSCTClient(run_id, auth_token="UO+2GXL9XqSgcVJijWk5WnbPXPit5ot5nfkLAHAr7SaqROfSCWycabpp/wxyY8+I", base_url="http://localhost:5000")
143
- client.submit_results(result_table)
argus/db/.gitkeep DELETED
File without changes
argus/db/argus_json.py DELETED
@@ -1,14 +0,0 @@
1
- from datetime import datetime
2
- import json
3
- from uuid import UUID
4
-
5
-
6
- class ArgusJSONEncoder(json.JSONEncoder):
7
- def default(self, obj):
8
- match obj:
9
- case UUID():
10
- return str(obj)
11
- case datetime():
12
- return obj.isoformat(sep=' ', timespec='milliseconds')
13
- case _:
14
- return json.JSONEncoder.default(self, obj)