Skip to content

Commit f20b597

Browse files
committed
[tests] Added tests for WHOIS creation #1034
Added tests for checking if `fetch_whois_details` task is called properly or not, and for checking creation of WHOIS record for a device if the last_ip recorded is public. As now whois record is also fetched whenever fetching a device, there is an increase in query count in some of the tests. Closes #1034 Signed-off-by: Aman Jagotra <[email protected]>
1 parent cb3ee3d commit f20b597

File tree

4 files changed

+82
-11
lines changed

4 files changed

+82
-11
lines changed

openwisp_controller/config/base/device.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,8 @@ def _check_changed_fields(self):
308308
self._get_initial_values_for_checked_fields()
309309
# Execute method for checked for each field in self._changed_checked_fields
310310
for field in self._changed_checked_fields:
311-
getattr(self, f'_check_{field}_changed')()
311+
if hasattr(self, f'_check_{field}_changed'):
312+
getattr(self, f'_check_{field}_changed')()
312313

313314
def _is_deferred(self, field):
314315
"""
@@ -377,16 +378,20 @@ def trigger_whois_lookup(self):
377378
"""Trigger WHOIS lookup if the last IP has changed and is public IP."""
378379
from ipaddress import ip_address
379380

380-
from .. import tasks
381+
from ..tasks import fetch_whois_details
381382

382383
if self._initial_last_ip == models.DEFERRED:
383384
return
384385
# Trigger fetch WHOIS lookup if it does not exist
385386
# or if the last IP has changed and is a public IP
386387
if (
387-
not hasattr(self, 'whoisinfo') or self.last_ip != self._initial_last_ip
388-
) and ip_address(self.last_ip).is_global:
389-
tasks.fetch_whois_details.delay(self.pk, self.last_ip)
388+
(not hasattr(self, 'whois_info') or self.last_ip != self._initial_last_ip)
389+
and self.last_ip
390+
and ip_address(self.last_ip).is_global
391+
):
392+
transaction.on_commit(
393+
lambda: fetch_whois_details.delay(device_pk=self.pk, ip=self.last_ip)
394+
)
390395

391396
self._initial_last_ip = self.last_ip
392397

openwisp_controller/config/tests/test_controller.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ def test_get_cached_checksum(self):
195195
self.assertEqual(mocked_view_debug.call_count, 1)
196196

197197
with self.subTest('update_last_ip updates the cache'):
198-
with self.assertNumQueries(3):
198+
with self.assertNumQueries(4):
199199
with patch.object(
200200
controller_views_logger, 'debug'
201201
) as mocked_view_debug:
@@ -1314,12 +1314,12 @@ def test_ip_fields_not_duplicated(self):
13141314
c2 = self._create_config(device=d2)
13151315
org2 = self._create_org(name='org2', shared_secret='123456')
13161316
c3 = self._create_config(organization=org2)
1317-
with self.assertNumQueries(7):
1317+
with self.assertNumQueries(8):
13181318
self.client.get(
13191319
reverse('controller:device_checksum', args=[c3.device.pk]),
13201320
{'key': c3.device.key, 'management_ip': '192.168.1.99'},
13211321
)
1322-
with self.assertNumQueries(7):
1322+
with self.assertNumQueries(8):
13231323
self.client.get(
13241324
reverse('controller:device_checksum', args=[c1.device.pk]),
13251325
{'key': c1.device.key, 'management_ip': '192.168.1.99'},
@@ -1332,7 +1332,7 @@ def test_ip_fields_not_duplicated(self):
13321332
)
13331333
# triggers more queries because devices with conflicting addresses
13341334
# need to be updated, luckily it does not happen often
1335-
with self.assertNumQueries(9):
1335+
with self.assertNumQueries(11):
13361336
self.client.get(
13371337
reverse('controller:device_checksum', args=[c2.device.pk]),
13381338
{'key': c2.device.key, 'management_ip': '192.168.1.99'},
@@ -1361,14 +1361,14 @@ def test_organization_shares_management_ip_address_space(self):
13611361
org1_config = self._create_config(organization=org1)
13621362
org2 = self._create_org(name='org2', shared_secret='org2')
13631363
org2_config = self._create_config(organization=org2)
1364-
with self.assertNumQueries(7):
1364+
with self.assertNumQueries(8):
13651365
self.client.get(
13661366
reverse('controller:device_checksum', args=[org1_config.device_id]),
13671367
{'key': org1_config.device.key, 'management_ip': '192.168.1.99'},
13681368
)
13691369
# Device from another organization sends conflicting management IP
13701370
# Extra queries due to conflict resolution
1371-
with self.assertNumQueries(9):
1371+
with self.assertNumQueries(11):
13721372
self.client.get(
13731373
reverse('controller:device_checksum', args=[org2_config.device_id]),
13741374
{'key': org2_config.device.key, 'management_ip': '192.168.1.99'},

openwisp_controller/config/tests/test_device.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,8 @@ def test_device_field_changed_checks(self):
524524
device.management_ip = '10.0.0.1'
525525
device.group_id = device_group.id
526526
device.organization_id = self._create_org().id
527+
# assigning a random ip to last_ip
528+
device.last_ip = '172.217.22.14'
527529
# Another query is generated due to "config.set_status_modified"
528530
# on name change
529531
with self.assertNumQueries(3):
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
from unittest import mock
2+
3+
from django.test import TransactionTestCase
4+
from swapper import load_model
5+
6+
from ..tasks import fetch_whois_details
7+
from .utils import CreateDeviceMixin
8+
9+
Device = load_model('config', 'Device')
10+
WHOISInfo = load_model('config', 'WHOISInfo')
11+
12+
13+
class TestWHOISInfo(CreateDeviceMixin, TransactionTestCase):
14+
@mock.patch.object(fetch_whois_details, 'delay')
15+
def test_task_called(self, mocked_task):
16+
with self.subTest('task called when last_ip is public'):
17+
device = self._create_device(last_ip='172.217.22.14')
18+
mocked_task.assert_called()
19+
mocked_task.reset_mock()
20+
21+
with self.subTest('task not called when last_ip is private'):
22+
device.last_ip = '10.0.0.1'
23+
device.save()
24+
mocked_task.assert_not_called()
25+
mocked_task.reset_mock()
26+
27+
with self.subTest('task not called when last_ip is not changed'):
28+
device.last_ip = '10.0.0.1'
29+
device.save()
30+
mocked_task.assert_not_called()
31+
mocked_task.reset_mock()
32+
33+
def test_whois_info_creation(self):
34+
# mocking the geoip2 client to return a mock response
35+
with mock.patch(
36+
'openwisp_controller.config.tasks.geoip2.webservice.Client'
37+
) as mock_client:
38+
# mocking the response from the geoip2 client
39+
mock_response = mock.MagicMock()
40+
mock_response.city.name = 'Mountain View'
41+
mock_response.country.name = 'United States'
42+
mock_response.continent.name = 'North America'
43+
mock_response.postal.code = '94043'
44+
mock_response.traits.autonomous_system_organization = 'Google LLC'
45+
mock_response.traits.autonomous_system_number = 15169
46+
mock_response.traits.network = '172.217.22.0/24'
47+
mock_response.location.time_zone = 'America/Los_Angeles'
48+
mock_client.return_value.city.return_value = mock_response
49+
50+
# creating a device with a last public IP
51+
device = self._create_device(last_ip='172.217.22.14')
52+
device.refresh_from_db()
53+
54+
# fetching the WHOIS info for the device
55+
whois_info = device.whois_info
56+
self.assertEqual(whois_info.organization_name, 'Google LLC')
57+
self.assertEqual(whois_info.asn, '15169')
58+
self.assertEqual(whois_info.country, 'United States')
59+
self.assertEqual(whois_info.timezone, 'America/Los_Angeles')
60+
self.assertEqual(
61+
whois_info.address, 'Mountain View, United States, North America, 94043'
62+
)
63+
self.assertEqual(whois_info.cidr, '172.217.22.0/24')
64+
self.assertEqual(whois_info.last_public_ip, '172.217.22.14')

0 commit comments

Comments
 (0)