Skip to content

Commit f897c15

Browse files
johannaenglandhmpf
authored andcommitted
Add tests for planned maintenance
1 parent 69300c6 commit f897c15

File tree

2 files changed

+203
-8
lines changed

2 files changed

+203
-8
lines changed

tests/plannedmaintenance/test_models.py

Lines changed: 90 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,78 @@
33
from django.test import TestCase, tag
44
from django.utils import timezone
55

6-
from argus.auth.factories import PersonUserFactory
6+
from argus.plannedmaintenance.factories import PlannedMaintenanceFactory
77
from argus.plannedmaintenance.models import MODIFICATION_WINDOW_PM, PlannedMaintenanceTask
88
from argus.util.testing import disconnect_signals, connect_signals
99

1010

11+
@tag("database")
12+
class PlannedMaintenanceQuerySetTests(TestCase):
13+
def setUp(self):
14+
disconnect_signals()
15+
16+
now = timezone.now()
17+
self.future_pm = PlannedMaintenanceFactory(start_time=now + timedelta(days=1))
18+
self.current_pm = PlannedMaintenanceFactory(start_time=now - timedelta(minutes=5))
19+
self.past_pm = PlannedMaintenanceFactory(start_time=now - timedelta(days=1), end_time=now - timedelta(hours=12))
20+
21+
def teardown(self):
22+
connect_signals()
23+
24+
def test_future_returns_only_pms_with_start_time_in_future(self):
25+
future_pms = PlannedMaintenanceTask.objects.future()
26+
27+
self.assertNotIn(self.current_pm, future_pms)
28+
self.assertNotIn(self.past_pm, future_pms)
29+
self.assertIn(self.future_pm, future_pms)
30+
31+
def test_past_returns_only_pms_with_end_time_in_past(self):
32+
past_pms = PlannedMaintenanceTask.objects.past()
33+
34+
self.assertNotIn(self.current_pm, past_pms)
35+
self.assertNotIn(self.future_pm, past_pms)
36+
self.assertIn(self.past_pm, past_pms)
37+
38+
def test_current_returns_only_pms_with_start_time_in_past_and_end_time_in_future(self):
39+
current_pms = PlannedMaintenanceTask.objects.current()
40+
41+
self.assertNotIn(self.future_pm, current_pms)
42+
self.assertNotIn(self.past_pm, current_pms)
43+
self.assertIn(self.current_pm, current_pms)
44+
45+
def test_active_at_time_returns_only_pms_with_start_time_before_and_end_time_after(self):
46+
active_at_time_pms = PlannedMaintenanceTask.objects.active_at_time(
47+
self.future_pm.start_time + timedelta(minutes=1)
48+
)
49+
50+
self.assertNotIn(self.past_pm, active_at_time_pms)
51+
self.assertIn(self.future_pm, active_at_time_pms)
52+
self.assertIn(self.current_pm, active_at_time_pms)
53+
54+
1155
@tag("database")
1256
class PlannedMaintenanceTaskTests(TestCase):
1357
def setUp(self):
1458
disconnect_signals()
1559

16-
self.user = PersonUserFactory()
60+
now = timezone.now()
61+
self.future_pm = PlannedMaintenanceFactory(start_time=now + timedelta(days=1))
62+
self.current_pm = PlannedMaintenanceFactory(start_time=now - timedelta(minutes=5))
63+
self.past_pm = PlannedMaintenanceFactory(
64+
start_time=timezone.now() - MODIFICATION_WINDOW_PM - timedelta(hours=2),
65+
end_time=timezone.now() - MODIFICATION_WINDOW_PM - timedelta(hours=1),
66+
)
1767

1868
def teardown(self):
1969
connect_signals()
2070

2171
def test_given_open_pm_task_modifiable_is_true(self):
22-
open_pm_task = PlannedMaintenanceTask(owner=self.user)
23-
72+
open_pm_task = PlannedMaintenanceTask(created_by=self.user)
2473
self.assertTrue(open_pm_task.modifiable)
2574

