Skip to content

Commit 8d50e96

Browse files
committed
add protocol tests for UNSUBSCRIBE packet
1 parent 1bb729b commit 8d50e96

File tree

1 file changed

+117
-0
lines changed

1 file changed

+117
-0
lines changed

tests/test_unsubscribe.py

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# SPDX-FileCopyrightText: 2023 Vladimír Kotal
2+
#
3+
# SPDX-License-Identifier: Unlicense
4+
5+
"""unsubscribe tests"""
6+
7+
import logging
8+
import ssl
9+
10+
import pytest
11+
from mocket import Mocket
12+
13+
import adafruit_minimqtt.adafruit_minimqtt as MQTT
14+
15+
16+
# pylint: disable=unused-argument
17+
def handle_unsubscribe(client, user_data, topic, pid):
18+
"""
19+
Record topics into user data.
20+
"""
21+
assert topic
22+
23+
user_data.append(topic)
24+
25+
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.
29+
testdata = [
30+
# short topic with remaining length encoded as single byte
31+
(
32+
"foo/bar",
33+
bytearray([0xB0, 0x02, 0x00, 0x01]),
34+
bytearray(
35+
[
36+
0xA2, # fixed header
37+
0x0B, # remaining length
38+
0x00, # message ID
39+
0x01,
40+
0x00, # topic length
41+
0x07,
42+
0x66, # topic
43+
0x6F,
44+
0x6F,
45+
0x2F,
46+
0x62,
47+
0x61,
48+
0x72,
49+
]
50+
),
51+
),
52+
# remaining length is encoded as 2 bytes due to long topic name.
53+
(
54+
"f" + "o" * 257,
55+
bytearray([0xB0, 0x02, 0x00, 0x01]),
56+
bytearray(
57+
[
58+
0xA2, # fixed header
59+
0x86, # remaining length
60+
0x02,
61+
0x00, # message ID
62+
0x01,
63+
0x01, # topic length
64+
0x02,
65+
0x66, # topic
66+
]
67+
+ [0x6F] * 257
68+
),
69+
),
70+
]
71+
72+
73+
@pytest.mark.parametrize(
74+
"topic,to_send,exp_recv", testdata, ids=["short_topic", "long_topic"]
75+
)
76+
def test_unsubscribe(topic, to_send, exp_recv) -> None:
77+
"""
78+
Protocol level testing of UNSUBSCRIBE and UNSUBACK packet handling.
79+
80+
Nothing will travel over the wire, it is all fake.
81+
Also, the topics are not subscribed into.
82+
"""
83+
logging.basicConfig()
84+
logger = logging.getLogger(__name__)
85+
logger.setLevel(logging.DEBUG)
86+
87+
host = "localhost"
88+
port = 1883
89+
90+
unsubscribed_topics = []
91+
mqtt_client = MQTT.MQTT(
92+
broker=host,
93+
port=port,
94+
ssl_context=ssl.create_default_context(),
95+
connect_retries=1,
96+
user_data=unsubscribed_topics,
97+
)
98+
99+
mqtt_client.on_unsubscribe = handle_unsubscribe
100+
101+
# patch is_connected() to avoid CONNECT/CONNACK handling.
102+
mqtt_client.is_connected = lambda: True
103+
mocket = Mocket(to_send)
104+
# pylint: disable=protected-access
105+
mqtt_client._sock = mocket
106+
107+
mqtt_client.logger = logger
108+
109+
# pylint: disable=protected-access
110+
mqtt_client._subscribed_topics = [topic]
111+
112+
# pylint: disable=logging-fstring-interpolation
113+
logger.info(f"unsubscribing from {topic}")
114+
mqtt_client.unsubscribe(topic)
115+
116+
assert topic in unsubscribed_topics
117+
assert mocket.sent == exp_recv

0 commit comments

Comments
 (0)