|
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