|
4 | 4 | import time |
5 | 5 | from datetime import timedelta |
6 | 6 | from typing import Any |
7 | | -from unittest.mock import ANY, patch |
| 7 | +from unittest.mock import ANY, AsyncMock, Mock, patch |
8 | 8 |
|
9 | 9 | import pytest |
10 | 10 | from bleak_retry_connector import AllocationChange, Allocations, BleakSlotManager |
@@ -1328,3 +1328,81 @@ class TestBluetoothManager2(BluetoothManager): |
1328 | 1328 |
|
1329 | 1329 | TestBluetoothManager2(bluetooth_adapters, slot_manager) |
1330 | 1330 | assert "does not implement _discover_service_info" in caplog.text |
| 1331 | + |
| 1332 | + |
| 1333 | +@pytest.mark.asyncio |
| 1334 | +async def test_is_operating_degraded_on_linux_with_mgmt() -> None: |
| 1335 | + """Test is_operating_degraded returns False on Linux with mgmt control.""" |
| 1336 | + mock_bluetooth_adapters = FakeBluetoothAdapters() |
| 1337 | + manager = BluetoothManager( |
| 1338 | + mock_bluetooth_adapters, |
| 1339 | + slot_manager=Mock(), |
| 1340 | + ) |
| 1341 | + |
| 1342 | + with ( |
| 1343 | + patch("habluetooth.manager.IS_LINUX", True), |
| 1344 | + patch.object(manager, "_mgmt_ctl", Mock()), |
| 1345 | + ): |
| 1346 | + # Mock mgmt_ctl being available |
| 1347 | + assert manager.is_operating_degraded() is False |
| 1348 | + |
| 1349 | + |
| 1350 | +@pytest.mark.asyncio |
| 1351 | +async def test_is_operating_degraded_on_linux_without_mgmt() -> None: |
| 1352 | + """Test is_operating_degraded returns True on Linux without mgmt control.""" |
| 1353 | + mock_bluetooth_adapters = FakeBluetoothAdapters() |
| 1354 | + manager = BluetoothManager( |
| 1355 | + mock_bluetooth_adapters, |
| 1356 | + slot_manager=Mock(), |
| 1357 | + ) |
| 1358 | + |
| 1359 | + with patch("habluetooth.manager.IS_LINUX", True): |
| 1360 | + # mgmt_ctl is None by default |
| 1361 | + assert manager._mgmt_ctl is None |
| 1362 | + assert manager.is_operating_degraded() is True |
| 1363 | + |
| 1364 | + |
| 1365 | +@pytest.mark.asyncio |
| 1366 | +async def test_is_operating_degraded_on_non_linux() -> None: |
| 1367 | + """Test is_operating_degraded returns False on non-Linux systems.""" |
| 1368 | + mock_bluetooth_adapters = FakeBluetoothAdapters() |
| 1369 | + manager = BluetoothManager( |
| 1370 | + mock_bluetooth_adapters, |
| 1371 | + slot_manager=Mock(), |
| 1372 | + ) |
| 1373 | + |
| 1374 | + with patch("habluetooth.manager.IS_LINUX", False): |
| 1375 | + # Should return False regardless of mgmt_ctl state |
| 1376 | + assert manager.is_operating_degraded() is False |
| 1377 | + |
| 1378 | + # Even with mgmt_ctl set |
| 1379 | + manager._mgmt_ctl = Mock() |
| 1380 | + assert manager.is_operating_degraded() is False |
| 1381 | + |
| 1382 | + |
| 1383 | +@pytest.mark.asyncio |
| 1384 | +async def test_is_operating_degraded_after_permission_error() -> None: |
| 1385 | + """Test is_operating_degraded after mgmt setup fails with permission error.""" |
| 1386 | + mock_bluetooth_adapters = FakeBluetoothAdapters() |
| 1387 | + manager = BluetoothManager( |
| 1388 | + mock_bluetooth_adapters, |
| 1389 | + slot_manager=Mock(), |
| 1390 | + ) |
| 1391 | + |
| 1392 | + with ( |
| 1393 | + patch("habluetooth.manager.IS_LINUX", True), |
| 1394 | + patch("habluetooth.manager.MGMTBluetoothCtl") as mock_mgmt_class, |
| 1395 | + ): |
| 1396 | + # Make setup fail with permission error |
| 1397 | + mock_mgmt_instance = Mock() |
| 1398 | + mock_mgmt_instance.setup = AsyncMock( |
| 1399 | + side_effect=PermissionError("No permission") |
| 1400 | + ) |
| 1401 | + mock_mgmt_class.return_value = mock_mgmt_instance |
| 1402 | + |
| 1403 | + # Setup should handle the error and set mgmt_ctl to None |
| 1404 | + await manager.async_setup() |
| 1405 | + |
| 1406 | + # Should be in degraded mode |
| 1407 | + assert manager._mgmt_ctl is None |
| 1408 | + assert manager.is_operating_degraded() is True |
0 commit comments