Skip to content

Commit 71da915

Browse files
committed
[req-change] Simplified code
1 parent 21002f3 commit 71da915

File tree

5 files changed

+67
-84
lines changed

5 files changed

+67
-84
lines changed

openwisp_controller/config/base/device.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -437,10 +437,14 @@ def get_temp_config_instance(self, **options):
437437

438438
def should_skip_push_update(self):
439439
"""
440-
Returns True if the device should skip push update.
441-
Can be overridden with custom logic if needed.
440+
Check if push update should be skipped for this device.
441+
442+
Clears the skip flag after reading it.
442443
"""
443-
return getattr(self, "_skip_push_update", False)
444+
result = getattr(self, "_skip_push_update", False)
445+
if result:
446+
delattr(self, "_skip_push_update")
447+
return result
444448

445449
def skip_push_update_on_save(self):
446450
"""
@@ -450,14 +454,6 @@ def skip_push_update_on_save(self):
450454
"""
451455
self._skip_push_update = True
452456

453-
def clear_skip_push_update(self):
454-
"""
455-
Clears the skip push update flag.
456-
This should be called after the flag has been checked and consumed.
457-
"""
458-
if hasattr(self, "_skip_push_update"):
459-
delattr(self, "_skip_push_update")
460-
461457
def can_be_updated(self):
462458
"""
463459
returns True if the device can and should be updated

openwisp_controller/config/controller/views.py

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ class DeviceRegisterView(UpdateLastIpMixin, CsrfExtemptMixin, View):
289289
model = Device
290290
org_config_settings_model = OrganizationConfigSettings
291291

292-
UPDATABLE_FIELDS = ["os", "model", "system"]
292+
UPDATABLE_FIELDS = ["name", "os", "model", "system"]
293293

294294
def init_object(self, **kwargs):
295295
"""
@@ -405,11 +405,13 @@ def post(self, request, *args, **kwargs):
405405
# update hw info
406406
for attr in self.UPDATABLE_FIELDS:
407407
if attr in request.POST:
408+
if attr == "name":
409+
if self._should_update_hostname(request, device):
410+
device.skip_push_update_on_save()
411+
else:
412+
# Don't update Device.name
413+
continue
408414
setattr(device, attr, request.POST.get(attr))
409-
# update hostname if it's not a default/generic value
410-
if self._should_update_hostname(request, device):
411-
device.name = request.POST.get("name")
412-
device.skip_push_update_on_save()
413415
config = device.config
414416
# if get queryset fails, instantiate a new Device and Config
415417
except self.model.DoesNotExist:
@@ -470,24 +472,15 @@ def _should_update_hostname(self, request, device):
470472
471473
This prevents overwriting user configured hostnames with default/generic values.
472474
"""
473-
if "name" not in request.POST:
474-
return False
475-
476475
name = request.POST.get("name")
477476
mac_address = device.mac_address
478-
# normalize MAC address format (strip colons/dashes and lowercase)
479477
normalized_mac = (
480478
mac_address.replace(":", "").replace("-", "").lower()
481479
if mac_address
482480
else None
483481
)
484-
# normalize hostname for comparison
485482
normalized_name = name.replace(":", "").replace("-", "").lower()
486-
# don't update if hostname equals the MAC address
487-
if normalized_name == normalized_mac:
488-
return False
489-
490-
return True
483+
return normalized_name != normalized_mac
491484

492485

493486
class GetVpnView(SingleObjectMixin, View):

openwisp_controller/config/tests/test_controller.py

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from django.core.exceptions import ValidationError
66
from django.http.response import Http404
77
from django.test import TestCase
8-
from django.urls import reverse
8+
from django.urls import reverse, reverse_lazy
99
from swapper import load_model
1010

1111
from openwisp_utils.tests import capture_any_output, catch_signal
@@ -38,13 +38,8 @@
3838
Organization = load_model("openwisp_users", "Organization")
3939

4040

41-
class TestController(CreateConfigTemplateMixin, TestVpnX509Mixin, TestCase):
42-
"""
43-
tests for config.controller
44-
"""
45-
46-
def setUp(self):
47-
self.register_url = reverse("controller:device_register")
41+
class TestControllerMixin:
42+
register_url = reverse_lazy("controller:device_register")
4843

4944
def _create_org(self, shared_secret=TEST_ORG_SHARED_SECRET, **kwargs):
5045
org = super()._create_org(**kwargs)
@@ -53,6 +48,27 @@ def _create_org(self, shared_secret=TEST_ORG_SHARED_SECRET, **kwargs):
5348
)
5449
return org
5550

51+
def _get_reregistration_payload(self, device, **kwargs):
52+
data = {
53+
"secret": str(device.organization.config_settings.shared_secret),
54+
"key": TEST_CONSISTENT_KEY,
55+
"mac_address": device.mac_address,
56+
"backend": "netjsonconfig.OpenWrt",
57+
"model": "TP-Link TL-WDR4300 v2",
58+
"os": "OpenWrt 18.06-SNAPSHOT r7312-e60be11330",
59+
"system": "Atheros AR9344 rev 3",
60+
}
61+
data.update(**kwargs)
62+
return data
63+
64+
65+
class TestController(
66+
TestControllerMixin, CreateConfigTemplateMixin, TestVpnX509Mixin, TestCase
67+
):
68+
"""
69+
tests for config.controller
70+
"""
71+
5672
def _check_header(self, response):
5773
self.assertEqual(response["X-Openwisp-Controller"], "true")
5874

@@ -820,7 +836,8 @@ def test_device_registration_update_hw_info_no_config(self):
820836
self.assertEqual(d.system, params["system"])
821837
self.assertEqual(d.model, params["model"])
822838

823-
def test_device_registration_update_hostname(self):
839+
@patch.object(Device, 'skip_push_update_on_save')
840+
def test_device_registration_update_hostname(self, mocked_method):
824841
"""
825842
Test that hostname is updated when the name in payload
826843
is not the MAC address stored in OpenWISP
@@ -832,21 +849,16 @@ def test_device_registration_update_hostname(self):
832849
"key": TEST_CONSISTENT_KEY,
833850
}
834851
)
835-
params = {
836-
"secret": TEST_ORG_SHARED_SECRET,
837-
"name": "new-custom-hostname",
838-
"mac_address": TEST_MACADDR,
839-
"key": TEST_CONSISTENT_KEY,
840-
"backend": "netjsonconfig.OpenWrt",
841-
"model": "TP-Link TL-WDR4300 v2",
842-
"os": "OpenWrt 18.06-SNAPSHOT r7312-e60be11330",
843-
"system": "Atheros AR9344 rev 3",
844-
}
852+
params = self._get_reregistration_payload(
853+
device=device,
854+
name="new-custom-hostname",
855+
)
845856
self.assertNotEqual(device.name, params["name"])
846857
response = self.client.post(self.register_url, params)
847858
self.assertEqual(response.status_code, 201)
848859
device.refresh_from_db()
849860
self.assertEqual(device.name, "new-custom-hostname")
861+
mocked_method.assert_called_once()
850862

