Skip to content

Commit 9fb4c1e

Browse files
Integration tests for support Linode integration with alerts (#669)
* Create tests for Linode integration with alerts * Code review fixes * Remove test test_try_to_update_linode_alerts_legacy_and_aclp_at_the_same_time and add test test_update_linode_aclp_alerts * Apply code review suggestions * Submit code review suggestions
1 parent e2d958f commit 9fb4c1e

2 files changed

Lines changed: 165 additions & 2 deletions

File tree

test/integration/conftest.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,3 +728,69 @@ def test_monitor_client(get_monitor_token_for_db_entities):
728728
)
729729

730730
return client, entity_ids
731+
732+
733+
def get_alert_channels_list(test_linode_client):
734+
channels = list(test_linode_client.monitor.alert_channels())
735+
if len(channels) == 0:
736+
pytest.fail(
737+
"No alert channels available for testing. Please create an alert channel and try again."
738+
)
739+
740+
return channels
741+
742+
743+
@pytest.fixture(scope="session")
744+
def create_alert_service_definition(test_linode_client):
745+
rule_criteria = {
746+
"rules": [
747+
{
748+
"aggregate_function": "min",
749+
"dimension_filters": [
750+
{
751+
"dimension_label": "node_type",
752+
"label": "Node Type",
753+
"operator": "eq",
754+
"value": "primary",
755+
}
756+
],
757+
"label": "Memory Usage",
758+
"metric": "memory_usage",
759+
"operator": "eq",
760+
"threshold": 95,
761+
"unit": "percent",
762+
}
763+
]
764+
}
765+
trigger_conditions = {
766+
"criteria_condition": "ALL",
767+
"evaluation_period_seconds": 300,
768+
"polling_interval_seconds": 900,
769+
"trigger_occurrences": 3,
770+
}
771+
alert = test_linode_client.monitor.create_alert_definition(
772+
service_type="dbaas",
773+
label=get_test_label() + "-service-definition",
774+
severity=1,
775+
description="description",
776+
channel_ids=[get_alert_channels_list(test_linode_client)[0].id],
777+
rule_criteria=rule_criteria,
778+
trigger_conditions=trigger_conditions,
779+
)
780+
781+
yield alert
782+
783+
alert.delete()
784+
785+
786+
def get_system_alerts(client: LinodeClient):
787+
alerts = client.monitor.alert_definitions()
788+
system_alerts = []
789+
for alert in alerts.lists[0]:
790+
if alert.type == "system":
791+
system_alerts.append(alert)
792+
if len(system_alerts) == 0:
793+
raise Exception(
794+
"No system alert definitions found. Cannot run tests dependent on system alert definitions."
795+
)
796+
return system_alerts

test/integration/models/linode/test_linode.py

