Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add macros to API for compile time topic generation #38

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 124 additions & 0 deletions source/include/jobs.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,96 @@
#define JOBS_API_JOBID_NEXT "$next"
#define JOBS_API_JOBID_NEXT_LENGTH ( sizeof( JOBS_API_JOBID_NEXT ) - 1U )

#define JOBS_API_JOBID_NULL ""
#define JOBS_API_LEVEL_SEPARATOR "/"

#define JOBS_API_COMMON_LENGTH( thingNameLength ) \
( JOBS_API_PREFIX_LENGTH + ( thingNameLength ) + JOBS_API_BRIDGE_LENGTH )

/** @endcond */


/**
* @cond DOXYGEN_IGNORE
* Doxygen should ignore this macro as it is private.
*/

/* AWS IoT Jobs API topics. */
#define JOBS_TOPIC_COMMON( thingName, jobId, jobsApi ) \
( JOBS_API_PREFIX \
thingName \
JOBS_API_BRIDGE \
jobId \
jobsApi )
/** @endcond */

/**
* @ingroup jobs_constants
* @brief Topic string for subscribing to the NextJobExecutionChanged API.
*
* This macro should be used when the thing name is known at the compile time.
* If the thing name is not known at compile time, the #Jobs_GetTopic API
* should be used instead.
*
* @param thingName The thing name as registered with AWS IoT Core.
*/
#define JOBS_API_SUBSCRIBE_NEXTJOBCHANGED( thingName ) \
JOBS_TOPIC_COMMON( thingName, JOBS_API_JOBID_NULL, JOBS_API_NEXTJOBCHANGED )

/**
* @ingroup jobs_constants
* @brief Topic string for subscribing to the JobExecutionsChanged API.
*
* This macro should be used when the thing name is known at the compile time.
* If the thing name is not known at compile time, the #Jobs_GetTopic API
* should be used instead.
*
* @param thingName The thing name as registered with AWS IoT Core.
*/
#define JOBS_API_SUBSCRIBE_JOBSCHANGED( thingName ) \
JOBS_TOPIC_COMMON( thingName, JOBS_API_JOBID_NULL, JOBS_API_JOBSCHANGED )

/**
* @ingroup jobs_constants
* @brief Topic string for publishing to the StartNextPendingJobExecution API.
*
* This macro should be used when the thing name is known at the compile time.
* If the thing name is not known at compile time, the #Jobs_StartNext API
* should be used instead.
*
* @param thingName The thing name as registered with AWS IoT Core.
*/
#define JOBS_API_PUBLISH_STARTNEXT( thingName ) \
JOBS_TOPIC_COMMON( thingName, JOBS_API_JOBID_NULL, JOBS_API_STARTNEXT )

/**
* @ingroup jobs_constants
* @brief Topic string for publishing to the GetPendingJobExecutions API.
*
* This macro should be used when the thing name is known at the compile time.
* If the thing name is not known at compile time, the #Jobs_GetPending API
* should be used instead.
*
* @param thingName The thing name as registered with AWS IoT Core.
*/
#define JOBS_API_PUBLISH_GETPENDING( thingName ) \
JOBS_TOPIC_COMMON( thingName, JOBS_API_JOBID_NULL, JOBS_API_GETPENDING )

/**
* @ingroup jobs_constants
* @brief Topic string for querying the next pending job from the
* DescribeJobExecution API.
*
* This macro should be used when the thing name and jobID are known at the
* compile time. If next pending job is being queried, use $next as job ID.
Comment on lines +194 to +195
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is job ID ever known at compile time?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This macro's main utility would be for using the $next job ID. If you think that we should provide macros only for that case, I can limit the macro to generate topics only for the next job ID.

* If the thing name or job ID are not known at compile time, the #Jobs_Describe API
* should be used instead.
*
* @param thingName The thing name as registered with AWS IoT Core.
*/
#define JOBS_API_PUBLISH_DESCRIBENEXTJOB( thingName ) \
JOBS_TOPIC_COMMON( thingName, JOBS_API_JOBID_NEXT JOBS_API_LEVEL_SEPARATOR, JOBS_API_DESCRIBE )

