@@ -24,8 +24,10 @@ def handle_unsubscribe(client, user_data, topic, pid):
24
24
25
25
26
26
# The MQTT packet contents below were captured using Mosquitto client+server.
27
- # These are verbatim, except message ID that was changed from 2 to 1 since in the real world
28
- # capture the UNSUBSCRIBE packet followed the SUBSCRIBE packet.
27
+ # These are all verbatim, except:
28
+ # - message ID that was changed from 2 to 1 since in the real world
29
+ # the UNSUBSCRIBE packet followed the SUBSCRIBE packet.
30
+ # - the long list topics is sent as individual UNSUBSCRIBE packets by Mosquitto
29
31
testdata = [
30
32
# short topic with remaining length encoded as single byte
31
33
(
@@ -67,11 +69,37 @@ def handle_unsubscribe(client, user_data, topic, pid):
67
69
+ [0x6F ] * 257
68
70
),
69
71
),
72
+ # use list of topics for more coverage. If the range was (1, 10000), that would be
73
+ # long enough to use 3 bytes for remaining length, however that would make the test
74
+ # run for many minutes even on modern systems, so 1000 is used instead.
75
+ # This results in 2 bytes for the remaining length.
76
+ (
77
+ [f"foo/bar{ x :04} " for x in range (1 , 1000 )],
78
+ bytearray ([0xB0 , 0x02 , 0x00 , 0x01 ]),
79
+ bytearray (
80
+ [
81
+ 0xA2 , # fixed header
82
+ 0xBD , # remaining length
83
+ 0x65 ,
84
+ 0x00 , # message ID
85
+ 0x01 ,
86
+ ]
87
+ + sum (
88
+ [
89
+ [0x00 , 0x0B ] + list (f"foo/bar{ x :04} " .encode ("ascii" ))
90
+ for x in range (1 , 1000 )
91
+ ],
92
+ [],
93
+ )
94
+ ),
95
+ ),
70
96
]
71
97
72
98
73
99
@pytest .mark .parametrize (
74
- "topic,to_send,exp_recv" , testdata , ids = ["short_topic" , "long_topic" ]
100
+ "topic,to_send,exp_recv" ,
101
+ testdata ,
102
+ ids = ["short_topic" , "long_topic" , "topic_list_long" ],
75
103
)
76
104
def test_unsubscribe (topic , to_send , exp_recv ) -> None :
77
105
"""
@@ -107,11 +135,19 @@ def test_unsubscribe(topic, to_send, exp_recv) -> None:
107
135
mqtt_client .logger = logger
108
136
109
137
# pylint: disable=protected-access
110
- mqtt_client ._subscribed_topics = [topic ]
138
+ if isinstance (topic , str ):
139
+ mqtt_client ._subscribed_topics = [topic ]
140
+ elif isinstance (topic , list ):
141
+ mqtt_client ._subscribed_topics = topic
111
142
112
143
# pylint: disable=logging-fstring-interpolation
113
144
logger .info (f"unsubscribing from { topic } " )
114
145
mqtt_client .unsubscribe (topic )
115
146
116
- assert topic in unsubscribed_topics
147
+ if isinstance (topic , str ):
148
+ assert topic in unsubscribed_topics
149
+ elif isinstance (topic , list ):
150
+ for topic_name in topic :
151
+ assert topic_name in unsubscribed_topics
117
152
assert mocket .sent == exp_recv
153
+ assert len (mocket ._to_send ) == 0
0 commit comments