55/* Test data */
66#include "data/td/json_td.h" /* JSON_TD */
77
8+ /* CloudWatch API constants */
9+ #include "../../plugins/out_cloudwatch_logs/cloudwatch_api.h"
10+
811#define ERROR_ALREADY_EXISTS "{\"__type\":\"ResourceAlreadyExistsException\"}"
912/* not a real error code, but tests that the code can respond to any error */
1013#define ERROR_UNKNOWN "{\"__type\":\"UNKNOWN\"}"
1114
15+ /* JSON structure constants for test message generation */
16+ static const char * TEST_JSON_PREFIX = "{\"message\":\"" ;
17+ static const char * TEST_JSON_SUFFIX = "\"}" ;
18+
1219/* It writes a big JSON message (copied from TD test) */
1320void flb_test_cloudwatch_success (void )
1421{
@@ -393,6 +400,145 @@ void flb_test_cloudwatch_error_put_retention_policy(void)
393400 flb_destroy (ctx );
394401}
395402
403+ /* Helper function to create a large JSON message of specified size */
404+ static char * create_large_json_message (size_t target_size )
405+ {
406+ size_t prefix_len = strlen (TEST_JSON_PREFIX );
407+ size_t suffix_len = strlen (TEST_JSON_SUFFIX );
408+ size_t overhead = prefix_len + suffix_len ;
409+ size_t data_size ;
410+ char * json ;
411+
412+ /* Reject target_size too small for valid JSON structure */
413+ if (target_size < overhead + 1 ) {
414+ return NULL ;
415+ }
416+
417+ json = flb_malloc (target_size + 1 );
418+ if (!json ) {
419+ return NULL ;
420+ }
421+
422+ /* Build JSON: prefix + data + suffix */
423+ memcpy (json , TEST_JSON_PREFIX , prefix_len );
424+ data_size = target_size - overhead ;
425+
426+ /* Fill with 'A' characters */
427+ memset (json + prefix_len , 'A' , data_size );
428+
429+ /* Close JSON object */
430+ memcpy (json + prefix_len + data_size , TEST_JSON_SUFFIX , suffix_len );
431+ json [target_size ] = '\0' ;
432+
433+ /* Caller must free */
434+ return json ;
435+ }
436+
437+ /* Helper to setup and run a CloudWatch test with custom JSON data */
438+ static void run_cloudwatch_test_with_data (char * data , size_t data_len )
439+ {
440+ int ret ;
441+ flb_ctx_t * ctx ;
442+ int in_ffd ;
443+ int out_ffd ;
444+
445+ setenv ("FLB_CLOUDWATCH_PLUGIN_UNDER_TEST" , "true" , 1 );
446+
447+ ctx = flb_create ();
448+ TEST_CHECK (ctx != NULL );
449+
450+ in_ffd = flb_input (ctx , (char * ) "lib" , NULL );
451+ TEST_CHECK (in_ffd >= 0 );
452+ flb_input_set (ctx , in_ffd , "tag" , "test" , NULL );
453+
454+ out_ffd = flb_output (ctx , (char * ) "cloudwatch_logs" , NULL );
455+ TEST_CHECK (out_ffd >= 0 );
456+ flb_output_set (ctx , out_ffd , "match" , "test" , NULL );
457+ flb_output_set (ctx , out_ffd , "region" , "us-west-2" , NULL );
458+ flb_output_set (ctx , out_ffd , "log_group_name" , "fluent" , NULL );
459+ flb_output_set (ctx , out_ffd , "log_stream_prefix" , "from-fluent-" , NULL );
460+ flb_output_set (ctx , out_ffd , "auto_create_group" , "On" , NULL );
461+ flb_output_set (ctx , out_ffd , "net.keepalive" , "Off" , NULL );
462+ flb_output_set (ctx , out_ffd , "Retry_Limit" , "1" , NULL );
463+
464+ ret = flb_start (ctx );
465+ TEST_CHECK (ret == 0 );
466+
467+ if (data ) {
468+ flb_lib_push (ctx , in_ffd , data , data_len );
469+ }
470+
471+ sleep (2 );
472+ flb_stop (ctx );
473+ flb_destroy (ctx );
474+ }
475+
476+ /* Test event size at maximum allowed limit (should succeed without truncation) */
477+ void flb_test_cloudwatch_event_size_at_limit (void )
478+ {
479+ char * large_json ;
480+
481+ /* Create message at MAX_EVENT_LEN */
482+ large_json = create_large_json_message (MAX_EVENT_LEN );
483+ TEST_CHECK (large_json != NULL );
484+
485+ if (large_json ) {
486+ run_cloudwatch_test_with_data (large_json , strlen (large_json ));
487+ flb_free (large_json );
488+ }
489+ }
490+
491+ /* Test event size exceeding limit (should be truncated to MAX_EVENT_LEN) */
492+ void flb_test_cloudwatch_event_size_over_limit (void )
493+ {
494+ char * large_json ;
495+
496+ /* Create message exceeding MAX_EVENT_LEN by 1 byte to test truncation */
497+ large_json = create_large_json_message (MAX_EVENT_LEN + 1 );
498+ TEST_CHECK (large_json != NULL );
499+
500+ if (large_json ) {
501+ run_cloudwatch_test_with_data (large_json , strlen (large_json ));
502+ flb_free (large_json );
503+ }
504+ }
505+
506+ /* Test event with trailing backslash at truncation boundary */
507+ void flb_test_cloudwatch_event_truncation_with_backslash (void )
508+ {
509+ char * large_json ;
510+ size_t prefix_len = strlen (TEST_JSON_PREFIX );
511+ size_t suffix_len = strlen (TEST_JSON_SUFFIX );
512+ size_t total_len ;
513+ size_t data_len ;
514+ size_t i ;
515+
516+ /* Create base message exceeding MAX_EVENT_LEN */
517+ large_json = create_large_json_message (MAX_EVENT_LEN + 100 );
518+ TEST_CHECK (large_json != NULL );
519+
520+ if (large_json ) {
521+ total_len = strlen (large_json );
522+ data_len = total_len - prefix_len - suffix_len ;
523+
524+ /* Replace pairs of characters with valid escape sequence "\\" */
525+ for (i = 98 ; i < data_len - 1 ; i += 100 ) {
526+ large_json [prefix_len + i ] = '\\' ;
527+ large_json [prefix_len + i + 1 ] = '\\' ;
528+ }
529+
530+ size_t boundary = MAX_EVENT_LEN - 1 ; /* index in full JSON string */
531+ /* Ensure a backslash is at the exact truncation boundary */
532+ if (boundary + 1 < total_len - suffix_len ) {
533+ large_json [boundary ] = '\\' ;
534+ large_json [boundary + 1 ] = '\\' ;
535+ }
536+
537+ run_cloudwatch_test_with_data (large_json , strlen (large_json ));
538+ flb_free (large_json );
539+ }
540+ }
541+
396542/* Test list */
397543TEST_LIST = {
398544 {"success" , flb_test_cloudwatch_success },
@@ -405,5 +551,8 @@ TEST_LIST = {
405551 {"put_retention_policy_success" , flb_test_cloudwatch_put_retention_policy_success },
406552 {"already_exists_create_group_put_retention_policy" , flb_test_cloudwatch_already_exists_create_group_put_retention_policy },
407553 {"error_put_retention_policy" , flb_test_cloudwatch_error_put_retention_policy },
554+ {"event_size_at_limit" , flb_test_cloudwatch_event_size_at_limit },
555+ {"event_size_over_limit" , flb_test_cloudwatch_event_size_over_limit },
556+ {"event_truncation_with_backslash" , flb_test_cloudwatch_event_truncation_with_backslash },
408557 {NULL , NULL }
409558};
0 commit comments