@@ -24,8 +24,10 @@ def handle_unsubscribe(client, user_data, topic, pid):
2424
2525
2626# 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
2931testdata = [
3032 # short topic with remaining length encoded as single byte
3133 (
@@ -67,11 +69,37 @@ def handle_unsubscribe(client, user_data, topic, pid):
6769 + [0x6F ] * 257
6870 ),
6971 ),
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+ ),
7096]
7197
7298
7399@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" ],
75103)
76104def test_unsubscribe (topic , to_send , exp_recv ) -> None :
77105 """
@@ -107,11 +135,19 @@ def test_unsubscribe(topic, to_send, exp_recv) -> None:
107135 mqtt_client .logger = logger
108136
109137 # 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
111142
112143 # pylint: disable=logging-fstring-interpolation
113144 logger .info (f"unsubscribing from { topic } " )
114145 mqtt_client .unsubscribe (topic )
115146
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
117152 assert mocket .sent == exp_recv
153+ assert len (mocket ._to_send ) == 0
0 commit comments