Skip to content

Commit 741148f

Browse files
committed
[tests] Strengthened concurrent-guard test and added WebSocket push-path coverage for pending #423
- The mixed-success+pending concurrent-guard subtest now drives UpgradeOperation.upgrade() directly (with DeviceConnection.get_working_connection mocked to bypass the network) and asserts the new op transitions to status="aborted" with the expected log line, rather than only verifying the queryset filter - New test_pending_transition_publishes_batch_status_with_pending_count covers the push path: it connects a BatchUpgradeProgressConsumer, transitions a child op to pending via save, and asserts the post_save -> BatchUpgradeProgressPublisher.update_batch_status -> publish_batch_status chain emits a batch_status payload with pending=1, completed=0 and the batch staying at in-progress Related to #423
1 parent 58be29a commit 741148f

2 files changed

Lines changed: 48 additions & 9 deletions

File tree

openwisp_firmware_upgrader/tests/test_models.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -878,15 +878,17 @@ def test_batch_with_mixed_success_and_pending_children(self):
878878
batch=batch,
879879
status="in-progress",
880880
)
881-
blocking = (
882-
UpgradeOperation.objects.filter(
883-
device=device_fw.device,
884-
status__in=("in-progress", "pending"),
885-
)
886-
.exclude(pk=new_op.pk)
887-
.values_list("pk", flat=True)
888-
)
889-
self.assertIn(still_pending.pk, list(blocking))
881+
with mock.patch(
882+
"openwisp_controller.connection.models.DeviceConnection."
883+
"get_working_connection",
884+
return_value=mock.MagicMock(),
885+
):
886+
new_op.upgrade()
887+
new_op.refresh_from_db()
888+
self.assertEqual(new_op.status, "aborted")
889+
self.assertIn("Another upgrade operation is in progress", new_op.log)
890+
still_pending.refresh_from_db()
891+
self.assertEqual(still_pending.status, "pending")
890892

891893
def test_pending_count_property(self):
892894
device_fw = self._create_device_firmware()

openwisp_firmware_upgrader/tests/test_websockets.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,3 +748,40 @@ async def test_device_consumer_snapshot_includes_pending(self, *args):
748748
self.assertEqual(response["type"], "operation_update")
749749
self.assertEqual(response["operation"]["status"], "pending")
750750
await communicator.disconnect()
751+
752+
@patch(_mock_upgrade, return_value=True)
753+
@patch(_mock_connect, return_value=True)
754+
async def test_pending_transition_publishes_batch_status_with_pending_count(
755+
self, *args
756+
):
757+
build = await sync_to_async(self._get_build)()
758+
device_fw = await sync_to_async(self._create_device_firmware)()
759+
batch = await sync_to_async(BatchUpgradeOperation.objects.create)(
760+
build=build, is_persistent=True, status="in-progress"
761+
)
762+
op = await sync_to_async(UpgradeOperation.objects.create)(
763+
device=device_fw.device,
764+
image=device_fw.image,
765+
batch=batch,
766+
status="in-progress",
767+
is_persistent=True,
768+
)
769+
communicator = await self._get_batch_upgrade_progress_communicator(
770+
str(batch.pk)
771+
)
772+
op.status = "pending"
773+
await sync_to_async(op.save)()
774+
batch_status = None
775+
for _ in range(10):
776+
response = await asyncio.wait_for(
777+
communicator.receive_json_from(), timeout=1
778+
)
779+
if response.get("type") == "batch_status":
780+
batch_status = response
781+
break
782+
self.assertIsNotNone(batch_status)
783+
self.assertEqual(batch_status["status"], "in-progress")
784+
self.assertEqual(batch_status["pending"], 1)
785+
self.assertEqual(batch_status["completed"], 0)
786+
self.assertEqual(batch_status["total"], 1)
787+
await communicator.disconnect()

0 commit comments

Comments
 (0)