Skip to content

Commit 6ddba19

Browse files
kstribrnAmznaggarg
andauthored
Add support for optional job document fields (#115)
FileType (for example) is optional in a job document. If the field exists, parse it. If not, skip it. --------- Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>
1 parent c2b768a commit 6ddba19

File tree

3 files changed

+171
-54
lines changed

3 files changed

+171
-54
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
-G "Unix Makefiles" \
1919
-DCMAKE_BUILD_TYPE=Debug \
2020
-DUNITTEST=1 \
21-
-DCMAKE_C_FLAGS='--coverage -Wall -Wextra -Werror'
21+
-DCMAKE_C_FLAGS='-Wall -Wextra -Werror'
2222
make -C build/ all
2323
- name: Test
2424
run: |
@@ -28,9 +28,9 @@ jobs:
2828
- name: Run Coverage
2929
run: |
3030
make -C build/ coverage
31-
declare -a EXCLUDE=("\*test\*" "\*CMakeCCompilerId\*" "\*mocks\*" "\*source\*" "\*vendor/unity\*" "\*_deps\*")
31+
declare -a EXCLUDE=("\*_deps\*")
3232
echo ${EXCLUDE[@]} | xargs lcov --rc lcov_branch_coverage=1 -r build/coverage.info -o build/coverage.info
33-
lcov --rc lcov_branch_coverage=1 --list build/coverage.info
33+
lcov --rc branch_coverage=1 --summary build/coverage.info
3434
- name: Check Coverage
3535
uses: FreeRTOS/CI-CD-Github-Actions/coverage-cop@main
3636
with:

source/otaJobParser/job_parser.c

Lines changed: 56 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,20 @@ static JSONStatus_t populateCommonFields( const char * jobDoc,
3030
int32_t fileIndex,
3131
AfrOtaJobDocumentFields_t * result );
3232

33+
/**
34+
* @brief Populates optional, common job document fields in result
35+
*
36+
* @param jobDoc FreeRTOS OTA job document
37+
* @param jobDocLength OTA job document length
38+
* @param fileIndex The index of the file to use
39+
* @param result Job document structure to populate
40+
* @return JSONStatus_t JSON parsing status
41+
*/
42+
static JSONStatus_t populateOptionalCommonFields( const char * jobDoc,
43+
const size_t jobDocLength,
44+
int32_t fileIndex,
45+
AfrOtaJobDocumentFields_t * result );
46+
3347
/**
3448
* @brief Populates MQTT job document fields in result
3549
*
@@ -278,9 +292,40 @@ static JSONStatus_t populateCommonFields( const char * jobDoc,
278292
result->signatureLen = ( uint32_t ) jsonValueLength;
279293
}
280294

295+
if( jsonResult == JSONSuccess )
296+
{
297+
jsonResult = populateOptionalCommonFields( jobDoc,
298+
jobDocLength,
299+
fileIndex,
300+
result );
301+
}
302+
281303
return jsonResult;
282304
}
283305

306+
static JSONStatus_t populateOptionalCommonFields( const char * jobDoc,
307+
const size_t jobDocLength,
308+
int32_t fileIndex,
309+
AfrOtaJobDocumentFields_t * result )
310+
{
311+
JSONStatus_t jsonResult = JSONNotFound;
312+
char queryString[ 33 ];
313+
size_t queryStringLength;
314+
315+
buildIndexedFileQueryString( fileIndex,
316+
"fileType",
317+
8U,
318+
queryString,
319+
&queryStringLength );
320+
jsonResult = searchUintValue( jobDoc,
321+
jobDocLength,
322+
queryString,
323+
queryStringLength,
324+
&( result->fileType ) );
325+
326+
return ( jsonResult == JSONBadParameter ) ? jsonResult : JSONSuccess;
327+
}
328+
284329
static JSONStatus_t populateMqttStreamingFields( const char * jobDoc,
285330
const size_t jobDocLength,
286331
AfrOtaJobDocumentFields_t * result )
@@ -320,33 +365,19 @@ static JSONStatus_t populateHttpStreamingFields( const char * jobDoc,
320365
size_t queryStringLength;
321366

322367
buildIndexedFileQueryString( fileIndex,
323-
"fileType",
324-
8U,
368+
"auth_scheme",
369+
11U,
325370
queryString,
326371
&queryStringLength );
327-
jsonResult = searchUintValue( jobDoc,
328-
jobDocLength,
329-
queryString,
330-
queryStringLength,
331-
&( result->fileType ) );
332-
333-
if( jsonResult == JSONSuccess )
334-
{
335-
buildIndexedFileQueryString( fileIndex,
336-
"auth_scheme",
337-
11U,
338-
queryString,
339-
&queryStringLength );
340-
jsonResult = JSON_SearchConst( jobDoc,
341-
jobDocLength,
342-
queryString,
343-
queryStringLength,
344-
&jsonValue,
345-
&jsonValueLength,
346-
NULL );
347-
result->authScheme = jsonValue;
348-
result->authSchemeLen = ( uint32_t ) jsonValueLength;
349-
}
372+
jsonResult = JSON_SearchConst( jobDoc,
373+
jobDocLength,
374+
queryString,
375+
queryStringLength,
376+
&jsonValue,
377+
&jsonValueLength,
378+
NULL );
379+
result->authScheme = jsonValue;
380+
result->authSchemeLen = ( uint32_t ) jsonValueLength;
350381

351382
if( jsonResult == JSONSuccess )
352383
{

test/unit-test/job_parser_utest.c

Lines changed: 112 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,47 @@ void test_populateJobDocFields_returnsTrue_givenValidMqttDocument( void )
109109
TEST_ASSERT_EQUAL( UINT32_MAX, documentFields.authSchemeLen );
110110
}
111111

112+
void test_populateJobDocFields_returnsTrue_givenValidMqttDocumentWithOptionalFields( void )
113+
{
114+
const char * document = "{\"afr_ota\":{\"protocols\":[\"MQTT\"],"
115+
"\"streamname\":\"AFR_OTA-streamname\",\"files\":[{"
116+
"\"filepath\":\"/device\",\"filesize\": "
117+
"123456789,\"fileid\":0,\"fileType\":1234,\"certfile\":\"certfile."
118+
"cert\",\"sig-sha256-ecdsa\":\"signature_hash_"
119+
"239871\"}]}}";
120+
121+
result = false;
122+
result = populateJobDocFields( document,
123+
strlen( document ),
124+
0,
125+
&documentFields );
126+
127+
TEST_ASSERT_TRUE( result );
128+
TEST_ASSERT_EQUAL( 123456789U, documentFields.fileSize );
129+
TEST_ASSERT_EQUAL( 0U, documentFields.fileId );
130+
TEST_ASSERT_EQUAL_STRING_LEN( "certfile.cert",
131+
documentFields.certfile,
132+
strlen( "certfile.cert" ) );
133+
TEST_ASSERT_EQUAL( strlen( "certfile.cert" ), documentFields.certfileLen );
134+
TEST_ASSERT_EQUAL_STRING_LEN( "signature_hash_239871",
135+
documentFields.signature,
136+
strlen( "signature_hash_239871" ) );
137+
TEST_ASSERT_EQUAL( strlen( "signature_hash_239871" ),
138+
documentFields.signatureLen );
139+
TEST_ASSERT_EQUAL_STRING_LEN( "/device",
140+
documentFields.filepath,
141+
strlen( "/device" ) );
142+
TEST_ASSERT_EQUAL( strlen( "/device" ), documentFields.filepathLen );
143+
TEST_ASSERT_EQUAL_STRING_LEN( "AFR_OTA-streamname",
144+
documentFields.imageRef,
145+
strlen( "AFR_OTA-streamname" ) );
146+
TEST_ASSERT_EQUAL( strlen( "AFR_OTA-streamname" ),
147+
documentFields.imageRefLen );
148+
TEST_ASSERT_EQUAL( 1234U, documentFields.fileType );
149+
TEST_ASSERT_NULL( documentFields.authScheme );
150+
TEST_ASSERT_EQUAL( UINT32_MAX, documentFields.authSchemeLen );
151+
}
152+
112153
void test_populateJobDocFields_returnsTrue_givenValidMultiFileMqttDocument( void )
113154
{
114155
const char * document = "{\"afr_ota\":{\"protocols\":[\"MQTT\"],"
@@ -185,13 +226,60 @@ void test_populateJobDocFields_returnsTrue_givenValidMultiFileMqttDocument( void
185226
}
186227

187228
void test_populateJobDocFields_returnsTrue_givenValidHttpDocument( void )
229+
{
230+
const char * document = "{\"afr_ota\":{\"protocols\":[\"HTTP\"],\"files\":["
231+
"{\"filepath\":\"/"
232+
"device\",\"filesize\":343135,\"fileid\":0,"
233+
"\"certfile\":\"/strangepath/"
234+
"certificate.cert\",\"update_data_url\":\"presignedS3Url.s3.amazon."
235+
"com\",\"auth_scheme\":\"aws.s3.presigned\",\"sig-"
236+
"sha256-ecdsa\":\"SIGNATUREHASH+ASDFLKJ123===\"}]}"
237+
"}";
238+
239+
result = false;
240+
result = populateJobDocFields( document,
241+
strlen( document ),
242+
0,
243+
&documentFields );
244+
245+
TEST_ASSERT_TRUE( result );
246+
TEST_ASSERT_EQUAL( 343135U, documentFields.fileSize );
247+
TEST_ASSERT_EQUAL( 0U, documentFields.fileId );
248+
TEST_ASSERT_EQUAL_STRING_LEN( "/strangepath/certificate.cert",
249+
documentFields.certfile,
250+
strlen( "/strangepath/certificate.cert" ) );
251+
TEST_ASSERT_EQUAL( strlen( "/strangepath/certificate.cert" ),
252+
documentFields.certfileLen );
253+
TEST_ASSERT_EQUAL_STRING_LEN( "SIGNATUREHASH+ASDFLKJ123===",
254+
documentFields.signature,
255+
strlen( "SIGNATUREHASH+ASDFLKJ123===" ) );
256+
TEST_ASSERT_EQUAL( strlen( "SIGNATUREHASH+ASDFLKJ123===" ),
257+
documentFields.signatureLen );
258+
TEST_ASSERT_EQUAL_STRING_LEN( "/device",
259+
documentFields.filepath,
260+
strlen( "/device" ) );
261+
TEST_ASSERT_EQUAL( strlen( "/device" ), documentFields.filepathLen );
262+
TEST_ASSERT_EQUAL_STRING_LEN( "presignedS3Url.s3.amazon.com",
263+
documentFields.imageRef,
264+
strlen( "presignedS3Url.s3.amazon.com" ) );
265+
TEST_ASSERT_EQUAL( strlen( "presignedS3Url.s3.amazon.com" ),
266+
documentFields.imageRefLen );
267+
TEST_ASSERT_EQUAL_STRING_LEN( "aws.s3.presigned",
268+
documentFields.authScheme,
269+
strlen( "aws.s3.presigned" ) );
270+
TEST_ASSERT_EQUAL( strlen( "aws.s3.presigned" ),
271+
documentFields.authSchemeLen );
272+
TEST_ASSERT_EQUAL( UINT32_MAX, documentFields.fileType );
273+
}
274+
275+
void test_populateJobDocFields_returnsTrue_givenValidHttpDocumentWithOptionalFields( void )
188276
{
189277
const char * document = "{\"afr_ota\":{\"protocols\":[\"HTTP\"],\"files\":["
190278
"{\"filepath\":\"/"
191279
"device\",\"filesize\":343135,\"fileid\":0,"
192280
"\"certfile\":\"/strangepath/"
193281
"certificate.cert\",\"fileType\": "
194-
"2,\"update_data_url\":\"presignedS3Url.s3.amazon."
282+
"1234,\"update_data_url\":\"presignedS3Url.s3.amazon."
195283
"com\",\"auth_scheme\":\"aws.s3.presigned\",\"sig-"
196284
"sha256-ecdsa\":\"SIGNATUREHASH+ASDFLKJ123===\"}]}"
197285
"}";
@@ -205,7 +293,7 @@ void test_populateJobDocFields_returnsTrue_givenValidHttpDocument( void )
205293
TEST_ASSERT_TRUE( result );
206294
TEST_ASSERT_EQUAL( 343135U, documentFields.fileSize );
207295
TEST_ASSERT_EQUAL( 0U, documentFields.fileId );
208-
TEST_ASSERT_EQUAL( 2U, documentFields.fileType );
296+
TEST_ASSERT_EQUAL( 1234U, documentFields.fileType );
209297
TEST_ASSERT_EQUAL_STRING_LEN( "/strangepath/certificate.cert",
210298
documentFields.certfile,
211299
strlen( "/strangepath/certificate.cert" ) );
@@ -339,6 +427,7 @@ void test_populateJobDocFields_returnsTrue_givenValidMultiProtocolDocument( void
339427
TEST_ASSERT_TRUE( result );
340428
TEST_ASSERT_EQUAL( 123456789U, documentFields.fileSize );
341429
TEST_ASSERT_EQUAL( 0U, documentFields.fileId );
430+
TEST_ASSERT_EQUAL( 66U, documentFields.fileType );
342431
TEST_ASSERT_EQUAL_STRING_LEN( "certfile.cert",
343432
documentFields.certfile,
344433
strlen( "certfile.cert" ) );
@@ -357,11 +446,31 @@ void test_populateJobDocFields_returnsTrue_givenValidMultiProtocolDocument( void
357446
strlen( "AFR_OTA-streamname" ) );
358447
TEST_ASSERT_EQUAL( strlen( "AFR_OTA-streamname" ),
359448
documentFields.imageRefLen );
360-
TEST_ASSERT_EQUAL( UINT32_MAX, documentFields.fileType );
361449
TEST_ASSERT_NULL( documentFields.authScheme );
362450
TEST_ASSERT_EQUAL( UINT32_MAX, documentFields.authSchemeLen );
363451
}
364452

453+
void test_populateJobDocFields_returnsFalse_givenValidInvalidOptionalFields( void )
454+
{
455+
const char * document = "{\"afr_ota\":{\"protocols\":[\"HTTP\"],\"files\":["
456+
"{\"filepath\":\"/"
457+
"device\",\"filesize\":343135,\"fileid\":0,"
458+
"\"certfile\":\"/strangepath/"
459+
"certificate.cert\",\"fileType\": \"badParameter\","
460+
"\"update_data_url\":\"presignedS3Url.s3.amazon."
461+
"com\",\"auth_scheme\":\"aws.s3.presigned\",\"sig-"
462+
"sha256-ecdsa\":\"SIGNATUREHASH+ASDFLKJ123===\"}]}"
463+
"}";
464+
465+
result = false;
466+
result = populateJobDocFields( document,
467+
strlen( document ),
468+
0,
469+
&documentFields );
470+
471+
TEST_ASSERT_FALSE( result );
472+
}
473+
365474
void test_populateJobDocFields_returnsFalse_whenEmptyProtocol( void )
366475
{
367476
const char *
@@ -529,29 +638,6 @@ void test_populateJobDocFields_returnsFalse_whenMqttDocMissingStreamName( void )
529638
TEST_ASSERT_FALSE( result );
530639
}
531640

532-
void test_populateJobDocFields_returnsFalse_whenHttpDocMissingFileType( void )
533-
{
534-
const char * document = "{\"afr_ota\":{\"protocols\":[\"HTTP\"],\"files\":["
535-
"{\"filepath\":\"/"
536-
"device\",\"filesize\":343135,\"fileid\":0,"
537-
"\"certfile\":\"/strangepath/"
538-
"certificate.cert\",\"update_data_url\":\"${aws:"
539-
"iot:s3-presigned-url:https://"
540-
"s3.region.amazonaws.com/joe-ota/SignedImages/"
541-
"ffdac2a7-0f70-4f47-8940-886ad260445c}\",\"auth_"
542-
"scheme\":\"aws.s3.presigned\",\"sig-sha256-"
543-
"ecdsa\":\"MEQCIGOTD5owb5s3R3+"
544-
"OlxH5UZcy52Vuz6QrJhg83F8t8tBfAiBTNiX0e8RR5JOzHfSqW"
545-
"Kq4WJC/xUwMrcdHEWgSAKfGQA==\"}]}}";
546-
547-
result = populateJobDocFields( document,
548-
strlen( document ),
549-
0,
550-
&documentFields );
551-
552-
TEST_ASSERT_FALSE( result );
553-
}
554-
555641
void test_populateJobDocFields_returnsFalse_whenHttpDocEmptyUrl( void )
556642
{
557643
const char * document = "{\"afr_ota\":{\"protocols\":[\"HTTP\"],\"files\":["

0 commit comments

Comments
 (0)