Lines changed: 99 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import ipaddress
22
import time
3-
from test.integration.conftest import get_region
3+
from test.integration.conftest import get_region, get_system_alerts
44
from test.integration.helpers import (
55
get_test_label,
66
retry_sending_request,
@@ -10,7 +10,7 @@
1010

1111
import pytest
1212

13-
from linode_api4.errors import ApiError
13+
from linode_api4.errors import ApiError, UnexpectedResponseError
1414
from linode_api4.objects import (
1515
Config,
1616
ConfigInterface,
@@ -231,10 +231,36 @@ def get_status(linode: Instance, status: str):
231231
return linode.status == status
232232

233233

234+
def wait_for_clone_complete_and_delete_linode(
235+
interval: int, timeout: int, linode: Instance
236+
) -> object:
237+
end_time = time.time() + timeout
238+
while time.time() < end_time:
239+
try:
240+
return linode.delete()
241+
except ApiError as err:
242+
if "[400] Linode is the target of an ongoing clone" not in str(err):
243+
raise UnexpectedResponseError(f"Unexpected delete linode error")
244+
time.sleep(interval)
245+
raise TimeoutError(
246+
f"Timeout Error: not possible to delete just cloned linode in {timeout} seconds"
247+
)
248+
249+
234250
def instance_type_condition(linode: Instance, type: str):
235251
return type in str(linode.type)
236252

237253

254+
def test_get_linodes_verify_alerts(test_linode_client, create_linode):
255+
linodes_list = test_linode_client.linode.instances().lists[0]
256+
assert len(linodes_list) > 0
257+
assert linodes_list[0].alerts.cpu
258+
assert linodes_list[0].alerts.io
259+
assert linodes_list[0].alerts.network_in
260+
assert linodes_list[0].alerts.network_out
261+
assert linodes_list[0].alerts.transfer_quota
262+
263+
238264
def test_get_linode(test_linode_client, linode_with_volume_firewall):
239265
linode = test_linode_client.load(Instance, linode_with_volume_firewall.id)
240266

@@ -283,6 +309,8 @@ def test_linode_rebuild(test_linode_client):
283309

284310
assert linode.status == "rebuilding"
285311
assert linode.image.id == "linode/debian12"
312+
assert linode.alerts.cpu
313+
assert linode.alerts.io
286314

287315
assert linode.disk_encryption == InstanceDiskEncryptionType.disabled
288316

@@ -346,6 +374,75 @@ def test_linode_reboot(create_linode):
346374
assert linode.status == "running"
347375

348376

377+
def test_linode_alerts_workflow(test_linode_client, create_linode):
378+
linode = create_linode
379+
parent_linode_id = create_linode.id
380+
assert linode.alerts.cpu == 90
381+
assert linode.alerts.io == 10000
382+
assert linode.alerts.network_in == 10
383+
assert linode.alerts.network_out == 10
384+
assert linode.alerts.transfer_quota == 80
385+
assert isinstance(linode.alerts.system_alerts, list)
386+
assert isinstance(linode.alerts.user_alerts, list)
387+
388+
linode = test_linode_client.load(Instance, parent_linode_id)
389+
assert linode.alerts.cpu == 90
390+
assert linode.alerts.io == 10000
391+
assert linode.alerts.network_in == 10
392+
assert linode.alerts.network_out == 10
393+
assert linode.alerts.transfer_quota == 80
394+
assert isinstance(linode.alerts.system_alerts, list)
395+
assert isinstance(linode.alerts.user_alerts, list)
396+
397+
linode.alerts = {
398+
"cpu": 50,
399+
"io": 6000,
400+
"network_in": 20,
401+
"network_out": 20,
402+
"transfer_quota": 40,
403+
}
404+
linode_save_status = linode.save()
405+
assert linode_save_status == True
406+
assert linode.alerts["cpu"] == 50
407+
assert linode.alerts["io"] == 6000
408+
assert linode.alerts["network_in"] == 20
409+
assert linode.alerts["network_out"] == 20
410+
assert linode.alerts["transfer_quota"] == 40
411+
412+
wait_for_condition(10, 100, get_status, linode, "running")
413+
new_linode = retry_sending_request(
414+
5,
415+
linode.clone,
416+
region=linode.region.id,
417+
instance_type=linode.type.id,
418+
label=get_test_label(),
419+
)
420+
assert new_linode.alerts.cpu == 90
421+
assert new_linode.alerts.io == 10000
422+
assert new_linode.alerts.network_in == 10
423+
assert new_linode.alerts.network_out == 10
424+
assert new_linode.alerts.transfer_quota == 80
425+
assert isinstance(new_linode.alerts.system_alerts, list)
426+
assert isinstance(new_linode.alerts.user_alerts, list)
427+
428+
wait_for_clone_complete_and_delete_linode(10, 100, new_linode)
429+
430+
431+
def test_update_linode_aclp_alerts(
432+
test_linode_client, create_linode, create_alert_service_definition
433+
):
434+
linode = create_linode
435+
sample_system_alert = get_system_alerts(test_linode_client)[0].id
436+
437+
linode.alerts = {
438+
"user_alerts": [create_alert_service_definition.id],
439+
"system_alerts": [sample_system_alert],
440+
}
441+
linode.save()
442+
assert linode.alerts["user_alerts"] == [create_alert_service_definition.id]
443+
assert linode.alerts["system_alerts"] == [sample_system_alert]
444+
445+
349446
def test_linode_shutdown(create_linode):
350447
linode = create_linode
351448

0 commit comments

Comments
 (0)