From a13728d87d97fd608bc94b2c8ab77a40c4eca31f Mon Sep 17 00:00:00 2001 From: dcristoloveanu Date: Wed, 10 Feb 2016 11:47:32 -0800 Subject: [PATCH] Add unit tests for batch with proeprties --- .../eventhubclient_ll_requirements.docm | Bin 100383 -> 100590 bytes c/eventhub_client/src/eventhubclient_ll.c | 100 +- .../eventhubclient_ll_unittests.cpp | 1091 ++++++++++++++++- 3 files changed, 1143 insertions(+), 48 deletions(-) diff --git a/c/eventhub_client/devdoc/requirement_docs/eventhubclient_ll_requirements.docm b/c/eventhub_client/devdoc/requirement_docs/eventhubclient_ll_requirements.docm index 7b8192bfb789a87b9ef20092f65c8b2c1e462e2b..214d368314d90aadde99dd588739c8fe9d318040 100644 GIT binary patch delta 52496 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%0D&dED!DK0WOTtKybied^cq_V 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 diff --git a/c/eventhub_client/src/eventhubclient_ll.c b/c/eventhub_client/src/eventhubclient_ll.c index 438e80f9..7c228c20 100644 --- a/c/eventhub_client/src/eventhubclient_ll.c +++ b/c/eventhub_client/src/eventhubclient_ll.c @@ -100,6 +100,7 @@ static int ValidateEventDataList(EVENTDATA_HANDLE *eventDataList, size_t count) } else { + /* Codes_SRS_EVENTHUBCLIENT_LL_01_097: [The partition key for each event shall be obtained by calling EventData_getPartitionKey.] */ const char* currPartKey = EventData_GetPartitionKey(eventDataList[index]); if (index == 0) { @@ -710,6 +711,7 @@ EVENTHUBCLIENT_RESULT EventHubClient_LL_SendBatchAsync(EVENTHUBCLIENT_LL_HANDLE { EVENTHUBCLIENT_RESULT result; /* Codes_SRS_EVENTHUBCLIENT_LL_07_012: [EventHubClient_LL_SendBatchAsync shall return EVENTHUBCLIENT_INVALLID_ARG if eventhubClientLLHandle or eventDataList are NULL or if sendAsnycConfirmationCallback equals NULL and userContextCallback does not equal NULL.] */ + /* Codes_SRS_EVENTHUBCLIENT_LL_01_095: [EventHubClient_LL_SendBatchAsync shall return EVENTHUBCLIENT_INVALID_ARG if the count argument is zero.] */ if (eventhub_client_ll == NULL || eventDataList == NULL || count == 0 || (sendAsyncConfirmationCallback == NULL && userContextCallback != NULL)) { result = EVENTHUBCLIENT_INVALID_ARG; @@ -720,7 +722,7 @@ EVENTHUBCLIENT_RESULT EventHubClient_LL_SendBatchAsync(EVENTHUBCLIENT_LL_HANDLE size_t index; if (ValidateEventDataList(eventDataList, count) != 0) { - /* Codes_SRS_EVENTHUBCLIENT_LL_07_013: [EventHubClient_LL_SendBatchAsync shall return EVENTHUBCLIENT_ERROR for any Error that is encountered.] */ + /* Codes_Tests_SRS_EVENTHUBCLIENT_LL_01_096: [If the partitionKey properties on the events in the batch are not the same then EventHubClient_LL_SendBatchAsync shall fail and return EVENTHUBCLIENT_ERROR.] */ result = EVENTHUBCLIENT_ERROR; LOG_ERROR; } @@ -729,6 +731,7 @@ EVENTHUBCLIENT_RESULT EventHubClient_LL_SendBatchAsync(EVENTHUBCLIENT_LL_HANDLE EVENTHUB_EVENT_LIST *newEntry = (EVENTHUB_EVENT_LIST*)malloc(sizeof(EVENTHUB_EVENT_LIST)); if (newEntry == NULL) { + /* Codes_SRS_EVENTHUBCLIENT_LL_07_013: [EventHubClient_LL_SendBatchAsync shall return EVENTHUBCLIENT_ERROR for any Error that is encountered.] */ result = EVENTHUBCLIENT_ERROR; LOG_ERROR; } @@ -739,6 +742,7 @@ EVENTHUBCLIENT_RESULT EventHubClient_LL_SendBatchAsync(EVENTHUBCLIENT_LL_HANDLE newEntry->eventDataList = malloc(sizeof(EVENTDATA_HANDLE)*count); if (newEntry->eventDataList == NULL) { + /* Codes_SRS_EVENTHUBCLIENT_LL_07_013: [EventHubClient_LL_SendBatchAsync shall return EVENTHUBCLIENT_ERROR for any Error that is encountered.] */ free(newEntry); result = EVENTHUBCLIENT_ERROR; LOG_ERROR; @@ -822,8 +826,9 @@ static int create_properties_map(EVENTDATA_HANDLE event_data_handle, AMQP_VALUE* /* Codes_SRS_EVENTHUBCLIENT_LL_01_054: [If the number of event data entries for the message is 1 (not batched) the event data properties shall be added as application properties to the message.] */ /* Codes_SRS_EVENTHUBCLIENT_LL_01_055: [A map shall be created to hold the application properties by calling amqpvalue_create_map.] */ *uamqp_properties_map = amqpvalue_create_map(); - if (uamqp_properties_map == NULL) + if (*uamqp_properties_map == NULL) { + /* Codes_SRS_EVENTHUBCLIENT_LL_01_094: [If any error occurs during serializing each event properties and data that are part of the batch, the callback associated with the message shall be called with EVENTHUBCLIENT_CONFIRMATION_ERROR and the message shall be freed from the pending list.] */ LogError("Cannot build uAMQP properties map.\r\n"); result = __LINE__; } @@ -863,6 +868,7 @@ static int create_properties_map(EVENTDATA_HANDLE event_data_handle, AMQP_VALUE* if (i < property_count) { /* Codes_SRS_EVENTHUBCLIENT_LL_01_059: [If any error is encountered while creating the application properties the callback associated with the message shall be called with EVENTHUBCLIENT_CONFIRMATION_ERROR and the message shall be freed from the pending list.] */ + /* Codes_SRS_EVENTHUBCLIENT_LL_01_094: [If any error occurs during serializing each event properties and data that are part of the batch, the callback associated with the message shall be called with EVENTHUBCLIENT_CONFIRMATION_ERROR and the message shall be freed from the pending list.] */ LogError("Could not fill all properties in the uAMQP properties map.\r\n"); amqpvalue_destroy(*uamqp_properties_map); result = __LINE__; @@ -935,6 +941,7 @@ int create_batch_message(MESSAGE_HANDLE message, EVENTDATA_HANDLE* event_data_li /* Codes_SRS_EVENTHUBCLIENT_LL_01_093: [If the property count is 0 for an event part of the batch, then no property map shall be serialized for that event.] */ if (uamqp_properties_map != NULL) { + /* Codes_SRS_EVENTHUBCLIENT_LL_01_087: [The properties shall be serialized as AMQP application_properties.] */ application_properties = amqpvalue_create_application_properties(uamqp_properties_map); if (application_properties == NULL) { @@ -942,59 +949,64 @@ int create_batch_message(MESSAGE_HANDLE message, EVENTDATA_HANDLE* event_data_li } else { - size_t property_payload_length = 0; - + /* Codes_SRS_EVENTHUBCLIENT_LL_01_091: [The size needed for the properties and data section shall be obtained by calling amqpvalue_get_encoded_size.] */ if (amqpvalue_get_encoded_size(application_properties, &temp_length) != 0) - { - is_error = true; - } - - payload_length += temp_length; - } - } - - /* Codes_SRS_EVENTHUBCLIENT_LL_01_091: [The size needed for the properties and data section shall be obtained by calling amqpvalue_get_encoded_size.] */ - if (amqpvalue_get_encoded_size(data_value, &temp_length) != 0) - { - /* Codes_SRS_EVENTHUBCLIENT_LL_01_094: [If any error occurs during serializing each event properties and data that are part of the batch, the callback associated with the message shall be called with EVENTHUBCLIENT_CONFIRMATION_ERROR and the message shall be freed from the pending list.] */ - is_error = true; - } - else - { - EVENT_DATA_BINARY event_data_binary; - - payload_length += temp_length; - - event_data_binary.length = 0; - /* Codes_SRS_EVENTHUBCLIENT_LL_01_090: [Enough memory shall be allocated to hold the properties and binary payload for each event part of the batch.] */ - event_data_binary.bytes = (unsigned char*)malloc(payload_length); - if (event_data_binary.bytes == NULL) - { - /* Codes_SRS_EVENTHUBCLIENT_LL_01_094: [If any error occurs during serializing each event properties and data that are part of the batch, the callback associated with the message shall be called with EVENTHUBCLIENT_CONFIRMATION_ERROR and the message shall be freed from the pending list.] */ - is_error = true; - } - else - { - /* Codes_SRS_EVENTHUBCLIENT_LL_01_092: [The properties and binary data shall be encoded by calling amqpvalue_encode and passing an encoding function that places the encoded data into the memory allocated for the event.] */ - if (((uamqp_properties_map != NULL) && (amqpvalue_encode(application_properties, &encode_callback, &event_data_binary) != 0)) || - (amqpvalue_encode(data_value, &encode_callback, &event_data_binary) != 0)) { /* Codes_SRS_EVENTHUBCLIENT_LL_01_094: [If any error occurs during serializing each event properties and data that are part of the batch, the callback associated with the message shall be called with EVENTHUBCLIENT_CONFIRMATION_ERROR and the message shall be freed from the pending list.] */ is_error = true; } else { - /* Codes_SRS_EVENTHUBCLIENT_LL_01_085: [The event shall be added to the message by into a separate data section by calling message_add_body_amqp_data.] */ - /* Codes_SRS_EVENTHUBCLIENT_LL_01_086: [The buffer passed to message_add_body_amqp_data shall contain the properties and the binary event payload serialized as AMQP values.] */ - BINARY_DATA body_binary_data = { event_data_binary.bytes, event_data_binary.length }; - if (message_add_body_amqp_data(message, body_binary_data) != 0) + payload_length += temp_length; + } + } + } + + if (!is_error) + { + /* Codes_SRS_EVENTHUBCLIENT_LL_01_091: [The size needed for the properties and data section shall be obtained by calling amqpvalue_get_encoded_size.] */ + if (amqpvalue_get_encoded_size(data_value, &temp_length) != 0) + { + /* Codes_SRS_EVENTHUBCLIENT_LL_01_094: [If any error occurs during serializing each event properties and data that are part of the batch, the callback associated with the message shall be called with EVENTHUBCLIENT_CONFIRMATION_ERROR and the message shall be freed from the pending list.] */ + is_error = true; + } + else + { + EVENT_DATA_BINARY event_data_binary; + + payload_length += temp_length; + + event_data_binary.length = 0; + /* Codes_SRS_EVENTHUBCLIENT_LL_01_090: [Enough memory shall be allocated to hold the properties and binary payload for each event part of the batch.] */ + event_data_binary.bytes = (unsigned char*)malloc(payload_length); + if (event_data_binary.bytes == NULL) + { + /* Codes_SRS_EVENTHUBCLIENT_LL_01_094: [If any error occurs during serializing each event properties and data that are part of the batch, the callback associated with the message shall be called with EVENTHUBCLIENT_CONFIRMATION_ERROR and the message shall be freed from the pending list.] */ + is_error = true; + } + else + { + /* Codes_SRS_EVENTHUBCLIENT_LL_01_092: [The properties and binary data shall be encoded by calling amqpvalue_encode and passing an encoding function that places the encoded data into the memory allocated for the event.] */ + if (((uamqp_properties_map != NULL) && (amqpvalue_encode(application_properties, &encode_callback, &event_data_binary) != 0)) || + (amqpvalue_encode(data_value, &encode_callback, &event_data_binary) != 0)) { - /* Codes_SRS_EVENTHUBCLIENT_LL_01_089: [If message_add_body_amqp_data fails, the callback associated with the message shall be called with EVENTHUBCLIENT_CONFIRMATION_ERROR and the message shall be freed from the pending list.] */ + /* Codes_SRS_EVENTHUBCLIENT_LL_01_094: [If any error occurs during serializing each event properties and data that are part of the batch, the callback associated with the message shall be called with EVENTHUBCLIENT_CONFIRMATION_ERROR and the message shall be freed from the pending list.] */ is_error = true; } - } + else + { + /* Codes_SRS_EVENTHUBCLIENT_LL_01_085: [The event shall be added to the message by into a separate data section by calling message_add_body_amqp_data.] */ + /* Codes_SRS_EVENTHUBCLIENT_LL_01_086: [The buffer passed to message_add_body_amqp_data shall contain the properties and the binary event payload serialized as AMQP values.] */ + BINARY_DATA body_binary_data = { event_data_binary.bytes, event_data_binary.length }; + if (message_add_body_amqp_data(message, body_binary_data) != 0) + { + /* Codes_SRS_EVENTHUBCLIENT_LL_01_089: [If message_add_body_amqp_data fails, the callback associated with the message shall be called with EVENTHUBCLIENT_CONFIRMATION_ERROR and the message shall be freed from the pending list.] */ + is_error = true; + } + } - free(event_data_binary.bytes); + free(event_data_binary.bytes); + } } } diff --git a/c/eventhub_client/tests/eventhubclient_ll_unittests/eventhubclient_ll_unittests.cpp b/c/eventhub_client/tests/eventhubclient_ll_unittests/eventhubclient_ll_unittests.cpp index 6734fa89..2183268f 100644 --- a/c/eventhub_client/tests/eventhubclient_ll_unittests/eventhubclient_ll_unittests.cpp +++ b/c/eventhub_client/tests/eventhubclient_ll_unittests/eventhubclient_ll_unittests.cpp @@ -130,8 +130,8 @@ static const char* const* no_property_keys_ptr = no_property_keys; static const char* const* no_property_values_ptr = no_property_values; static size_t no_property_size = 0; -static unsigned char* g_expected_encoded_buffer[2]; -static size_t g_expected_encoded_length[2]; +static unsigned char* g_expected_encoded_buffer[3]; +static size_t g_expected_encoded_length[3]; static size_t g_expected_encoded_counter; static const char* TEXT_MESSAGE = "Hello From EventHubClient Unit Tests"; @@ -3132,7 +3132,7 @@ BEGIN_TEST_SUITE(eventhubclient_ll_unittests) const char* const two_property_values[] = { "test_property_value", "prop_value_2" }; const char* const* two_property_keys_ptr = two_property_keys; const char* const* two_property_values_ptr = two_property_values; - size_t one_property_size = 2; + size_t two_properties_size = 2; STRICT_EXPECTED_CALL(mocks, message_create()); STRICT_EXPECTED_CALL(mocks, EventData_GetData(TEST_CLONED_EVENTDATA_HANDLE_1, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) @@ -3142,7 +3142,7 @@ BEGIN_TEST_SUITE(eventhubclient_ll_unittests) STRICT_EXPECTED_CALL(mocks, Map_GetInternals(TEST_MAP_HANDLE, IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) .CopyOutArgumentBuffer(2, &two_property_keys_ptr, sizeof(two_property_keys_ptr)) .CopyOutArgumentBuffer(3, &two_property_values_ptr, sizeof(two_property_values_ptr)) - .CopyOutArgumentBuffer(4, &one_property_size, sizeof(one_property_size)); + .CopyOutArgumentBuffer(4, &two_properties_size, sizeof(two_properties_size)); STRICT_EXPECTED_CALL(mocks, amqpvalue_create_map()) .SetReturn(TEST_UAMQP_MAP); STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("test_property_key")) @@ -3706,6 +3706,7 @@ BEGIN_TEST_SUITE(eventhubclient_ll_unittests) EventHubClient_LL_Destroy(eventHubHandle); } +#if 0 /* Tests_SRS_EVENTHUBCLIENT_LL_01_082: [If the number of event data entries for the message is greater than 1 (batched) then the message format shall be set to 0x80013700 by calling message_set_message_format.] */ /* Tests_SRS_EVENTHUBCLIENT_LL_01_084: [For each event in the batch:] */ /* Tests_SRS_EVENTHUBCLIENT_LL_01_085: [The event shall be added to the message by into a separate data section by calling message_add_body_amqp_data.] */ @@ -4339,4 +4340,1086 @@ BEGIN_TEST_SUITE(eventhubclient_ll_unittests) EventHubClient_LL_Destroy(eventHubHandle); } + /* Tests_SRS_EVENTHUBCLIENT_LL_01_086: [The buffer passed to message_add_body_amqp_data shall contain the properties and the binary event payload serialized as AMQP values.] */ + /* Tests_SRS_EVENTHUBCLIENT_LL_01_090: [Enough memory shall be allocated to hold the properties and binary payload for each event part of the batch.] */ + /* Tests_SRS_EVENTHUBCLIENT_LL_01_091: [The size needed for the properties and data section shall be obtained by calling amqpvalue_get_encoded_size.] */ + /* Tests_SRS_EVENTHUBCLIENT_LL_01_092: [The properties and binary data shall be encoded by calling amqpvalue_encode and passing an encoding function that places the encoded data into the memory allocated for the event.] */ + /* Tests_SRS_EVENTHUBCLIENT_LL_01_087: [The properties shall be serialized as AMQP application_properties.] */ + TEST_FUNCTION(a_batched_event_with_2_properties_gets_the_properties_added_to_the_payload) + { + // arrange + CEventHubClientLLMocks mocks; + setup_createfromconnectionstring_success(&mocks); + EVENTHUBCLIENT_LL_HANDLE eventHubHandle = EventHubClient_LL_CreateFromConnectionString(CONNECTION_STRING, TEST_EVENTHUB_PATH); + setup_messenger_initialize_success(&mocks); + EventHubClient_LL_DoWork(eventHubHandle); + saved_on_message_sender_state_changed(saved_message_sender_context, MESSAGE_SENDER_STATE_OPEN, MESSAGE_SENDER_STATE_IDLE); + EVENTDATA_HANDLE batch[] = { TEST_EVENTDATA_HANDLE_1, TEST_EVENTDATA_HANDLE_2 }; + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_1)) + .SetReturn(TEST_CLONED_EVENTDATA_HANDLE_1); + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_2)) + .SetReturn(TEST_CLONED_EVENTDATA_HANDLE_2); + (void)EventHubClient_LL_SendBatchAsync(eventHubHandle, batch, sizeof(batch) / sizeof(EVENTDATA_HANDLE), sendAsyncConfirmationCallback, (void*)0x4242); + mocks.ResetAllCalls(); + + unsigned char test_data[] = { 0x42 }; + unsigned char* buffer = test_data; + size_t length = sizeof(test_data); + g_expected_encoded_counter = 0; + + const char* const two_property_keys[] = { "test_property_key", "prop_key_2" }; + const char* const two_property_values[] = { "test_property_value", "prop_value_2" }; + const char* const* two_property_keys_ptr = two_property_keys; + const char* const* two_property_values_ptr = two_property_values; + size_t two_properties_size = 2; + + STRICT_EXPECTED_CALL(mocks, message_create()); + STRICT_EXPECTED_CALL(mocks, message_set_message_format(TEST_MESSAGE_HANDLE, MICROSOFT_MESSAGE_FORMAT)); + + // 1st event + STRICT_EXPECTED_CALL(mocks, EventData_GetData(TEST_CLONED_EVENTDATA_HANDLE_1, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &buffer, sizeof(buffer)) + .CopyOutArgumentBuffer(3, &length, sizeof(length)); + STRICT_EXPECTED_CALL(mocks, EventData_Properties(TEST_CLONED_EVENTDATA_HANDLE_1)); + STRICT_EXPECTED_CALL(mocks, Map_GetInternals(TEST_MAP_HANDLE, IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &two_property_keys_ptr, sizeof(two_property_keys_ptr)) + .CopyOutArgumentBuffer(3, &two_property_values_ptr, sizeof(two_property_values_ptr)) + .CopyOutArgumentBuffer(4, &two_properties_size, sizeof(two_properties_size)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_map()) + .SetReturn(TEST_UAMQP_MAP); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("test_property_key")) + .SetReturn(TEST_PROPERTY_1_KEY_AMQP_VALUE); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("test_property_value")) + .SetReturn(TEST_PROPERTY_1_VALUE_AMQP_VALUE); + STRICT_EXPECTED_CALL(mocks, amqpvalue_set_map_value(TEST_UAMQP_MAP, TEST_PROPERTY_1_KEY_AMQP_VALUE, TEST_PROPERTY_1_VALUE_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("prop_key_2")) + .SetReturn(TEST_PROPERTY_2_KEY_AMQP_VALUE); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("prop_value_2")) + .SetReturn(TEST_PROPERTY_2_VALUE_AMQP_VALUE); + STRICT_EXPECTED_CALL(mocks, amqpvalue_set_map_value(TEST_UAMQP_MAP, TEST_PROPERTY_2_KEY_AMQP_VALUE, TEST_PROPERTY_2_VALUE_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_PROPERTY_1_KEY_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_PROPERTY_1_VALUE_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_PROPERTY_2_KEY_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_PROPERTY_2_VALUE_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_application_properties(TEST_UAMQP_MAP)) + .SetReturn(TEST_APPLICATION_PROPERTIES_1); + unsigned char properties_encoded_data[] = { 0x42, 0x43, 0x44 }; + size_t properties_encoded_size = sizeof(properties_encoded_data); + STRICT_EXPECTED_CALL(mocks, amqpvalue_get_encoded_size(TEST_APPLICATION_PROPERTIES_1, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &properties_encoded_size, sizeof(properties_encoded_size)); + amqp_binary amqy_binary = { test_data, length }; + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_data(amqy_binary)) + .SetReturn(TEST_DATA_1); + unsigned char encoded_data_1[] = { 0x42 }; + size_t data_encoded_size = sizeof(encoded_data_1); + STRICT_EXPECTED_CALL(mocks, amqpvalue_get_encoded_size(TEST_DATA_1, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &data_encoded_size, sizeof(data_encoded_size)); + STRICT_EXPECTED_CALL(mocks, gballoc_malloc(data_encoded_size + properties_encoded_size)); + g_expected_encoded_buffer[0] = properties_encoded_data; + g_expected_encoded_length[0] = properties_encoded_size; + g_expected_encoded_buffer[1] = encoded_data_1; + g_expected_encoded_length[1] = data_encoded_size; + STRICT_EXPECTED_CALL(mocks, amqpvalue_encode(TEST_APPLICATION_PROPERTIES_1, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .IgnoreArgument(2).IgnoreArgument(3); + STRICT_EXPECTED_CALL(mocks, amqpvalue_encode(TEST_DATA_1, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .IgnoreArgument(2).IgnoreArgument(3); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_APPLICATION_PROPERTIES_1)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_UAMQP_MAP)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_DATA_1)); + unsigned char combined_encoded_data[] = { 0x42, 0x43, 0x44, 0x42 }; + BINARY_DATA binary_data = { combined_encoded_data, data_encoded_size + properties_encoded_size }; + STRICT_EXPECTED_CALL(mocks, message_add_body_amqp_data(TEST_MESSAGE_HANDLE, binary_data)); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + + //2nd event + STRICT_EXPECTED_CALL(mocks, EventData_GetData(TEST_CLONED_EVENTDATA_HANDLE_2, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &buffer, sizeof(buffer)) + .CopyOutArgumentBuffer(3, &length, sizeof(length)); + STRICT_EXPECTED_CALL(mocks, EventData_Properties(TEST_CLONED_EVENTDATA_HANDLE_2)); + STRICT_EXPECTED_CALL(mocks, Map_GetInternals(TEST_MAP_HANDLE, IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &no_property_keys, sizeof(no_property_keys)) + .CopyOutArgumentBuffer(3, &no_property_values, sizeof(no_property_values)) + .CopyOutArgumentBuffer(4, &no_property_size, sizeof(no_property_size)); + amqy_binary = { test_data, length }; + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_data(amqy_binary)) + .SetReturn(TEST_DATA_2); + unsigned char encoded_data_2[] = { 0x43, 0x44 }; + data_encoded_size = sizeof(encoded_data_2); + STRICT_EXPECTED_CALL(mocks, amqpvalue_get_encoded_size(TEST_DATA_2, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &data_encoded_size, sizeof(data_encoded_size)); + STRICT_EXPECTED_CALL(mocks, gballoc_malloc(data_encoded_size)); + g_expected_encoded_buffer[2] = encoded_data_2; + g_expected_encoded_length[2] = data_encoded_size; + STRICT_EXPECTED_CALL(mocks, amqpvalue_encode(TEST_DATA_2, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .IgnoreArgument(2).IgnoreArgument(3); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_DATA_2)); + binary_data = { encoded_data_2, data_encoded_size }; + STRICT_EXPECTED_CALL(mocks, message_add_body_amqp_data(TEST_MESSAGE_HANDLE, binary_data)); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + + STRICT_EXPECTED_CALL(mocks, messagesender_send(TEST_MESSAGE_SENDER_HANDLE, TEST_MESSAGE_HANDLE, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .IgnoreArgument(3).IgnoreArgument(4); + STRICT_EXPECTED_CALL(mocks, message_destroy(TEST_MESSAGE_HANDLE)); + + STRICT_EXPECTED_CALL(mocks, connection_dowork(TEST_CONNECTION_HANDLE)); + + // act + EventHubClient_LL_DoWork(eventHubHandle); + + // assert + mocks.AssertActualAndExpectedCalls(); + + // cleanup + EventHubClient_LL_Destroy(eventHubHandle); + } + + /* Tests_SRS_EVENTHUBCLIENT_LL_01_094: [If any error occurs during serializing each event properties and data that are part of the batch, the callback associated with the message shall be called with EVENTHUBCLIENT_CONFIRMATION_ERROR and the message shall be freed from the pending list.] */ + TEST_FUNCTION(when_creating_the_properties_map_fails_then_the_callback_is_triggered_with_ERROR) + { + // arrange + CEventHubClientLLMocks mocks; + setup_createfromconnectionstring_success(&mocks); + EVENTHUBCLIENT_LL_HANDLE eventHubHandle = EventHubClient_LL_CreateFromConnectionString(CONNECTION_STRING, TEST_EVENTHUB_PATH); + setup_messenger_initialize_success(&mocks); + EventHubClient_LL_DoWork(eventHubHandle); + saved_on_message_sender_state_changed(saved_message_sender_context, MESSAGE_SENDER_STATE_OPEN, MESSAGE_SENDER_STATE_IDLE); + EVENTDATA_HANDLE batch[] = { TEST_EVENTDATA_HANDLE_1, TEST_EVENTDATA_HANDLE_2 }; + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_1)) + .SetReturn(TEST_CLONED_EVENTDATA_HANDLE_1); + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_2)) + .SetReturn(TEST_CLONED_EVENTDATA_HANDLE_2); + (void)EventHubClient_LL_SendBatchAsync(eventHubHandle, batch, sizeof(batch) / sizeof(EVENTDATA_HANDLE), sendAsyncConfirmationCallback, (void*)0x4242); + mocks.ResetAllCalls(); + + unsigned char test_data[] = { 0x42 }; + unsigned char* buffer = test_data; + size_t length = sizeof(test_data); + g_expected_encoded_counter = 0; + + const char* const two_property_keys[] = { "test_property_key", "prop_key_2" }; + const char* const two_property_values[] = { "test_property_value", "prop_value_2" }; + const char* const* two_property_keys_ptr = two_property_keys; + const char* const* two_property_values_ptr = two_property_values; + size_t two_properties_size = 2; + + STRICT_EXPECTED_CALL(mocks, message_create()); + STRICT_EXPECTED_CALL(mocks, message_set_message_format(TEST_MESSAGE_HANDLE, MICROSOFT_MESSAGE_FORMAT)); + + // 1st event + STRICT_EXPECTED_CALL(mocks, EventData_GetData(TEST_CLONED_EVENTDATA_HANDLE_1, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &buffer, sizeof(buffer)) + .CopyOutArgumentBuffer(3, &length, sizeof(length)); + STRICT_EXPECTED_CALL(mocks, EventData_Properties(TEST_CLONED_EVENTDATA_HANDLE_1)); + STRICT_EXPECTED_CALL(mocks, Map_GetInternals(TEST_MAP_HANDLE, IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &two_property_keys_ptr, sizeof(two_property_keys_ptr)) + .CopyOutArgumentBuffer(3, &two_property_values_ptr, sizeof(two_property_values_ptr)) + .CopyOutArgumentBuffer(4, &two_properties_size, sizeof(two_properties_size)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_map()) + .SetReturn((AMQP_VALUE)NULL); + + STRICT_EXPECTED_CALL(mocks, message_destroy(TEST_MESSAGE_HANDLE)); + STRICT_EXPECTED_CALL(mocks, sendAsyncConfirmationCallback(EVENTHUBCLIENT_CONFIRMATION_ERROR, (void*)0x4242)); + EXPECTED_CALL(mocks, DList_RemoveEntryList(IGNORED_PTR_ARG)); + STRICT_EXPECTED_CALL(mocks, EventData_Destroy(TEST_CLONED_EVENTDATA_HANDLE_1)); + STRICT_EXPECTED_CALL(mocks, EventData_Destroy(TEST_CLONED_EVENTDATA_HANDLE_2)); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + + STRICT_EXPECTED_CALL(mocks, connection_dowork(TEST_CONNECTION_HANDLE)); + + // act + EventHubClient_LL_DoWork(eventHubHandle); + + // assert + mocks.AssertActualAndExpectedCalls(); + + // cleanup + EventHubClient_LL_Destroy(eventHubHandle); + } + + /* Tests_SRS_EVENTHUBCLIENT_LL_01_094: [If any error occurs during serializing each event properties and data that are part of the batch, the callback associated with the message shall be called with EVENTHUBCLIENT_CONFIRMATION_ERROR and the message shall be freed from the pending list.] */ + TEST_FUNCTION(when_creating_the_key_for_the_first_property_string_fails_then_the_callback_is_triggered_with_ERROR) + { + // arrange + CEventHubClientLLMocks mocks; + setup_createfromconnectionstring_success(&mocks); + EVENTHUBCLIENT_LL_HANDLE eventHubHandle = EventHubClient_LL_CreateFromConnectionString(CONNECTION_STRING, TEST_EVENTHUB_PATH); + setup_messenger_initialize_success(&mocks); + EventHubClient_LL_DoWork(eventHubHandle); + saved_on_message_sender_state_changed(saved_message_sender_context, MESSAGE_SENDER_STATE_OPEN, MESSAGE_SENDER_STATE_IDLE); + EVENTDATA_HANDLE batch[] = { TEST_EVENTDATA_HANDLE_1, TEST_EVENTDATA_HANDLE_2 }; + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_1)) + .SetReturn(TEST_CLONED_EVENTDATA_HANDLE_1); + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_2)) + .SetReturn(TEST_CLONED_EVENTDATA_HANDLE_2); + (void)EventHubClient_LL_SendBatchAsync(eventHubHandle, batch, sizeof(batch) / sizeof(EVENTDATA_HANDLE), sendAsyncConfirmationCallback, (void*)0x4242); + mocks.ResetAllCalls(); + + unsigned char test_data[] = { 0x42 }; + unsigned char* buffer = test_data; + size_t length = sizeof(test_data); + g_expected_encoded_counter = 0; + + const char* const two_property_keys[] = { "test_property_key", "prop_key_2" }; + const char* const two_property_values[] = { "test_property_value", "prop_value_2" }; + const char* const* two_property_keys_ptr = two_property_keys; + const char* const* two_property_values_ptr = two_property_values; + size_t two_properties_size = 2; + + STRICT_EXPECTED_CALL(mocks, message_create()); + STRICT_EXPECTED_CALL(mocks, message_set_message_format(TEST_MESSAGE_HANDLE, MICROSOFT_MESSAGE_FORMAT)); + + // 1st event + STRICT_EXPECTED_CALL(mocks, EventData_GetData(TEST_CLONED_EVENTDATA_HANDLE_1, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &buffer, sizeof(buffer)) + .CopyOutArgumentBuffer(3, &length, sizeof(length)); + STRICT_EXPECTED_CALL(mocks, EventData_Properties(TEST_CLONED_EVENTDATA_HANDLE_1)); + STRICT_EXPECTED_CALL(mocks, Map_GetInternals(TEST_MAP_HANDLE, IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &two_property_keys_ptr, sizeof(two_property_keys_ptr)) + .CopyOutArgumentBuffer(3, &two_property_values_ptr, sizeof(two_property_values_ptr)) + .CopyOutArgumentBuffer(4, &two_properties_size, sizeof(two_properties_size)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_map()) + .SetReturn(TEST_UAMQP_MAP); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("test_property_key")) + .SetReturn((AMQP_VALUE)NULL); + + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_UAMQP_MAP)); + STRICT_EXPECTED_CALL(mocks, message_destroy(TEST_MESSAGE_HANDLE)); + STRICT_EXPECTED_CALL(mocks, sendAsyncConfirmationCallback(EVENTHUBCLIENT_CONFIRMATION_ERROR, (void*)0x4242)); + EXPECTED_CALL(mocks, DList_RemoveEntryList(IGNORED_PTR_ARG)); + STRICT_EXPECTED_CALL(mocks, EventData_Destroy(TEST_CLONED_EVENTDATA_HANDLE_1)); + STRICT_EXPECTED_CALL(mocks, EventData_Destroy(TEST_CLONED_EVENTDATA_HANDLE_2)); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + + STRICT_EXPECTED_CALL(mocks, connection_dowork(TEST_CONNECTION_HANDLE)); + + // act + EventHubClient_LL_DoWork(eventHubHandle); + + // assert + mocks.AssertActualAndExpectedCalls(); + + // cleanup + EventHubClient_LL_Destroy(eventHubHandle); + } + + /* Tests_SRS_EVENTHUBCLIENT_LL_01_094: [If any error occurs during serializing each event properties and data that are part of the batch, the callback associated with the message shall be called with EVENTHUBCLIENT_CONFIRMATION_ERROR and the message shall be freed from the pending list.] */ + TEST_FUNCTION(when_creating_the_value_for_the_first_property_string_fails_then_the_callback_is_triggered_with_ERROR) + { + // arrange + CEventHubClientLLMocks mocks; + setup_createfromconnectionstring_success(&mocks); + EVENTHUBCLIENT_LL_HANDLE eventHubHandle = EventHubClient_LL_CreateFromConnectionString(CONNECTION_STRING, TEST_EVENTHUB_PATH); + setup_messenger_initialize_success(&mocks); + EventHubClient_LL_DoWork(eventHubHandle); + saved_on_message_sender_state_changed(saved_message_sender_context, MESSAGE_SENDER_STATE_OPEN, MESSAGE_SENDER_STATE_IDLE); + EVENTDATA_HANDLE batch[] = { TEST_EVENTDATA_HANDLE_1, TEST_EVENTDATA_HANDLE_2 }; + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_1)) + .SetReturn(TEST_CLONED_EVENTDATA_HANDLE_1); + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_2)) + .SetReturn(TEST_CLONED_EVENTDATA_HANDLE_2); + (void)EventHubClient_LL_SendBatchAsync(eventHubHandle, batch, sizeof(batch) / sizeof(EVENTDATA_HANDLE), sendAsyncConfirmationCallback, (void*)0x4242); + mocks.ResetAllCalls(); + + unsigned char test_data[] = { 0x42 }; + unsigned char* buffer = test_data; + size_t length = sizeof(test_data); + g_expected_encoded_counter = 0; + + const char* const two_property_keys[] = { "test_property_key", "prop_key_2" }; + const char* const two_property_values[] = { "test_property_value", "prop_value_2" }; + const char* const* two_property_keys_ptr = two_property_keys; + const char* const* two_property_values_ptr = two_property_values; + size_t two_properties_size = 2; + + STRICT_EXPECTED_CALL(mocks, message_create()); + STRICT_EXPECTED_CALL(mocks, message_set_message_format(TEST_MESSAGE_HANDLE, MICROSOFT_MESSAGE_FORMAT)); + + // 1st event + STRICT_EXPECTED_CALL(mocks, EventData_GetData(TEST_CLONED_EVENTDATA_HANDLE_1, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &buffer, sizeof(buffer)) + .CopyOutArgumentBuffer(3, &length, sizeof(length)); + STRICT_EXPECTED_CALL(mocks, EventData_Properties(TEST_CLONED_EVENTDATA_HANDLE_1)); + STRICT_EXPECTED_CALL(mocks, Map_GetInternals(TEST_MAP_HANDLE, IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &two_property_keys_ptr, sizeof(two_property_keys_ptr)) + .CopyOutArgumentBuffer(3, &two_property_values_ptr, sizeof(two_property_values_ptr)) + .CopyOutArgumentBuffer(4, &two_properties_size, sizeof(two_properties_size)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_map()) + .SetReturn(TEST_UAMQP_MAP); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("test_property_key")) + .SetReturn(TEST_PROPERTY_1_KEY_AMQP_VALUE); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("test_property_value")) + .SetReturn((AMQP_VALUE)NULL); + + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_PROPERTY_1_KEY_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_UAMQP_MAP)); + STRICT_EXPECTED_CALL(mocks, message_destroy(TEST_MESSAGE_HANDLE)); + STRICT_EXPECTED_CALL(mocks, sendAsyncConfirmationCallback(EVENTHUBCLIENT_CONFIRMATION_ERROR, (void*)0x4242)); + EXPECTED_CALL(mocks, DList_RemoveEntryList(IGNORED_PTR_ARG)); + STRICT_EXPECTED_CALL(mocks, EventData_Destroy(TEST_CLONED_EVENTDATA_HANDLE_1)); + STRICT_EXPECTED_CALL(mocks, EventData_Destroy(TEST_CLONED_EVENTDATA_HANDLE_2)); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + + STRICT_EXPECTED_CALL(mocks, connection_dowork(TEST_CONNECTION_HANDLE)); + + // act + EventHubClient_LL_DoWork(eventHubHandle); + + // assert + mocks.AssertActualAndExpectedCalls(); + + // cleanup + EventHubClient_LL_Destroy(eventHubHandle); + } + + /* Tests_SRS_EVENTHUBCLIENT_LL_01_094: [If any error occurs during serializing each event properties and data that are part of the batch, the callback associated with the message shall be called with EVENTHUBCLIENT_CONFIRMATION_ERROR and the message shall be freed from the pending list.] */ + TEST_FUNCTION(when_setting_the_first_property_in_the_properties_map_fails_then_the_callback_is_triggered_with_ERROR) + { + // arrange + CEventHubClientLLMocks mocks; + setup_createfromconnectionstring_success(&mocks); + EVENTHUBCLIENT_LL_HANDLE eventHubHandle = EventHubClient_LL_CreateFromConnectionString(CONNECTION_STRING, TEST_EVENTHUB_PATH); + setup_messenger_initialize_success(&mocks); + EventHubClient_LL_DoWork(eventHubHandle); + saved_on_message_sender_state_changed(saved_message_sender_context, MESSAGE_SENDER_STATE_OPEN, MESSAGE_SENDER_STATE_IDLE); + EVENTDATA_HANDLE batch[] = { TEST_EVENTDATA_HANDLE_1, TEST_EVENTDATA_HANDLE_2 }; + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_1)) + .SetReturn(TEST_CLONED_EVENTDATA_HANDLE_1); + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_2)) + .SetReturn(TEST_CLONED_EVENTDATA_HANDLE_2); + (void)EventHubClient_LL_SendBatchAsync(eventHubHandle, batch, sizeof(batch) / sizeof(EVENTDATA_HANDLE), sendAsyncConfirmationCallback, (void*)0x4242); + mocks.ResetAllCalls(); + + unsigned char test_data[] = { 0x42 }; + unsigned char* buffer = test_data; + size_t length = sizeof(test_data); + g_expected_encoded_counter = 0; + + const char* const two_property_keys[] = { "test_property_key", "prop_key_2" }; + const char* const two_property_values[] = { "test_property_value", "prop_value_2" }; + const char* const* two_property_keys_ptr = two_property_keys; + const char* const* two_property_values_ptr = two_property_values; + size_t two_properties_size = 2; + + STRICT_EXPECTED_CALL(mocks, message_create()); + STRICT_EXPECTED_CALL(mocks, message_set_message_format(TEST_MESSAGE_HANDLE, MICROSOFT_MESSAGE_FORMAT)); + + // 1st event + STRICT_EXPECTED_CALL(mocks, EventData_GetData(TEST_CLONED_EVENTDATA_HANDLE_1, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &buffer, sizeof(buffer)) + .CopyOutArgumentBuffer(3, &length, sizeof(length)); + STRICT_EXPECTED_CALL(mocks, EventData_Properties(TEST_CLONED_EVENTDATA_HANDLE_1)); + STRICT_EXPECTED_CALL(mocks, Map_GetInternals(TEST_MAP_HANDLE, IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &two_property_keys_ptr, sizeof(two_property_keys_ptr)) + .CopyOutArgumentBuffer(3, &two_property_values_ptr, sizeof(two_property_values_ptr)) + .CopyOutArgumentBuffer(4, &two_properties_size, sizeof(two_properties_size)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_map()) + .SetReturn(TEST_UAMQP_MAP); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("test_property_key")) + .SetReturn(TEST_PROPERTY_1_KEY_AMQP_VALUE); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("test_property_value")) + .SetReturn(TEST_PROPERTY_1_VALUE_AMQP_VALUE); + STRICT_EXPECTED_CALL(mocks, amqpvalue_set_map_value(TEST_UAMQP_MAP, TEST_PROPERTY_1_KEY_AMQP_VALUE, TEST_PROPERTY_1_VALUE_AMQP_VALUE)) + .SetReturn(1); + + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_PROPERTY_1_KEY_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_PROPERTY_1_VALUE_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_UAMQP_MAP)); + STRICT_EXPECTED_CALL(mocks, message_destroy(TEST_MESSAGE_HANDLE)); + STRICT_EXPECTED_CALL(mocks, sendAsyncConfirmationCallback(EVENTHUBCLIENT_CONFIRMATION_ERROR, (void*)0x4242)); + EXPECTED_CALL(mocks, DList_RemoveEntryList(IGNORED_PTR_ARG)); + STRICT_EXPECTED_CALL(mocks, EventData_Destroy(TEST_CLONED_EVENTDATA_HANDLE_1)); + STRICT_EXPECTED_CALL(mocks, EventData_Destroy(TEST_CLONED_EVENTDATA_HANDLE_2)); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + + STRICT_EXPECTED_CALL(mocks, connection_dowork(TEST_CONNECTION_HANDLE)); + + // act + EventHubClient_LL_DoWork(eventHubHandle); + + // assert + mocks.AssertActualAndExpectedCalls(); + + // cleanup + EventHubClient_LL_Destroy(eventHubHandle); + } + + /* Tests_SRS_EVENTHUBCLIENT_LL_01_094: [If any error occurs during serializing each event properties and data that are part of the batch, the callback associated with the message shall be called with EVENTHUBCLIENT_CONFIRMATION_ERROR and the message shall be freed from the pending list.] */ + TEST_FUNCTION(when_creating_the_key_for_the_second_property_in_the_properties_map_fails_then_the_callback_is_triggered_with_ERROR) + { + // arrange + CEventHubClientLLMocks mocks; + setup_createfromconnectionstring_success(&mocks); + EVENTHUBCLIENT_LL_HANDLE eventHubHandle = EventHubClient_LL_CreateFromConnectionString(CONNECTION_STRING, TEST_EVENTHUB_PATH); + setup_messenger_initialize_success(&mocks); + EventHubClient_LL_DoWork(eventHubHandle); + saved_on_message_sender_state_changed(saved_message_sender_context, MESSAGE_SENDER_STATE_OPEN, MESSAGE_SENDER_STATE_IDLE); + EVENTDATA_HANDLE batch[] = { TEST_EVENTDATA_HANDLE_1, TEST_EVENTDATA_HANDLE_2 }; + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_1)) + .SetReturn(TEST_CLONED_EVENTDATA_HANDLE_1); + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_2)) + .SetReturn(TEST_CLONED_EVENTDATA_HANDLE_2); + (void)EventHubClient_LL_SendBatchAsync(eventHubHandle, batch, sizeof(batch) / sizeof(EVENTDATA_HANDLE), sendAsyncConfirmationCallback, (void*)0x4242); + mocks.ResetAllCalls(); + + unsigned char test_data[] = { 0x42 }; + unsigned char* buffer = test_data; + size_t length = sizeof(test_data); + g_expected_encoded_counter = 0; + + const char* const two_property_keys[] = { "test_property_key", "prop_key_2" }; + const char* const two_property_values[] = { "test_property_value", "prop_value_2" }; + const char* const* two_property_keys_ptr = two_property_keys; + const char* const* two_property_values_ptr = two_property_values; + size_t two_properties_size = 2; + + STRICT_EXPECTED_CALL(mocks, message_create()); + STRICT_EXPECTED_CALL(mocks, message_set_message_format(TEST_MESSAGE_HANDLE, MICROSOFT_MESSAGE_FORMAT)); + + // 1st event + STRICT_EXPECTED_CALL(mocks, EventData_GetData(TEST_CLONED_EVENTDATA_HANDLE_1, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &buffer, sizeof(buffer)) + .CopyOutArgumentBuffer(3, &length, sizeof(length)); + STRICT_EXPECTED_CALL(mocks, EventData_Properties(TEST_CLONED_EVENTDATA_HANDLE_1)); + STRICT_EXPECTED_CALL(mocks, Map_GetInternals(TEST_MAP_HANDLE, IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &two_property_keys_ptr, sizeof(two_property_keys_ptr)) + .CopyOutArgumentBuffer(3, &two_property_values_ptr, sizeof(two_property_values_ptr)) + .CopyOutArgumentBuffer(4, &two_properties_size, sizeof(two_properties_size)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_map()) + .SetReturn(TEST_UAMQP_MAP); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("test_property_key")) + .SetReturn(TEST_PROPERTY_1_KEY_AMQP_VALUE); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("test_property_value")) + .SetReturn(TEST_PROPERTY_1_VALUE_AMQP_VALUE); + STRICT_EXPECTED_CALL(mocks, amqpvalue_set_map_value(TEST_UAMQP_MAP, TEST_PROPERTY_1_KEY_AMQP_VALUE, TEST_PROPERTY_1_VALUE_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("prop_key_2")) + .SetReturn((AMQP_VALUE)NULL); + + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_PROPERTY_1_KEY_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_PROPERTY_1_VALUE_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_UAMQP_MAP)); + STRICT_EXPECTED_CALL(mocks, message_destroy(TEST_MESSAGE_HANDLE)); + STRICT_EXPECTED_CALL(mocks, sendAsyncConfirmationCallback(EVENTHUBCLIENT_CONFIRMATION_ERROR, (void*)0x4242)); + EXPECTED_CALL(mocks, DList_RemoveEntryList(IGNORED_PTR_ARG)); + STRICT_EXPECTED_CALL(mocks, EventData_Destroy(TEST_CLONED_EVENTDATA_HANDLE_1)); + STRICT_EXPECTED_CALL(mocks, EventData_Destroy(TEST_CLONED_EVENTDATA_HANDLE_2)); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + + STRICT_EXPECTED_CALL(mocks, connection_dowork(TEST_CONNECTION_HANDLE)); + + // act + EventHubClient_LL_DoWork(eventHubHandle); + + // assert + mocks.AssertActualAndExpectedCalls(); + + // cleanup + EventHubClient_LL_Destroy(eventHubHandle); + } + + /* Tests_SRS_EVENTHUBCLIENT_LL_01_094: [If any error occurs during serializing each event properties and data that are part of the batch, the callback associated with the message shall be called with EVENTHUBCLIENT_CONFIRMATION_ERROR and the message shall be freed from the pending list.] */ + TEST_FUNCTION(when_creating_the_value_for_the_second_property_in_the_properties_map_fails_then_the_callback_is_triggered_with_ERROR) + { + // arrange + CEventHubClientLLMocks mocks; + setup_createfromconnectionstring_success(&mocks); + EVENTHUBCLIENT_LL_HANDLE eventHubHandle = EventHubClient_LL_CreateFromConnectionString(CONNECTION_STRING, TEST_EVENTHUB_PATH); + setup_messenger_initialize_success(&mocks); + EventHubClient_LL_DoWork(eventHubHandle); + saved_on_message_sender_state_changed(saved_message_sender_context, MESSAGE_SENDER_STATE_OPEN, MESSAGE_SENDER_STATE_IDLE); + EVENTDATA_HANDLE batch[] = { TEST_EVENTDATA_HANDLE_1, TEST_EVENTDATA_HANDLE_2 }; + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_1)) + .SetReturn(TEST_CLONED_EVENTDATA_HANDLE_1); + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_2)) + .SetReturn(TEST_CLONED_EVENTDATA_HANDLE_2); + (void)EventHubClient_LL_SendBatchAsync(eventHubHandle, batch, sizeof(batch) / sizeof(EVENTDATA_HANDLE), sendAsyncConfirmationCallback, (void*)0x4242); + mocks.ResetAllCalls(); + + unsigned char test_data[] = { 0x42 }; + unsigned char* buffer = test_data; + size_t length = sizeof(test_data); + g_expected_encoded_counter = 0; + + const char* const two_property_keys[] = { "test_property_key", "prop_key_2" }; + const char* const two_property_values[] = { "test_property_value", "prop_value_2" }; + const char* const* two_property_keys_ptr = two_property_keys; + const char* const* two_property_values_ptr = two_property_values; + size_t two_properties_size = 2; + + STRICT_EXPECTED_CALL(mocks, message_create()); + STRICT_EXPECTED_CALL(mocks, message_set_message_format(TEST_MESSAGE_HANDLE, MICROSOFT_MESSAGE_FORMAT)); + + // 1st event + STRICT_EXPECTED_CALL(mocks, EventData_GetData(TEST_CLONED_EVENTDATA_HANDLE_1, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &buffer, sizeof(buffer)) + .CopyOutArgumentBuffer(3, &length, sizeof(length)); + STRICT_EXPECTED_CALL(mocks, EventData_Properties(TEST_CLONED_EVENTDATA_HANDLE_1)); + STRICT_EXPECTED_CALL(mocks, Map_GetInternals(TEST_MAP_HANDLE, IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &two_property_keys_ptr, sizeof(two_property_keys_ptr)) + .CopyOutArgumentBuffer(3, &two_property_values_ptr, sizeof(two_property_values_ptr)) + .CopyOutArgumentBuffer(4, &two_properties_size, sizeof(two_properties_size)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_map()) + .SetReturn(TEST_UAMQP_MAP); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("test_property_key")) + .SetReturn(TEST_PROPERTY_1_KEY_AMQP_VALUE); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("test_property_value")) + .SetReturn(TEST_PROPERTY_1_VALUE_AMQP_VALUE); + STRICT_EXPECTED_CALL(mocks, amqpvalue_set_map_value(TEST_UAMQP_MAP, TEST_PROPERTY_1_KEY_AMQP_VALUE, TEST_PROPERTY_1_VALUE_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("prop_key_2")) + .SetReturn(TEST_PROPERTY_2_KEY_AMQP_VALUE); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("prop_value_2")) + .SetReturn((AMQP_VALUE)NULL); + + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_PROPERTY_1_KEY_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_PROPERTY_1_VALUE_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_PROPERTY_2_KEY_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_UAMQP_MAP)); + STRICT_EXPECTED_CALL(mocks, message_destroy(TEST_MESSAGE_HANDLE)); + STRICT_EXPECTED_CALL(mocks, sendAsyncConfirmationCallback(EVENTHUBCLIENT_CONFIRMATION_ERROR, (void*)0x4242)); + EXPECTED_CALL(mocks, DList_RemoveEntryList(IGNORED_PTR_ARG)); + STRICT_EXPECTED_CALL(mocks, EventData_Destroy(TEST_CLONED_EVENTDATA_HANDLE_1)); + STRICT_EXPECTED_CALL(mocks, EventData_Destroy(TEST_CLONED_EVENTDATA_HANDLE_2)); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + + STRICT_EXPECTED_CALL(mocks, connection_dowork(TEST_CONNECTION_HANDLE)); + + // act + EventHubClient_LL_DoWork(eventHubHandle); + + // assert + mocks.AssertActualAndExpectedCalls(); + + // cleanup + EventHubClient_LL_Destroy(eventHubHandle); + } + + /* Tests_SRS_EVENTHUBCLIENT_LL_01_094: [If any error occurs during serializing each event properties and data that are part of the batch, the callback associated with the message shall be called with EVENTHUBCLIENT_CONFIRMATION_ERROR and the message shall be freed from the pending list.] */ + TEST_FUNCTION(when_adding_the_second_property_to_the_map_fails_then_the_callback_is_triggered_with_ERROR) + { + // arrange + CEventHubClientLLMocks mocks; + setup_createfromconnectionstring_success(&mocks); + EVENTHUBCLIENT_LL_HANDLE eventHubHandle = EventHubClient_LL_CreateFromConnectionString(CONNECTION_STRING, TEST_EVENTHUB_PATH); + setup_messenger_initialize_success(&mocks); + EventHubClient_LL_DoWork(eventHubHandle); + saved_on_message_sender_state_changed(saved_message_sender_context, MESSAGE_SENDER_STATE_OPEN, MESSAGE_SENDER_STATE_IDLE); + EVENTDATA_HANDLE batch[] = { TEST_EVENTDATA_HANDLE_1, TEST_EVENTDATA_HANDLE_2 }; + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_1)) + .SetReturn(TEST_CLONED_EVENTDATA_HANDLE_1); + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_2)) + .SetReturn(TEST_CLONED_EVENTDATA_HANDLE_2); + (void)EventHubClient_LL_SendBatchAsync(eventHubHandle, batch, sizeof(batch) / sizeof(EVENTDATA_HANDLE), sendAsyncConfirmationCallback, (void*)0x4242); + mocks.ResetAllCalls(); + + unsigned char test_data[] = { 0x42 }; + unsigned char* buffer = test_data; + size_t length = sizeof(test_data); + g_expected_encoded_counter = 0; + + const char* const two_property_keys[] = { "test_property_key", "prop_key_2" }; + const char* const two_property_values[] = { "test_property_value", "prop_value_2" }; + const char* const* two_property_keys_ptr = two_property_keys; + const char* const* two_property_values_ptr = two_property_values; + size_t two_properties_size = 2; + + STRICT_EXPECTED_CALL(mocks, message_create()); + STRICT_EXPECTED_CALL(mocks, message_set_message_format(TEST_MESSAGE_HANDLE, MICROSOFT_MESSAGE_FORMAT)); + + // 1st event + STRICT_EXPECTED_CALL(mocks, EventData_GetData(TEST_CLONED_EVENTDATA_HANDLE_1, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &buffer, sizeof(buffer)) + .CopyOutArgumentBuffer(3, &length, sizeof(length)); + STRICT_EXPECTED_CALL(mocks, EventData_Properties(TEST_CLONED_EVENTDATA_HANDLE_1)); + STRICT_EXPECTED_CALL(mocks, Map_GetInternals(TEST_MAP_HANDLE, IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &two_property_keys_ptr, sizeof(two_property_keys_ptr)) + .CopyOutArgumentBuffer(3, &two_property_values_ptr, sizeof(two_property_values_ptr)) + .CopyOutArgumentBuffer(4, &two_properties_size, sizeof(two_properties_size)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_map()) + .SetReturn(TEST_UAMQP_MAP); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("test_property_key")) + .SetReturn(TEST_PROPERTY_1_KEY_AMQP_VALUE); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("test_property_value")) + .SetReturn(TEST_PROPERTY_1_VALUE_AMQP_VALUE); + STRICT_EXPECTED_CALL(mocks, amqpvalue_set_map_value(TEST_UAMQP_MAP, TEST_PROPERTY_1_KEY_AMQP_VALUE, TEST_PROPERTY_1_VALUE_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("prop_key_2")) + .SetReturn(TEST_PROPERTY_2_KEY_AMQP_VALUE); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("prop_value_2")) + .SetReturn(TEST_PROPERTY_2_VALUE_AMQP_VALUE); + STRICT_EXPECTED_CALL(mocks, amqpvalue_set_map_value(TEST_UAMQP_MAP, TEST_PROPERTY_2_KEY_AMQP_VALUE, TEST_PROPERTY_2_VALUE_AMQP_VALUE)) + .SetReturn(1); + + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_PROPERTY_1_KEY_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_PROPERTY_1_VALUE_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_PROPERTY_2_KEY_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_PROPERTY_2_VALUE_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_UAMQP_MAP)); + STRICT_EXPECTED_CALL(mocks, message_destroy(TEST_MESSAGE_HANDLE)); + STRICT_EXPECTED_CALL(mocks, sendAsyncConfirmationCallback(EVENTHUBCLIENT_CONFIRMATION_ERROR, (void*)0x4242)); + EXPECTED_CALL(mocks, DList_RemoveEntryList(IGNORED_PTR_ARG)); + STRICT_EXPECTED_CALL(mocks, EventData_Destroy(TEST_CLONED_EVENTDATA_HANDLE_1)); + STRICT_EXPECTED_CALL(mocks, EventData_Destroy(TEST_CLONED_EVENTDATA_HANDLE_2)); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + + STRICT_EXPECTED_CALL(mocks, connection_dowork(TEST_CONNECTION_HANDLE)); + + // act + EventHubClient_LL_DoWork(eventHubHandle); + + // assert + mocks.AssertActualAndExpectedCalls(); + + // cleanup + EventHubClient_LL_Destroy(eventHubHandle); + } + + /* Tests_SRS_EVENTHUBCLIENT_LL_01_094: [If any error occurs during serializing each event properties and data that are part of the batch, the callback associated with the message shall be called with EVENTHUBCLIENT_CONFIRMATION_ERROR and the message shall be freed from the pending list.] */ + TEST_FUNCTION(when_creating_the_application_properties_object_fails_then_the_callback_is_triggered_with_ERROR) + { + // arrange + CEventHubClientLLMocks mocks; + setup_createfromconnectionstring_success(&mocks); + EVENTHUBCLIENT_LL_HANDLE eventHubHandle = EventHubClient_LL_CreateFromConnectionString(CONNECTION_STRING, TEST_EVENTHUB_PATH); + setup_messenger_initialize_success(&mocks); + EventHubClient_LL_DoWork(eventHubHandle); + saved_on_message_sender_state_changed(saved_message_sender_context, MESSAGE_SENDER_STATE_OPEN, MESSAGE_SENDER_STATE_IDLE); + EVENTDATA_HANDLE batch[] = { TEST_EVENTDATA_HANDLE_1, TEST_EVENTDATA_HANDLE_2 }; + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_1)) + .SetReturn(TEST_CLONED_EVENTDATA_HANDLE_1); + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_2)) + .SetReturn(TEST_CLONED_EVENTDATA_HANDLE_2); + (void)EventHubClient_LL_SendBatchAsync(eventHubHandle, batch, sizeof(batch) / sizeof(EVENTDATA_HANDLE), sendAsyncConfirmationCallback, (void*)0x4242); + mocks.ResetAllCalls(); + + unsigned char test_data[] = { 0x42 }; + unsigned char* buffer = test_data; + size_t length = sizeof(test_data); + g_expected_encoded_counter = 0; + + const char* const two_property_keys[] = { "test_property_key", "prop_key_2" }; + const char* const two_property_values[] = { "test_property_value", "prop_value_2" }; + const char* const* two_property_keys_ptr = two_property_keys; + const char* const* two_property_values_ptr = two_property_values; + size_t two_properties_size = 2; + + STRICT_EXPECTED_CALL(mocks, message_create()); + STRICT_EXPECTED_CALL(mocks, message_set_message_format(TEST_MESSAGE_HANDLE, MICROSOFT_MESSAGE_FORMAT)); + + // 1st event + STRICT_EXPECTED_CALL(mocks, EventData_GetData(TEST_CLONED_EVENTDATA_HANDLE_1, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &buffer, sizeof(buffer)) + .CopyOutArgumentBuffer(3, &length, sizeof(length)); + STRICT_EXPECTED_CALL(mocks, EventData_Properties(TEST_CLONED_EVENTDATA_HANDLE_1)); + STRICT_EXPECTED_CALL(mocks, Map_GetInternals(TEST_MAP_HANDLE, IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &two_property_keys_ptr, sizeof(two_property_keys_ptr)) + .CopyOutArgumentBuffer(3, &two_property_values_ptr, sizeof(two_property_values_ptr)) + .CopyOutArgumentBuffer(4, &two_properties_size, sizeof(two_properties_size)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_map()) + .SetReturn(TEST_UAMQP_MAP); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("test_property_key")) + .SetReturn(TEST_PROPERTY_1_KEY_AMQP_VALUE); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("test_property_value")) + .SetReturn(TEST_PROPERTY_1_VALUE_AMQP_VALUE); + STRICT_EXPECTED_CALL(mocks, amqpvalue_set_map_value(TEST_UAMQP_MAP, TEST_PROPERTY_1_KEY_AMQP_VALUE, TEST_PROPERTY_1_VALUE_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("prop_key_2")) + .SetReturn(TEST_PROPERTY_2_KEY_AMQP_VALUE); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("prop_value_2")) + .SetReturn(TEST_PROPERTY_2_VALUE_AMQP_VALUE); + STRICT_EXPECTED_CALL(mocks, amqpvalue_set_map_value(TEST_UAMQP_MAP, TEST_PROPERTY_2_KEY_AMQP_VALUE, TEST_PROPERTY_2_VALUE_AMQP_VALUE)); + amqp_binary amqy_binary = { test_data, length }; + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_data(amqy_binary)) + .SetReturn(TEST_DATA_1); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_application_properties(TEST_UAMQP_MAP)) + .SetReturn((AMQP_VALUE)NULL); + + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_DATA_1)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_PROPERTY_1_KEY_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_PROPERTY_1_VALUE_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_PROPERTY_2_KEY_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_PROPERTY_2_VALUE_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_UAMQP_MAP)); + STRICT_EXPECTED_CALL(mocks, message_destroy(TEST_MESSAGE_HANDLE)); + STRICT_EXPECTED_CALL(mocks, sendAsyncConfirmationCallback(EVENTHUBCLIENT_CONFIRMATION_ERROR, (void*)0x4242)); + EXPECTED_CALL(mocks, DList_RemoveEntryList(IGNORED_PTR_ARG)); + STRICT_EXPECTED_CALL(mocks, EventData_Destroy(TEST_CLONED_EVENTDATA_HANDLE_1)); + STRICT_EXPECTED_CALL(mocks, EventData_Destroy(TEST_CLONED_EVENTDATA_HANDLE_2)); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + + STRICT_EXPECTED_CALL(mocks, connection_dowork(TEST_CONNECTION_HANDLE)); + + // act + EventHubClient_LL_DoWork(eventHubHandle); + + // assert + mocks.AssertActualAndExpectedCalls(); + + // cleanup + EventHubClient_LL_Destroy(eventHubHandle); + } + + /* Tests_SRS_EVENTHUBCLIENT_LL_01_094: [If any error occurs during serializing each event properties and data that are part of the batch, the callback associated with the message shall be called with EVENTHUBCLIENT_CONFIRMATION_ERROR and the message shall be freed from the pending list.] */ + TEST_FUNCTION(when_getting_the_encoded_size_for_the_properties_fails_then_the_callback_is_triggered_with_ERROR) + { + // arrange + CEventHubClientLLMocks mocks; + setup_createfromconnectionstring_success(&mocks); + EVENTHUBCLIENT_LL_HANDLE eventHubHandle = EventHubClient_LL_CreateFromConnectionString(CONNECTION_STRING, TEST_EVENTHUB_PATH); + setup_messenger_initialize_success(&mocks); + EventHubClient_LL_DoWork(eventHubHandle); + saved_on_message_sender_state_changed(saved_message_sender_context, MESSAGE_SENDER_STATE_OPEN, MESSAGE_SENDER_STATE_IDLE); + EVENTDATA_HANDLE batch[] = { TEST_EVENTDATA_HANDLE_1, TEST_EVENTDATA_HANDLE_2 }; + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_1)) + .SetReturn(TEST_CLONED_EVENTDATA_HANDLE_1); + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_2)) + .SetReturn(TEST_CLONED_EVENTDATA_HANDLE_2); + (void)EventHubClient_LL_SendBatchAsync(eventHubHandle, batch, sizeof(batch) / sizeof(EVENTDATA_HANDLE), sendAsyncConfirmationCallback, (void*)0x4242); + mocks.ResetAllCalls(); + + unsigned char test_data[] = { 0x42 }; + unsigned char* buffer = test_data; + size_t length = sizeof(test_data); + g_expected_encoded_counter = 0; + + const char* const two_property_keys[] = { "test_property_key", "prop_key_2" }; + const char* const two_property_values[] = { "test_property_value", "prop_value_2" }; + const char* const* two_property_keys_ptr = two_property_keys; + const char* const* two_property_values_ptr = two_property_values; + size_t two_properties_size = 2; + + STRICT_EXPECTED_CALL(mocks, message_create()); + STRICT_EXPECTED_CALL(mocks, message_set_message_format(TEST_MESSAGE_HANDLE, MICROSOFT_MESSAGE_FORMAT)); + + // 1st event + STRICT_EXPECTED_CALL(mocks, EventData_GetData(TEST_CLONED_EVENTDATA_HANDLE_1, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &buffer, sizeof(buffer)) + .CopyOutArgumentBuffer(3, &length, sizeof(length)); + STRICT_EXPECTED_CALL(mocks, EventData_Properties(TEST_CLONED_EVENTDATA_HANDLE_1)); + STRICT_EXPECTED_CALL(mocks, Map_GetInternals(TEST_MAP_HANDLE, IGNORED_PTR_ARG, IGNORED_PTR_ARG, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &two_property_keys_ptr, sizeof(two_property_keys_ptr)) + .CopyOutArgumentBuffer(3, &two_property_values_ptr, sizeof(two_property_values_ptr)) + .CopyOutArgumentBuffer(4, &two_properties_size, sizeof(two_properties_size)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_map()) + .SetReturn(TEST_UAMQP_MAP); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("test_property_key")) + .SetReturn(TEST_PROPERTY_1_KEY_AMQP_VALUE); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("test_property_value")) + .SetReturn(TEST_PROPERTY_1_VALUE_AMQP_VALUE); + STRICT_EXPECTED_CALL(mocks, amqpvalue_set_map_value(TEST_UAMQP_MAP, TEST_PROPERTY_1_KEY_AMQP_VALUE, TEST_PROPERTY_1_VALUE_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("prop_key_2")) + .SetReturn(TEST_PROPERTY_2_KEY_AMQP_VALUE); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_string("prop_value_2")) + .SetReturn(TEST_PROPERTY_2_VALUE_AMQP_VALUE); + STRICT_EXPECTED_CALL(mocks, amqpvalue_set_map_value(TEST_UAMQP_MAP, TEST_PROPERTY_2_KEY_AMQP_VALUE, TEST_PROPERTY_2_VALUE_AMQP_VALUE)); + amqp_binary amqy_binary = { test_data, length }; + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_data(amqy_binary)) + .SetReturn(TEST_DATA_1); + STRICT_EXPECTED_CALL(mocks, amqpvalue_create_application_properties(TEST_UAMQP_MAP)) + .SetReturn(TEST_APPLICATION_PROPERTIES_1); + unsigned char properties_encoded_data[] = { 0x42, 0x43, 0x44 }; + size_t properties_encoded_size = sizeof(properties_encoded_data); + STRICT_EXPECTED_CALL(mocks, amqpvalue_get_encoded_size(TEST_APPLICATION_PROPERTIES_1, IGNORED_PTR_ARG)) + .CopyOutArgumentBuffer(2, &properties_encoded_size, sizeof(properties_encoded_size)) + .SetReturn(1); + + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_DATA_1)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_APPLICATION_PROPERTIES_1)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_PROPERTY_1_KEY_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_PROPERTY_1_VALUE_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_PROPERTY_2_KEY_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_PROPERTY_2_VALUE_AMQP_VALUE)); + STRICT_EXPECTED_CALL(mocks, amqpvalue_destroy(TEST_UAMQP_MAP)); + STRICT_EXPECTED_CALL(mocks, message_destroy(TEST_MESSAGE_HANDLE)); + STRICT_EXPECTED_CALL(mocks, sendAsyncConfirmationCallback(EVENTHUBCLIENT_CONFIRMATION_ERROR, (void*)0x4242)); + EXPECTED_CALL(mocks, DList_RemoveEntryList(IGNORED_PTR_ARG)); + STRICT_EXPECTED_CALL(mocks, EventData_Destroy(TEST_CLONED_EVENTDATA_HANDLE_1)); + STRICT_EXPECTED_CALL(mocks, EventData_Destroy(TEST_CLONED_EVENTDATA_HANDLE_2)); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + + STRICT_EXPECTED_CALL(mocks, connection_dowork(TEST_CONNECTION_HANDLE)); + + // act + EventHubClient_LL_DoWork(eventHubHandle); + + // assert + mocks.AssertActualAndExpectedCalls(); + + // cleanup + EventHubClient_LL_Destroy(eventHubHandle); + } +#endif + + /* EventHubClient_LL_SendBatchAsync */ + + /* Tests_SRS_EVENTHUBCLIENT_LL_07_012: [EventHubClient_LL_SendBatchAsync shall return EVENTHUBCLIENT_INVALID_ARG if eventhubClientLLHandle or eventDataList are NULL or if sendAsnycConfirmationCallback equals NULL and userContextCallback does not equal NULL.] */ + TEST_FUNCTION(EventHubClient_LL_SendBatchAsync_with_NULL_sendAsyncConfirmationCallbackandNonNullUSerContext_fails) + { + // arrange + CEventHubClientLLMocks mocks; + EVENTDATA_HANDLE batch[] = { TEST_EVENTDATA_HANDLE_1, TEST_EVENTDATA_HANDLE_2 }; + + setup_createfromconnectionstring_success(&mocks); + EVENTHUBCLIENT_LL_HANDLE eventHubHandle = EventHubClient_LL_CreateFromConnectionString(CONNECTION_STRING, TEST_EVENTHUB_PATH); + mocks.ResetAllCalls(); + + // act + EVENTHUBCLIENT_RESULT result = EventHubClient_LL_SendBatchAsync(eventHubHandle, batch, sizeof(batch) / sizeof(batch[0]), NULL, &g_confirmationResult); + + //assert + ASSERT_ARE_EQUAL(EVENTHUBCLIENT_RESULT, EVENTHUBCLIENT_INVALID_ARG, result); + mocks.AssertActualAndExpectedCalls(); + + //cleanup + EventHubClient_LL_Destroy(eventHubHandle); + } + + /* Tests_SRS_EVENTHUBCLIENT_LL_07_012: [EventHubClient_LL_SendBatchAsync shall return EVENTHUBCLIENT_INVALID_ARG if eventhubClientLLHandle or eventDataList are NULL or if sendAsnycConfirmationCallback equals NULL and userContextCallback does not equal NULL.] */ + TEST_FUNCTION(EventHubClient_LL_SendBatchAsync_with_NULL_eventHubLLHandle_fails) + { + // arrange + CEventHubClientLLMocks mocks; + EVENTDATA_HANDLE batch[] = { TEST_EVENTDATA_HANDLE_1, TEST_EVENTDATA_HANDLE_2 }; + + // act + EVENTHUBCLIENT_RESULT result = EventHubClient_LL_SendBatchAsync(NULL, batch, sizeof(batch) / sizeof(batch[0]), sendAsyncConfirmationCallback, &g_confirmationResult); + + //assert + ASSERT_ARE_EQUAL(EVENTHUBCLIENT_RESULT, EVENTHUBCLIENT_INVALID_ARG, result); + } + + /* Tests_SRS_EVENTHUBCLIENT_LL_07_012: [EventHubClient_LL_SendBatchAsync shall return EVENTHUBCLIENT_INVALID_ARG if eventhubClientLLHandle or eventDataList are NULL or if sendAsnycConfirmationCallback equals NULL and userContextCallback does not equal NULL.] */ + TEST_FUNCTION(EventHubClient_LL_SendBatchAsync_with_NULL_event_data_list_fails) + { + // arrange + CEventHubClientLLMocks mocks; + EVENTDATA_HANDLE batch[] = { TEST_EVENTDATA_HANDLE_1, TEST_EVENTDATA_HANDLE_2 }; + setup_createfromconnectionstring_success(&mocks); + EVENTHUBCLIENT_LL_HANDLE eventHubHandle = EventHubClient_LL_CreateFromConnectionString(CONNECTION_STRING, TEST_EVENTHUB_PATH); + mocks.ResetAllCalls(); + + // act + EVENTHUBCLIENT_RESULT result = EventHubClient_LL_SendBatchAsync(eventHubHandle, NULL, sizeof(batch) / sizeof(batch[0]), sendAsyncConfirmationCallback, &g_confirmationResult); + + //assert + ASSERT_ARE_EQUAL(EVENTHUBCLIENT_RESULT, EVENTHUBCLIENT_INVALID_ARG, result); + mocks.AssertActualAndExpectedCalls(); + + //cleanup + EventHubClient_LL_Destroy(eventHubHandle); + } + + /* Tests_SRS_EVENTHUBCLIENT_LL_01_095: [EventHubClient_LL_SendBatchAsync shall return EVENTHUBCLIENT_INVALID_ARG if the count argument is zero.] */ + TEST_FUNCTION(EventHubClient_LL_SendBatchAsync_with_zero_count_fails) + { + // arrange + CEventHubClientLLMocks mocks; + EVENTDATA_HANDLE batch[] = { TEST_EVENTDATA_HANDLE_1, TEST_EVENTDATA_HANDLE_2 }; + setup_createfromconnectionstring_success(&mocks); + EVENTHUBCLIENT_LL_HANDLE eventHubHandle = EventHubClient_LL_CreateFromConnectionString(CONNECTION_STRING, TEST_EVENTHUB_PATH); + mocks.ResetAllCalls(); + + // act + EVENTHUBCLIENT_RESULT result = EventHubClient_LL_SendBatchAsync(eventHubHandle, batch, 0, sendAsyncConfirmationCallback, &g_confirmationResult); + + //assert + ASSERT_ARE_EQUAL(EVENTHUBCLIENT_RESULT, EVENTHUBCLIENT_INVALID_ARG, result); + mocks.AssertActualAndExpectedCalls(); + + //cleanup + EventHubClient_LL_Destroy(eventHubHandle); + } + + /* Tests_SRS_EVENTHUBCLIENT_LL_07_014: [EventHubClient_LL_SendBatchAsync shall clone each item in the eventDataList by calling EventData_Clone.] */ + /* Tests_SRS_EVENTHUBCLIENT_LL_07_015: [On success EventHubClient_LL_SendBatchAsync shall return EVENTHUBCLIENT_OK.] */ + /* Tests_SRS_EVENTHUBCLIENT_LL_01_097: [The partition key for each event shall be obtained by calling EventData_getPartitionKey.] */ + TEST_FUNCTION(EventHubClient_LL_SendBatchAsync_clones_the_event_data) + { + // arrange + CEventHubClientLLMocks mocks; + EVENTDATA_HANDLE batch[] = { TEST_EVENTDATA_HANDLE_1, TEST_EVENTDATA_HANDLE_2 }; + setup_createfromconnectionstring_success(&mocks); + EVENTHUBCLIENT_LL_HANDLE eventHubHandle = EventHubClient_LL_CreateFromConnectionString(CONNECTION_STRING, TEST_EVENTHUB_PATH); + mocks.ResetAllCalls(); + + STRICT_EXPECTED_CALL(mocks, EventData_GetPartitionKey(TEST_EVENTDATA_HANDLE_1)) + .SetReturn("partitionKey"); + STRICT_EXPECTED_CALL(mocks, EventData_GetPartitionKey(TEST_EVENTDATA_HANDLE_2)) + .SetReturn("partitionKey"); + EXPECTED_CALL(mocks, gballoc_malloc(IGNORED_NUM_ARG)); + EXPECTED_CALL(mocks, gballoc_malloc(IGNORED_NUM_ARG)); + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_1)) + .SetReturn(TEST_CLONED_EVENTDATA_HANDLE_1); + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_2)) + .SetReturn(TEST_CLONED_EVENTDATA_HANDLE_2); + EXPECTED_CALL(mocks, DList_InsertTailList(IGNORED_PTR_ARG, IGNORED_PTR_ARG)); + + // act + EVENTHUBCLIENT_RESULT result = EventHubClient_LL_SendBatchAsync(eventHubHandle, batch, sizeof(batch) / sizeof(batch[0]), sendAsyncConfirmationCallback, &g_confirmationResult); + + //assert + ASSERT_ARE_EQUAL(EVENTHUBCLIENT_RESULT, EVENTHUBCLIENT_OK, result); + mocks.AssertActualAndExpectedCalls(); + + //cleanup + EventHubClient_LL_Destroy(eventHubHandle); + } + + /* Tests_SRS_EVENTHUBCLIENT_LL_01_097: [The partition key for each event shall be obtained by calling EventData_getPartitionKey.] */ + /* Tests_SRS_EVENTHUBCLIENT_LL_01_096: [If the partitionKey properties on the events in the batch are not the same then EventHubClient_LL_SendBatchAsync shall fail and return EVENTHUBCLIENT_ERROR.] */ + TEST_FUNCTION(when_the_partitions_on_the_events_do_not_match_then_EventHubClient_LL_SendBatchAsync_fails) + { + // arrange + CEventHubClientLLMocks mocks; + EVENTDATA_HANDLE batch[] = { TEST_EVENTDATA_HANDLE_1, TEST_EVENTDATA_HANDLE_2 }; + setup_createfromconnectionstring_success(&mocks); + EVENTHUBCLIENT_LL_HANDLE eventHubHandle = EventHubClient_LL_CreateFromConnectionString(CONNECTION_STRING, TEST_EVENTHUB_PATH); + mocks.ResetAllCalls(); + + STRICT_EXPECTED_CALL(mocks, EventData_GetPartitionKey(TEST_EVENTDATA_HANDLE_1)) + .SetReturn("partitionKey1"); + STRICT_EXPECTED_CALL(mocks, EventData_GetPartitionKey(TEST_EVENTDATA_HANDLE_2)) + .SetReturn("partitionKey2"); + + // act + EVENTHUBCLIENT_RESULT result = EventHubClient_LL_SendBatchAsync(eventHubHandle, batch, sizeof(batch) / sizeof(batch[0]), sendAsyncConfirmationCallback, &g_confirmationResult); + + //assert + ASSERT_ARE_EQUAL(EVENTHUBCLIENT_RESULT, EVENTHUBCLIENT_ERROR, result); + mocks.AssertActualAndExpectedCalls(); + + //cleanup + EventHubClient_LL_Destroy(eventHubHandle); + } + + /* Tests_SRS_EVENTHUBCLIENT_LL_07_013: [EventHubClient_LL_SendBatchAsync shall return EVENTHUBCLIENT_ERROR for any Error that is encountered.] */ + TEST_FUNCTION(when_allocating_memory_for_the_event_batch_fails_then_EventHubClient_LL_SendBatchAsync_fails) + { + // arrange + CEventHubClientLLMocks mocks; + EVENTDATA_HANDLE batch[] = { TEST_EVENTDATA_HANDLE_1, TEST_EVENTDATA_HANDLE_2 }; + setup_createfromconnectionstring_success(&mocks); + EVENTHUBCLIENT_LL_HANDLE eventHubHandle = EventHubClient_LL_CreateFromConnectionString(CONNECTION_STRING, TEST_EVENTHUB_PATH); + mocks.ResetAllCalls(); + + STRICT_EXPECTED_CALL(mocks, EventData_GetPartitionKey(TEST_EVENTDATA_HANDLE_1)) + .SetReturn("partitionKey"); + STRICT_EXPECTED_CALL(mocks, EventData_GetPartitionKey(TEST_EVENTDATA_HANDLE_2)) + .SetReturn("partitionKey"); + EXPECTED_CALL(mocks, gballoc_malloc(IGNORED_NUM_ARG)) + .SetReturn((void*)NULL); + + // act + EVENTHUBCLIENT_RESULT result = EventHubClient_LL_SendBatchAsync(eventHubHandle, batch, sizeof(batch) / sizeof(batch[0]), sendAsyncConfirmationCallback, &g_confirmationResult); + + //assert + ASSERT_ARE_EQUAL(EVENTHUBCLIENT_RESULT, EVENTHUBCLIENT_ERROR, result); + mocks.AssertActualAndExpectedCalls(); + + //cleanup + EventHubClient_LL_Destroy(eventHubHandle); + } + + /* Tests_SRS_EVENTHUBCLIENT_LL_07_013: [EventHubClient_LL_SendBatchAsync shall return EVENTHUBCLIENT_ERROR for any Error that is encountered.] */ + TEST_FUNCTION(when_allocating_memory_for_the_list_of_events_fails_then_EventHubClient_LL_SendBatchAsync_fails) + { + // arrange + CEventHubClientLLMocks mocks; + EVENTDATA_HANDLE batch[] = { TEST_EVENTDATA_HANDLE_1, TEST_EVENTDATA_HANDLE_2 }; + setup_createfromconnectionstring_success(&mocks); + EVENTHUBCLIENT_LL_HANDLE eventHubHandle = EventHubClient_LL_CreateFromConnectionString(CONNECTION_STRING, TEST_EVENTHUB_PATH); + mocks.ResetAllCalls(); + + STRICT_EXPECTED_CALL(mocks, EventData_GetPartitionKey(TEST_EVENTDATA_HANDLE_1)) + .SetReturn("partitionKey"); + STRICT_EXPECTED_CALL(mocks, EventData_GetPartitionKey(TEST_EVENTDATA_HANDLE_2)) + .SetReturn("partitionKey"); + EXPECTED_CALL(mocks, gballoc_malloc(IGNORED_NUM_ARG)); + EXPECTED_CALL(mocks, gballoc_malloc(IGNORED_NUM_ARG)) + .SetReturn((void*)NULL); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + + // act + EVENTHUBCLIENT_RESULT result = EventHubClient_LL_SendBatchAsync(eventHubHandle, batch, sizeof(batch) / sizeof(batch[0]), sendAsyncConfirmationCallback, &g_confirmationResult); + + //assert + ASSERT_ARE_EQUAL(EVENTHUBCLIENT_RESULT, EVENTHUBCLIENT_ERROR, result); + mocks.AssertActualAndExpectedCalls(); + + //cleanup + EventHubClient_LL_Destroy(eventHubHandle); + } + + /* Tests_SRS_EVENTHUBCLIENT_LL_07_013: [EventHubClient_LL_SendBatchAsync shall return EVENTHUBCLIENT_ERROR for any Error that is encountered.] */ + TEST_FUNCTION(when_cloning_the_first_item_fails_EventHubClient_LL_SendBatchAsync_fails) + { + // arrange + CEventHubClientLLMocks mocks; + EVENTDATA_HANDLE batch[] = { TEST_EVENTDATA_HANDLE_1, TEST_EVENTDATA_HANDLE_2 }; + setup_createfromconnectionstring_success(&mocks); + EVENTHUBCLIENT_LL_HANDLE eventHubHandle = EventHubClient_LL_CreateFromConnectionString(CONNECTION_STRING, TEST_EVENTHUB_PATH); + mocks.ResetAllCalls(); + + STRICT_EXPECTED_CALL(mocks, EventData_GetPartitionKey(TEST_EVENTDATA_HANDLE_1)) + .SetReturn("partitionKey"); + STRICT_EXPECTED_CALL(mocks, EventData_GetPartitionKey(TEST_EVENTDATA_HANDLE_2)) + .SetReturn("partitionKey"); + EXPECTED_CALL(mocks, gballoc_malloc(IGNORED_NUM_ARG)); + EXPECTED_CALL(mocks, gballoc_malloc(IGNORED_NUM_ARG)); + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_1)) + .SetReturn((EVENTDATA_HANDLE)NULL); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + + // act + EVENTHUBCLIENT_RESULT result = EventHubClient_LL_SendBatchAsync(eventHubHandle, batch, sizeof(batch) / sizeof(batch[0]), sendAsyncConfirmationCallback, &g_confirmationResult); + + //assert + ASSERT_ARE_EQUAL(EVENTHUBCLIENT_RESULT, EVENTHUBCLIENT_ERROR, result); + mocks.AssertActualAndExpectedCalls(); + + //cleanup + EventHubClient_LL_Destroy(eventHubHandle); + } + + /* Tests_SRS_EVENTHUBCLIENT_LL_07_013: [EventHubClient_LL_SendBatchAsync shall return EVENTHUBCLIENT_ERROR for any Error that is encountered.] */ + TEST_FUNCTION(when_cloning_the_second_item_fails_EventHubClient_LL_SendBatchAsync_fails) + { + // arrange + CEventHubClientLLMocks mocks; + EVENTDATA_HANDLE batch[] = { TEST_EVENTDATA_HANDLE_1, TEST_EVENTDATA_HANDLE_2 }; + setup_createfromconnectionstring_success(&mocks); + EVENTHUBCLIENT_LL_HANDLE eventHubHandle = EventHubClient_LL_CreateFromConnectionString(CONNECTION_STRING, TEST_EVENTHUB_PATH); + mocks.ResetAllCalls(); + + STRICT_EXPECTED_CALL(mocks, EventData_GetPartitionKey(TEST_EVENTDATA_HANDLE_1)) + .SetReturn("partitionKey"); + STRICT_EXPECTED_CALL(mocks, EventData_GetPartitionKey(TEST_EVENTDATA_HANDLE_2)) + .SetReturn("partitionKey"); + EXPECTED_CALL(mocks, gballoc_malloc(IGNORED_NUM_ARG)); + EXPECTED_CALL(mocks, gballoc_malloc(IGNORED_NUM_ARG)); + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_1)) + .SetReturn(TEST_CLONED_EVENTDATA_HANDLE_1); + STRICT_EXPECTED_CALL(mocks, EventData_Clone(TEST_EVENTDATA_HANDLE_2)) + .SetReturn((EVENTDATA_HANDLE)NULL); + STRICT_EXPECTED_CALL(mocks, EventData_Destroy(TEST_CLONED_EVENTDATA_HANDLE_1)); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + EXPECTED_CALL(mocks, gballoc_free(IGNORED_PTR_ARG)); + + // act + EVENTHUBCLIENT_RESULT result = EventHubClient_LL_SendBatchAsync(eventHubHandle, batch, sizeof(batch) / sizeof(batch[0]), sendAsyncConfirmationCallback, &g_confirmationResult); + + //assert + ASSERT_ARE_EQUAL(EVENTHUBCLIENT_RESULT, EVENTHUBCLIENT_ERROR, result); + mocks.AssertActualAndExpectedCalls(); + + //cleanup + EventHubClient_LL_Destroy(eventHubHandle); + } + END_TEST_SUITE(eventhubclient_ll_unittests)