aws_rl_env / aws_infra /tests /test_cloudwatch.py
Sizzing's picture
Upload folder using huggingface_hub
c745a99 verified
import io
import json
import os
import time
import zipfile
from urllib.parse import urlparse
import pytest
from botocore.exceptions import ClientError
import uuid as _uuid_mod
def test_cloudwatch_metrics(cw):
cw.put_metric_data(
Namespace="MyApp",
MetricData=[
{"MetricName": "RequestCount", "Value": 42.0, "Unit": "Count"},
{"MetricName": "Latency", "Value": 123.5, "Unit": "Milliseconds"},
],
)
resp = cw.list_metrics(Namespace="MyApp")
names = [m["MetricName"] for m in resp["Metrics"]]
assert "RequestCount" in names
assert "Latency" in names
def test_cloudwatch_alarm(cw):
cw.put_metric_alarm(
AlarmName="high-latency",
MetricName="Latency",
Namespace="MyApp",
Statistic="Average",
Period=60,
EvaluationPeriods=1,
Threshold=500.0,
ComparisonOperator="GreaterThanThreshold",
)
resp = cw.describe_alarms(AlarmNames=["high-latency"])
assert len(resp["MetricAlarms"]) == 1
def test_cloudwatch_logs_metric_filter(logs):
logs.create_log_group(logGroupName="/test/mf")
logs.put_metric_filter(
logGroupName="/test/mf",
filterName="err-count",
filterPattern="ERROR",
metricTransformations=[{"metricName": "ErrorCount", "metricNamespace": "Test", "metricValue": "1"}],
)
resp = logs.describe_metric_filters(logGroupName="/test/mf")
assert len(resp["metricFilters"]) == 1
assert resp["metricFilters"][0]["filterName"] == "err-count"
logs.delete_metric_filter(logGroupName="/test/mf", filterName="err-count")
resp2 = logs.describe_metric_filters(logGroupName="/test/mf")
assert len(resp2["metricFilters"]) == 0
def test_cloudwatch_logs_insights_stub(logs):
logs.create_log_group(logGroupName="/test/insights")
resp = logs.start_query(
logGroupName="/test/insights",
startTime=0,
endTime=9999999999,
queryString="fields @timestamp | limit 10",
)
query_id = resp["queryId"]
assert query_id
results = logs.get_query_results(queryId=query_id)
assert results["status"] in ("Complete", "Running")
def test_cloudwatch_dashboard(cw):
body = json.dumps({"widgets": [{"type": "text", "properties": {"markdown": "Hello"}}]})
cw.put_dashboard(DashboardName="test-dash", DashboardBody=body)
resp = cw.get_dashboard(DashboardName="test-dash")
assert resp["DashboardName"] == "test-dash"
assert "DashboardBody" in resp
listed = cw.list_dashboards()
assert any(d["DashboardName"] == "test-dash" for d in listed["DashboardEntries"])
cw.delete_dashboards(DashboardNames=["test-dash"])
# Migrated from test_cw.py
def test_cloudwatch_put_list_metrics_v2(cw):
cw.put_metric_data(
Namespace="CWv2",
MetricData=[
{
"MetricName": "Reqs",
"Value": 100.0,
"Unit": "Count",
"Dimensions": [{"Name": "API", "Value": "/users"}],
},
{"MetricName": "Errs", "Value": 5.0, "Unit": "Count"},
],
)
resp = cw.list_metrics(Namespace="CWv2")
names = [m["MetricName"] for m in resp["Metrics"]]
assert "Reqs" in names
assert "Errs" in names
resp_filtered = cw.list_metrics(Namespace="CWv2", MetricName="Reqs")
assert all(m["MetricName"] == "Reqs" for m in resp_filtered["Metrics"])
def test_cloudwatch_get_metric_statistics_v2(cw):
cw.put_metric_data(
Namespace="CWStat2",
MetricData=[
{"MetricName": "Duration", "Value": 100.0, "Unit": "Milliseconds"},
{"MetricName": "Duration", "Value": 200.0, "Unit": "Milliseconds"},
],
)
resp = cw.get_metric_statistics(
Namespace="CWStat2",
MetricName="Duration",
Period=60,
StartTime=time.time() - 600,
EndTime=time.time() + 600,
Statistics=["Average", "Sum", "SampleCount", "Minimum", "Maximum"],
)
assert len(resp["Datapoints"]) >= 1
dp = resp["Datapoints"][0]
assert "Average" in dp
assert "Sum" in dp
assert "SampleCount" in dp
assert "Minimum" in dp
assert "Maximum" in dp
def test_cloudwatch_put_metric_alarm_v2(cw):
cw.put_metric_alarm(
AlarmName="cw-v2-high-err",
MetricName="Errors",
Namespace="CWv2Alarms",
Statistic="Sum",
Period=300,
EvaluationPeriods=2,
Threshold=10.0,
ComparisonOperator="GreaterThanOrEqualToThreshold",
AlarmActions=["arn:aws:sns:us-east-1:000000000000:alarm-topic"],
AlarmDescription="Fires when errors >= 10",
)
resp = cw.describe_alarms(AlarmNames=["cw-v2-high-err"])
alarm = resp["MetricAlarms"][0]
assert alarm["AlarmName"] == "cw-v2-high-err"
assert alarm["Threshold"] == 10.0
assert alarm["ComparisonOperator"] == "GreaterThanOrEqualToThreshold"
assert alarm["EvaluationPeriods"] == 2
def test_cloudwatch_describe_alarms_v2(cw):
for i in range(3):
cw.put_metric_alarm(
AlarmName=f"cw-da-v2-{i}",
MetricName="M",
Namespace="N",
Statistic="Sum",
Period=60,
EvaluationPeriods=1,
Threshold=float(i),
ComparisonOperator="GreaterThanThreshold",
)
resp = cw.describe_alarms(AlarmNamePrefix="cw-da-v2-")
names = [a["AlarmName"] for a in resp["MetricAlarms"]]
for i in range(3):
assert f"cw-da-v2-{i}" in names
def test_cloudwatch_delete_alarms_v2(cw):
cw.put_metric_alarm(
AlarmName="cw-del-v2",
MetricName="M",
Namespace="N",
Statistic="Sum",
Period=60,
EvaluationPeriods=1,
Threshold=1.0,
ComparisonOperator="GreaterThanThreshold",
)
cw.delete_alarms(AlarmNames=["cw-del-v2"])
resp = cw.describe_alarms(AlarmNames=["cw-del-v2"])
assert len(resp["MetricAlarms"]) == 0
def test_cloudwatch_set_alarm_state_v2(cw):
cw.put_metric_alarm(
AlarmName="cw-state-v2",
MetricName="M",
Namespace="N",
Statistic="Sum",
Period=60,
EvaluationPeriods=1,
Threshold=1.0,
ComparisonOperator="GreaterThanThreshold",
)
initial = cw.describe_alarms(AlarmNames=["cw-state-v2"])["MetricAlarms"][0]
assert initial["StateValue"] == "INSUFFICIENT_DATA"
cw.set_alarm_state(
AlarmName="cw-state-v2",
StateValue="ALARM",
StateReason="Manual trigger for testing",
)
after = cw.describe_alarms(AlarmNames=["cw-state-v2"])["MetricAlarms"][0]
assert after["StateValue"] == "ALARM"
assert after["StateReason"] == "Manual trigger for testing"
def test_cloudwatch_get_metric_data_v2(cw):
cw.put_metric_data(
Namespace="CWData2",
MetricData=[{"MetricName": "Hits", "Value": 42.0, "Unit": "Count"}],
)
resp = cw.get_metric_data(
MetricDataQueries=[
{
"Id": "q1",
"MetricStat": {
"Metric": {"Namespace": "CWData2", "MetricName": "Hits"},
"Period": 60,
"Stat": "Sum",
},
"ReturnData": True,
}
],
StartTime=time.time() - 600,
EndTime=time.time() + 600,
)
assert len(resp["MetricDataResults"]) == 1
assert resp["MetricDataResults"][0]["Id"] == "q1"
assert resp["MetricDataResults"][0]["StatusCode"] == "Complete"
assert len(resp["MetricDataResults"][0]["Values"]) >= 1
def test_cloudwatch_tags_v2(cw):
cw.put_metric_alarm(
AlarmName="cw-tag-v2",
MetricName="M",
Namespace="N",
Statistic="Sum",
Period=60,
EvaluationPeriods=1,
Threshold=1.0,
ComparisonOperator="GreaterThanThreshold",
)
arn = cw.describe_alarms(AlarmNames=["cw-tag-v2"])["MetricAlarms"][0]["AlarmArn"]
cw.tag_resource(
ResourceARN=arn,
Tags=[
{"Key": "env", "Value": "prod"},
{"Key": "team", "Value": "sre"},
],
)
resp = cw.list_tags_for_resource(ResourceARN=arn)
tag_map = {t["Key"]: t["Value"] for t in resp["Tags"]}
assert tag_map["env"] == "prod"
assert tag_map["team"] == "sre"
cw.untag_resource(ResourceARN=arn, TagKeys=["env"])
resp2 = cw.list_tags_for_resource(ResourceARN=arn)
assert not any(t["Key"] == "env" for t in resp2["Tags"])
assert any(t["Key"] == "team" for t in resp2["Tags"])
def test_cloudwatch_composite_alarm(cw):
import uuid as _uuid
child = f"intg-child-alarm-{_uuid.uuid4().hex[:8]}"
composite = f"intg-comp-alarm-{_uuid.uuid4().hex[:8]}"
cw.put_metric_alarm(
AlarmName=child,
ComparisonOperator="GreaterThanThreshold",
EvaluationPeriods=1,
MetricName="CPUUtilization",
Namespace="AWS/EC2",
Period=60,
Statistic="Average",
Threshold=80.0,
)
child_arn = cw.describe_alarms(AlarmNames=[child])["MetricAlarms"][0]["AlarmArn"]
cw.put_composite_alarm(
AlarmName=composite,
AlarmRule=f"ALARM({child_arn})",
AlarmDescription="composite test",
)
resp = cw.describe_alarms(AlarmNames=[composite], AlarmTypes=["CompositeAlarm"])
assert any(a["AlarmName"] == composite for a in resp.get("CompositeAlarms", []))
cw.delete_alarms(AlarmNames=[child, composite])
def test_cloudwatch_describe_alarms_for_metric(cw):
import uuid as _uuid
alarm_name = f"intg-afm-{_uuid.uuid4().hex[:8]}"
cw.put_metric_alarm(
AlarmName=alarm_name,
ComparisonOperator="GreaterThanThreshold",
EvaluationPeriods=1,
MetricName="NetworkIn",
Namespace="AWS/EC2",
Period=60,
Statistic="Sum",
Threshold=1000.0,
)
resp = cw.describe_alarms_for_metric(
MetricName="NetworkIn",
Namespace="AWS/EC2",
)
assert any(a["AlarmName"] == alarm_name for a in resp.get("MetricAlarms", []))
cw.delete_alarms(AlarmNames=[alarm_name])
def test_cloudwatch_describe_alarm_history(cw):
import uuid as _uuid
alarm_name = f"intg-hist-{_uuid.uuid4().hex[:8]}"
cw.put_metric_alarm(
AlarmName=alarm_name,
ComparisonOperator="GreaterThanThreshold",
EvaluationPeriods=1,
MetricName="DiskReadOps",
Namespace="AWS/EC2",
Period=60,
Statistic="Average",
Threshold=50.0,
)
cw.set_alarm_state(AlarmName=alarm_name, StateValue="ALARM", StateReason="test")
resp = cw.describe_alarm_history(AlarmName=alarm_name)
assert "AlarmHistoryItems" in resp
cw.delete_alarms(AlarmNames=[alarm_name])
def test_cloudwatch_get_metric_data_time_range(cw):
"""GetMetricData respects StartTime/EndTime filtering."""
import datetime
now = datetime.datetime.utcnow()
past = now - datetime.timedelta(hours=2)
cw.put_metric_data(
Namespace="qa/cw",
MetricData=[{"MetricName": "Requests", "Value": 100.0, "Unit": "Count"}],
)
resp = cw.get_metric_data(
MetricDataQueries=[
{
"Id": "m1",
"MetricStat": {
"Metric": {"Namespace": "qa/cw", "MetricName": "Requests"},
"Period": 60,
"Stat": "Sum",
},
}
],
StartTime=past,
EndTime=now + datetime.timedelta(minutes=5),
)
result = next((r for r in resp["MetricDataResults"] if r["Id"] == "m1"), None)
assert result is not None
assert result["StatusCode"] == "Complete"
assert len(result["Values"]) >= 1
assert sum(result["Values"]) >= 100.0
def test_cloudwatch_alarm_state_transitions(cw):
"""SetAlarmState changes alarm state correctly."""
cw.put_metric_alarm(
AlarmName="qa-cw-state-alarm",
MetricName="Errors",
Namespace="qa/cw",
Statistic="Sum",
Period=60,
EvaluationPeriods=1,
Threshold=10.0,
ComparisonOperator="GreaterThanThreshold",
)
cw.set_alarm_state(AlarmName="qa-cw-state-alarm", StateValue="ALARM", StateReason="Testing")
alarms = cw.describe_alarms(AlarmNames=["qa-cw-state-alarm"])["MetricAlarms"]
assert alarms[0]["StateValue"] == "ALARM"
cw.set_alarm_state(AlarmName="qa-cw-state-alarm", StateValue="OK", StateReason="Resolved")
alarms2 = cw.describe_alarms(AlarmNames=["qa-cw-state-alarm"])["MetricAlarms"]
assert alarms2[0]["StateValue"] == "OK"
def test_cloudwatch_list_metrics_namespace_filter(cw):
"""ListMetrics with Namespace filter returns only matching metrics."""
cw.put_metric_data(Namespace="qa/ns-a", MetricData=[{"MetricName": "MetA", "Value": 1.0}])
cw.put_metric_data(Namespace="qa/ns-b", MetricData=[{"MetricName": "MetB", "Value": 1.0}])
resp = cw.list_metrics(Namespace="qa/ns-a")
names = [m["MetricName"] for m in resp["Metrics"]]
assert "MetA" in names
assert "MetB" not in names
def test_cloudwatch_put_metric_data_statistics_values(cw):
"""PutMetricData with Values/Counts array stores multiple data points."""
cw.put_metric_data(
Namespace="qa/cw-multi",
MetricData=[
{
"MetricName": "Latency",
"Values": [10.0, 20.0, 30.0],
"Counts": [1.0, 2.0, 1.0],
"Unit": "Milliseconds",
}
],
)
resp = cw.list_metrics(Namespace="qa/cw-multi")
assert any(m["MetricName"] == "Latency" for m in resp["Metrics"])
def test_cloudwatch_enable_alarm_actions(cw):
cw.put_metric_alarm(
AlarmName="heimdall-enable-actions",
MetricName="M",
Namespace="N",
Statistic="Sum",
Period=60,
EvaluationPeriods=1,
Threshold=1.0,
ComparisonOperator="GreaterThanThreshold",
ActionsEnabled=False,
)
alarm = cw.describe_alarms(AlarmNames=["heimdall-enable-actions"])["MetricAlarms"][0]
assert alarm["ActionsEnabled"] is False
cw.enable_alarm_actions(AlarmNames=["heimdall-enable-actions"])
alarm = cw.describe_alarms(AlarmNames=["heimdall-enable-actions"])["MetricAlarms"][0]
assert alarm["ActionsEnabled"] is True
cw.delete_alarms(AlarmNames=["heimdall-enable-actions"])
def test_cloudwatch_disable_alarm_actions(cw):
cw.put_metric_alarm(
AlarmName="heimdall-disable-actions",
MetricName="M",
Namespace="N",
Statistic="Sum",
Period=60,
EvaluationPeriods=1,
Threshold=1.0,
ComparisonOperator="GreaterThanThreshold",
ActionsEnabled=True,
)
alarm = cw.describe_alarms(AlarmNames=["heimdall-disable-actions"])["MetricAlarms"][0]
assert alarm["ActionsEnabled"] is True
cw.disable_alarm_actions(AlarmNames=["heimdall-disable-actions"])
alarm = cw.describe_alarms(AlarmNames=["heimdall-disable-actions"])["MetricAlarms"][0]
assert alarm["ActionsEnabled"] is False
cw.delete_alarms(AlarmNames=["heimdall-disable-actions"])