/**
* @ingroup jobs_constants
* @brief The size needed to hold the longest topic for a given thing name length.
Expand Down Expand Up @@ -192,6 +277,13 @@ typedef enum
*
* @note The thingName parameter does not need a NUL terminator.
*
* @note The AWS IoT Jobs service does not require clients to subscribe
* to the "/accepted" and "/rejected" response topics for the APIs that
* accept requests on PUBLISH topics. The Jobs service will send responses
* to requests from clients irrespective of whether they have subscribed to
* response topics or not. For more information, refer to the AWS docs here:
* https://docs.aws.amazon.com/iot/latest/developerguide/jobs-mqtt-api.html
*
* <b>Example</b>
* @code{c}
*
Expand Down Expand Up @@ -370,6 +462,14 @@ JobsStatus_t Jobs_MatchTopic( char * topic,
*
* @note The thingName parameter does not need a NUL terminator.
*
* @note The AWS IoT Jobs service does not require clients to subscribe
* to the "/accepted" and "/rejected" response topics of the
* GetPendingJobExecutions API.
* The Jobs service will send responses to requests published to the API
* from clients irrespective of whether they have subscribed to response topics
* or not. For more information, refer to the AWS docs here:
* https://docs.aws.amazon.com/iot/latest/developerguide/jobs-mqtt-api.html
*
* <b>Example</b>
* @code{c}
*
Expand Down Expand Up @@ -428,6 +528,14 @@ JobsStatus_t Jobs_GetPending( char * buffer,
*
* @note The thingName parameter does not need a NUL terminator.
*
* @note The AWS IoT Jobs service does not require clients to subscribe
* to the "/accepted" and "/rejected" response topics of the
* StartNextPendingJobExecution API.
* The Jobs service will send responses to requests published to the API
* from clients irrespective of whether they have subscribed to response topics
* or not. For more information, refer to the AWS docs here:
* https://docs.aws.amazon.com/iot/latest/developerguide/jobs-mqtt-api.html
*
* <b>Example</b>
* @code{c}
*
Expand Down Expand Up @@ -491,6 +599,14 @@ JobsStatus_t Jobs_StartNext( char * buffer,
*
* @note The thingName and jobId parameters do not need a NUL terminator.
*
* @note The AWS IoT Jobs service does not require clients to subscribe
* to the "/accepted" and "/rejected" response topics of the
* DescribeJobExecution API.
* The Jobs service will send responses to requests published to the API
* from clients irrespective of whether they have subscribed to response topics
* or not. For more information, refer to the AWS docs here:
* https://docs.aws.amazon.com/iot/latest/developerguide/jobs-mqtt-api.html
*
* <b>Example</b>
* @code{c}
*
Expand Down Expand Up @@ -560,6 +676,14 @@ JobsStatus_t Jobs_Describe( char * buffer,
*
* @note The thingName and jobId parameters do not need a NUL terminator.
*
* @note The AWS IoT Jobs service does not require clients to subscribe
* to the "/accepted" and "/rejected" response topics of the
* UpdateJobExecution API.
* The Jobs service will send responses to requests published to the API
* from clients irrespective of whether they have subscribed to response topics
* or not. For more information, refer to the AWS docs here:
* https://docs.aws.amazon.com/iot/latest/developerguide/jobs-mqtt-api.html
*
* <b>Example</b>
* @code{c}
*
Expand Down
39 changes: 35 additions & 4 deletions test/unit-test/jobs_utest.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@
#define jobId_ "1234"
#define jobIdLength_ ( sizeof( jobId_ ) - 1 )

/* Common prefix of Jobs topics. */
#define PREFIX JOBS_API_PREFIX name_ JOBS_API_BRIDGE

/* ============================ UNITY FIXTURES ============================ */

