|
1 | 1 | """Tests for API.""" |
2 | 2 |
|
3 | 3 | import asyncio |
| 4 | +from unittest import mock |
4 | 5 |
|
5 | 6 | import pytest |
6 | | -import serial |
7 | 7 | import zigpy.config |
8 | 8 | import zigpy.exceptions |
9 | 9 | import zigpy.types as t |
10 | 10 |
|
11 | | -from zigpy_xbee import api as xbee_api, types as xbee_t, uart |
| 11 | +from zigpy_xbee import api as xbee_api, types as xbee_t |
12 | 12 | from zigpy_xbee.exceptions import ATCommandError, ATCommandException, InvalidCommand |
13 | 13 | from zigpy_xbee.zigbee.application import ControllerApplication |
14 | 14 |
|
15 | | -import tests.async_mock as mock |
16 | | - |
17 | 15 | DEVICE_CONFIG = zigpy.config.SCHEMA_DEVICE( |
18 | 16 | { |
19 | 17 | zigpy.config.CONF_DEVICE_PATH: "/dev/null", |
|
26 | 24 | def api(): |
27 | 25 | """Sample XBee API fixture.""" |
28 | 26 | api = xbee_api.XBee(DEVICE_CONFIG) |
29 | | - api._uart = mock.MagicMock() |
| 27 | + api._uart = mock.AsyncMock() |
30 | 28 | return api |
31 | 29 |
|
32 | 30 |
|
33 | | -async def test_connect(monkeypatch): |
| 31 | +async def test_connect(): |
34 | 32 | """Test connect.""" |
35 | 33 | api = xbee_api.XBee(DEVICE_CONFIG) |
36 | | - monkeypatch.setattr(uart, "connect", mock.AsyncMock()) |
37 | | - await api.connect() |
| 34 | + api._command = mock.AsyncMock(spec=api._command) |
| 35 | + |
| 36 | + with mock.patch("zigpy_xbee.uart.connect"): |
| 37 | + await api.connect() |
| 38 | + |
| 39 | + |
| 40 | +async def test_connect_initial_timeout_success(): |
| 41 | + """Test connect, initial command times out.""" |
| 42 | + api = xbee_api.XBee(DEVICE_CONFIG) |
| 43 | + api._at_command = mock.AsyncMock(side_effect=asyncio.TimeoutError) |
| 44 | + api.init_api_mode = mock.AsyncMock(return_value=True) |
| 45 | + |
| 46 | + with mock.patch("zigpy_xbee.uart.connect"): |
| 47 | + await api.connect() |
| 48 | + |
| 49 | + |
| 50 | +async def test_connect_initial_timeout_failure(): |
| 51 | + """Test connect, initial command times out.""" |
| 52 | + api = xbee_api.XBee(DEVICE_CONFIG) |
| 53 | + api._at_command = mock.AsyncMock(side_effect=asyncio.TimeoutError) |
| 54 | + api.init_api_mode = mock.AsyncMock(return_value=False) |
| 55 | + |
| 56 | + with mock.patch("zigpy_xbee.uart.connect") as mock_connect: |
| 57 | + with pytest.raises(zigpy.exceptions.APIException): |
| 58 | + await api.connect() |
38 | 59 |
|
| 60 | + assert mock_connect.return_value.disconnect.mock_calls == [mock.call()] |
39 | 61 |
|
40 | | -def test_close(api): |
| 62 | + |
| 63 | +async def test_disconnect(api): |
41 | 64 | """Test connection close.""" |
42 | 65 | uart = api._uart |
43 | | - api.close() |
| 66 | + await api.disconnect() |
44 | 67 |
|
45 | 68 | assert api._uart is None |
46 | | - assert uart.close.call_count == 1 |
| 69 | + assert uart.disconnect.call_count == 1 |
47 | 70 |
|
48 | 71 |
|
49 | 72 | def test_commands(): |
@@ -599,97 +622,10 @@ def test_handle_many_to_one_rri(api): |
599 | 622 | api._handle_many_to_one_rri(ieee, nwk, 0) |
600 | 623 |
|
601 | 624 |
|
602 | | -@mock.patch.object(xbee_api.XBee, "_at_command", new_callable=mock.AsyncMock) |
603 | | -@mock.patch.object(uart, "connect", return_value=mock.MagicMock()) |
604 | | -async def test_probe_success(mock_connect, mock_at_cmd): |
605 | | - """Test device probing.""" |
606 | | - |
607 | | - res = await xbee_api.XBee.probe(DEVICE_CONFIG) |
608 | | - assert res is True |
609 | | - assert mock_connect.call_count == 1 |
610 | | - assert mock_connect.await_count == 1 |
611 | | - assert mock_connect.call_args[0][0] == DEVICE_CONFIG |
612 | | - assert mock_at_cmd.call_count == 1 |
613 | | - assert mock_connect.return_value.close.call_count == 1 |
614 | | - |
615 | | - |
616 | | -@mock.patch.object(xbee_api.XBee, "init_api_mode", return_value=True) |
617 | | -@mock.patch.object(xbee_api.XBee, "_at_command", side_effect=asyncio.TimeoutError) |
618 | | -@mock.patch.object(uart, "connect", return_value=mock.MagicMock()) |
619 | | -async def test_probe_success_api_mode(mock_connect, mock_at_cmd, mock_api_mode): |
620 | | - """Test device probing.""" |
621 | | - |
622 | | - res = await xbee_api.XBee.probe(DEVICE_CONFIG) |
623 | | - assert res is True |
624 | | - assert mock_connect.call_count == 1 |
625 | | - assert mock_connect.await_count == 1 |
626 | | - assert mock_connect.call_args[0][0] == DEVICE_CONFIG |
627 | | - assert mock_at_cmd.call_count == 1 |
628 | | - assert mock_api_mode.call_count == 1 |
629 | | - assert mock_connect.return_value.close.call_count == 1 |
630 | | - |
631 | | - |
632 | | -@mock.patch.object(xbee_api.XBee, "init_api_mode") |
633 | | -@mock.patch.object(xbee_api.XBee, "_at_command", side_effect=asyncio.TimeoutError) |
634 | | -@mock.patch.object(uart, "connect", return_value=mock.MagicMock()) |
635 | | -@pytest.mark.parametrize( |
636 | | - "exception", |
637 | | - (asyncio.TimeoutError, serial.SerialException, zigpy.exceptions.APIException), |
638 | | -) |
639 | | -async def test_probe_fail(mock_connect, mock_at_cmd, mock_api_mode, exception): |
640 | | - """Test device probing fails.""" |
641 | | - |
642 | | - mock_api_mode.side_effect = exception |
643 | | - mock_api_mode.reset_mock() |
644 | | - mock_at_cmd.reset_mock() |
645 | | - mock_connect.reset_mock() |
646 | | - res = await xbee_api.XBee.probe(DEVICE_CONFIG) |
647 | | - assert res is False |
648 | | - assert mock_connect.call_count == 1 |
649 | | - assert mock_connect.await_count == 1 |
650 | | - assert mock_connect.call_args[0][0] == DEVICE_CONFIG |
651 | | - assert mock_at_cmd.call_count == 1 |
652 | | - assert mock_api_mode.call_count == 1 |
653 | | - assert mock_connect.return_value.close.call_count == 1 |
654 | | - |
655 | | - |
656 | | -@mock.patch.object(xbee_api.XBee, "init_api_mode", return_value=False) |
657 | | -@mock.patch.object(xbee_api.XBee, "_at_command", side_effect=asyncio.TimeoutError) |
658 | | -@mock.patch.object(uart, "connect", return_value=mock.MagicMock()) |
659 | | -async def test_probe_fail_api_mode(mock_connect, mock_at_cmd, mock_api_mode): |
660 | | - """Test device probing fails.""" |
661 | | - |
662 | | - mock_api_mode.reset_mock() |
663 | | - mock_at_cmd.reset_mock() |
664 | | - mock_connect.reset_mock() |
665 | | - res = await xbee_api.XBee.probe(DEVICE_CONFIG) |
666 | | - assert res is False |
667 | | - assert mock_connect.call_count == 1 |
668 | | - assert mock_connect.await_count == 1 |
669 | | - assert mock_connect.call_args[0][0] == DEVICE_CONFIG |
670 | | - assert mock_at_cmd.call_count == 1 |
671 | | - assert mock_api_mode.call_count == 1 |
672 | | - assert mock_connect.return_value.close.call_count == 1 |
673 | | - |
674 | | - |
675 | | -@mock.patch.object(xbee_api.XBee, "connect", return_value=mock.MagicMock()) |
676 | | -async def test_xbee_new(conn_mck): |
677 | | - """Test new class method.""" |
678 | | - api = await xbee_api.XBee.new(mock.sentinel.application, DEVICE_CONFIG) |
679 | | - assert isinstance(api, xbee_api.XBee) |
680 | | - assert conn_mck.call_count == 1 |
681 | | - assert conn_mck.await_count == 1 |
682 | | - |
683 | | - |
684 | | -@mock.patch.object(xbee_api.XBee, "connect", return_value=mock.MagicMock()) |
685 | | -async def test_connection_lost(conn_mck): |
| 625 | +async def test_connection_lost(api): |
686 | 626 | """Test `connection_lost` propagataion.""" |
687 | | - api = await xbee_api.XBee.new(mock.sentinel.application, DEVICE_CONFIG) |
688 | | - await api.connect() |
689 | | - |
690 | | - app = api._app = mock.MagicMock() |
| 627 | + api.set_application(mock.AsyncMock()) |
691 | 628 |
|
692 | 629 | err = RuntimeError() |
693 | 630 | api.connection_lost(err) |
694 | | - |
695 | | - app.connection_lost.assert_called_once_with(err) |
| 631 | + api._app.connection_lost.assert_called_once_with(err) |
0 commit comments