pypck 0.8.10__tar.gz → 0.8.11__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pypck-0.8.10/pypck.egg-info → pypck-0.8.11}/PKG-INFO +1 -1
- pypck-0.8.11/VERSION +1 -0
- pypck-0.8.11/pypck/py.typed +0 -0
- {pypck-0.8.10 → pypck-0.8.11/pypck.egg-info}/PKG-INFO +1 -1
- {pypck-0.8.10 → pypck-0.8.11}/pypck.egg-info/SOURCES.txt +2 -0
- {pypck-0.8.10 → pypck-0.8.11}/pyproject.toml +3 -0
- pypck-0.8.11/tests/test_connection.py +155 -0
- {pypck-0.8.10 → pypck-0.8.11}/tests/test_dyn_text.py +3 -9
- pypck-0.8.11/tests/test_input.py +46 -0
- pypck-0.8.10/VERSION +0 -1
- pypck-0.8.10/tests/test_connection.py +0 -471
- {pypck-0.8.10 → pypck-0.8.11}/LICENSE +0 -0
- {pypck-0.8.10 → pypck-0.8.11}/README.md +0 -0
- {pypck-0.8.10 → pypck-0.8.11}/pypck/__init__.py +0 -0
- {pypck-0.8.10 → pypck-0.8.11}/pypck/connection.py +0 -0
- {pypck-0.8.10 → pypck-0.8.11}/pypck/helpers.py +0 -0
- {pypck-0.8.10 → pypck-0.8.11}/pypck/inputs.py +0 -0
- {pypck-0.8.10 → pypck-0.8.11}/pypck/lcn_addr.py +0 -0
- {pypck-0.8.10 → pypck-0.8.11}/pypck/lcn_defs.py +0 -0
- {pypck-0.8.10 → pypck-0.8.11}/pypck/module.py +0 -0
- {pypck-0.8.10 → pypck-0.8.11}/pypck/pck_commands.py +0 -0
- {pypck-0.8.10 → pypck-0.8.11}/pypck/request_handlers.py +0 -0
- {pypck-0.8.10 → pypck-0.8.11}/pypck/timeout_retry.py +0 -0
- {pypck-0.8.10 → pypck-0.8.11}/pypck.egg-info/dependency_links.txt +0 -0
- {pypck-0.8.10 → pypck-0.8.11}/pypck.egg-info/not-zip-safe +0 -0
- {pypck-0.8.10 → pypck-0.8.11}/pypck.egg-info/top_level.txt +0 -0
- {pypck-0.8.10 → pypck-0.8.11}/setup.cfg +0 -0
- {pypck-0.8.10 → pypck-0.8.11}/tests/test_commands.py +0 -0
- {pypck-0.8.10 → pypck-0.8.11}/tests/test_messages.py +0 -0
- {pypck-0.8.10 → pypck-0.8.11}/tests/test_vars.py +0 -0
pypck-0.8.11/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.8.11
|
|
File without changes
|
|
@@ -11,6 +11,7 @@ pypck/lcn_addr.py
|
|
|
11
11
|
pypck/lcn_defs.py
|
|
12
12
|
pypck/module.py
|
|
13
13
|
pypck/pck_commands.py
|
|
14
|
+
pypck/py.typed
|
|
14
15
|
pypck/request_handlers.py
|
|
15
16
|
pypck/timeout_retry.py
|
|
16
17
|
pypck.egg-info/PKG-INFO
|
|
@@ -21,5 +22,6 @@ pypck.egg-info/top_level.txt
|
|
|
21
22
|
tests/test_commands.py
|
|
22
23
|
tests/test_connection.py
|
|
23
24
|
tests/test_dyn_text.py
|
|
25
|
+
tests/test_input.py
|
|
24
26
|
tests/test_messages.py
|
|
25
27
|
tests/test_vars.py
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"""Connection tests."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
from unittest.mock import AsyncMock, Mock, call, patch
|
|
5
|
+
|
|
6
|
+
import pytest
|
|
7
|
+
|
|
8
|
+
from pypck import inputs
|
|
9
|
+
from pypck.connection import (
|
|
10
|
+
PchkAuthenticationError,
|
|
11
|
+
PchkConnectionFailedError,
|
|
12
|
+
PchkConnectionManager,
|
|
13
|
+
PchkConnectionRefusedError,
|
|
14
|
+
PchkLicenseError,
|
|
15
|
+
)
|
|
16
|
+
from pypck.lcn_defs import LcnEvent
|
|
17
|
+
from pypck.pck_commands import PckGenerator
|
|
18
|
+
|
|
19
|
+
from .conftest import HOST, PASSWORD, PORT, USERNAME, MockPchkConnectionManager
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
async def test_close_without_connect(pypck_client: MockPchkConnectionManager) -> None:
|
|
23
|
+
"""Test closing of PchkConnectionManager without connecting."""
|
|
24
|
+
await pypck_client.async_close()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@patch.object(PchkConnectionManager, "open_connection")
|
|
28
|
+
@patch.object(PchkConnectionManager, "scan_segment_couplers")
|
|
29
|
+
async def test_async_connect(
|
|
30
|
+
mock_scan_segment_couplers: AsyncMock,
|
|
31
|
+
mock_open_connection: AsyncMock,
|
|
32
|
+
) -> None:
|
|
33
|
+
"""Test successful connection."""
|
|
34
|
+
pypck_client = PchkConnectionManager(HOST, PORT, USERNAME, PASSWORD)
|
|
35
|
+
connect_task = asyncio.create_task(pypck_client.async_connect())
|
|
36
|
+
await asyncio.sleep(0)
|
|
37
|
+
|
|
38
|
+
pypck_client.license_error_future.set_result(True)
|
|
39
|
+
pypck_client.authentication_completed_future.set_result(True)
|
|
40
|
+
pypck_client.segment_scan_completed_event.set()
|
|
41
|
+
|
|
42
|
+
await connect_task
|
|
43
|
+
|
|
44
|
+
mock_scan_segment_couplers.assert_awaited()
|
|
45
|
+
mock_open_connection.assert_awaited()
|
|
46
|
+
assert pypck_client.is_ready()
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@patch.object(PchkConnectionManager, "ping")
|
|
50
|
+
@patch.object(PchkConnectionManager, "open_connection")
|
|
51
|
+
@patch.object(PchkConnectionManager, "scan_segment_couplers")
|
|
52
|
+
@patch.object(PchkConnectionManager, "send_command")
|
|
53
|
+
async def test_successful_connection_procedure(
|
|
54
|
+
mock_send_command: AsyncMock,
|
|
55
|
+
mock_scan_segment_couplers: AsyncMock,
|
|
56
|
+
mock_open_connection: AsyncMock,
|
|
57
|
+
mock_ping: AsyncMock,
|
|
58
|
+
) -> None:
|
|
59
|
+
"""Test successful connection procedure."""
|
|
60
|
+
pypck_client = PchkConnectionManager(HOST, PORT, USERNAME, PASSWORD)
|
|
61
|
+
connect_task = asyncio.create_task(pypck_client.async_connect())
|
|
62
|
+
await asyncio.sleep(0)
|
|
63
|
+
|
|
64
|
+
await pypck_client.async_process_input(inputs.AuthUsername())
|
|
65
|
+
mock_send_command.assert_awaited_with(USERNAME, to_host=True)
|
|
66
|
+
|
|
67
|
+
await pypck_client.async_process_input(inputs.AuthPassword())
|
|
68
|
+
mock_send_command.assert_awaited_with(PASSWORD, to_host=True)
|
|
69
|
+
|
|
70
|
+
await pypck_client.async_process_input(inputs.AuthOk())
|
|
71
|
+
mock_send_command.assert_awaited_with(PckGenerator.set_dec_mode(), to_host=True)
|
|
72
|
+
assert pypck_client.authentication_completed_future.result()
|
|
73
|
+
|
|
74
|
+
await pypck_client.async_process_input(inputs.DecModeSet())
|
|
75
|
+
mock_send_command.assert_awaited_with(
|
|
76
|
+
PckGenerator.set_operation_mode(
|
|
77
|
+
pypck_client.dim_mode, pypck_client.status_mode
|
|
78
|
+
),
|
|
79
|
+
to_host=True,
|
|
80
|
+
)
|
|
81
|
+
assert pypck_client.license_error_future.result()
|
|
82
|
+
|
|
83
|
+
await connect_task
|
|
84
|
+
|
|
85
|
+
mock_open_connection.assert_awaited()
|
|
86
|
+
mock_scan_segment_couplers.assert_awaited()
|
|
87
|
+
mock_ping.assert_awaited()
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
@pytest.mark.parametrize("side_effect", [ConnectionRefusedError, OSError])
|
|
91
|
+
async def test_connection_error(side_effect: ConnectionRefusedError | OSError) -> None:
|
|
92
|
+
"""Test connection error."""
|
|
93
|
+
with (
|
|
94
|
+
patch.object(PchkConnectionManager, "open_connection", side_effect=side_effect),
|
|
95
|
+
pytest.raises(PchkConnectionRefusedError),
|
|
96
|
+
):
|
|
97
|
+
pypck_client = PchkConnectionManager(HOST, PORT, USERNAME, PASSWORD)
|
|
98
|
+
await pypck_client.async_connect()
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@patch.object(PchkConnectionManager, "open_connection")
|
|
102
|
+
async def test_authentication_error(mock_open_connection: AsyncMock) -> None:
|
|
103
|
+
"""Test wrong login credentials."""
|
|
104
|
+
pypck_client = PchkConnectionManager(HOST, PORT, USERNAME, PASSWORD)
|
|
105
|
+
connect_task = asyncio.create_task(pypck_client.async_connect())
|
|
106
|
+
await asyncio.sleep(0)
|
|
107
|
+
await pypck_client.async_process_input(inputs.AuthFailed())
|
|
108
|
+
|
|
109
|
+
with (
|
|
110
|
+
pytest.raises(PchkAuthenticationError),
|
|
111
|
+
):
|
|
112
|
+
await connect_task
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@patch.object(PchkConnectionManager, "open_connection")
|
|
116
|
+
async def test_license_error(mock_open_connection: AsyncMock) -> None:
|
|
117
|
+
"""Test wrong login credentials."""
|
|
118
|
+
pypck_client = PchkConnectionManager(HOST, PORT, USERNAME, PASSWORD)
|
|
119
|
+
connect_task = asyncio.create_task(pypck_client.async_connect())
|
|
120
|
+
await asyncio.sleep(0)
|
|
121
|
+
await pypck_client.async_process_input(inputs.LicenseError())
|
|
122
|
+
|
|
123
|
+
with (
|
|
124
|
+
pytest.raises(PchkLicenseError),
|
|
125
|
+
):
|
|
126
|
+
await connect_task
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
@patch.object(PchkConnectionManager, "open_connection")
|
|
130
|
+
async def test_timeout_error(mock_open_connection: AsyncMock) -> None:
|
|
131
|
+
"""Test timeout when connecting."""
|
|
132
|
+
with pytest.raises(PchkConnectionFailedError):
|
|
133
|
+
pypck_client = PchkConnectionManager(HOST, PORT, USERNAME, PASSWORD)
|
|
134
|
+
await pypck_client.async_connect(timeout=0)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
async def test_lcn_connected(pypck_client: MockPchkConnectionManager) -> None:
|
|
138
|
+
"""Test lcn connected events."""
|
|
139
|
+
event_callback = Mock()
|
|
140
|
+
pypck_client.register_for_events(event_callback)
|
|
141
|
+
await pypck_client.async_connect()
|
|
142
|
+
|
|
143
|
+
# bus disconnected
|
|
144
|
+
await pypck_client.async_process_input(inputs.LcnConnState(is_lcn_connected=False))
|
|
145
|
+
assert not pypck_client.is_lcn_connected
|
|
146
|
+
event_callback.assert_has_calls(
|
|
147
|
+
(call(LcnEvent.BUS_CONNECTION_STATUS_CHANGED), call(LcnEvent.BUS_DISCONNECTED))
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
# bus connected
|
|
151
|
+
await pypck_client.async_process_input(inputs.LcnConnState(is_lcn_connected=True))
|
|
152
|
+
assert pypck_client.is_lcn_connected
|
|
153
|
+
event_callback.assert_has_calls(
|
|
154
|
+
(call(LcnEvent.BUS_CONNECTION_STATUS_CHANGED), call(LcnEvent.BUS_CONNECTED))
|
|
155
|
+
)
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
"""Module connection tests."""
|
|
2
2
|
|
|
3
|
-
from unittest.mock import patch
|
|
4
|
-
|
|
5
3
|
import pytest
|
|
6
4
|
|
|
7
5
|
from pypck.lcn_addr import LcnAddr
|
|
8
|
-
from pypck.module import ModuleConnection
|
|
9
6
|
|
|
10
7
|
from .conftest import MockPchkConnectionManager
|
|
11
8
|
|
|
@@ -58,7 +55,6 @@ TEST_VECTORS = {
|
|
|
58
55
|
}
|
|
59
56
|
|
|
60
57
|
|
|
61
|
-
@pytest.mark.asyncio
|
|
62
58
|
@pytest.mark.parametrize("text, parts", TEST_VECTORS.items())
|
|
63
59
|
async def test_dyn_text(
|
|
64
60
|
pypck_client: MockPchkConnectionManager,
|
|
@@ -66,14 +62,12 @@ async def test_dyn_text(
|
|
|
66
62
|
parts: tuple[bytes, bytes, bytes, bytes, bytes],
|
|
67
63
|
) -> None:
|
|
68
64
|
"""Tests for dynamic text."""
|
|
69
|
-
# await pypck_client.async_connect()
|
|
70
65
|
module = pypck_client.get_address_conn(LcnAddr(0, 10, False))
|
|
71
66
|
|
|
72
|
-
|
|
73
|
-
await module.dyn_text(3, text)
|
|
67
|
+
await module.dyn_text(3, text)
|
|
74
68
|
|
|
75
|
-
send_command.assert_awaited()
|
|
76
|
-
await_args = (call.args for call in send_command.await_args_list)
|
|
69
|
+
module.send_command.assert_awaited() # type: ignore[attr-defined]
|
|
70
|
+
await_args = (call.args for call in module.send_command.await_args_list) # type: ignore[attr-defined]
|
|
77
71
|
_, commands = zip(*await_args)
|
|
78
72
|
|
|
79
73
|
for i, part in enumerate(parts):
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""Test the data flow for Input objects."""
|
|
2
|
+
|
|
3
|
+
from unittest.mock import patch
|
|
4
|
+
|
|
5
|
+
from pypck.inputs import Input, ModInput
|
|
6
|
+
from pypck.lcn_addr import LcnAddr
|
|
7
|
+
from pypck.module import ModuleConnection
|
|
8
|
+
|
|
9
|
+
from .conftest import MockPchkConnectionManager
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
async def test_message_to_input(pypck_client: MockPchkConnectionManager) -> None:
|
|
13
|
+
"""Test data flow from message to input."""
|
|
14
|
+
inp = Input()
|
|
15
|
+
message = "dummy_message"
|
|
16
|
+
with patch.object(
|
|
17
|
+
pypck_client, "async_process_input"
|
|
18
|
+
) as pypck_client_process_input:
|
|
19
|
+
with patch("pypck.inputs.InputParser.parse", return_value=[inp]) as inp_parse:
|
|
20
|
+
await pypck_client.process_message(message)
|
|
21
|
+
|
|
22
|
+
inp_parse.assert_called_with(message)
|
|
23
|
+
pypck_client_process_input.assert_awaited_with(inp)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
async def test_physical_to_logical_segment_id(
|
|
27
|
+
pypck_client: MockPchkConnectionManager,
|
|
28
|
+
) -> None:
|
|
29
|
+
"""Test conversion from logical to physical segment id."""
|
|
30
|
+
pypck_client.local_seg_id = 20
|
|
31
|
+
module = pypck_client.get_address_conn(LcnAddr(20, 7, False))
|
|
32
|
+
assert isinstance(module, ModuleConnection)
|
|
33
|
+
with (
|
|
34
|
+
patch("tests.conftest.MockPchkConnectionManager.is_ready", return_value=True),
|
|
35
|
+
patch.object(module, "async_process_input") as module_process_input,
|
|
36
|
+
):
|
|
37
|
+
inp = ModInput(LcnAddr(20, 7, False))
|
|
38
|
+
await pypck_client.async_process_input(inp)
|
|
39
|
+
|
|
40
|
+
inp = ModInput(LcnAddr(0, 7, False))
|
|
41
|
+
await pypck_client.async_process_input(inp)
|
|
42
|
+
|
|
43
|
+
inp = ModInput(LcnAddr(4, 7, False))
|
|
44
|
+
await pypck_client.async_process_input(inp)
|
|
45
|
+
|
|
46
|
+
assert module_process_input.await_count == 3
|
pypck-0.8.10/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0.8.10
|
|
@@ -1,471 +0,0 @@
|
|
|
1
|
-
"""Connection tests."""
|
|
2
|
-
|
|
3
|
-
import asyncio
|
|
4
|
-
import json
|
|
5
|
-
from unittest.mock import Mock, call
|
|
6
|
-
|
|
7
|
-
import pytest
|
|
8
|
-
|
|
9
|
-
from pypck.connection import (
|
|
10
|
-
PchkAuthenticationError,
|
|
11
|
-
PchkConnectionFailedError,
|
|
12
|
-
PchkConnectionRefusedError,
|
|
13
|
-
PchkLicenseError,
|
|
14
|
-
)
|
|
15
|
-
from pypck.lcn_addr import LcnAddr
|
|
16
|
-
from pypck.lcn_defs import LcnEvent
|
|
17
|
-
from pypck.module import ModuleConnection
|
|
18
|
-
|
|
19
|
-
from .conftest import MockPchkConnectionManager
|
|
20
|
-
from .mock_pchk import MockPchkServer
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@pytest.mark.asyncio
|
|
24
|
-
async def test_close_without_connect(pypck_client: MockPchkConnectionManager) -> None:
|
|
25
|
-
"""Test closing of PchkConnectionManager without connecting."""
|
|
26
|
-
await pypck_client.async_close()
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@pytest.mark.asyncio
|
|
30
|
-
async def test_authenticate(
|
|
31
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
32
|
-
) -> None:
|
|
33
|
-
"""Test authentication procedure."""
|
|
34
|
-
await pypck_client.async_connect()
|
|
35
|
-
assert pypck_client.is_ready()
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
@pytest.mark.asyncio
|
|
39
|
-
async def test_port_error(
|
|
40
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
41
|
-
) -> None:
|
|
42
|
-
"""Test wrong port."""
|
|
43
|
-
pypck_client.port = 55555
|
|
44
|
-
with pytest.raises(PchkConnectionRefusedError):
|
|
45
|
-
await pypck_client.async_connect()
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
@pytest.mark.asyncio
|
|
49
|
-
async def test_authentication_error(
|
|
50
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
51
|
-
) -> None:
|
|
52
|
-
"""Test wrong login credentials."""
|
|
53
|
-
pypck_client.password = "wrong_password"
|
|
54
|
-
with pytest.raises(PchkAuthenticationError):
|
|
55
|
-
await pypck_client.async_connect()
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
@pytest.mark.asyncio
|
|
59
|
-
async def test_license_error(
|
|
60
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
61
|
-
) -> None:
|
|
62
|
-
"""Test license error."""
|
|
63
|
-
pchk_server.set_license_error(True)
|
|
64
|
-
|
|
65
|
-
with pytest.raises(PchkLicenseError):
|
|
66
|
-
await pypck_client.async_connect()
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
@pytest.mark.asyncio
|
|
70
|
-
async def test_timeout_error(
|
|
71
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
72
|
-
) -> None:
|
|
73
|
-
"""Test timeout when connecting."""
|
|
74
|
-
with pytest.raises(PchkConnectionFailedError):
|
|
75
|
-
await pypck_client.async_connect(timeout=0)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
@pytest.mark.asyncio
|
|
79
|
-
async def test_lcn_connected(
|
|
80
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
81
|
-
) -> None:
|
|
82
|
-
"""Test lcn disconnected event."""
|
|
83
|
-
event_callback = Mock()
|
|
84
|
-
pypck_client.register_for_events(event_callback)
|
|
85
|
-
await pypck_client.async_connect()
|
|
86
|
-
await pchk_server.send_message("$io:#LCN:connected")
|
|
87
|
-
await pypck_client.received("$io:#LCN:connected")
|
|
88
|
-
|
|
89
|
-
event_callback.assert_has_calls(
|
|
90
|
-
[
|
|
91
|
-
call(LcnEvent.BUS_CONNECTION_STATUS_CHANGED),
|
|
92
|
-
call(LcnEvent.BUS_CONNECTED),
|
|
93
|
-
]
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
@pytest.mark.asyncio
|
|
98
|
-
async def test_lcn_disconnected(
|
|
99
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
100
|
-
) -> None:
|
|
101
|
-
"""Test lcn disconnected event."""
|
|
102
|
-
event_callback = Mock()
|
|
103
|
-
pypck_client.register_for_events(event_callback)
|
|
104
|
-
await pypck_client.async_connect()
|
|
105
|
-
await pchk_server.send_message("$io:#LCN:disconnected")
|
|
106
|
-
await pypck_client.received("$io:#LCN:disconnected")
|
|
107
|
-
|
|
108
|
-
event_callback.assert_has_calls(
|
|
109
|
-
[call(LcnEvent.BUS_CONNECTION_STATUS_CHANGED), call(LcnEvent.BUS_DISCONNECTED)]
|
|
110
|
-
)
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
@pytest.mark.asyncio
|
|
114
|
-
async def test_connection_lost(
|
|
115
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
116
|
-
) -> None:
|
|
117
|
-
"""Test pchk server connection close."""
|
|
118
|
-
event_callback = Mock()
|
|
119
|
-
pypck_client.register_for_events(event_callback)
|
|
120
|
-
await pypck_client.async_connect()
|
|
121
|
-
|
|
122
|
-
await pchk_server.stop()
|
|
123
|
-
# ensure that pypck_client is about to be closed
|
|
124
|
-
await pypck_client.wait_closed()
|
|
125
|
-
|
|
126
|
-
event_callback.assert_has_calls([call(LcnEvent.CONNECTION_LOST)])
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
@pytest.mark.asyncio
|
|
130
|
-
async def test_multiple_connections(
|
|
131
|
-
pchk_server: MockPchkServer,
|
|
132
|
-
pypck_client: MockPchkConnectionManager,
|
|
133
|
-
pchk_server_2: MockPchkServer,
|
|
134
|
-
pypck_client_2: MockPchkConnectionManager,
|
|
135
|
-
) -> None:
|
|
136
|
-
"""Test that two independent connections can coexists."""
|
|
137
|
-
await pypck_client_2.async_connect()
|
|
138
|
-
|
|
139
|
-
event_callback = Mock()
|
|
140
|
-
pypck_client.register_for_events(event_callback)
|
|
141
|
-
await pypck_client.async_connect()
|
|
142
|
-
|
|
143
|
-
await pchk_server.stop()
|
|
144
|
-
await pypck_client.wait_closed()
|
|
145
|
-
|
|
146
|
-
event_callback.assert_has_calls([call(LcnEvent.CONNECTION_LOST)])
|
|
147
|
-
|
|
148
|
-
assert len(pypck_client.task_registry.tasks) == 0
|
|
149
|
-
assert len(pypck_client_2.task_registry.tasks) > 0
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
@pytest.mark.asyncio
|
|
153
|
-
async def test_segment_coupler_search(
|
|
154
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
155
|
-
) -> None:
|
|
156
|
-
"""Test segment coupler search."""
|
|
157
|
-
await pypck_client.async_connect()
|
|
158
|
-
await pypck_client.scan_segment_couplers(3, 0)
|
|
159
|
-
|
|
160
|
-
assert await pchk_server.received(">G003003.SK")
|
|
161
|
-
assert await pchk_server.received(">G003003.SK")
|
|
162
|
-
assert await pchk_server.received(">G003003.SK")
|
|
163
|
-
|
|
164
|
-
assert pypck_client.is_ready()
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
@pytest.mark.asyncio
|
|
168
|
-
async def test_segment_coupler_response(
|
|
169
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
170
|
-
) -> None:
|
|
171
|
-
"""Test segment coupler response."""
|
|
172
|
-
await pypck_client.async_connect()
|
|
173
|
-
|
|
174
|
-
assert pypck_client.local_seg_id == 0
|
|
175
|
-
|
|
176
|
-
await pchk_server.send_message("=M000005.SK020")
|
|
177
|
-
await pchk_server.send_message("=M021021.SK021")
|
|
178
|
-
await pchk_server.send_message("=M022010.SK022")
|
|
179
|
-
assert await pypck_client.received("=M000005.SK020")
|
|
180
|
-
assert await pypck_client.received("=M021021.SK021")
|
|
181
|
-
assert await pypck_client.received("=M022010.SK022")
|
|
182
|
-
|
|
183
|
-
assert pypck_client.local_seg_id == 20
|
|
184
|
-
assert set(pypck_client.segment_coupler_ids) == {20, 21, 22}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
@pytest.mark.asyncio
|
|
188
|
-
async def test_module_scan(
|
|
189
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
190
|
-
) -> None:
|
|
191
|
-
"""Test module scan."""
|
|
192
|
-
await pypck_client.async_connect()
|
|
193
|
-
await pypck_client.scan_modules(3, 0)
|
|
194
|
-
|
|
195
|
-
assert await pchk_server.received(">G000003!LEER")
|
|
196
|
-
assert await pchk_server.received(">G000003!LEER")
|
|
197
|
-
assert await pchk_server.received(">G000003!LEER")
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
@pytest.mark.asyncio
|
|
201
|
-
async def test_module_sn_response(
|
|
202
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
203
|
-
) -> None:
|
|
204
|
-
"""Test module scan."""
|
|
205
|
-
await pypck_client.async_connect()
|
|
206
|
-
module = pypck_client.get_address_conn(LcnAddr(0, 7, False))
|
|
207
|
-
|
|
208
|
-
message = "=M000007.SN1AB20A123401FW190B11HW015"
|
|
209
|
-
await pchk_server.send_message(message)
|
|
210
|
-
assert await pypck_client.received(message)
|
|
211
|
-
|
|
212
|
-
assert await module.serial_known
|
|
213
|
-
assert module.hardware_serial == 0x1AB20A1234
|
|
214
|
-
assert module.manu == 1
|
|
215
|
-
assert module.software_serial == 0x190B11
|
|
216
|
-
assert module.hardware_type.value == 15
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
@pytest.mark.asyncio
|
|
220
|
-
async def test_send_command_to_server(
|
|
221
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
222
|
-
) -> None:
|
|
223
|
-
"""Test sending a command to the PCHK server."""
|
|
224
|
-
await pypck_client.async_connect()
|
|
225
|
-
message = ">M000007.PIN003"
|
|
226
|
-
await pypck_client.send_command(message)
|
|
227
|
-
assert await pchk_server.received(message)
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
@pytest.mark.asyncio
|
|
231
|
-
async def test_ping(
|
|
232
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
233
|
-
) -> None:
|
|
234
|
-
"""Test if pings are send."""
|
|
235
|
-
await pypck_client.async_connect()
|
|
236
|
-
assert await pchk_server.received("^ping0")
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
@pytest.mark.asyncio
|
|
240
|
-
async def test_add_address_connections(pypck_client: MockPchkConnectionManager) -> None:
|
|
241
|
-
"""Test if new address connections are added on request."""
|
|
242
|
-
lcn_addr = LcnAddr(0, 10, False)
|
|
243
|
-
assert lcn_addr not in pypck_client.address_conns
|
|
244
|
-
|
|
245
|
-
addr_conn = pypck_client.get_address_conn(lcn_addr)
|
|
246
|
-
assert isinstance(addr_conn, ModuleConnection)
|
|
247
|
-
|
|
248
|
-
assert lcn_addr in pypck_client.address_conns
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
@pytest.mark.asyncio
|
|
252
|
-
async def test_add_address_connections_by_message(
|
|
253
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
254
|
-
) -> None:
|
|
255
|
-
"""Test if new address connections are added by received message."""
|
|
256
|
-
await pypck_client.async_connect()
|
|
257
|
-
lcn_addr = LcnAddr(0, 10, False)
|
|
258
|
-
assert lcn_addr not in pypck_client.address_conns
|
|
259
|
-
|
|
260
|
-
message = ":M000010A1050"
|
|
261
|
-
await pchk_server.send_message(message)
|
|
262
|
-
assert await pypck_client.received(message)
|
|
263
|
-
|
|
264
|
-
assert lcn_addr in pypck_client.address_conns
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
@pytest.mark.asyncio
|
|
268
|
-
async def test_groups_static_membership_discovery(
|
|
269
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
270
|
-
) -> None:
|
|
271
|
-
"""Test module scan."""
|
|
272
|
-
await pypck_client.async_connect()
|
|
273
|
-
module = pypck_client.get_address_conn(LcnAddr(0, 10, False))
|
|
274
|
-
assert isinstance(module, ModuleConnection)
|
|
275
|
-
|
|
276
|
-
task = asyncio.create_task(module.request_static_groups())
|
|
277
|
-
assert await pchk_server.received(">M000010.GP")
|
|
278
|
-
await pchk_server.send_message("=M000010.GP012011200051")
|
|
279
|
-
assert await task == {
|
|
280
|
-
LcnAddr(0, 11, True),
|
|
281
|
-
LcnAddr(0, 200, True),
|
|
282
|
-
LcnAddr(0, 51, True),
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
@pytest.mark.asyncio
|
|
287
|
-
async def test_groups_dynamic_membership_discovery(
|
|
288
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
289
|
-
) -> None:
|
|
290
|
-
"""Test module scan."""
|
|
291
|
-
await pypck_client.async_connect()
|
|
292
|
-
module = pypck_client.get_address_conn(LcnAddr(0, 10, False))
|
|
293
|
-
assert isinstance(module, ModuleConnection)
|
|
294
|
-
|
|
295
|
-
task = asyncio.create_task(module.request_dynamic_groups())
|
|
296
|
-
assert await pchk_server.received(">M000010.GD")
|
|
297
|
-
await pchk_server.send_message("=M000010.GD008011200051")
|
|
298
|
-
assert await task == {
|
|
299
|
-
LcnAddr(0, 11, True),
|
|
300
|
-
LcnAddr(0, 200, True),
|
|
301
|
-
LcnAddr(0, 51, True),
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
@pytest.mark.asyncio
|
|
306
|
-
async def test_groups_membership_discovery(
|
|
307
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
308
|
-
) -> None:
|
|
309
|
-
"""Test module scan."""
|
|
310
|
-
await pypck_client.async_connect()
|
|
311
|
-
module = pypck_client.get_address_conn(LcnAddr(0, 10, False))
|
|
312
|
-
assert isinstance(module, ModuleConnection)
|
|
313
|
-
|
|
314
|
-
task = asyncio.create_task(module.request_groups())
|
|
315
|
-
assert await pchk_server.received(">M000010.GP")
|
|
316
|
-
await pchk_server.send_message("=M000010.GP012011200051")
|
|
317
|
-
assert await pchk_server.received(">M000010.GD")
|
|
318
|
-
await pchk_server.send_message("=M000010.GD008015100052")
|
|
319
|
-
assert await task == {
|
|
320
|
-
LcnAddr(0, 11, True),
|
|
321
|
-
LcnAddr(0, 200, True),
|
|
322
|
-
LcnAddr(0, 51, True),
|
|
323
|
-
LcnAddr(0, 15, True),
|
|
324
|
-
LcnAddr(0, 100, True),
|
|
325
|
-
LcnAddr(0, 52, True),
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
@pytest.mark.asyncio
|
|
330
|
-
async def test_multiple_serial_requests(
|
|
331
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
332
|
-
) -> None:
|
|
333
|
-
"""Test module scan."""
|
|
334
|
-
await pypck_client.async_connect()
|
|
335
|
-
|
|
336
|
-
pypck_client.get_address_conn(LcnAddr(0, 10, False))
|
|
337
|
-
pypck_client.get_address_conn(LcnAddr(0, 11, False))
|
|
338
|
-
pypck_client.get_address_conn(LcnAddr(0, 12, False))
|
|
339
|
-
|
|
340
|
-
assert await pchk_server.received(">M000010.SN")
|
|
341
|
-
assert await pchk_server.received(">M000011.SN")
|
|
342
|
-
assert await pchk_server.received(">M000012.SN")
|
|
343
|
-
|
|
344
|
-
message = "=M000010.SN1AB20A123401FW190B11HW015"
|
|
345
|
-
await pchk_server.send_message(message)
|
|
346
|
-
assert await pypck_client.received(message)
|
|
347
|
-
|
|
348
|
-
await pypck_client.async_close()
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
@pytest.mark.asyncio
|
|
352
|
-
async def test_dump_modules_no_segement_couplers(
|
|
353
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
354
|
-
) -> None:
|
|
355
|
-
"""Test module information dumping."""
|
|
356
|
-
await pypck_client.async_connect()
|
|
357
|
-
|
|
358
|
-
for msg in (
|
|
359
|
-
"=M000007.SN1AB20A123401FW190B11HW015",
|
|
360
|
-
"=M000008.SN1BB20A123401FW1A0B11HW015",
|
|
361
|
-
"=M000007.GP012011200051",
|
|
362
|
-
"=M000008.GP012011220051",
|
|
363
|
-
"=M000007.GD008015100052",
|
|
364
|
-
"=M000008.GD008015120052",
|
|
365
|
-
):
|
|
366
|
-
await pchk_server.send_message(msg)
|
|
367
|
-
assert await pypck_client.received(msg)
|
|
368
|
-
|
|
369
|
-
dump = pypck_client.dump_modules()
|
|
370
|
-
json.dumps(dump)
|
|
371
|
-
|
|
372
|
-
assert dump == {
|
|
373
|
-
"0": {
|
|
374
|
-
"7": {
|
|
375
|
-
"segment": 0,
|
|
376
|
-
"address": 7,
|
|
377
|
-
"is_local_segment": True,
|
|
378
|
-
"serials": {
|
|
379
|
-
"hardware_serial": "1AB20A1234",
|
|
380
|
-
"manu": "01",
|
|
381
|
-
"software_serial": "190B11",
|
|
382
|
-
"hardware_type": "15",
|
|
383
|
-
"hardware_name": "LCN-SH-Plus",
|
|
384
|
-
},
|
|
385
|
-
"name": "",
|
|
386
|
-
"comment": "",
|
|
387
|
-
"oem_text": ["", "", "", ""],
|
|
388
|
-
"groups": {"static": [11, 51, 200], "dynamic": [15, 52, 100]},
|
|
389
|
-
},
|
|
390
|
-
"8": {
|
|
391
|
-
"segment": 0,
|
|
392
|
-
"address": 8,
|
|
393
|
-
"is_local_segment": True,
|
|
394
|
-
"serials": {
|
|
395
|
-
"hardware_serial": "1BB20A1234",
|
|
396
|
-
"manu": "01",
|
|
397
|
-
"software_serial": "1A0B11",
|
|
398
|
-
"hardware_type": "15",
|
|
399
|
-
"hardware_name": "LCN-SH-Plus",
|
|
400
|
-
},
|
|
401
|
-
"name": "",
|
|
402
|
-
"comment": "",
|
|
403
|
-
"oem_text": ["", "", "", ""],
|
|
404
|
-
"groups": {"static": [11, 51, 220], "dynamic": [15, 52, 120]},
|
|
405
|
-
},
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
@pytest.mark.asyncio
|
|
411
|
-
async def test_dump_modules_multi_segment(
|
|
412
|
-
pchk_server: MockPchkServer, pypck_client: MockPchkConnectionManager
|
|
413
|
-
) -> None:
|
|
414
|
-
"""Test module information dumping."""
|
|
415
|
-
await pypck_client.async_connect()
|
|
416
|
-
|
|
417
|
-
# Populate the bus topology information
|
|
418
|
-
for msg in (
|
|
419
|
-
"=M000007.SK020",
|
|
420
|
-
"=M022008.SK022",
|
|
421
|
-
"=M000007.SN1AB20A123401FW190B11HW015",
|
|
422
|
-
"=M022008.SN1BB20A123401FW1A0B11HW015",
|
|
423
|
-
"=M000007.GP012011200051",
|
|
424
|
-
"=M022008.GP012011220051",
|
|
425
|
-
"=M000007.GD008015100052",
|
|
426
|
-
"=M022008.GD008015120052",
|
|
427
|
-
):
|
|
428
|
-
await pchk_server.send_message(msg)
|
|
429
|
-
assert await pypck_client.received(msg)
|
|
430
|
-
|
|
431
|
-
dump = pypck_client.dump_modules()
|
|
432
|
-
json.dumps(dump)
|
|
433
|
-
|
|
434
|
-
assert dump == {
|
|
435
|
-
"20": {
|
|
436
|
-
"7": {
|
|
437
|
-
"segment": 20,
|
|
438
|
-
"address": 7,
|
|
439
|
-
"is_local_segment": True,
|
|
440
|
-
"serials": {
|
|
441
|
-
"hardware_serial": "1AB20A1234",
|
|
442
|
-
"manu": "01",
|
|
443
|
-
"software_serial": "190B11",
|
|
444
|
-
"hardware_type": "15",
|
|
445
|
-
"hardware_name": "LCN-SH-Plus",
|
|
446
|
-
},
|
|
447
|
-
"name": "",
|
|
448
|
-
"comment": "",
|
|
449
|
-
"oem_text": ["", "", "", ""],
|
|
450
|
-
"groups": {"static": [11, 51, 200], "dynamic": [15, 52, 100]},
|
|
451
|
-
},
|
|
452
|
-
},
|
|
453
|
-
"22": {
|
|
454
|
-
"8": {
|
|
455
|
-
"segment": 22,
|
|
456
|
-
"address": 8,
|
|
457
|
-
"is_local_segment": False,
|
|
458
|
-
"serials": {
|
|
459
|
-
"hardware_serial": "1BB20A1234",
|
|
460
|
-
"manu": "01",
|
|
461
|
-
"software_serial": "1A0B11",
|
|
462
|
-
"hardware_type": "15",
|
|
463
|
-
"hardware_name": "LCN-SH-Plus",
|
|
464
|
-
},
|
|
465
|
-
"name": "",
|
|
466
|
-
"comment": "",
|
|
467
|
-
"oem_text": ["", "", "", ""],
|
|
468
|
-
"groups": {"static": [11, 51, 220], "dynamic": [15, 52, 120]},
|
|
469
|
-
},
|
|
470
|
-
},
|
|
471
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|