2675
def test_given_recently_ended_pm_task_modifiable_is_true(self):
27-
open_pm_task = PlannedMaintenanceTask(
28-
owner=self.user,
76+
open_pm_task = PlannedMaintenanceFactory(
77+
created_by=self.user,
2978
start_time=timezone.now() - timedelta(hours=1),
3079
end_time=timezone.now(),
3180
)
@@ -34,9 +83,42 @@ def test_given_recently_ended_pm_task_modifiable_is_true(self):
3483

3584
def test_given_long_ago_ended_pm_task_modifiable_is_false(self):
3685
open_pm_task = PlannedMaintenanceTask(
37-
owner=self.user,
86+
created_by=self.user,
3887
start_time=timezone.now() - MODIFICATION_WINDOW_PM - timedelta(hours=2),
3988
end_time=timezone.now() - MODIFICATION_WINDOW_PM - timedelta(hours=1),
4089
)
90+
self.assertFalse(self.past_pm.modifiable)
91+
92+
def test_given_active_pm_current_is_true(self):
93+
pm = PlannedMaintenanceFactory(start_time=timezone.now() - timedelta(minutes=5))
94+
self.assertTrue(pm.current)
95+
96+
def test_given_past_pm_current_is_false(self):
97+
now = timezone.now()
98+
pm = PlannedMaintenanceFactory(start_time=now - timedelta(days=1), end_time=now - timedelta(hours=12))
99+
self.assertFalse(pm.current)
100+
101+
def test_given_future_pm_current_is_false(self):
102+
pm = PlannedMaintenanceFactory(start_time=timezone.now() + timedelta(days=1))
103+
self.assertFalse(pm.current)
104+
105+
def test_given_future_pm_cancel_deletes_task(self):
106+
pm_id = self.future_pm.id
107+
self.future_pm.cancel()
108+
109+
self.assertFalse(PlannedMaintenanceTask.objects.filter(id=pm_id).exists())
110+
111+
def test_given_past_pm_cancel_does_nothing(self):
112+
past_end_time = self.past_pm.end_time
113+
self.past_pm.cancel()
114+
self.past_pm.refresh_from_db()
115+
116+
self.assertEqual(self.past_pm.end_time, past_end_time)
117+
118+
def test_given_current_pm_cancel_sets_end_time(self):
119+
current_pm_end_time = self.current_pm.end_time
120+
self.current_pm.cancel()
121+
self.current_pm.refresh_from_db()
41122

42-
self.assertFalse(open_pm_task.modifiable)
123+
self.assertNotEqual(self.current_pm.end_time, current_pm_end_time)
124+
self.assertLess(self.current_pm.end_time, timezone.now())
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
from datetime import timedelta
2+
3+
from django.test import TestCase, tag
4+
from django.utils import timezone
5+
6+
from argus.filter.factories import FilterFactory
7+
from argus.incident.factories import EventFactory, StatefulIncidentFactory
8+
from argus.incident.models import Event, Incident
9+
from argus.plannedmaintenance.factories import PlannedMaintenanceFactory
10+
from argus.plannedmaintenance.models import PlannedMaintenanceTask
11+
from argus.plannedmaintenance.utils import (
12+
event_covered_by_planned_maintenance,
13+
incidents_covered_by_planned_maintenance_task,
14+
)
15+
from argus.util.testing import disconnect_signals, connect_signals
16+
17+
18+
@tag("database")
19+
class TestIncidentsCoveredByPlannedMaintenanceTask(TestCase):
20+
def setUp(self):
21+
disconnect_signals()
22+
self.open_incident = StatefulIncidentFactory(level=5)
23+
self.maxlevel_filter = FilterFactory(filter={"maxlevel": 5})
24+
25+
def teardown(self):
26+
connect_signals()
27+
28+
def test_returns_only_open_incidents(self):
29+
closed_incident = StatefulIncidentFactory(end_time=timezone.now())
30+
pm = PlannedMaintenanceFactory()
31+
pm.filters.add(self.maxlevel_filter)
32+
incidents = incidents_covered_by_planned_maintenance_task(queryset=Incident.objects.all(), pm_task=pm)
33+
34+
self.assertIn(self.open_incident, incidents)
35+
self.assertNotIn(closed_incident, incidents)
36+
37+
def test_given_past_pm_returns_no_incidents(self):
38+
pm = PlannedMaintenanceFactory(
39+
start_time=timezone.now() - timedelta(days=2), end_time=timezone.now() - timedelta(days=1)
40+
)
41+
pm.filters.add(self.maxlevel_filter)
42+
43+
incidents = incidents_covered_by_planned_maintenance_task(queryset=Incident.objects.all(), pm_task=pm)
44+
self.assertFalse(incidents)
45+
46+
def test_given_future_pm_returns_no_incidents(self):
47+
pm = PlannedMaintenanceFactory(start_time=timezone.now() + timedelta(days=2))
48+
pm.filters.add(self.maxlevel_filter)
49+
50+
incidents = incidents_covered_by_planned_maintenance_task(queryset=Incident.objects.all(), pm_task=pm)
51+
self.assertFalse(incidents)
52+
53+
def test_given_filter_only_returns_incidents_matching_filter(self):
54+
important_incident = StatefulIncidentFactory(level=1)
55+
pm = PlannedMaintenanceFactory()
56+
pm.filters.add(FilterFactory(filter={"maxlevel": 1}))
57+
58+
incidents = incidents_covered_by_planned_maintenance_task(queryset=Incident.objects.all(), pm_task=pm)
59+
60+
self.assertIn(important_incident, incidents)
61+
self.assertNotIn(self.open_incident, incidents)
62+
63+
64+
@tag("database")
65+
class TestEventCoveredByPlannedMaintenanceTasks(TestCase):
66+
def setUp(self):
67+
disconnect_signals()
68+
self.start_event = EventFactory(type=Event.Type.INCIDENT_START)
69+
self.current_pm = PlannedMaintenanceFactory()
70+
self.maxlevel_filter = FilterFactory(filter={"maxlevel": 5})
71+
72+
def teardown(self):
73+
connect_signals()
74+
75+
def test_given_relevant_event_return_true(self):
76+
self.current_pm.filters.add(self.maxlevel_filter)
77+
78+
covered = event_covered_by_planned_maintenance(self.start_event)
79+
80+
self.assertTrue(covered)
81+
82+
def test_given_wrong_event_type_return_false(self):
83+
self.current_pm.filters.add(FilterFactory(filter={"event_type": Event.Type.ACKNOWLEDGE}))
84+
85+
covered = event_covered_by_planned_maintenance(self.start_event)
86+
87+
self.assertFalse(covered)
88+
89+
def test_given_wrong_maxlevel_return_false(self):
90+
self.current_pm.filters.add(FilterFactory(filter={"maxlevel": 1}))
91+
92+
covered = event_covered_by_planned_maintenance(self.start_event)
93+
94+
self.assertFalse(covered)
95+
96+
def test_given_pm_with_multiple_filters_only_matching_one_filter_return_false(self):
97+
self.current_pm.filters.add(FilterFactory(filter={"maxlevel": 1}))
98+
self.current_pm.filters.add(FilterFactory(filter={"event_type": Event.Type.INCIDENT_START}))
99+
100+
covered = event_covered_by_planned_maintenance(self.start_event)
101+
102+
self.assertFalse(covered)
103+
104+
def test_given_no_pms_active_at_time_return_false(self):
105+
now = timezone.now()
106+
past_pm = PlannedMaintenanceFactory(start_time=now - timedelta(days=5), end_time=now - timedelta(days=4))
107+
past_pm.filters.add(self.maxlevel_filter)
108+
109+
covered = event_covered_by_planned_maintenance(
110+
self.start_event, PlannedMaintenanceTask.objects.filter(id=past_pm.id)
111+
)
112+
113+
self.assertFalse(covered)

0 commit comments

Comments
 (0)