/* * AWS IoT Device Shadow v1.3.0 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ /** * @file shadow_utest.c * @brief Tests for the user-facing API functions (declared in shadow.h). */ /* Standard includes. */ #include #include /* Test framework includes. */ #include "unity.h" /* Shadow include. */ #include "shadow.h" /*-----------------------------------------------------------*/ /** * @brief The Thing Name shared among all the tests. */ #define TEST_THING_NAME "TestThingName" /** * @brief The length of #TEST_THING_NAME. */ #define TEST_THING_NAME_LENGTH ( sizeof( TEST_THING_NAME ) - 1 ) /** * @brief The shadow topic string "update" shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_STRING_UPDATE "$aws/things/TestThingName/shadow/update" /** * @brief The shadow topic string "update/accepted" shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_STRING_UPDATE_ACCEPTED "$aws/things/TestThingName/shadow/update/accepted" /** * @brief The shadow topic string "update/rejected" shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_STRING_UPDATE_REJECTED "$aws/things/TestThingName/shadow/update/rejected" /** * @brief The shadow topic string "update/documents" shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_STRING_UPDATE_DOCUMENTS "$aws/things/TestThingName/shadow/update/documents" /** * @brief The shadow topic string "update/delta" shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_STRING_UPDATE_DELTA "$aws/things/TestThingName/shadow/update/delta" /** * @brief The shadow topic string "get" shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_STRING_GET "$aws/things/TestThingName/shadow/get" /** * @brief The shadow topic string "get/accepted" shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_STRING_GET_ACCEPTED "$aws/things/TestThingName/shadow/get/accepted" /** * @brief The shadow topic string "get/rejected" shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_STRING_GET_REJECTED "$aws/things/TestThingName/shadow/get/rejected" /** * @brief The shadow topic string "delete" shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_STRING_DELETE "$aws/things/TestThingName/shadow/delete" /** * @brief The shadow topic string "delete/accepted" shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_STRING_DELETE_ACCEPTED "$aws/things/TestThingName/shadow/delete/accepted" /** * @brief The shadow topic string "delete/rejected" shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_STRING_DELETE_REJECTED "$aws/things/TestThingName/shadow/delete/rejected" /** * @brief The length of #TEST_CLASSIC_TOPIC_STRING_UPDATE shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_LENGTH_UPDATE ( ( uint16_t ) sizeof( TEST_CLASSIC_TOPIC_STRING_UPDATE ) - 1U ) /** * @brief The length of #TEST_CLASSIC_TOPIC_STRING_UPDATE_ACCEPTED shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_LENGTH_UPDATE_ACCEPTED ( ( uint16_t ) sizeof( TEST_CLASSIC_TOPIC_STRING_UPDATE_ACCEPTED ) - 1U ) /** * @brief The length of #TEST_CLASSIC_TOPIC_STRING_UPDATE_REJECTED shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_LENGTH_UPDATE_REJECTED ( ( uint16_t ) sizeof( TEST_CLASSIC_TOPIC_STRING_UPDATE_REJECTED ) - 1U ) /** * @brief The length of #TEST_CLASSIC_TOPIC_STRING_UPDATE_DOCUMENTS shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_LENGTH_UPDATE_DOCUMENTS ( ( uint16_t ) sizeof( TEST_CLASSIC_TOPIC_STRING_UPDATE_DOCUMENTS ) - 1U ) /** * @brief The length of #TEST_CLASSIC_TOPIC_STRING_UPDATE_DELTA shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_LENGTH_UPDATE_DELTA ( ( uint16_t ) sizeof( TEST_CLASSIC_TOPIC_STRING_UPDATE_DELTA ) - 1U ) /** * @brief The length of #TEST_CLASSIC_TOPIC_STRING_GET shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_LENGTH_GET ( ( uint16_t ) sizeof( TEST_CLASSIC_TOPIC_STRING_GET ) - 1U ) /** * @brief The length of #TEST_CLASSIC_TOPIC_STRING_GET_ACCEPTED shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_LENGTH_GET_ACCEPTED ( ( uint16_t ) sizeof( TEST_CLASSIC_TOPIC_STRING_GET_ACCEPTED ) - 1U ) /** * @brief The length of #TEST_CLASSIC_TOPIC_STRING_GET_REJECTED shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_LENGTH_GET_REJECTED ( ( uint16_t ) sizeof( TEST_CLASSIC_TOPIC_STRING_GET_REJECTED ) - 1U ) /** * @brief The length of #TEST_CLASSIC_TOPIC_STRING_DELETE shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_LENGTH_DELETE ( ( uint16_t ) sizeof( TEST_CLASSIC_TOPIC_STRING_DELETE ) - 1U ) /** * @brief The length of #TEST_CLASSIC_TOPIC_STRING_DELETE_ACCEPTED shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_LENGTH_DELETE_ACCEPTED ( ( uint16_t ) sizeof( TEST_CLASSIC_TOPIC_STRING_DELETE_ACCEPTED ) - 1U ) /** * @brief The length of #TEST_CLASSIC_TOPIC_STRING_DELETE_REJECTED shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_LENGTH_DELETE_REJECTED ( ( uint16_t ) sizeof( TEST_CLASSIC_TOPIC_STRING_DELETE_REJECTED ) - 1U ) /** * @brief A topic string with an empty thing name. */ #define TEST_TOPIC_STRING_EMPTY_THINGNAME "$aws/things/" /** * @brief A topic string with an invalid thing name. */ #define TEST_TOPIC_STRING_INVALID_THINGNAME "$aws/things//" /** * @brief A topic string with an un-terminated thing name */ #define TEST_TOPIC_STRING_UNTERMINATED_THINGNAME "$aws/things/TestThingName" /** * @brief A topic string with an empty shadow root. */ #define TEST_TOPIC_STRING_EMPTY_SHADOW_ROOT "$aws/things/TestThingName/" /** * @brief A topic string with an invalid shadow root. */ #define TEST_TOPIC_STRING_INVALID_SHADOW_ROOT "$aws/things/TestThingName/invalid" /** * @brief A topic string with an empty shadow message type. */ #define TEST_CLASSIC_TOPIC_STRING_EMPTY_SHADOW_MESSAGE_TYPE "$aws/things/TestThingName/shadow" /** * @brief A topic string that is not related to Shadow. */ #define TEST_CLASSIC_TOPIC_STRING_INVALID_SHADOW_RESPONSE "$aws/things/TestThingName/shadow/invalid/invalid" /** * @brief A topic string that is not related to Shadow. */ #define TEST_CLASSIC_TOPIC_STRING_INVALID_GET_REJECTED "$aws/things/TestThingName/shadow/get/rejected/gibberish" /** * @brief A topic string that is not related to Shadow. */ #define TEST_TOPIC_STRING_INVALID_PREFIX "$aws/jobs/TestThingName/shadow/get/rejected" /** * @brief The length of #TEST_TOPIC_STRING_INVALID_PREFIX shared among all shadow test cases. */ #define TEST_TOPIC_LENGTH_INVALID_PREFIX ( ( uint16_t ) sizeof( TEST_TOPIC_STRING_INVALID_PREFIX ) - 1U ) /** * @brief The length of #TEST_TOPIC_STRING_EMPTY_THINGNAME shared among all shadow test cases. */ #define TEST_TOPIC_LENGTH_EMPTY_THINGNAME ( ( uint16_t ) sizeof( TEST_TOPIC_STRING_EMPTY_THINGNAME ) - 1U ) /** * @brief The length of #TEST_TOPIC_STRING_INVALID_THINGNAME shared among all shadow test cases. */ #define TEST_TOPIC_LENGTH_INVALID_THINGNAME ( ( uint16_t ) sizeof( TEST_TOPIC_STRING_INVALID_THINGNAME ) - 1U ) /** * @brief The length of #TEST_TOPIC_STRING_UNTERMINATED_THINGNAME shared among all shadow test cases. */ #define TEST_TOPIC_LENGTH_UNTERMINATED_THINGNAME ( ( uint16_t ) sizeof( TEST_TOPIC_STRING_UNTERMINATED_THINGNAME ) - 1U ) /** * @brief The length of #TEST_TOPIC_STRING_EMPTY_SHADOW_ROOT shared among all shadow test cases. */ #define TEST_TOPIC_LENGTH_EMPTY_SHADOW_ROOT ( ( uint16_t ) sizeof( TEST_TOPIC_STRING_EMPTY_SHADOW_ROOT ) - 1U ) /** * @brief The length of #TEST_TOPIC_STRING_INVALID_SHADOW_ROOT shared among all shadow test cases. */ #define TEST_TOPIC_LENGTH_INVALID_SHADOW_ROOT ( ( uint16_t ) sizeof( TEST_TOPIC_STRING_INVALID_SHADOW_ROOT ) - 1U ) /** * @brief The length of #TEST_CLASSIC_TOPIC_STRING_EMPTY_SHADOW_MESSAGE_TYPE shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_LENGTH_EMPTY_SHADOW_MESSAGE_TYPE ( ( uint16_t ) sizeof( TEST_CLASSIC_TOPIC_STRING_EMPTY_SHADOW_MESSAGE_TYPE ) - 1U ) /** * @brief The length of #TEST_CLASSIC_TOPIC_STRING_INVALID_SHADOW_RESPONSE shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_LENGTH_INVALID_SHADOW_RESPONSE ( ( uint16_t ) sizeof( TEST_CLASSIC_TOPIC_STRING_INVALID_SHADOW_RESPONSE ) - 1U ) /** * @brief The length of #TEST_CLASSIC_TOPIC_STRING_INVALID_GET_REJECTED shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_LENGTH_INVALID_GET_REJECTED ( ( uint16_t ) sizeof( TEST_CLASSIC_TOPIC_STRING_INVALID_GET_REJECTED ) - 1U ) /** * @brief The init value for a topic buffer. */ #define TEST_CLASSIC_TOPIC_BUFFER_INITIALIZE "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789abcdefghijklmno" /** * @brief The init value for a topic buffer. */ #define TEST_CLASSIC_TOPIC_BUFFER_MODIFIED "$aws/things/TestThingName/shadow/get/acceptedklmno" /** * @brief The length of #TEST_CLASSIC_TOPIC_STRING_DELETE_REJECTED shared among all Classic shadow test cases. */ #define TEST_CLASSIC_TOPIC_BUFFER_LENGTH ( ( uint16_t ) sizeof( TEST_CLASSIC_TOPIC_BUFFER_INITIALIZE ) - 1U ) /** * @brief The Shadow Name shared among all the named shadow tests. */ #define TEST_SHADOW_NAME "TestShadowName" /** * @brief The length of #TEST_SHADOW_NAME. */ #define TEST_SHADOW_NAME_LENGTH ( sizeof( TEST_SHADOW_NAME ) - 1 ) /** * @brief The shadow topic string "update" shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_STRING_UPDATE "$aws/things/TestThingName/shadow/name/TestShadowName/update" /** * @brief The shadow topic string "update/accepted" shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_STRING_UPDATE_ACCEPTED "$aws/things/TestThingName/shadow/name/TestShadowName/update/accepted" /** * @brief The shadow topic string "update/rejected" shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_STRING_UPDATE_REJECTED "$aws/things/TestThingName/shadow/name/TestShadowName/update/rejected" /** * @brief The shadow topic string "update/documents" shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_STRING_UPDATE_DOCUMENTS "$aws/things/TestThingName/shadow/name/TestShadowName/update/documents" /** * @brief The shadow topic string "update/delta" shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_STRING_UPDATE_DELTA "$aws/things/TestThingName/shadow/name/TestShadowName/update/delta" /** * @brief The shadow topic string "get" shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_STRING_GET "$aws/things/TestThingName/shadow/name/TestShadowName/get" /** * @brief The shadow topic string "get/accepted" shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_STRING_GET_ACCEPTED "$aws/things/TestThingName/shadow/name/TestShadowName/get/accepted" /** * @brief The shadow topic string "get/rejected" shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_STRING_GET_REJECTED "$aws/things/TestThingName/shadow/name/TestShadowName/get/rejected" /** * @brief The shadow topic string "delete" shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_STRING_DELETE "$aws/things/TestThingName/shadow/name/TestShadowName/delete" /** * @brief The shadow topic string "delete/accepted" shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_STRING_DELETE_ACCEPTED "$aws/things/TestThingName/shadow/name/TestShadowName/delete/accepted" /** * @brief The shadow topic string "delete/rejected" shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_STRING_DELETE_REJECTED "$aws/things/TestThingName/shadow/name/TestShadowName/delete/rejected" /** * @brief The length of #TEST_NAMED_TOPIC_STRING_UPDATE shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_LENGTH_UPDATE ( ( uint16_t ) sizeof( TEST_NAMED_TOPIC_STRING_UPDATE ) - 1U ) /** * @brief The length of #TEST_NAMED_TOPIC_STRING_UPDATE_ACCEPTED shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_LENGTH_UPDATE_ACCEPTED ( ( uint16_t ) sizeof( TEST_NAMED_TOPIC_STRING_UPDATE_ACCEPTED ) - 1U ) /** * @brief The length of #TEST_NAMED_TOPIC_STRING_UPDATE_REJECTED shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_LENGTH_UPDATE_REJECTED ( ( uint16_t ) sizeof( TEST_NAMED_TOPIC_STRING_UPDATE_REJECTED ) - 1U ) /** * @brief The length of #TEST_NAMED_TOPIC_STRING_UPDATE_DOCUMENTS shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_LENGTH_UPDATE_DOCUMENTS ( ( uint16_t ) sizeof( TEST_NAMED_TOPIC_STRING_UPDATE_DOCUMENTS ) - 1U ) /** * @brief The length of #TEST_NAMED_TOPIC_STRING_UPDATE_DELTA shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_LENGTH_UPDATE_DELTA ( ( uint16_t ) sizeof( TEST_NAMED_TOPIC_STRING_UPDATE_DELTA ) - 1U ) /** * @brief The length of #TEST_NAMED_TOPIC_STRING_GET shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_LENGTH_GET ( ( uint16_t ) sizeof( TEST_NAMED_TOPIC_STRING_GET ) - 1U ) /** * @brief The length of #TEST_NAMED_TOPIC_STRING_GET_ACCEPTED shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_LENGTH_GET_ACCEPTED ( ( uint16_t ) sizeof( TEST_NAMED_TOPIC_STRING_GET_ACCEPTED ) - 1U ) /** * @brief The length of #TEST_NAMED_TOPIC_STRING_GET_REJECTED shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_LENGTH_GET_REJECTED ( ( uint16_t ) sizeof( TEST_NAMED_TOPIC_STRING_GET_REJECTED ) - 1U ) /** * @brief The length of #TEST_NAMED_TOPIC_STRING_DELETE shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_LENGTH_DELETE ( ( uint16_t ) sizeof( TEST_NAMED_TOPIC_STRING_DELETE ) - 1U ) /** * @brief The length of #TEST_NAMED_TOPIC_STRING_DELETE_ACCEPTED shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_LENGTH_DELETE_ACCEPTED ( ( uint16_t ) sizeof( TEST_NAMED_TOPIC_STRING_DELETE_ACCEPTED ) - 1U ) /** * @brief The length of #TEST_NAMED_TOPIC_STRING_DELETE_REJECTED shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_LENGTH_DELETE_REJECTED ( ( uint16_t ) sizeof( TEST_NAMED_TOPIC_STRING_DELETE_REJECTED ) - 1U ) /** * @brief A topic string with an empty shadow name. */ #define TEST_NAMED_TOPIC_STRING_EMPTY_SHADOWNAME "$aws/things/TestThingName/shadow/name/" /** * @brief A topic string with an invalid shadow name. */ #define TEST_NAMED_TOPIC_STRING_INVALID_SHADOWNAME "$aws/things/TestThingName/shadow/name//" /** * @brief A topic string with an un-terminated shadow name */ #define TEST_NAMED_TOPIC_STRING_UNTERMINATED_SHADOWNAME "$aws/things/TestThingName/shadow/name/TestShadowName" /** * @brief A topic string with an empty shadow message type. */ #define TEST_NAMED_TOPIC_STRING_EMPTY_SHADOW_MESSAGE_TYPE "$aws/things/TestThingName/shadow/name/TestShadowName/" /** * @brief A topic string that is not related to Shadow. */ #define TEST_NAMED_TOPIC_STRING_INVALID_SHADOW_RESPONSE "$aws/things/TestThingName/shadow/name/TestShadowName/invalid/invalid" /** * @brief A topic string that is not related to Shadow. */ #define TEST_NAMED_TOPIC_STRING_INVALID_GET_REJECTED "$aws/things/TestThingName/shadow/name/TestShadowName/get/rejected/gibberish" /** * @brief A topic string that exceeds the maximum Thing name length. */ #define TEST_NAMED_TOPIC_STRING_EXCEEDS_MAX_THING_NAME "$aws/things/TestThingName12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/shadow/name/TestShadowName/delete/rejected" /** * @brief A topic string that exceeds the maximum Shadow name length. */ #define TEST_NAMED_TOPIC_STRING_EXCEEDS_MAX_SHADOW_NAME "$aws/things/TestThingName/shadow/name/TestShadowName123456789012345678901234567890123456789012345678901234567890/delete/rejected" /** * @brief The length of #TEST_NAMED_TOPIC_STRING_EMPTY_SHADOWNAME shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_LENGTH_EMPTY_SHADOWNAME ( ( uint16_t ) sizeof( TEST_NAMED_TOPIC_STRING_EMPTY_SHADOWNAME ) - 1U ) /** * @brief The length of #TEST_NAMED_TOPIC_STRING_INVALID_SHADOWNAME shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_LENGTH_INVALID_SHADOWNAME ( ( uint16_t ) sizeof( TEST_NAMED_TOPIC_STRING_INVALID_SHADOWNAME ) - 1U ) /** * @brief The length of #TEST_NAMED_TOPIC_STRING_UNTERMINATED_SHADOWNAME shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_LENGTH_UNTERMINATED_SHADOWNAME ( ( uint16_t ) sizeof( TEST_NAMED_TOPIC_STRING_UNTERMINATED_SHADOWNAME ) - 1U ) /** * @brief The length of #TEST_NAMED_TOPIC_STRING_EMPTY_SHADOW_MESSAGE_TYPE shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_LENGTH_EMPTY_SHADOW_MESSAGE_TYPE ( ( uint16_t ) sizeof( TEST_NAMED_TOPIC_STRING_EMPTY_SHADOW_MESSAGE_TYPE ) - 1U ) /** * @brief The length of #TEST_NAMED_TOPIC_STRING_INVALID_SHADOW_RESPONSE shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_LENGTH_INVALID_SHADOW_RESPONSE ( ( uint16_t ) sizeof( TEST_NAMED_TOPIC_STRING_INVALID_SHADOW_RESPONSE ) - 1U ) /** * @brief The length of #TEST_NAMED_TOPIC_STRING_INVALID_GET_REJECTED shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_LENGTH_INVALID_GET_REJECTED ( ( uint16_t ) sizeof( TEST_NAMED_TOPIC_STRING_INVALID_GET_REJECTED ) - 1U ) /** * @brief The length of #TEST_NAMED_TOPIC_STRING_EXCEEDS_MAX_THING_NAME. */ #define TEST_NAMED_TOPIC_LENGTH_EXCEEDS_MAX_THING_NAME ( ( uint16_t ) sizeof( TEST_NAMED_TOPIC_STRING_EXCEEDS_MAX_THING_NAME ) - 1U ) /** * @brief The length of #TEST_NAMED_TOPIC_STRING_EXCEEDS_MAX_SHADOW_NAME. */ #define TEST_NAMED_TOPIC_LENGTH_EXCEEDS_MAX_SHADOW_NAME ( ( uint16_t ) sizeof( TEST_NAMED_TOPIC_STRING_EXCEEDS_MAX_SHADOW_NAME ) - 1U ) /** * @brief The init value for a topic buffer. */ #define TEST_NAMED_TOPIC_BUFFER_INITIALIZE "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789abcdefghijklmnopqrstuvwxyz123456789" /** * @brief The init value for a topic buffer. */ #define TEST_NAMED_TOPIC_BUFFER_MODIFIED "$aws/things/TestThingName/shadow/name/TestShadowName/get/accepted56789" /** * @brief The length of #TEST_NAMED_TOPIC_STRING_DELETE_REJECTED shared among all named shadow test cases. */ #define TEST_NAMED_TOPIC_BUFFER_LENGTH ( ( uint16_t ) sizeof( TEST_NAMED_TOPIC_BUFFER_INITIALIZE ) - 1U ) /** * @brief Maximum shadow name length. * Refer to https://docs.aws.amazon.com/general/latest/gr/iot-core.html#device-shadow-limits * for more details about the Device Shadow limits. */ #define SHADOW_NAME_MAX_LENGTH ( 64U ) /** * @brief Maximum thing name length. * Refer to https://docs.aws.amazon.com/general/latest/gr/iot-core.html#device-shadow-limits * for more details about the Device Shadow limits. */ #define SHADOW_THINGNAME_MAX_LENGTH ( 128U ) /*-----------------------------------------------------------*/ /* ============================ UNITY FIXTURES ============================ */ /* Called before each test method. */ void setUp() { } /* Called after each test method. */ void tearDown() { } /* Called at the beginning of the whole suite. */ void suiteSetUp() { } /* Called at the end of the whole suite. */ int suiteTearDown( int numFailures ) { return numFailures; } /*-----------------------------------------------------------*/ /** * @brief Tests the macros generate the expected strings for Classic shadows. */ void test_Shadow_Classic_MacrosString( void ) { /* Test Classic shadow topic strings through the deprecated legacy macros, to verify the legacy macros. */ TEST_ASSERT_EQUAL( TEST_CLASSIC_TOPIC_STRING_UPDATE, SHADOW_TOPIC_STRING_UPDATE( TEST_THING_NAME ) ); TEST_ASSERT_EQUAL( TEST_CLASSIC_TOPIC_STRING_UPDATE_ACCEPTED, SHADOW_TOPIC_STRING_UPDATE_ACCEPTED( TEST_THING_NAME ) ); TEST_ASSERT_EQUAL( TEST_CLASSIC_TOPIC_STRING_UPDATE_REJECTED, SHADOW_TOPIC_STRING_UPDATE_REJECTED( TEST_THING_NAME ) ); TEST_ASSERT_EQUAL( TEST_CLASSIC_TOPIC_STRING_UPDATE_DOCUMENTS, SHADOW_TOPIC_STRING_UPDATE_DOCUMENTS( TEST_THING_NAME ) ); TEST_ASSERT_EQUAL( TEST_CLASSIC_TOPIC_STRING_UPDATE_DELTA, SHADOW_TOPIC_STRING_UPDATE_DELTA( TEST_THING_NAME ) ); TEST_ASSERT_EQUAL( TEST_CLASSIC_TOPIC_STRING_GET, SHADOW_TOPIC_STRING_GET( TEST_THING_NAME ) ); TEST_ASSERT_EQUAL( TEST_CLASSIC_TOPIC_STRING_GET_ACCEPTED, SHADOW_TOPIC_STRING_GET_ACCEPTED( TEST_THING_NAME ) ); TEST_ASSERT_EQUAL( TEST_CLASSIC_TOPIC_STRING_GET_REJECTED, SHADOW_TOPIC_STRING_GET_REJECTED( TEST_THING_NAME ) ); TEST_ASSERT_EQUAL( TEST_CLASSIC_TOPIC_STRING_DELETE, SHADOW_TOPIC_STRING_DELETE( TEST_THING_NAME ) ); TEST_ASSERT_EQUAL( TEST_CLASSIC_TOPIC_STRING_DELETE_ACCEPTED, SHADOW_TOPIC_STRING_DELETE_ACCEPTED( TEST_THING_NAME ) ); TEST_ASSERT_EQUAL( TEST_CLASSIC_TOPIC_STRING_DELETE_REJECTED, SHADOW_TOPIC_STRING_DELETE_REJECTED( TEST_THING_NAME ) ); } /** * @brief Tests the macros generate the expected strings for named shadows. */ void test_Shadow_Named_MacrosString( void ) { TEST_ASSERT_EQUAL( TEST_NAMED_TOPIC_STRING_UPDATE, SHADOW_TOPIC_STR_UPDATE( TEST_THING_NAME, TEST_SHADOW_NAME ) ); TEST_ASSERT_EQUAL( TEST_NAMED_TOPIC_STRING_UPDATE_ACCEPTED, SHADOW_TOPIC_STR_UPDATE_ACC( TEST_THING_NAME, TEST_SHADOW_NAME ) ); TEST_ASSERT_EQUAL( TEST_NAMED_TOPIC_STRING_UPDATE_REJECTED, SHADOW_TOPIC_STR_UPDATE_REJ( TEST_THING_NAME, TEST_SHADOW_NAME ) ); TEST_ASSERT_EQUAL( TEST_NAMED_TOPIC_STRING_UPDATE_DOCUMENTS, SHADOW_TOPIC_STR_UPDATE_DOCS( TEST_THING_NAME, TEST_SHADOW_NAME ) ); TEST_ASSERT_EQUAL( TEST_NAMED_TOPIC_STRING_UPDATE_DELTA, SHADOW_TOPIC_STR_UPDATE_DELTA( TEST_THING_NAME, TEST_SHADOW_NAME ) ); TEST_ASSERT_EQUAL( TEST_NAMED_TOPIC_STRING_GET, SHADOW_TOPIC_STR_GET( TEST_THING_NAME, TEST_SHADOW_NAME ) ); TEST_ASSERT_EQUAL( TEST_NAMED_TOPIC_STRING_GET_ACCEPTED, SHADOW_TOPIC_STR_GET_ACC( TEST_THING_NAME, TEST_SHADOW_NAME ) ); TEST_ASSERT_EQUAL( TEST_NAMED_TOPIC_STRING_GET_REJECTED, SHADOW_TOPIC_STR_GET_REJ( TEST_THING_NAME, TEST_SHADOW_NAME ) ); TEST_ASSERT_EQUAL( TEST_NAMED_TOPIC_STRING_DELETE, SHADOW_TOPIC_STR_DELETE( TEST_THING_NAME, TEST_SHADOW_NAME ) ); TEST_ASSERT_EQUAL( TEST_NAMED_TOPIC_STRING_DELETE_ACCEPTED, SHADOW_TOPIC_STR_DELETE_ACC( TEST_THING_NAME, TEST_SHADOW_NAME ) ); TEST_ASSERT_EQUAL( TEST_NAMED_TOPIC_STRING_DELETE_REJECTED, SHADOW_TOPIC_STR_DELETE_REJ( TEST_THING_NAME, TEST_SHADOW_NAME ) ); } /*-----------------------------------------------------------*/ /** * @brief Tests the macros generate the expected strings length for Classic shadows. */ void test_Shadow_Classic_MacrosLength( void ) { /* Test Classic shadow topic lengths through the deprecated legacy macros, to verify the legacy macros. */ TEST_ASSERT_EQUAL( TEST_CLASSIC_TOPIC_LENGTH_UPDATE, SHADOW_TOPIC_LENGTH_UPDATE( TEST_THING_NAME_LENGTH ) ); TEST_ASSERT_EQUAL( TEST_CLASSIC_TOPIC_LENGTH_UPDATE_ACCEPTED, SHADOW_TOPIC_LENGTH_UPDATE_ACCEPTED( TEST_THING_NAME_LENGTH ) ); TEST_ASSERT_EQUAL( TEST_CLASSIC_TOPIC_LENGTH_UPDATE_REJECTED, SHADOW_TOPIC_LENGTH_UPDATE_REJECTED( TEST_THING_NAME_LENGTH ) ); TEST_ASSERT_EQUAL( TEST_CLASSIC_TOPIC_LENGTH_UPDATE_DOCUMENTS, SHADOW_TOPIC_LENGTH_UPDATE_DOCUMENTS( TEST_THING_NAME_LENGTH ) ); TEST_ASSERT_EQUAL( TEST_CLASSIC_TOPIC_LENGTH_UPDATE_DELTA, SHADOW_TOPIC_LENGTH_UPDATE_DELTA( TEST_THING_NAME_LENGTH ) ); TEST_ASSERT_EQUAL( TEST_CLASSIC_TOPIC_LENGTH_GET, SHADOW_TOPIC_LENGTH_GET( TEST_THING_NAME_LENGTH ) ); TEST_ASSERT_EQUAL( TEST_CLASSIC_TOPIC_LENGTH_GET_ACCEPTED, SHADOW_TOPIC_LENGTH_GET_ACCEPTED( TEST_THING_NAME_LENGTH ) ); TEST_ASSERT_EQUAL( TEST_CLASSIC_TOPIC_LENGTH_GET_REJECTED, SHADOW_TOPIC_LENGTH_GET_REJECTED( TEST_THING_NAME_LENGTH ) ); TEST_ASSERT_EQUAL( TEST_CLASSIC_TOPIC_LENGTH_DELETE, SHADOW_TOPIC_LENGTH_DELETE( TEST_THING_NAME_LENGTH ) ); TEST_ASSERT_EQUAL( TEST_CLASSIC_TOPIC_LENGTH_DELETE_ACCEPTED, SHADOW_TOPIC_LENGTH_DELETE_ACCEPTED( TEST_THING_NAME_LENGTH ) ); TEST_ASSERT_EQUAL( TEST_CLASSIC_TOPIC_LENGTH_DELETE_REJECTED, SHADOW_TOPIC_LENGTH_DELETE_REJECTED( TEST_THING_NAME_LENGTH ) ); } /** * @brief Tests the macros generate the expected strings length for named shadows. */ void test_Shadow_Named_MacrosLength( void ) { TEST_ASSERT_EQUAL( TEST_NAMED_TOPIC_LENGTH_UPDATE, SHADOW_TOPIC_LEN_UPDATE( TEST_THING_NAME_LENGTH, TEST_SHADOW_NAME_LENGTH ) ); TEST_ASSERT_EQUAL( TEST_NAMED_TOPIC_LENGTH_UPDATE_ACCEPTED, SHADOW_TOPIC_LEN_UPDATE_ACC( TEST_THING_NAME_LENGTH, TEST_SHADOW_NAME_LENGTH ) ); TEST_ASSERT_EQUAL( TEST_NAMED_TOPIC_LENGTH_UPDATE_REJECTED, SHADOW_TOPIC_LEN_UPDATE_REJ( TEST_THING_NAME_LENGTH, TEST_SHADOW_NAME_LENGTH ) ); TEST_ASSERT_EQUAL( TEST_NAMED_TOPIC_LENGTH_UPDATE_DOCUMENTS, SHADOW_TOPIC_LEN_UPDATE_DOCS( TEST_THING_NAME_LENGTH, TEST_SHADOW_NAME_LENGTH ) ); TEST_ASSERT_EQUAL( TEST_NAMED_TOPIC_LENGTH_UPDATE_DELTA, SHADOW_TOPIC_LEN_UPDATE_DELTA( TEST_THING_NAME_LENGTH, TEST_SHADOW_NAME_LENGTH ) ); TEST_ASSERT_EQUAL( TEST_NAMED_TOPIC_LENGTH_GET, SHADOW_TOPIC_LEN_GET( TEST_THING_NAME_LENGTH, TEST_SHADOW_NAME_LENGTH ) ); TEST_ASSERT_EQUAL( TEST_NAMED_TOPIC_LENGTH_GET_ACCEPTED, SHADOW_TOPIC_LEN_GET_ACC( TEST_THING_NAME_LENGTH, TEST_SHADOW_NAME_LENGTH ) ); TEST_ASSERT_EQUAL( TEST_NAMED_TOPIC_LENGTH_GET_REJECTED, SHADOW_TOPIC_LEN_GET_REJ( TEST_THING_NAME_LENGTH, TEST_SHADOW_NAME_LENGTH ) ); TEST_ASSERT_EQUAL( TEST_NAMED_TOPIC_LENGTH_DELETE, SHADOW_TOPIC_LEN_DELETE( TEST_THING_NAME_LENGTH, TEST_SHADOW_NAME_LENGTH ) ); TEST_ASSERT_EQUAL( TEST_NAMED_TOPIC_LENGTH_DELETE_ACCEPTED, SHADOW_TOPIC_LEN_DELETE_ACC( TEST_THING_NAME_LENGTH, TEST_SHADOW_NAME_LENGTH ) ); TEST_ASSERT_EQUAL( TEST_NAMED_TOPIC_LENGTH_DELETE_REJECTED, SHADOW_TOPIC_LEN_DELETE_REJ( TEST_THING_NAME_LENGTH, TEST_SHADOW_NAME_LENGTH ) ); } /*-----------------------------------------------------------*/ /** * @brief Tests the behavior of Shadow_AssembleTopicString() for Classic shadows, * with valid parameters. Tests Classic shadows through the deprecated legacy API macro * Shadow_GetTopicString(), to verify the legacy macro. */ void test_Shadow_AssembleTopicString_Classic_Happy_Path( void ) { ShadowStatus_t shadowStatus = SHADOW_SUCCESS; uint16_t outLength = 0U; char topicBufferExceeded[ TEST_CLASSIC_TOPIC_BUFFER_LENGTH ] = TEST_CLASSIC_TOPIC_BUFFER_INITIALIZE; uint16_t bufferSizeExceeded = TEST_CLASSIC_TOPIC_BUFFER_LENGTH; char topicBufferGetAccepted[ SHADOW_TOPIC_LENGTH_GET_ACCEPTED( TEST_THING_NAME_LENGTH ) ] = { 0 }; uint16_t bufferSizeGetAccepted = TEST_CLASSIC_TOPIC_LENGTH_GET_ACCEPTED; char topicBuffer[ SHADOW_TOPIC_LENGTH_MAX( TEST_THING_NAME_LENGTH ) ] = { 0 }; uint16_t bufferSize = SHADOW_TOPIC_LENGTH_MAX( TEST_THING_NAME_LENGTH ); uint16_t index = 0U; /* Lookup table for Shadow message string. */ static const uint16_t expectedBuffersSize[ ShadowTopicStringTypeMaxNum ] = { TEST_CLASSIC_TOPIC_LENGTH_UPDATE, TEST_CLASSIC_TOPIC_LENGTH_UPDATE_ACCEPTED, TEST_CLASSIC_TOPIC_LENGTH_UPDATE_REJECTED, TEST_CLASSIC_TOPIC_LENGTH_UPDATE_DOCUMENTS, TEST_CLASSIC_TOPIC_LENGTH_UPDATE_DELTA, TEST_CLASSIC_TOPIC_LENGTH_GET, TEST_CLASSIC_TOPIC_LENGTH_GET_ACCEPTED, TEST_CLASSIC_TOPIC_LENGTH_GET_REJECTED, TEST_CLASSIC_TOPIC_LENGTH_DELETE, TEST_CLASSIC_TOPIC_LENGTH_DELETE_ACCEPTED, TEST_CLASSIC_TOPIC_LENGTH_DELETE_REJECTED }; /* Lookup table for Shadow message string. */ static const char * const expectedBuffers[ ShadowTopicStringTypeMaxNum ] = { TEST_CLASSIC_TOPIC_STRING_UPDATE, TEST_CLASSIC_TOPIC_STRING_UPDATE_ACCEPTED, TEST_CLASSIC_TOPIC_STRING_UPDATE_REJECTED, TEST_CLASSIC_TOPIC_STRING_UPDATE_DOCUMENTS, TEST_CLASSIC_TOPIC_STRING_UPDATE_DELTA, TEST_CLASSIC_TOPIC_STRING_GET, TEST_CLASSIC_TOPIC_STRING_GET_ACCEPTED, TEST_CLASSIC_TOPIC_STRING_GET_REJECTED, TEST_CLASSIC_TOPIC_STRING_DELETE, TEST_CLASSIC_TOPIC_STRING_DELETE_ACCEPTED, TEST_CLASSIC_TOPIC_STRING_DELETE_REJECTED }; static const ShadowTopicStringType_t topicTypes[ ShadowTopicStringTypeMaxNum ] = { ShadowTopicStringTypeUpdate, ShadowTopicStringTypeUpdateAccepted, ShadowTopicStringTypeUpdateRejected, ShadowTopicStringTypeUpdateDocuments, ShadowTopicStringTypeUpdateDelta, ShadowTopicStringTypeGet, ShadowTopicStringTypeGetAccepted, ShadowTopicStringTypeGetRejected, ShadowTopicStringTypeDelete, ShadowTopicStringTypeDeleteAccepted, ShadowTopicStringTypeDeleteRejected }; /* Call Shadow_GetTopicString() with valid parameters but bufferSize exceeds topic string length * and verify result. */ shadowStatus = Shadow_GetTopicString( ShadowTopicStringTypeGetAccepted, TEST_THING_NAME, TEST_THING_NAME_LENGTH, &( topicBufferExceeded[ 0 ] ), bufferSizeExceeded, &outLength ); TEST_ASSERT_EQUAL_INT( SHADOW_SUCCESS, shadowStatus ); TEST_ASSERT_EQUAL_INT( TEST_CLASSIC_TOPIC_LENGTH_GET_ACCEPTED, outLength ); TEST_ASSERT_LESS_THAN( bufferSizeExceeded, outLength ); TEST_ASSERT_EQUAL_STRING_LEN( TEST_CLASSIC_TOPIC_BUFFER_MODIFIED, topicBufferExceeded, bufferSizeExceeded ); /* Call Shadow_GetTopicString() with valid parameters, bufferSize = expected outLength * and verify result. */ shadowStatus = Shadow_GetTopicString( ShadowTopicStringTypeGetAccepted, TEST_THING_NAME, TEST_THING_NAME_LENGTH, &( topicBufferGetAccepted[ 0 ] ), bufferSizeGetAccepted, &outLength ); TEST_ASSERT_EQUAL_INT( TEST_CLASSIC_TOPIC_LENGTH_GET_ACCEPTED, outLength ); TEST_ASSERT_EQUAL_STRING_LEN( TEST_CLASSIC_TOPIC_STRING_GET_ACCEPTED, topicBufferGetAccepted, bufferSizeGetAccepted ); for( index = 0U; index < ShadowTopicStringTypeMaxNum; index++ ) { /* Call Shadow_GetTopicString() with valid parameters with all types of topic string * and verify result. */ shadowStatus = Shadow_GetTopicString( topicTypes[ index ], TEST_THING_NAME, TEST_THING_NAME_LENGTH, &( topicBuffer[ 0 ] ), bufferSize, &outLength ); TEST_ASSERT_EQUAL_INT( expectedBuffersSize[ index ], outLength ); TEST_ASSERT_EQUAL_STRING_LEN( expectedBuffers[ index ], topicBuffer, outLength ); } /* Call Shadow_AssembleTopicString() with valid parameters. * Use classic shadow by passing NULL for shadow name and 0 for shadow name length. */ shadowStatus = Shadow_AssembleTopicString( ShadowTopicStringTypeGetAccepted, TEST_THING_NAME, TEST_THING_NAME_LENGTH, NULL, 0, &( topicBufferGetAccepted[ 0 ] ), bufferSizeGetAccepted, &outLength ); TEST_ASSERT_EQUAL_INT( TEST_CLASSIC_TOPIC_LENGTH_GET_ACCEPTED, outLength ); TEST_ASSERT_EQUAL_STRING_LEN( TEST_CLASSIC_TOPIC_STRING_GET_ACCEPTED, topicBufferGetAccepted, bufferSizeGetAccepted ); } /** * @brief Tests the behavior of Shadow_AssembleTopicString() for named shadows, with valid parameters. */ void test_Shadow_AssembleTopicString_Named_Happy_Path( void ) { ShadowStatus_t shadowStatus = SHADOW_SUCCESS; uint16_t outLength = 0U; char topicBufferExceeded[ TEST_NAMED_TOPIC_BUFFER_LENGTH ] = TEST_NAMED_TOPIC_BUFFER_INITIALIZE; uint16_t bufferSizeExceeded = TEST_NAMED_TOPIC_BUFFER_LENGTH; char topicBufferGetAccepted[ SHADOW_TOPIC_LEN_GET_ACC( TEST_THING_NAME_LENGTH, TEST_SHADOW_NAME_LENGTH ) ] = { 0 }; uint16_t bufferSizeGetAccepted = TEST_NAMED_TOPIC_LENGTH_GET_ACCEPTED; char topicBuffer[ SHADOW_TOPIC_LEN_MAX( TEST_THING_NAME_LENGTH, TEST_SHADOW_NAME_LENGTH ) ] = { 0 }; uint16_t bufferSize = SHADOW_TOPIC_LEN_MAX( TEST_THING_NAME_LENGTH, TEST_SHADOW_NAME_LENGTH ); uint16_t index = 0U; /* Lookup table for Shadow message string. */ static const uint16_t expectedBuffersSize[ ShadowTopicStringTypeMaxNum ] = { TEST_NAMED_TOPIC_LENGTH_UPDATE, TEST_NAMED_TOPIC_LENGTH_UPDATE_ACCEPTED, TEST_NAMED_TOPIC_LENGTH_UPDATE_REJECTED, TEST_NAMED_TOPIC_LENGTH_UPDATE_DOCUMENTS, TEST_NAMED_TOPIC_LENGTH_UPDATE_DELTA, TEST_NAMED_TOPIC_LENGTH_GET, TEST_NAMED_TOPIC_LENGTH_GET_ACCEPTED, TEST_NAMED_TOPIC_LENGTH_GET_REJECTED, TEST_NAMED_TOPIC_LENGTH_DELETE, TEST_NAMED_TOPIC_LENGTH_DELETE_ACCEPTED, TEST_NAMED_TOPIC_LENGTH_DELETE_REJECTED }; /* Lookup table for Shadow message string. */ static const char * const expectedBuffers[ ShadowTopicStringTypeMaxNum ] = { TEST_NAMED_TOPIC_STRING_UPDATE, TEST_NAMED_TOPIC_STRING_UPDATE_ACCEPTED, TEST_NAMED_TOPIC_STRING_UPDATE_REJECTED, TEST_NAMED_TOPIC_STRING_UPDATE_DOCUMENTS, TEST_NAMED_TOPIC_STRING_UPDATE_DELTA, TEST_NAMED_TOPIC_STRING_GET, TEST_NAMED_TOPIC_STRING_GET_ACCEPTED, TEST_NAMED_TOPIC_STRING_GET_REJECTED, TEST_NAMED_TOPIC_STRING_DELETE, TEST_NAMED_TOPIC_STRING_DELETE_ACCEPTED, TEST_NAMED_TOPIC_STRING_DELETE_REJECTED }; static const ShadowTopicStringType_t topicTypes[ ShadowTopicStringTypeMaxNum ] = { ShadowTopicStringTypeUpdate, ShadowTopicStringTypeUpdateAccepted, ShadowTopicStringTypeUpdateRejected, ShadowTopicStringTypeUpdateDocuments, ShadowTopicStringTypeUpdateDelta, ShadowTopicStringTypeGet, ShadowTopicStringTypeGetAccepted, ShadowTopicStringTypeGetRejected, ShadowTopicStringTypeDelete, ShadowTopicStringTypeDeleteAccepted, ShadowTopicStringTypeDeleteRejected }; /* Call Shadow_AssembleTopicString() with valid parameters but bufferSize exceeds topic string length * and verify result. */ shadowStatus = Shadow_AssembleTopicString( ShadowTopicStringTypeGetAccepted, TEST_THING_NAME, TEST_THING_NAME_LENGTH, TEST_SHADOW_NAME, TEST_SHADOW_NAME_LENGTH, &( topicBufferExceeded[ 0 ] ), bufferSizeExceeded, &outLength ); TEST_ASSERT_EQUAL_INT( SHADOW_SUCCESS, shadowStatus ); TEST_ASSERT_EQUAL_INT( TEST_NAMED_TOPIC_LENGTH_GET_ACCEPTED, outLength ); TEST_ASSERT_LESS_THAN( bufferSizeExceeded, outLength ); TEST_ASSERT_EQUAL_STRING_LEN( TEST_NAMED_TOPIC_BUFFER_MODIFIED, topicBufferExceeded, bufferSizeExceeded ); /* Call Shadow_AssembleTopicString() with valid parameters, bufferSize = expected outLength * and verify result. */ shadowStatus = Shadow_AssembleTopicString( ShadowTopicStringTypeGetAccepted, TEST_THING_NAME, TEST_THING_NAME_LENGTH, TEST_SHADOW_NAME, TEST_SHADOW_NAME_LENGTH, &( topicBufferGetAccepted[ 0 ] ), bufferSizeGetAccepted, &outLength ); TEST_ASSERT_EQUAL_INT( TEST_NAMED_TOPIC_LENGTH_GET_ACCEPTED, outLength ); TEST_ASSERT_EQUAL_STRING_LEN( TEST_NAMED_TOPIC_STRING_GET_ACCEPTED, topicBufferGetAccepted, bufferSizeGetAccepted ); for( index = 0U; index < ShadowTopicStringTypeMaxNum; index++ ) { /* Call Shadow_AssembleTopicString() with valid parameters with all types of topic string * and verify result. */ shadowStatus = Shadow_AssembleTopicString( topicTypes[ index ], TEST_THING_NAME, TEST_THING_NAME_LENGTH, TEST_SHADOW_NAME, TEST_SHADOW_NAME_LENGTH, &( topicBuffer[ 0 ] ), bufferSize, &outLength ); TEST_ASSERT_EQUAL_INT( expectedBuffersSize[ index ], outLength ); TEST_ASSERT_EQUAL_STRING_LEN( expectedBuffers[ index ], topicBuffer, outLength ); } } /*-----------------------------------------------------------*/ /** * @brief Tests the behavior of Shadow_AssembleTopicString() with invalid parameters */ void test_Shadow_AssembleTopicString_Invalid_Parameters( void ) { ShadowStatus_t shadowStatus = SHADOW_SUCCESS; uint16_t outLength = 0U; ShadowTopicStringType_t topicType = ShadowTopicStringTypeGetAccepted; char classicTopicBuffer[ TEST_CLASSIC_TOPIC_LENGTH_GET_ACCEPTED ]; uint16_t classicBufferSize = TEST_CLASSIC_TOPIC_LENGTH_GET_ACCEPTED; char namedTopicBuffer[ TEST_NAMED_TOPIC_LENGTH_GET_ACCEPTED ]; uint16_t namedBufferSize = TEST_NAMED_TOPIC_LENGTH_GET_ACCEPTED; /* Call Shadow_AssembleTopicString() with various combinations of * incorrect parameters. */ shadowStatus = Shadow_AssembleTopicString( 0, "", 0, SHADOW_NAME_CLASSIC, 0, classicTopicBuffer, classicBufferSize, &outLength ); TEST_ASSERT_EQUAL_INT( SHADOW_BAD_PARAMETER, shadowStatus ); shadowStatus = Shadow_AssembleTopicString( 0, NULL, 0, SHADOW_NAME_CLASSIC, 0, classicTopicBuffer, classicBufferSize, &outLength ); TEST_ASSERT_EQUAL_INT( SHADOW_BAD_PARAMETER, shadowStatus ); shadowStatus = Shadow_AssembleTopicString( topicType, TEST_THING_NAME, TEST_THING_NAME_LENGTH, SHADOW_NAME_CLASSIC, 0, NULL, 0, &outLength ); TEST_ASSERT_EQUAL_INT( SHADOW_BAD_PARAMETER, shadowStatus ); shadowStatus = Shadow_AssembleTopicString( ShadowTopicStringTypeMaxNum + 1, TEST_THING_NAME, TEST_THING_NAME_LENGTH, SHADOW_NAME_CLASSIC, 0, classicTopicBuffer, classicBufferSize, &outLength ); TEST_ASSERT_EQUAL_INT( SHADOW_BAD_PARAMETER, shadowStatus ); shadowStatus = Shadow_AssembleTopicString( topicType, TEST_THING_NAME, TEST_THING_NAME_LENGTH, SHADOW_NAME_CLASSIC, 0, classicTopicBuffer, classicBufferSize, NULL ); TEST_ASSERT_EQUAL_INT( SHADOW_BAD_PARAMETER, shadowStatus ); shadowStatus = Shadow_AssembleTopicString( topicType, TEST_THING_NAME, TEST_THING_NAME_LENGTH, NULL, 1, namedTopicBuffer, namedBufferSize, &outLength ); TEST_ASSERT_EQUAL_INT( SHADOW_BAD_PARAMETER, shadowStatus ); shadowStatus = Shadow_AssembleTopicString( topicType, TEST_THING_NAME, SHADOW_THINGNAME_MAX_LENGTH + 1, TEST_SHADOW_NAME, TEST_SHADOW_NAME_LENGTH, namedTopicBuffer, namedBufferSize, &outLength ); TEST_ASSERT_EQUAL_INT( SHADOW_BAD_PARAMETER, shadowStatus ); shadowStatus = Shadow_AssembleTopicString( topicType, TEST_THING_NAME, TEST_THING_NAME_LENGTH, TEST_SHADOW_NAME, SHADOW_NAME_MAX_LENGTH + 1, namedTopicBuffer, namedBufferSize, &outLength ); TEST_ASSERT_EQUAL_INT( SHADOW_BAD_PARAMETER, shadowStatus ); shadowStatus = Shadow_AssembleTopicString( topicType, TEST_THING_NAME, TEST_THING_NAME_LENGTH, SHADOW_NAME_CLASSIC, 0, classicTopicBuffer, 0, &outLength ); TEST_ASSERT_EQUAL_INT( SHADOW_BUFFER_TOO_SMALL, shadowStatus ); shadowStatus = Shadow_AssembleTopicString( topicType, TEST_THING_NAME, TEST_THING_NAME_LENGTH, SHADOW_NAME_CLASSIC, 0, classicTopicBuffer, ( classicBufferSize - 1 ), &outLength ); TEST_ASSERT_EQUAL_INT( SHADOW_BUFFER_TOO_SMALL, shadowStatus ); shadowStatus = Shadow_AssembleTopicString( topicType, TEST_THING_NAME, TEST_THING_NAME_LENGTH, TEST_SHADOW_NAME, TEST_SHADOW_NAME_LENGTH, namedTopicBuffer, ( namedBufferSize - 1 ), &outLength ); TEST_ASSERT_EQUAL_INT( SHADOW_BUFFER_TOO_SMALL, shadowStatus ); } /*-----------------------------------------------------------*/ /** * @brief Tests the behavior of Shadow_MatchTopicString() for classic shadow with valid parameters. Tests Classic * shadows through the deprecated legacy API Shadow_MatchTopic(). */ void test_Shadow_MatchTopicString_Classic_Happy_Path( void ) { ShadowStatus_t shadowStatus = SHADOW_SUCCESS; ShadowMessageType_t messageType = ShadowMessageTypeMaxNum; const char * pThingName = NULL; uint16_t thingNameLength = 0U; const char topicBuffer[ TEST_CLASSIC_TOPIC_LENGTH_UPDATE_ACCEPTED ] = TEST_CLASSIC_TOPIC_STRING_UPDATE_ACCEPTED; uint16_t bufferSize = TEST_CLASSIC_TOPIC_LENGTH_UPDATE_ACCEPTED; /* Call Shadow_MatchTopic() with valid parameters and verify result. */ shadowStatus = Shadow_MatchTopic( &( topicBuffer[ 0 ] ), bufferSize, &messageType, &pThingName, &thingNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_SUCCESS, shadowStatus ); TEST_ASSERT_EQUAL_INT( TEST_THING_NAME_LENGTH, thingNameLength ); TEST_ASSERT_EQUAL_INT( ShadowMessageTypeUpdateAccepted, messageType ); TEST_ASSERT_EQUAL_STRING_LEN( TEST_THING_NAME, pThingName, TEST_THING_NAME_LENGTH ); shadowStatus = Shadow_MatchTopic( &( topicBuffer[ 0 ] ), bufferSize, &messageType, NULL, &thingNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_SUCCESS, shadowStatus ); TEST_ASSERT_EQUAL_INT( TEST_THING_NAME_LENGTH, thingNameLength ); TEST_ASSERT_EQUAL_INT( ShadowMessageTypeUpdateAccepted, messageType ); shadowStatus = Shadow_MatchTopic( &( topicBuffer[ 0 ] ), bufferSize, &messageType, &pThingName, NULL ); TEST_ASSERT_EQUAL_INT( SHADOW_SUCCESS, shadowStatus ); TEST_ASSERT_EQUAL_INT( ShadowMessageTypeUpdateAccepted, messageType ); TEST_ASSERT_EQUAL_STRING_LEN( TEST_THING_NAME, pThingName, TEST_THING_NAME_LENGTH ); shadowStatus = Shadow_MatchTopic( &( topicBuffer[ 0 ] ), bufferSize, &messageType, NULL, NULL ); TEST_ASSERT_EQUAL_INT( SHADOW_SUCCESS, shadowStatus ); TEST_ASSERT_EQUAL_INT( ShadowMessageTypeUpdateAccepted, messageType ); } /** * @brief Tests the behavior of Shadow_MatchTopicString() for named shadows with valid parameters. */ void test_Shadow_MatchTopicString_Named_Happy_Path( void ) { ShadowStatus_t shadowStatus = SHADOW_SUCCESS; ShadowMessageType_t messageType = ShadowMessageTypeMaxNum; const char * pThingName = NULL; uint8_t thingNameLength = 0U; const char * pShadowName = NULL; uint8_t shadowNameLength = 0U; const char topicBuffer[ TEST_NAMED_TOPIC_LENGTH_UPDATE_ACCEPTED ] = TEST_NAMED_TOPIC_STRING_UPDATE_ACCEPTED; uint16_t bufferSize = TEST_NAMED_TOPIC_LENGTH_UPDATE_ACCEPTED; /* Call Shadow_MatchTopicString() with valid parameters and verify result. */ shadowStatus = Shadow_MatchTopicString( &( topicBuffer[ 0 ] ), bufferSize, &messageType, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_SUCCESS, shadowStatus ); TEST_ASSERT_EQUAL_INT( TEST_THING_NAME_LENGTH, thingNameLength ); TEST_ASSERT_EQUAL_INT( ShadowMessageTypeUpdateAccepted, messageType ); TEST_ASSERT_EQUAL_STRING_LEN( TEST_THING_NAME, pThingName, TEST_THING_NAME_LENGTH ); TEST_ASSERT_EQUAL_INT( TEST_SHADOW_NAME_LENGTH, shadowNameLength ); TEST_ASSERT_EQUAL_STRING_LEN( TEST_SHADOW_NAME, pShadowName, TEST_SHADOW_NAME_LENGTH ); shadowStatus = Shadow_MatchTopicString( &( topicBuffer[ 0 ] ), bufferSize, &messageType, &pThingName, NULL, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_SUCCESS, shadowStatus ); TEST_ASSERT_EQUAL_INT( ShadowMessageTypeUpdateAccepted, messageType ); TEST_ASSERT_EQUAL_STRING_LEN( TEST_THING_NAME, pThingName, TEST_THING_NAME_LENGTH ); TEST_ASSERT_EQUAL_INT( TEST_SHADOW_NAME_LENGTH, shadowNameLength ); TEST_ASSERT_EQUAL_STRING_LEN( TEST_SHADOW_NAME, pShadowName, TEST_SHADOW_NAME_LENGTH ); shadowStatus = Shadow_MatchTopicString( &( topicBuffer[ 0 ] ), bufferSize, &messageType, &pThingName, &thingNameLength, NULL, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_SUCCESS, shadowStatus ); TEST_ASSERT_EQUAL_INT( TEST_THING_NAME_LENGTH, thingNameLength ); TEST_ASSERT_EQUAL_INT( ShadowMessageTypeUpdateAccepted, messageType ); TEST_ASSERT_EQUAL_STRING_LEN( TEST_THING_NAME, pThingName, TEST_THING_NAME_LENGTH ); TEST_ASSERT_EQUAL_INT( TEST_SHADOW_NAME_LENGTH, shadowNameLength ); shadowStatus = Shadow_MatchTopicString( &( topicBuffer[ 0 ] ), bufferSize, &messageType, &pThingName, &thingNameLength, &pShadowName, NULL ); TEST_ASSERT_EQUAL_INT( SHADOW_SUCCESS, shadowStatus ); TEST_ASSERT_EQUAL_INT( TEST_THING_NAME_LENGTH, thingNameLength ); TEST_ASSERT_EQUAL_INT( ShadowMessageTypeUpdateAccepted, messageType ); TEST_ASSERT_EQUAL_STRING_LEN( TEST_THING_NAME, pThingName, TEST_THING_NAME_LENGTH ); TEST_ASSERT_EQUAL_STRING_LEN( TEST_SHADOW_NAME, pShadowName, TEST_SHADOW_NAME_LENGTH ); shadowStatus = Shadow_MatchTopicString( &( topicBuffer[ 0 ] ), bufferSize, &messageType, &pThingName, &thingNameLength, NULL, NULL ); TEST_ASSERT_EQUAL_INT( SHADOW_SUCCESS, shadowStatus ); TEST_ASSERT_EQUAL_INT( TEST_THING_NAME_LENGTH, thingNameLength ); TEST_ASSERT_EQUAL_INT( ShadowMessageTypeUpdateAccepted, messageType ); TEST_ASSERT_EQUAL_STRING_LEN( TEST_THING_NAME, pThingName, TEST_THING_NAME_LENGTH ); } /*-----------------------------------------------------------*/ /** * @brief Tests the behavior of Shadow_MatchTopicString() with various * invalid parameters */ void test_Shadow_MatchTopicString_Invalid_Parameters( void ) { ShadowStatus_t shadowStatus = SHADOW_SUCCESS; ShadowMessageType_t messageType = ShadowMessageTypeMaxNum; const char * pThingName = NULL; uint8_t thingNameLength = 0U; const char * pShadowName = NULL; uint8_t shadowNameLength = 0U; const char classicTopicBuffer[ TEST_CLASSIC_TOPIC_LENGTH_UPDATE_ACCEPTED ] = TEST_CLASSIC_TOPIC_STRING_UPDATE_ACCEPTED; uint16_t classicBufferSize = TEST_CLASSIC_TOPIC_LENGTH_UPDATE_ACCEPTED; const char namedTopicBuffer[ TEST_NAMED_TOPIC_LENGTH_UPDATE_ACCEPTED ] = TEST_NAMED_TOPIC_STRING_UPDATE_ACCEPTED; uint16_t namedBufferSize = TEST_NAMED_TOPIC_LENGTH_UPDATE_ACCEPTED; /* Call Shadow_MatchTopicString() with various combinations of * incorrect parameters. */ shadowStatus = Shadow_MatchTopicString( NULL, classicBufferSize, &messageType, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_BAD_PARAMETER, shadowStatus ); shadowStatus = Shadow_MatchTopicString( classicTopicBuffer, 0, &messageType, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_BAD_PARAMETER, shadowStatus ); shadowStatus = Shadow_MatchTopicString( classicTopicBuffer, classicBufferSize, NULL, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_BAD_PARAMETER, shadowStatus ); shadowStatus = Shadow_MatchTopicString( TEST_TOPIC_STRING_INVALID_PREFIX, TEST_TOPIC_LENGTH_INVALID_PREFIX, &messageType, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_FAIL, shadowStatus ); shadowStatus = Shadow_MatchTopicString( TEST_TOPIC_STRING_EMPTY_THINGNAME, TEST_TOPIC_LENGTH_EMPTY_THINGNAME, &messageType, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_THINGNAME_PARSE_FAILED, shadowStatus ); shadowStatus = Shadow_MatchTopicString( TEST_TOPIC_STRING_INVALID_THINGNAME, TEST_TOPIC_LENGTH_INVALID_THINGNAME, &messageType, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_THINGNAME_PARSE_FAILED, shadowStatus ); shadowStatus = Shadow_MatchTopicString( TEST_TOPIC_STRING_UNTERMINATED_THINGNAME, TEST_TOPIC_LENGTH_UNTERMINATED_THINGNAME, &messageType, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_THINGNAME_PARSE_FAILED, shadowStatus ); shadowStatus = Shadow_MatchTopicString( TEST_NAMED_TOPIC_STRING_EXCEEDS_MAX_THING_NAME, TEST_NAMED_TOPIC_LENGTH_EXCEEDS_MAX_THING_NAME, &messageType, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_THINGNAME_PARSE_FAILED, shadowStatus ); shadowStatus = Shadow_MatchTopicString( TEST_TOPIC_STRING_EMPTY_SHADOW_ROOT, TEST_TOPIC_LENGTH_EMPTY_SHADOW_ROOT, &messageType, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_ROOT_PARSE_FAILED, shadowStatus ); shadowStatus = Shadow_MatchTopicString( TEST_TOPIC_STRING_INVALID_SHADOW_ROOT, TEST_TOPIC_LENGTH_INVALID_SHADOW_ROOT, &messageType, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_ROOT_PARSE_FAILED, shadowStatus ); shadowStatus = Shadow_MatchTopicString( TEST_NAMED_TOPIC_STRING_EMPTY_SHADOWNAME, TEST_NAMED_TOPIC_LENGTH_EMPTY_SHADOWNAME, &messageType, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_SHADOWNAME_PARSE_FAILED, shadowStatus ); shadowStatus = Shadow_MatchTopicString( TEST_NAMED_TOPIC_STRING_INVALID_SHADOWNAME, TEST_NAMED_TOPIC_LENGTH_INVALID_SHADOWNAME, &messageType, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_SHADOWNAME_PARSE_FAILED, shadowStatus ); shadowStatus = Shadow_MatchTopicString( TEST_NAMED_TOPIC_STRING_UNTERMINATED_SHADOWNAME, TEST_NAMED_TOPIC_LENGTH_UNTERMINATED_SHADOWNAME, &messageType, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_SHADOWNAME_PARSE_FAILED, shadowStatus ); shadowStatus = Shadow_MatchTopicString( TEST_NAMED_TOPIC_STRING_EXCEEDS_MAX_SHADOW_NAME, TEST_NAMED_TOPIC_LENGTH_EXCEEDS_MAX_SHADOW_NAME, &messageType, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_SHADOWNAME_PARSE_FAILED, shadowStatus ); shadowStatus = Shadow_MatchTopicString( TEST_CLASSIC_TOPIC_STRING_EMPTY_SHADOW_MESSAGE_TYPE, TEST_CLASSIC_TOPIC_LENGTH_EMPTY_SHADOW_MESSAGE_TYPE, &messageType, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_MESSAGE_TYPE_PARSE_FAILED, shadowStatus ); shadowStatus = Shadow_MatchTopicString( TEST_NAMED_TOPIC_STRING_EMPTY_SHADOW_MESSAGE_TYPE, TEST_NAMED_TOPIC_LENGTH_EMPTY_SHADOW_MESSAGE_TYPE, &messageType, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_MESSAGE_TYPE_PARSE_FAILED, shadowStatus ); shadowStatus = Shadow_MatchTopicString( TEST_CLASSIC_TOPIC_STRING_INVALID_SHADOW_RESPONSE, TEST_CLASSIC_TOPIC_LENGTH_INVALID_SHADOW_RESPONSE, &messageType, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_MESSAGE_TYPE_PARSE_FAILED, shadowStatus ); shadowStatus = Shadow_MatchTopicString( TEST_NAMED_TOPIC_STRING_INVALID_SHADOW_RESPONSE, TEST_NAMED_TOPIC_LENGTH_INVALID_SHADOW_RESPONSE, &messageType, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_MESSAGE_TYPE_PARSE_FAILED, shadowStatus ); shadowStatus = Shadow_MatchTopicString( TEST_CLASSIC_TOPIC_STRING_INVALID_GET_REJECTED, TEST_CLASSIC_TOPIC_LENGTH_INVALID_GET_REJECTED, &messageType, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_MESSAGE_TYPE_PARSE_FAILED, shadowStatus ); shadowStatus = Shadow_MatchTopicString( TEST_NAMED_TOPIC_STRING_INVALID_GET_REJECTED, TEST_NAMED_TOPIC_LENGTH_INVALID_GET_REJECTED, &messageType, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_MESSAGE_TYPE_PARSE_FAILED, shadowStatus ); shadowStatus = Shadow_MatchTopicString( classicTopicBuffer, classicBufferSize - 1, &messageType, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_MESSAGE_TYPE_PARSE_FAILED, shadowStatus ); shadowStatus = Shadow_MatchTopicString( namedTopicBuffer, namedBufferSize - 1, &messageType, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_MESSAGE_TYPE_PARSE_FAILED, shadowStatus ); shadowStatus = Shadow_MatchTopicString( classicTopicBuffer, classicBufferSize + 1, &messageType, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_MESSAGE_TYPE_PARSE_FAILED, shadowStatus ); shadowStatus = Shadow_MatchTopicString( namedTopicBuffer, namedBufferSize + 1, &messageType, &pThingName, &thingNameLength, &pShadowName, &shadowNameLength ); TEST_ASSERT_EQUAL_INT( SHADOW_MESSAGE_TYPE_PARSE_FAILED, shadowStatus ); } /*-----------------------------------------------------------*/