134134 */
135135#define TEST_MQTT_TOPIC_2 CLIENT_IDENTIFIER "/iot/integration/test2"
136136
137+ /**
138+ * @brief Sample topic filter 3 to use in tests.
139+ */
140+ #define TEST_MQTT_TOPIC_3 CLIENT_IDENTIFIER "/iot/integration/testTopic3"
141+
142+ /**
143+ * @brief Sample topic filter 4 to use in tests.
144+ */
145+ #define TEST_MQTT_TOPIC_4 CLIENT_IDENTIFIER "/iot/integration/testFour"
146+
147+ /**
148+ * @brief Sample topic filter 5 to use in tests.
149+ */
150+ #define TEST_MQTT_TOPIC_5 CLIENT_IDENTIFIER "/iot/integration/testTopicName5"
151+
137152/**
138153 * @brief Length of sample topic filter.
139154 */
@@ -1006,6 +1021,7 @@ TEST_GROUP_RUNNER( coreMQTT_Integration_AWS_IoT_Compatible )
10061021 RUN_TEST_CASE ( coreMQTT_Integration_AWS_IoT_Compatible , test_MQTT_ProcessLoop_KeepAlive );
10071022 RUN_TEST_CASE ( coreMQTT_Integration_AWS_IoT_Compatible , test_MQTT_Resend_Unacked_Publish_QoS1 );
10081023 RUN_TEST_CASE ( coreMQTT_Integration_AWS_IoT_Compatible , test_MQTT_Restore_Session_Duplicate_Incoming_Publish_Qos1 );
1024+ RUN_TEST_CASE ( coreMQTT_Integration_AWS_IoT_Compatible , test_MQTT_SubUnsub_Multiple_Topics );
10091025 RUN_TEST_CASE ( coreMQTT_Integration_AWS_IoT_Compatible , test_MQTT_Publish_With_Retain_Flag );
10101026}
10111027
@@ -1027,6 +1043,7 @@ TEST_GROUP_RUNNER( coreMQTT_Integration )
10271043 RUN_TEST_CASE ( coreMQTT_Integration , test_MQTT_Resend_Unacked_Publish_QoS2 );
10281044 RUN_TEST_CASE ( coreMQTT_Integration , test_MQTT_Restore_Session_Duplicate_Incoming_Publish_Qos2 );
10291045 RUN_TEST_CASE ( coreMQTT_Integration , test_MQTT_Publish_With_Retain_Flag );
1046+ RUN_TEST_CASE ( coreMQTT_Integration , test_MQTT_SubUnsub_Multiple_Topics );
10301047}
10311048
10321049/* ========================== Test Cases ============================ */
@@ -1823,6 +1840,128 @@ void test_MQTT_Publish_With_Retain_Flag( void )
18231840 TEST_ASSERT_FALSE ( receivedRetainedMessage );
18241841}
18251842
1843+ /**
1844+ * @brief Tests Subscribe and Unsubscribe operations to multiple topic filters
1845+ * in a single API call.
1846+ * The test subscribes to 6 topics, and then publishes to the same topics one
1847+ * at a time. The broker is expected to route the publish message back to the
1848+ * test for all topics.
1849+ */
1850+ void test_MQTT_Subscribe_Unsubscribe_Multiple_Topics ( void )
1851+ {
1852+ MQTTSubscribeInfo_t subscribeParams [ 5 ];
1853+ char * topicList [ 5 ];
1854+ size_t i ;
1855+ const size_t topicCount = 5U ;
1856+ MQTTQoS_t qos ;
1857+
1858+ topicList [ 0 ] = TEST_MQTT_TOPIC ;
1859+ topicList [ 1 ] = TEST_MQTT_TOPIC_2 ;
1860+ topicList [ 2 ] = TEST_MQTT_TOPIC_3 ;
1861+ topicList [ 3 ] = TEST_MQTT_TOPIC_4 ;
1862+ topicList [ 4 ] = TEST_MQTT_TOPIC_5 ;
1863+
1864+ for ( i = 0 ; i < topicCount ; i ++ )
1865+ {
1866+ subscribeParams [ i ].pTopicFilter = topicList [ i ];
1867+ subscribeParams [ i ].topicFilterLength = strlen ( topicList [ i ] );
1868+ subscribeParams [ i ].qos = ( i % 2 );
1869+ }
1870+
1871+ globalSubscribePacketIdentifier = MQTT_GetPacketId ( & context );
1872+ /* Check that the packet ID is valid according to the MQTT spec. */
1873+ TEST_ASSERT_NOT_EQUAL ( MQTT_PACKET_ID_INVALID , globalSubscribePacketIdentifier );
1874+ TEST_ASSERT_NOT_EQUAL ( 0U , globalSubscribePacketIdentifier );
1875+
1876+ /* Subscribe to all topics. */
1877+ TEST_ASSERT_EQUAL ( MQTTSuccess , MQTT_Subscribe ( & context ,
1878+ subscribeParams ,
1879+ topicCount ,
1880+ globalSubscribePacketIdentifier ) );
1881+
1882+ /* Expect a SUBACK from the broker for the subscribe operation. */
1883+ TEST_ASSERT_FALSE ( receivedSubAck );
1884+ TEST_ASSERT_EQUAL ( MQTTSuccess ,
1885+ processLoopWithTimeout ( & context , MQTT_PROCESS_LOOP_TIMEOUT_MS ) );
1886+ TEST_ASSERT_TRUE ( receivedSubAck );
1887+
1888+ /* Publish to the same topic, that we subscribed to. */
1889+ for ( i = 0 ; i < topicCount ; i ++ )
1890+ {
1891+ /* Set Qos to be either 1 or 0. */
1892+ qos = ( i % 2 );
1893+
1894+ TEST_ASSERT_EQUAL ( MQTTSuccess , publishToTopic (
1895+ & context ,
1896+ topicList [ i ],
1897+ false, /* setRetainFlag */
1898+ false, /* isDuplicate */
1899+ qos , /* QoS */
1900+ MQTT_GetPacketId ( & context ) ) );
1901+
1902+ /* Reset the PUBACK flag. */
1903+ receivedPubAck = false;
1904+
1905+ /* Expect a PUBACK response for the PUBLISH and an incoming PUBLISH for the
1906+ * same message that we published (as we have subscribed to the same topic). */
1907+ TEST_ASSERT_EQUAL ( MQTTSuccess ,
1908+ processLoopWithTimeout ( & context , MQTT_PROCESS_LOOP_TIMEOUT_MS ) );
1909+
1910+ /* Only wait for PUBACK if QoS is not QoS0. */
1911+ if ( qos != MQTTQoS0 )
1912+ {
1913+ /* Make sure we have received PUBACK response. */
1914+ TEST_ASSERT_TRUE ( receivedPubAck );
1915+ }
1916+
1917+ /* Make sure that we have received the same message from the server,
1918+ * that was published (as we have subscribed to the same topic). */
1919+ TEST_ASSERT_EQUAL ( qos , incomingInfo .qos );
1920+ TEST_ASSERT_EQUAL ( strlen ( topicList [ i ] ), incomingInfo .topicNameLength );
1921+ TEST_ASSERT_EQUAL_MEMORY ( topicList [ i ],
1922+ incomingInfo .pTopicName ,
1923+ strlen ( topicList [ i ] ) );
1924+ TEST_ASSERT_EQUAL ( strlen ( MQTT_EXAMPLE_MESSAGE ), incomingInfo .payloadLength );
1925+ TEST_ASSERT_EQUAL_MEMORY ( MQTT_EXAMPLE_MESSAGE ,
1926+ incomingInfo .pPayload ,
1927+ incomingInfo .payloadLength );
1928+ }
1929+
1930+ globalUnsubscribePacketIdentifier = MQTT_GetPacketId ( & context );
1931+ /* Check that the packet ID is valid according to the MQTT spec. */
1932+ TEST_ASSERT_NOT_EQUAL ( MQTT_PACKET_ID_INVALID , globalUnsubscribePacketIdentifier );
1933+ TEST_ASSERT_NOT_EQUAL ( 0U , globalUnsubscribePacketIdentifier );
1934+
1935+ /* Un-subscribe from all the topics. */
1936+ TEST_ASSERT_EQUAL ( MQTTSuccess , MQTT_Unsubscribe (
1937+ & context , subscribeParams , topicCount , globalUnsubscribePacketIdentifier ) );
1938+
1939+ receivedUnsubAck = false;
1940+
1941+ /* Expect an UNSUBACK from the broker for the unsubscribe operation. */
1942+ TEST_ASSERT_EQUAL ( MQTTSuccess ,
1943+ processLoopWithTimeout ( & context , MQTT_PROCESS_LOOP_TIMEOUT_MS ) );
1944+ TEST_ASSERT_TRUE ( receivedUnsubAck );
1945+ }
1946+
1947+ /**
1948+ * @brief Verifies the correct behavior of MQTT library when sending multiple
1949+ * subscribe and unsubscribe requests in a single API call.
1950+ */
1951+ TEST ( coreMQTT_Integration_AWS_IoT_Compatible , test_MQTT_SubUnsub_Multiple_Topics )
1952+ {
1953+ test_MQTT_Subscribe_Unsubscribe_Multiple_Topics ();
1954+ }
1955+
1956+ /**
1957+ * @brief Verifies the correct behavior of MQTT library when sending multiple
1958+ * subscribe and unsubscribe requests in a single API call.
1959+ */
1960+ TEST ( coreMQTT_Integration , test_MQTT_SubUnsub_Multiple_Topics )
1961+ {
1962+ test_MQTT_Subscribe_Unsubscribe_Multiple_Topics ();
1963+ }
1964+
18261965/* Include test_MQTT_Publish_With_Retain_Flag test case in both test groups to
18271966 * run it against AWS IoT and a different broker */
18281967TEST ( coreMQTT_Integration_AWS_IoT_Compatible , test_MQTT_Publish_With_Retain_Flag )
0 commit comments