851863
def test_device_registration_hostname_not_updated_when_mac_address(self):
852864
"""
@@ -860,16 +872,10 @@ def test_device_registration_hostname_not_updated_when_mac_address(self):
860872
"key": TEST_CONSISTENT_KEY,
861873
}
862874
)
863-
params = {
864-
"secret": TEST_ORG_SHARED_SECRET,
865-
"name": TEST_MACADDR,
866-
"mac_address": TEST_MACADDR,
867-
"key": TEST_CONSISTENT_KEY,
868-
"backend": "netjsonconfig.OpenWrt",
869-
"model": "TP-Link TL-WDR4300 v2",
870-
"os": "OpenWrt 18.06-SNAPSHOT r7312-e60be11330",
871-
"system": "Atheros AR9344 rev 3",
872-
}
875+
params = self._get_reregistration_payload(
876+
device=device,
877+
name=TEST_MACADDR,
878+
)
873879
response = self.client.post(self.register_url, params)
874880
self.assertEqual(response.status_code, 201)
875881
device.refresh_from_db()
@@ -881,25 +887,22 @@ def test_device_registration_hostname_comparison_case_insensitive(self):
881887
with different formats (colons, dashes, no separators)
882888
"""
883889
mac_address = "00:11:22:33:aa:BB"
884-
d = self._create_device_config(
890+
device = self._create_device_config(
885891
device_opts={
886892
"mac_address": mac_address,
887893
"name": "configured-hostname",
888894
"key": TEST_CONSISTENT_KEY,
889895
}
890896
)
891-
params = {
892-
"secret": TEST_ORG_SHARED_SECRET,
893-
"name": "00-11-22-33-AA-bb",
894-
"mac_address": mac_address,
895-
"key": TEST_CONSISTENT_KEY,
896-
"backend": "netjsonconfig.OpenWrt",
897-
}
897+
params = self._get_reregistration_payload(
898+
device=device,
899+
name="00-11-22-33-aa-bb",
900+
)
898901
response = self.client.post(self.register_url, params)
899902
self.assertEqual(response.status_code, 201)
900-
d.refresh_from_db()
903+
device.refresh_from_db()
901904
# Hostname should not be changed
902-
self.assertEqual(d.name, "configured-hostname")
905+
self.assertEqual(device.name, "configured-hostname")
903906

904907
def test_device_report_status_running(self):
905908
"""

openwisp_controller/connection/apps.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ def _launch_update_config(cls, device):
9090

9191
# Check if push update should be skipped
9292
if device.should_skip_push_update():
93-
device.clear_skip_push_update()
9493
return
9594
update_config.delay(str(device.pk))
9695

openwisp_controller/connection/tests/test_tasks.py

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55

66
from celery.exceptions import SoftTimeLimitExceeded
77
from django.test import TestCase, TransactionTestCase
8-
from django.urls import reverse
98
from swapper import load_model
109

10+
from ...config.tests.test_controller import TestControllerMixin
1111
from .. import tasks
1212
from .utils import CreateConnectionsMixin
1313

@@ -89,28 +89,20 @@ def test_launch_command_exception(self, *args):
8989
self.assertEqual(command.output, "Internal system error: test error\n")
9090

9191

92-
class TestTransactionTasks(CreateConnectionsMixin, TransactionTestCase):
92+
class TestTransactionTasks(
93+
TestControllerMixin, CreateConnectionsMixin, TransactionTestCase
94+
):
9395
@mock.patch.object(tasks.update_config, "delay")
9496
def test_update_config_hostname_changed_on_reregister(self, mocked_update_config):
95-
org = self._get_org()
96-
config_settings = OrganizationConfigSettings.objects.create(
97-
organization=org, context={}, shared_secret="secret"
98-
)
99-
device = self._create_device(
100-
name="AA-BB-CC-DD-EE-FF", organization=org, key="test-key"
101-
)
102-
self._create_config(device=device)
97+
device = self._create_device_config()
10398
self._create_device_connection(device=device)
10499
# Trigger re-registration with new hostname
105100
response = self.client.post(
106-
reverse("controller:device_register"),
107-
{
108-
"name": "new-hostname",
109-
"secret": str(config_settings.shared_secret),
110-
"key": str(device.key),
111-
"mac_address": device.mac_address,
112-
"backend": "netjsonconfig.OpenWrt",
113-
},
101+
self.register_url,
102+
self._get_reregistration_payload(
103+
device,
104+
name="new-hostname",
105+
),
114106
)
115107
self.assertEqual(response.status_code, 201)
116108
mocked_update_config.assert_not_called()

0 commit comments

Comments
 (0)