1
1
import asyncio
2
- from collections .abc import Callable
3
2
import datetime
4
3
import json
5
4
import logging
16
15
from deebot_client .commands .json .battery import GetBattery
17
16
from deebot_client .commands .json .volume import SetVolume
18
17
from deebot_client .const import DataType
19
- from deebot_client .event_bus import EventBus
20
18
from deebot_client .exceptions import AuthenticationError
21
19
from deebot_client .models import Configuration , DeviceInfo
22
- from deebot_client .mqtt_client import MqttClient , MqttConfiguration , SubscriberInfo
20
+ from deebot_client .mqtt_client import MqttClient , MqttConfiguration
23
21
24
- from .fixtures .mqtt_server import MqttServer
25
-
26
- _WAITING_AFTER_RESTART = 30
27
-
28
-
29
- async def _verify_subscribe (
30
- test_client : Client , device_info : DeviceInfo , mock : Mock , * , expected_called : bool
31
- ) -> None :
32
- command = "test"
33
- data = json .dumps ({"test" : str (datetime .datetime .now ())}).encode ("utf-8" )
34
- topic = f"iot/atr/{ command } /{ device_info .did } /{ device_info .get_class } /{ device_info .resource } /j"
35
- await test_client .publish (topic , data )
36
-
37
- await asyncio .sleep (0.1 )
38
- if expected_called :
39
- mock .assert_called_with (command , data )
40
- else :
41
- mock .assert_not_called ()
42
-
43
- mock .reset_mock ()
44
-
45
-
46
- async def _subscribe (
47
- mqtt_client : MqttClient , device_info : DeviceInfo
48
- ) -> tuple [Mock , Mock , Callable [[], None ]]:
49
- events = Mock (spec = EventBus )
50
- callback = MagicMock ()
51
- unsubscribe = await mqtt_client .subscribe (
52
- SubscriberInfo (device_info , events , callback )
53
- )
54
- await asyncio .sleep (0.1 )
55
- return (events , callback , unsubscribe )
22
+ from .mqtt_util import subscribe , verify_subscribe
56
23
57
24
58
25
async def test_last_message_received_at (
@@ -75,63 +42,6 @@ async def test_last_message_received_at(
75
42
assert mqtt_client .last_message_received_at == expected
76
43
77
44
78
- @pytest .mark .skip (reason = "Wait for sbtinstruments/aiomqtt#232 be merged" )
79
- @pytest .mark .timeout (_WAITING_AFTER_RESTART + 10 )
80
- async def test_client_reconnect_on_broker_error (
81
- mqtt_client : MqttClient ,
82
- mqtt_server : MqttServer ,
83
- device_info : DeviceInfo ,
84
- mqtt_config : MqttConfiguration ,
85
- caplog : pytest .LogCaptureFixture ,
86
- ) -> None :
87
- (_ , callback , _ ) = await _subscribe (mqtt_client , device_info )
88
- async with Client (
89
- hostname = mqtt_config .hostname ,
90
- port = mqtt_config .port ,
91
- identifier = "Test-helper" ,
92
- tls_context = mqtt_config .ssl_context ,
93
- ) as client :
94
- # test client cannot be used as we restart the broker in this test
95
- await _verify_subscribe (client , device_info , callback , expected_called = True )
96
-
97
- caplog .clear ()
98
- mqtt_server .stop ()
99
- await asyncio .sleep (0.1 )
100
-
101
- assert (
102
- "deebot_client.mqtt_client" ,
103
- logging .WARNING ,
104
- "Connection lost; Reconnecting in 5 seconds ..." ,
105
- ) in caplog .record_tuples
106
- caplog .clear ()
107
-
108
- mqtt_server .run ()
109
-
110
- expected_log_tuple = (
111
- "deebot_client.mqtt_client" ,
112
- logging .DEBUG ,
113
- "All mqtt tasks created" ,
114
- )
115
- for i in range (_WAITING_AFTER_RESTART ):
116
- print (f"Wait for success reconnect... { i } /{ _WAITING_AFTER_RESTART } " )
117
- if expected_log_tuple in caplog .record_tuples :
118
- async with Client (
119
- hostname = mqtt_config .hostname ,
120
- port = mqtt_config .port ,
121
- identifier = "Test-helper" ,
122
- tls_context = mqtt_config .ssl_context ,
123
- ) as client :
124
- # test client cannot be used as we restart the broker in this test
125
- await _verify_subscribe (
126
- client , device_info , callback , expected_called = True
127
- )
128
- return
129
-
130
- await asyncio .sleep (1 )
131
-
132
- pytest .fail ("Reconnect failed" )
133
-
134
-
135
45
_test_MqttConfiguration_data = [
136
46
("cn" , None , "mq.ecouser.net" ),
137
47
("cn" , "localhost" , "localhost" ),
@@ -182,38 +92,38 @@ def test_MqttConfiguration_hostname_none(config: Configuration) -> None:
182
92
async def test_client_bot_subscription (
183
93
mqtt_client : MqttClient , device_info : DeviceInfo , test_mqtt_client : Client
184
94
) -> None :
185
- (_ , callback , unsubscribe ) = await _subscribe (mqtt_client , device_info )
95
+ (_ , callback , unsubscribe ) = await subscribe (mqtt_client , device_info )
186
96
187
- await _verify_subscribe (
97
+ await verify_subscribe (
188
98
test_mqtt_client , device_info , callback , expected_called = True
189
99
)
190
100
191
101
unsubscribe ()
192
102
await asyncio .sleep (0.1 )
193
103
194
- await _verify_subscribe (
104
+ await verify_subscribe (
195
105
test_mqtt_client , device_info , callback , expected_called = False
196
106
)
197
107
198
108
199
109
async def test_client_reconnect_manual (
200
110
mqtt_client : MqttClient , device_info : DeviceInfo , test_mqtt_client : Client
201
111
) -> None :
202
- (_ , callback , _ ) = await _subscribe (mqtt_client , device_info )
112
+ (_ , callback , _ ) = await subscribe (mqtt_client , device_info )
203
113
204
- await _verify_subscribe (
114
+ await verify_subscribe (
205
115
test_mqtt_client , device_info , callback , expected_called = True
206
116
)
207
117
208
118
await mqtt_client .disconnect ()
209
- await _verify_subscribe (
119
+ await verify_subscribe (
210
120
test_mqtt_client , device_info , callback , expected_called = False
211
121
)
212
122
213
123
await mqtt_client .connect ()
214
124
await asyncio .sleep (0.1 )
215
125
216
- await _verify_subscribe (
126
+ await verify_subscribe (
217
127
test_mqtt_client , device_info , callback , expected_called = True
218
128
)
219
129
@@ -244,7 +154,7 @@ async def test_p2p_success(
244
154
test_mqtt_client : Client ,
245
155
) -> None :
246
156
"""Test p2p workflow on SetVolume."""
247
- (events , _ , _ ) = await _subscribe (mqtt_client , device_info )
157
+ (events , _ , _ ) = await subscribe (mqtt_client , device_info )
248
158
assert len (mqtt_client ._received_p2p_commands ) == 0
249
159
250
160
command_object = Mock (spec = SetVolume )
@@ -293,7 +203,7 @@ async def test_p2p_not_supported(
293
203
caplog : pytest .LogCaptureFixture ,
294
204
) -> None :
295
205
"""Test that unsupported command will be logged."""
296
- await _subscribe (mqtt_client , device_info )
206
+ await subscribe (mqtt_client , device_info )
297
207
command_name : str = GetBattery .name
298
208
299
209
await _publish_p2p (
@@ -344,7 +254,7 @@ async def test_p2p_to_late(
344
254
"""Test p2p when response comes in to late."""
345
255
# reduce ttl to 1 seconds
346
256
mqtt_client ._received_p2p_commands = TTLCache (maxsize = 60 * 60 , ttl = 1 )
347
- await _subscribe (mqtt_client , device_info )
257
+ await subscribe (mqtt_client , device_info )
348
258
assert len (mqtt_client ._received_p2p_commands ) == 0
349
259
350
260
command_object = Mock (spec = SetVolume )
@@ -393,7 +303,7 @@ async def test_p2p_parse_error(
393
303
caplog : pytest .LogCaptureFixture ,
394
304
) -> None :
395
305
"""Test p2p parse error."""
396
- await _subscribe (mqtt_client , device_info )
306
+ await subscribe (mqtt_client , device_info )
397
307
398
308
command_object = Mock (spec = SetVolume )
399
309
command_name = SetVolume .name
0 commit comments