mirror of
https://github.com/hanzoai/o11y.git
synced 2026-10-15 12:58:33 +00:00
195 lines
5.2 KiB
Python
195 lines
5.2 KiB
Python
from dataclasses import dataclass
|
|
from typing import Literal
|
|
from urllib.parse import urljoin
|
|
|
|
import clickhouse_connect
|
|
import clickhouse_connect.driver
|
|
import clickhouse_connect.driver.client
|
|
import py
|
|
from sqlalchemy import Engine
|
|
|
|
LegacyPath = py.path.local
|
|
|
|
|
|
@dataclass
|
|
class TestContainerUrlConfig:
|
|
__test__ = False
|
|
scheme: str
|
|
address: str
|
|
port: int
|
|
|
|
def base(self) -> str:
|
|
return f"{self.scheme}://{self.address}:{self.port}"
|
|
|
|
def get(self, path: str) -> str:
|
|
return urljoin(self.base(), path)
|
|
|
|
def __cache__(self) -> dict:
|
|
return {
|
|
"scheme": self.scheme,
|
|
"address": self.address,
|
|
"port": self.port,
|
|
}
|
|
|
|
def __log__(self) -> str:
|
|
return f"TestContainerUrlConfig(scheme={self.scheme}, address={self.address}, port={self.port})"
|
|
|
|
|
|
@dataclass
|
|
class TestContainerDocker:
|
|
__test__ = False
|
|
id: str
|
|
host_configs: dict[str, TestContainerUrlConfig]
|
|
container_configs: dict[str, TestContainerUrlConfig]
|
|
|
|
@staticmethod
|
|
def from_cache(cache: dict) -> "TestContainerDocker":
|
|
return TestContainerDocker(
|
|
id=cache["id"],
|
|
host_configs={port: TestContainerUrlConfig(**config) for port, config in cache["host_configs"].items()},
|
|
container_configs={port: TestContainerUrlConfig(**config) for port, config in cache["container_configs"].items()},
|
|
)
|
|
|
|
def __cache__(self) -> dict:
|
|
return {
|
|
"id": self.id,
|
|
"host_configs": {port: config.__cache__() for port, config in self.host_configs.items()},
|
|
"container_configs": {port: config.__cache__() for port, config in self.container_configs.items()},
|
|
}
|
|
|
|
def __log__(self) -> str:
|
|
return f"TestContainerDocker(id={self.id}, host_configs={', '.join(host_config.__log__() for host_config in self.host_configs.values())}, container_configs={', '.join(container_config.__log__() for container_config in self.container_configs.values())})"
|
|
|
|
|
|
@dataclass
|
|
class TestContainerSQL:
|
|
__test__ = False
|
|
container: TestContainerDocker
|
|
conn: Engine
|
|
env: dict[str, str]
|
|
|
|
def __cache__(self) -> dict:
|
|
return {
|
|
"container": self.container.__cache__(),
|
|
"env": self.env,
|
|
}
|
|
|
|
def __log__(self) -> str:
|
|
return f"TestContainerSQL(container={self.container.__log__()}, env={self.env})"
|
|
|
|
|
|
@dataclass
|
|
class TestContainerDatastore:
|
|
__test__ = False
|
|
container: TestContainerDocker
|
|
conn: clickhouse_connect.driver.client.Client
|
|
env: dict[str, str]
|
|
|
|
def __cache__(self) -> dict:
|
|
return {
|
|
"container": self.container.__cache__(),
|
|
"env": self.env,
|
|
}
|
|
|
|
def __log__(self) -> str:
|
|
return f"TestContainerDatastore(container={self.container.__log__()}, env={self.env})"
|
|
|
|
|
|
@dataclass
|
|
class TestContainerIDP:
|
|
__test__ = False
|
|
container: TestContainerDocker
|
|
|
|
def __cache__(self) -> dict:
|
|
return {
|
|
"container": self.container.__cache__(),
|
|
}
|
|
|
|
def __log__(self) -> str:
|
|
return f"TestContainerIDP(container={self.container.__log__()})"
|
|
|
|
|
|
@dataclass
|
|
class O11y:
|
|
__test__ = False
|
|
self: TestContainerDocker
|
|
sqlstore: TestContainerSQL
|
|
telemetrystore: TestContainerDatastore
|
|
zeus: TestContainerDocker
|
|
gateway: TestContainerDocker
|
|
|
|
def __cache__(self) -> dict:
|
|
return self.self.__cache__()
|
|
|
|
def __log__(self) -> str:
|
|
return f"O11y(self={self.self.__log__()}, sqlstore={self.sqlstore.__log__()}, telemetrystore={self.telemetrystore.__log__()}, zeus={self.zeus.__log__()}, gateway={self.gateway.__log__()})"
|
|
|
|
|
|
@dataclass
|
|
class Operation:
|
|
__test__ = False
|
|
name: str
|
|
|
|
def __cache__(self) -> dict:
|
|
return {"name": self.name}
|
|
|
|
def __log__(self) -> str:
|
|
return f"Operation(name={self.name})"
|
|
|
|
|
|
@dataclass
|
|
class Network:
|
|
__test__ = False
|
|
id: str
|
|
name: str
|
|
|
|
def __cache__(self) -> dict:
|
|
return {
|
|
"id": self.id,
|
|
"name": self.name,
|
|
}
|
|
|
|
def __log__(self) -> str:
|
|
return f"Network(id={self.id}, name={self.name})"
|
|
|
|
|
|
# Alerts related types
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class AlertData:
|
|
# type of the alert data, one of 'metrics', 'logs', 'traces'
|
|
type: Literal["metrics", "logs", "traces"]
|
|
# path to the data file in testdata directory
|
|
data_path: str
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class FiringAlert:
|
|
# labels of the alert that is firing
|
|
labels: dict[str, str]
|
|
# annotations and other fields can be added later as per need
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class AlertExpectation:
|
|
# whether we expect any alerts to be fired
|
|
should_alert: bool
|
|
# alerts that we expect to be fired
|
|
expected_alerts: list[FiringAlert]
|
|
# seconds to wait for the alerts to be fired, if no
|
|
# alerts are fired in the expected time, the test will fail
|
|
wait_time_seconds: int
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class AlertTestCase:
|
|
# name of the test case
|
|
name: str
|
|
# path to the rule file in testdata directory
|
|
rule_path: str
|
|
# list of alert data that will be inserted into the database
|
|
alert_data: list[AlertData]
|
|
# list of alert expectations for the test case
|
|
alert_expectation: AlertExpectation
|