/* Called before each test method. */
Expand All @@ -67,6 +70,35 @@ int suiteTearDown( int numFailures )

/* ========================================================================== */

/**
* @brief Test that the topic generating macros are valid.
*/
void test_JobsPUBLISH__API_macros_are_v( void )
{
char * expectedTopic = NULL;

/* Test for NextJobExecutionChanged API topic. */
expectedTopic = PREFIX JOBS_API_NEXTJOBCHANGED;
TEST_ASSERT_EQUAL_STRING( expectedTopic, JOBS_API_SUBSCRIBE_NEXTJOBCHANGED( name_ ) );

/* Test for JobExecutionsChanged API topic. */
expectedTopic = PREFIX JOBS_API_JOBSCHANGED;
TEST_ASSERT_EQUAL_STRING( expectedTopic, JOBS_API_SUBSCRIBE_JOBSCHANGED( name_ ) );

/* Test for StartNextPendingJobExecution API topic. */
expectedTopic = PREFIX JOBS_API_STARTNEXT;
TEST_ASSERT_EQUAL_STRING( expectedTopic, JOBS_API_PUBLISH_STARTNEXT( name_ ) );

/* Test for GetPendingJobExecutions API topic. */
expectedTopic = PREFIX JOBS_API_GETPENDING;
TEST_ASSERT_EQUAL_STRING( expectedTopic, JOBS_API_PUBLISH_GETPENDING( name_ ) );

/* Test for DescribeJobExecution API topic for the "$next" job ID. */
expectedTopic = PREFIX JOBS_API_JOBID_NEXT "/" JOBS_API_DESCRIBE;
TEST_ASSERT_EQUAL_STRING( expectedTopic, JOBS_API_PUBLISH_DESCRIBENEXTJOB( name_ ) );
}


/**
* @brief Test that all topic enums are contiguous
*
Expand Down Expand Up @@ -251,7 +283,7 @@ void test_Jobs_buffer_lengths( void )
JobsStatus_t ret;
size_t len;
unsigned i = 0;
char expected1[] = JOBS_API_PREFIX name_ JOBS_API_BRIDGE JOBS_API_JOBSCHANGED;
char expected1[] = JOBS_API_SUBSCRIBE_JOBSCHANGED( name_ );
char expected2[] = JOBS_API_PREFIX name_ JOBS_API_BRIDGE "+/" JOBS_API_UPDATE JOBS_API_SUCCESS;

ret = Jobs_GetTopic( buf, sizeof( buf ), name_, nameLength_, JobsJobsChanged, NULL );
Expand Down Expand Up @@ -281,7 +313,6 @@ void test_Jobs_happy_path( void )
char buf[ JOBS_API_MAX_LENGTH( nameLength_ ) ];
size_t outLength;

#define PREFIX JOBS_API_PREFIX name_ JOBS_API_BRIDGE
char prefix[] = PREFIX;

#define TEST_SUCCESS( x ) \
Expand All @@ -300,7 +331,7 @@ void test_Jobs_happy_path( void )
TEST_ASSERT_EQUAL( ( sizeof( x ) - 1 ), outLength )

{
char expected[] = PREFIX JOBS_API_GETPENDING;
char expected[] = JOBS_API_PUBLISH_GETPENDING( name_ );

TEST_SUCCESS( Jobs_GetPending( buf, sizeof( buf ), name_, nameLength_, NULL ) );
TEST_SUCCESS( Jobs_GetPending( buf, sizeof( buf ), name_, nameLength_, &outLength ) );
Expand All @@ -312,7 +343,7 @@ void test_Jobs_happy_path( void )
}

{
char expected[] = PREFIX JOBS_API_STARTNEXT;
char expected[] = JOBS_API_PUBLISH_STARTNEXT( name_ );

TEST_SUCCESS( Jobs_StartNext( buf, sizeof( buf ), name_, nameLength_, NULL ) );
TEST_SUCCESS( Jobs_StartNext( buf, sizeof( buf ), name_, nameLength_, &outLength ) );
Expand Down