import datetime
from dbmind.common.tsdb import TsdbClientFactory
from dbmind.common.types import Alarm, ALARM_TYPES, ALARM_LEVEL
from dbmind.common.types import RootCause
from dbmind.common.types import Sequence
from dbmind.app.diagnosis.query.slow_sql import SlowQuery
from dbmind.metadatabase.ddl import create_metadatabase_schema
from dbmind.service import dai
from dbmind.constants import DISTINGUISHING_INSTANCE_LABEL
from dbmind.service.utils import SequenceUtils
create_metadatabase_schema()
golden_kpi = ('os_cpu_usage', 'os_mem_usage_rate',
'gaussdb_qps_by_instance', 'gaussdb_dynamic_used_memory')
def test_range_metrics(mock_dai):
minutes = 10
dai.get_latest_metric_value('prometheus_remote_storage_highest_timestamp_in_seconds').fetchone()
for metric in golden_kpi:
results = dai.get_latest_metric_sequence(metric, minutes).fetchall()
for sequence in results:
assert sequence.name in golden_kpi
assert sequence.length > 0
host = SequenceUtils.from_server(sequence)
assert host is not None and host != ''
def test_tsdb():
for metric in golden_kpi:
results = TsdbClientFactory.get_tsdb_client().get_current_metric_value(
metric_name=metric
)
for sequence in results:
assert isinstance(sequence, Sequence)
from_instance = SequenceUtils.from_server(sequence)
inner_results = TsdbClientFactory.get_tsdb_client().get_metric_range_data(
metric_name=metric,
label_config={DISTINGUISHING_INSTANCE_LABEL: from_instance},
params={'step': '30s'}
)
for inner_result in inner_results:
assert inner_result.name == metric
assert len(inner_result) > 0
def test_save_xxx():
host = '127.0.0.1'
metric_name = 'test_metric'
sequence = Sequence(tuple(range(0, 100)), tuple(range(100, 200)))
dai.save_forecast_sequence(host, metric_name, sequence)
future_alarm = Alarm(
instance=host,
alarm_content="disk occupied will exceed percentage threshold",
alarm_type=ALARM_TYPES.SYSTEM,
metric_name=metric_name,
alarm_level=ALARM_LEVEL.ERROR,
alarm_cause=RootCause.get('DISK_WILL_SPILL')
)
dai.save_future_alarms([future_alarm, future_alarm, future_alarm])
history_alarm = Alarm(
instance=host,
metric_name=metric_name,
alarm_content='found anomaly on %s' % metric_name,
alarm_type=ALARM_TYPES.SYSTEM,
alarm_level=ALARM_LEVEL.ERROR,
alarm_cause=RootCause.get('WORKING_IO_CONTENTION')
)
history_alarm.set_timestamp(100, 101)
dai.save_history_alarms([history_alarm, history_alarm, history_alarm])
slow_query = SlowQuery(
db_host='127.0.0.1',
db_port=1234,
schema_name='test_schema',
db_name='test_db',
query='select sleep(100);',
start_timestamp=1000,
duration_time=2,
hit_rate=0.90,
fetch_rate=1000,
cpu_time=100,
data_io_time=100
)
slow_query.add_cause(RootCause.get('LOCK_CONTENTION'))
dai.save_slow_queries([slow_query, slow_query, slow_query])
def test_estimate_appropriate_step(monkeypatch):
end = datetime.datetime.now()
start = end - datetime.timedelta(days=1)
total_seconds = (end - start).total_seconds()
def validate():
max_length = total_seconds // default_scrape_interval
tsdb_client = TsdbClientFactory.get_tsdb_client()
monkeypatch.setattr(tsdb_client, 'scrape_interval', default_scrape_interval)
step = dai.estimate_appropriate_step_ms(start, end) // 1000
actual_length = total_seconds // step
assert 0 < actual_length <= max_length
for default_scrape_interval in range(1, 60, 5):
validate()