Skip to content

Commit c892a06

Browse files
committed
[changes] Assert queries count in estimated location tests
Signed-off-by: DragnEmperor <[email protected]>
1 parent fd2eb34 commit c892a06

File tree

6 files changed

+56
-24
lines changed

6 files changed

+56
-24
lines changed

openwisp_controller/config/whois/service.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ def _create_or_update_estimated_location(
305305
device_location.full_clean()
306306
device_location.save()
307307
send_whois_task_notification(
308-
device_pk=self.device.pk,
308+
device=self.device,
309309
notify_type="estimated_location_created",
310310
actor=current_location,
311311
)
@@ -322,7 +322,7 @@ def _create_or_update_estimated_location(
322322
)
323323

324324
send_whois_task_notification(
325-
device_pk=self.device.pk,
325+
device=self.device,
326326
notify_type="estimated_location_updated",
327327
actor=current_location,
328328
)

openwisp_controller/config/whois/tasks.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,7 @@ class WHOISCeleryRetryTask(OpenwispCeleryTask):
2626
def on_failure(self, exc, task_id, args, kwargs, einfo):
2727
"""Notify the user about the failure of the WHOIS task."""
2828
device_pk = kwargs.get("device_pk")
29-
send_whois_task_notification(
30-
device_pk=device_pk, notify_type="whois_device_error"
31-
)
29+
send_whois_task_notification(device=device_pk, notify_type="whois_device_error")
3230
logger.error(f"WHOIS lookup failed. Details: {exc}")
3331
return super().on_failure(exc, task_id, args, kwargs, einfo)
3432

@@ -51,7 +49,7 @@ def _manage_whois_record(whois_details, whois_instance=None):
5149
else:
5250
whois_instance = WHOISInfo(**whois_details)
5351
whois_instance.full_clean()
54-
whois_instance.save()
52+
whois_instance.save(force_insert=True)
5553
return whois_instance, update_fields
5654

5755

openwisp_controller/config/whois/tests/utils.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,14 @@ def _task_called(self, mocked_task, task_name="WHOIS lookup"):
6161
org = self._get_org()
6262

6363
with self.subTest(f"{task_name} task called when last_ip is public"):
64-
with mock.patch("django.core.cache.cache.set") as mocked_set:
64+
with mock.patch("django.core.cache.cache.get") as mocked_get, mock.patch(
65+
"django.core.cache.cache.set"
66+
) as mocked_set:
67+
mocked_get.side_effect = [None, org.config_settings]
6568
device = self._create_device(last_ip="172.217.22.14")
6669
mocked_task.assert_called()
6770
mocked_set.assert_called_once()
71+
mocked_get.assert_called()
6872
mocked_task.reset_mock()
6973

7074
with self.subTest(
@@ -77,7 +81,7 @@ def _task_called(self, mocked_task, task_name="WHOIS lookup"):
7781
device.save()
7882
mocked_task.assert_called()
7983
mocked_set.assert_not_called()
80-
mocked_get.assert_called_once()
84+
mocked_get.assert_called()
8185
mocked_task.reset_mock()
8286

8387
with self.subTest(f"{task_name} task not called when last_ip not updated"):

openwisp_controller/config/whois/utils.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@
4141
}
4242

4343

44-
def send_whois_task_notification(device_pk, notify_type, actor=None):
44+
def send_whois_task_notification(device, notify_type, actor=None):
4545
Device = load_model("config", "Device")
46-
47-
device = Device.objects.get(pk=device_pk)
46+
if not isinstance(device, Device):
47+
device = Device.objects.get(pk=device)
4848
notify_details = MESSAGE_MAP[notify_type]
4949
notify.send(
5050
sender=actor or device,

openwisp_controller/geo/estimated_location/tasks.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,17 @@ def _handle_attach_existing_location(
3232
existing_location = existing_device_location.location
3333
# We need to remove existing estimated location of the device
3434
# if it is not shared
35-
if attached_devices_exists is False:
36-
current_location.delete()
3735
device_location.location = existing_location
3836
device_location.full_clean()
3937
device_location.save()
4038
logger.info(
4139
f"Estimated location saved successfully for {device.pk}"
4240
f" for IP: {ip_address}"
4341
)
42+
if attached_devices_exists is False:
43+
current_location.delete()
4444
send_whois_task_notification(
45-
device_pk=device.pk,
45+
device=device,
4646
notify_type="estimated_location_updated",
4747
actor=existing_location,
4848
)
@@ -94,23 +94,19 @@ def manage_estimated_locations(device_pk, ip_address):
9494
Device = load_model("config", "Device")
9595
DeviceLocation = load_model("geo", "DeviceLocation")
9696

97-
device = (
98-
Device.objects.select_related("devicelocation__location", "organization")
99-
.only("organization_id", "devicelocation")
100-
.get(pk=device_pk)
101-
)
97+
device = Device.objects.select_related("devicelocation__location").get(pk=device_pk)
10298

10399
devices_with_location = (
104-
Device.objects.select_related("devicelocation")
100+
Device.objects.only("devicelocation")
101+
.select_related("devicelocation__location")
105102
.filter(organization_id=device.organization_id)
106103
.filter(last_ip=ip_address, devicelocation__location__isnull=False)
107104
.exclude(pk=device.pk)
108105
)
109-
# If there are multiple devices with same last_ip then we need to inform
110-
# the user to resolve the conflict manually.
106+
111107
if devices_with_location.count() > 1:
112108
send_whois_task_notification(
113-
device_pk=device.pk, notify_type="estimated_location_error"
109+
device=device, notify_type="estimated_location_error"
114110
)
115111
logger.error(
116112
"Multiple devices with locations found with same "

openwisp_controller/geo/estimated_location/tests/tests.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from ....tests.utils import TestAdminMixin
1919
from ...tests.utils import TestGeoMixin
2020
from ..handlers import register_estimated_location_notification_types
21+
from ..tasks import manage_estimated_locations
2122
from .utils import TestEstimatedLocationMixin
2223

2324
Device = load_model("config", "Device")
@@ -282,9 +283,20 @@ def test_estimated_location_task_called(
282283
mocked_estimated_location_task.reset_mock()
283284

284285
@mock.patch.object(config_app_settings, "WHOIS_CONFIGURED", True)
286+
@mock.patch(
287+
"openwisp_controller.config.whois.service.send_whois_task_notification" # noqa
288+
)
289+
@mock.patch(
290+
"openwisp_controller.geo.estimated_location.tasks.send_whois_task_notification" # noqa
291+
)
292+
@mock.patch(
293+
"openwisp_controller.geo.estimated_location.tasks.manage_estimated_locations.delay" # noqa
294+
)
285295
@mock.patch(_ESTIMATED_LOCATION_INFO_LOGGER)
286296
@mock.patch(_WHOIS_GEOIP_CLIENT)
287-
def test_estimated_location_creation_and_update(self, mock_client, mock_info):
297+
def test_estimated_location_creation_and_update(
298+
self, mock_client, mock_info, _mocked_task, _mocked_notify, _mocked_notify2
299+
):
288300
connect_whois_handlers()
289301

290302
def _verify_location_details(device, mocked_response):
@@ -318,6 +330,8 @@ def _verify_location_details(device, mocked_response):
318330

319331
with self.subTest("Test Estimated location created when device is created"):
320332
device = self._create_device(last_ip="172.217.22.14")
333+
with self.assertNumQueries(14):
334+
manage_estimated_locations(device.pk, device.last_ip)
321335

322336
location = device.devicelocation.location
323337
mocked_response.ip_address = device.last_ip
@@ -338,6 +352,8 @@ def _verify_location_details(device, mocked_response):
338352
mocked_response.city.name = "New City"
339353
mock_client.return_value.city.return_value = mocked_response
340354
device.save()
355+
with self.assertNumQueries(8):
356+
manage_estimated_locations(device.pk, device.last_ip)
341357
device.refresh_from_db()
342358

343359
location = device.devicelocation.location
@@ -361,6 +377,8 @@ def _verify_location_details(device, mocked_response):
361377
mock_client.return_value.city.return_value = self._mocked_client_response()
362378
device.devicelocation.location.save(_set_estimated=True)
363379
device.save()
380+
with self.assertNumQueries(2):
381+
manage_estimated_locations(device.pk, device.last_ip)
364382
device.refresh_from_db()
365383

366384
location = device.devicelocation.location
@@ -379,12 +397,15 @@ def _verify_location_details(device, mocked_response):
379397
):
380398
Device.objects.all().delete()
381399
device1 = self._create_device(last_ip="172.217.22.10")
400+
manage_estimated_locations(device1.pk, device1.last_ip)
382401
mock_info.reset_mock()
383402
device2 = self._create_device(
384403
name="11:22:33:44:55:66",
385404
mac_address="11:22:33:44:55:66",
386405
last_ip="172.217.22.10",
387406
)
407+
with self.assertNumQueries(8):
408+
manage_estimated_locations(device2.pk, device2.last_ip)
388409

389410
self.assertEqual(
390411
device1.devicelocation.location.pk, device2.devicelocation.location.pk
@@ -400,15 +421,20 @@ def _verify_location_details(device, mocked_response):
400421
):
401422
Device.objects.all().delete()
402423
device1 = self._create_device(last_ip="172.217.22.10")
424+
manage_estimated_locations(device1.pk, device1.last_ip)
403425
device2 = self._create_device(
404426
name="11:22:33:44:55:66",
405427
mac_address="11:22:33:44:55:66",
406428
last_ip="172.217.22.11",
407429
)
430+
manage_estimated_locations(device2.pk, device2.last_ip)
408431
mock_info.reset_mock()
409432
old_location = device2.devicelocation.location
410433
device2.last_ip = "172.217.22.10"
411434
device2.save()
435+
# 3 queries related to notifications cleanup
436+
with self.assertNumQueries(16):
437+
manage_estimated_locations(device2.pk, device2.last_ip)
412438
mock_info.assert_called_once_with(
413439
f"Estimated location saved successfully for {device2.pk}"
414440
f" for IP: {device2.last_ip}"
@@ -427,17 +453,21 @@ def _verify_location_details(device, mocked_response):
427453
):
428454
Device.objects.all().delete()
429455
device1 = self._create_device(last_ip="172.217.22.10")
456+
manage_estimated_locations(device1.pk, device1.last_ip)
430457
device2 = self._create_device(
431458
name="11:22:33:44:55:66",
432459
mac_address="11:22:33:44:55:66",
433460
last_ip="172.217.22.11",
434461
)
462+
manage_estimated_locations(device2.pk, device2.last_ip)
435463
mock_info.reset_mock()
436464
old_location = device2.devicelocation.location
437465
old_location.is_estimated = False
438466
old_location.save()
439467
device2.last_ip = "172.217.22.10"
440468
device2.save()
469+
with self.assertNumQueries(2):
470+
manage_estimated_locations(device2.pk, device2.last_ip)
441471
mock_info.assert_called_once_with(
442472
f"Non Estimated location already set for {device2.pk}. Update"
443473
f" location manually as per IP: {device2.last_ip}"
@@ -456,17 +486,21 @@ def _verify_location_details(device, mocked_response):
456486
):
457487
Device.objects.all().delete()
458488
device1 = self._create_device(last_ip="172.217.22.10")
489+
manage_estimated_locations(device1.pk, device1.last_ip)
459490
device2 = self._create_device(
460491
name="11:22:33:44:55:66",
461492
mac_address="11:22:33:44:55:66",
462493
last_ip="172.217.22.10",
463494
)
495+
manage_estimated_locations(device2.pk, device2.last_ip)
464496
mock_info.reset_mock()
465497
self.assertEqual(
466498
device1.devicelocation.location.pk, device2.devicelocation.location.pk
467499
)
468500
device2.last_ip = "172.217.22.11"
469501
device2.save()
502+
with self.assertNumQueries(14):
503+
manage_estimated_locations(device2.pk, device2.last_ip)
470504
mock_info.assert_called_once_with(
471505
f"Estimated location saved successfully for {device2.pk}"
472506
f" for IP: {device2.last_ip}"

0 commit comments

Comments
 (0)