зеркало из https://github.com/Azure/c-pal.git
adding two functions to socket_transport API (#359)
* adding two functions to socket_transport API * changing function name * small fixes
This commit is contained in:
Родитель
2ddd023c53
Коммит
d79a408f35
|
@ -60,6 +60,7 @@ typedef struct SOCKET_BUFFER_TAG
|
|||
|
||||
MOCKABLE_FUNCTION(, SOCKET_TRANSPORT_HANDLE, socket_transport_create_client);
|
||||
MOCKABLE_FUNCTION(, SOCKET_TRANSPORT_HANDLE, socket_transport_create_server);
|
||||
MOCKABLE_FUNCTION(, SOCKET_TRANSPORT_HANDLE, socket_transport_create_from_socket, SOCKET_HANDLE, socket_handle);
|
||||
MOCKABLE_FUNCTION(, void, socket_transport_destroy, SOCKET_TRANSPORT_HANDLE, socket_transport);
|
||||
|
||||
MOCKABLE_FUNCTION(, int, socket_transport_connect, SOCKET_TRANSPORT_HANDLE, socket_transport, const char*, hostname, uint16_t, port, uint32_t, connection_timeout_ms);
|
||||
|
@ -72,6 +73,7 @@ MOCKABLE_FUNCTION(, SOCKET_SEND_RESULT, socket_transport_send, SOCKET_TRANSPORT_
|
|||
MOCKABLE_FUNCTION(, SOCKET_RECEIVE_RESULT, socket_transport_receive, SOCKET_TRANSPORT_HANDLE, socket_transport, SOCKET_BUFFER*, payload, uint32_t, buffer_count, uint32_t*, bytes_recv, uint32_t, flags, void*, data);
|
||||
|
||||
MOCKABLE_FUNCTION(, SOCKET_HANDLE, socket_transport_get_underlying_socket, SOCKET_TRANSPORT_HANDLE, socket_transport);
|
||||
MOCKABLE_FUNCTION(, bool, socket_transport_is_valid_socket, SOCKET_TRANSPORT_HANDLE, socket_transport_handle);
|
||||
```
|
||||
|
||||
### socket_transport_create_client
|
||||
|
@ -90,6 +92,14 @@ MOCKABLE_FUNCTION(, SOCKET_TRANSPORT_HANDLE, socket_transport_create_server);
|
|||
|
||||
`socket_transport_create_server` creates a binding socket transport.
|
||||
|
||||
### socket_transport_create_from_socket
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, SOCKET_TRANSPORT_HANDLE, socket_transport_create_from_socket, SOCKET_HANDLE, socket_handle);
|
||||
```
|
||||
|
||||
`socket_transport_create_from_socket` creates a client socket transport from a given socket handle.
|
||||
|
||||
### socket_transport_destroy
|
||||
|
||||
```c
|
||||
|
@ -154,3 +164,11 @@ MOCKABLE_FUNCTION(, SOCKET_HANDLE, socket_transport_get_underlying_socket, SOCKE
|
|||
```
|
||||
|
||||
`socket_transport_get_underlying_socket` returns the underlying socket.
|
||||
|
||||
### socket_transport_is_valid_socket
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, bool, socket_transport_is_valid_socket, SOCKET_TRANSPORT_HANDLE, socket_transport_handle);
|
||||
```
|
||||
|
||||
`socket_transport_check_valid_handle` checks that the internal socket is valid.
|
|
@ -13,6 +13,7 @@
|
|||
#include <cstdint>
|
||||
extern "C" {
|
||||
#else
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
|
@ -57,6 +58,7 @@ typedef struct SOCKET_BUFFER_TAG
|
|||
|
||||
MOCKABLE_FUNCTION(, SOCKET_TRANSPORT_HANDLE, socket_transport_create_client);
|
||||
MOCKABLE_FUNCTION(, SOCKET_TRANSPORT_HANDLE, socket_transport_create_server);
|
||||
MOCKABLE_FUNCTION(, SOCKET_TRANSPORT_HANDLE, socket_transport_create_from_socket, SOCKET_HANDLE, socket_handle);
|
||||
MOCKABLE_FUNCTION(, void, socket_transport_destroy, SOCKET_TRANSPORT_HANDLE, socket_transport);
|
||||
|
||||
MOCKABLE_FUNCTION(, int, socket_transport_connect, SOCKET_TRANSPORT_HANDLE, socket_transport, const char*, hostname, uint16_t, port, uint32_t, connection_timeout_ms);
|
||||
|
@ -69,6 +71,7 @@ MOCKABLE_FUNCTION(, SOCKET_SEND_RESULT, socket_transport_send, SOCKET_TRANSPORT_
|
|||
MOCKABLE_FUNCTION(, SOCKET_RECEIVE_RESULT, socket_transport_receive, SOCKET_TRANSPORT_HANDLE, socket_transport, SOCKET_BUFFER*, payload, uint32_t, buffer_count, uint32_t*, bytes_recv, uint32_t, flags, void*, data);
|
||||
|
||||
MOCKABLE_FUNCTION(, SOCKET_HANDLE, socket_transport_get_underlying_socket, SOCKET_TRANSPORT_HANDLE, socket_transport);
|
||||
MOCKABLE_FUNCTION(, bool, socket_transport_is_valid_socket, SOCKET_TRANSPORT_HANDLE, socket_transport_handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ typedef struct SOCKET_BUFFER_TAG
|
|||
|
||||
MOCKABLE_FUNCTION(, SOCKET_TRANSPORT_HANDLE, socket_transport_create_client);
|
||||
MOCKABLE_FUNCTION(, SOCKET_TRANSPORT_HANDLE, socket_transport_create_server);
|
||||
MOCKABLE_FUNCTION(, SOCKET_TRANSPORT_HANDLE, socket_transport_create_from_socket, SOCKET_HANDLE, socket_handle);
|
||||
MOCKABLE_FUNCTION(, void, socket_transport_destroy, SOCKET_TRANSPORT_HANDLE, socket_transport);
|
||||
|
||||
MOCKABLE_FUNCTION(, int, socket_transport_connect, SOCKET_TRANSPORT_HANDLE, socket_transport, const char*, hostname, uint16_t, port, uint32_t, connection_timeout_ms);
|
||||
|
@ -64,6 +65,7 @@ MOCKABLE_FUNCTION(, SOCKET_SEND_RESULT, socket_transport_send, SOCKET_TRANSPORT_
|
|||
MOCKABLE_FUNCTION(, SOCKET_RECEIVE_RESULT, socket_transport_receive, SOCKET_TRANSPORT_HANDLE, socket_transport, SOCKET_BUFFER*, payload, uint32_t, buffer_count, uint32_t*, bytes_recv, uint32_t, flags, void*, data);
|
||||
|
||||
MOCKABLE_FUNCTION(, SOCKET_HANDLE, socket_transport_get_underlying_socket, SOCKET_TRANSPORT_HANDLE, socket_transport);
|
||||
MOCKABLE_FUNCTION(, bool, socket_transport_is_valid_socket, SOCKET_TRANSPORT_HANDLE, socket_transport_handle);
|
||||
```
|
||||
|
||||
### socket_transport_create_client
|
||||
|
@ -98,6 +100,28 @@ MOCKABLE_FUNCTION(, SOCKET_TRANSPORT_HANDLE, socket_transport_create_server);
|
|||
|
||||
**SOCKET_TRANSPORT_LINUX_11_082: [** On success `socket_transport_create_server` shall return `SOCKET_TRANSPORT_HANDLE`. **]**
|
||||
|
||||
### socket_transport_create_from_socket
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, SOCKET_TRANSPORT_HANDLE, socket_transport_create_from_socket, SOCKET_HANDLE, socket_handle);
|
||||
```
|
||||
|
||||
`socket_transport_create_from_socket` creates a client socket transport from a given socket handle.
|
||||
|
||||
**SOCKET_TRANSPORT_LINUX_11_086: [** If socket_handle is an INVALID_SOCKET, `socket_transport_create_from_socket` shall fail and return `NULL`. **]**
|
||||
|
||||
**SOCKET_TRANSPORT_LINUX_11_087: [** `socket_transport_create_from_socket` shall allocate a new SOCKET_TRANSPORT object. **]**
|
||||
|
||||
**SOCKET_TRANSPORT_LINUX_11_088: [** `socket_transport_create_from_socket` shall call sm_create to create a sm_object with the type set to SOCKET_CLIENT. **]**
|
||||
|
||||
**SOCKET_TRANSPORT_LINUX_11_097: [** If `sm_open_begin` does not return `SM_EXEC_GRANTED`, `socket_transport_create_from_socket` shall fail and return `NULL`. **]**
|
||||
|
||||
**SOCKET_TRANSPORT_LINUX_11_096: [** `socket_transport_create_from_socket` shall assign the socket_handle to the new allocated socket transport. **]**
|
||||
|
||||
**SOCKET_TRANSPORT_LINUX_11_090: [** On any failure `socket_transport_create_from_socket` shall return `NULL`. **]**
|
||||
|
||||
**SOCKET_TRANSPORT_LINUX_11_091: [** On success `socket_transport_create_from_socket` shall return SOCKET_TRANSPORT_HANDLE. **]**
|
||||
|
||||
### socket_transport_destroy
|
||||
|
||||
```c
|
||||
|
@ -307,3 +331,17 @@ MOCKABLE_FUNCTION(, SOCKET_HANDLE, socket_transport_get_underlying_socket, SOCKE
|
|||
**SOCKET_TRANSPORT_LINUX_11_067: [** `socket_transport_get_underlying_socket` shall return the `SOCKET_HANDLE` socket value. **]**
|
||||
|
||||
**SOCKET_TRANSPORT_LINUX_11_068: [** `socket_transport_get_underlying_socket` shall call `sm_exec_end`. **]**
|
||||
|
||||
### socket_transport_is_valid_socket
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, bool, socket_transport_is_valid_socket, SOCKET_TRANSPORT_HANDLE, socket_transport_handle);
|
||||
```
|
||||
|
||||
`socket_transport_is_valid_socket` checks that the internal socket is valid.
|
||||
|
||||
**SOCKET_TRANSPORT_LINUX_11_093: [** If `socket_transport_handle` is `NULL`, `socket_transport_is_valid_socket` shall fail and return `false`. **]**
|
||||
|
||||
**SOCKET_TRANSPORT_LINUX_11_094: [** If the socket inside `socket_transport_handle` is an `INVALID_SOCKET`, `socket_transport_is_valid_socket` shall fail and return `false`. **]**
|
||||
|
||||
**SOCKET_TRANSPORT_LINUX_11_095: [** On success, `socket_transport_is_valid_socket` shall return `true`. **]**
|
|
@ -140,7 +140,7 @@ SOCKET_TRANSPORT_HANDLE socket_transport_create_client(void)
|
|||
else
|
||||
{
|
||||
// Codes_SOCKET_TRANSPORT_LINUX_11_003: [ socket_transport_create_client shall call sm_create to create a sm object with the type set to SOCKET_CLIENT. ]
|
||||
result->sm = sm_create("Socket_transport_win32");
|
||||
result->sm = sm_create("Socket_transport_linux");
|
||||
if (result->sm == NULL)
|
||||
{
|
||||
LogError("sm_create failed.");
|
||||
|
@ -172,7 +172,7 @@ SOCKET_TRANSPORT_HANDLE socket_transport_create_server(void)
|
|||
else
|
||||
{
|
||||
// Codes_SOCKET_TRANSPORT_LINUX_11_080: [ socket_transport_create_server shall call sm_create to create a sm object with the type set to SOCKET_BINDING. ]
|
||||
result->sm = sm_create("Socket_transport_win32");
|
||||
result->sm = sm_create("Socket_transport_linux");
|
||||
if (result->sm == NULL)
|
||||
{
|
||||
LogError("sm_create failed.");
|
||||
|
@ -191,6 +191,59 @@ all_ok:
|
|||
return result;
|
||||
}
|
||||
|
||||
SOCKET_TRANSPORT_HANDLE socket_transport_create_from_socket(SOCKET_HANDLE socket_handle)
|
||||
{
|
||||
SOCKET_TRANSPORT* result;
|
||||
|
||||
// Codes_SOCKET_TRANSPORT_LINUX_11_086: [ If socket_handle is an INVALID_SOCKET, socket_transport_create_from_socket shall fail and return NULL. ]
|
||||
if (socket_handle == INVALID_SOCKET)
|
||||
{
|
||||
LogError("Invalid socket, unable to create socket_transport_handle.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Codes_SOCKET_TRANSPORT_LINUX_11_087: [ socket_transport_create_from_socket shall allocate a new SOCKET_TRANSPORT object. ]
|
||||
result = malloc(sizeof(SOCKET_TRANSPORT));
|
||||
if (result == NULL)
|
||||
{
|
||||
LogError("failure allocating SOCKET_TRANSPORT: %zu", sizeof(SOCKET_TRANSPORT));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Codes_SOCKET_TRANSPORT_LINUX_11_088: [ socket_transport_create_from_socket shall call sm_create to create a sm_object with the type set to SOCKET_CLIENT. ]
|
||||
result->sm = sm_create("Socket_transport_win32");
|
||||
if (result->sm == NULL)
|
||||
{
|
||||
LogError("sm_create failed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Codes_SOCKET_TRANSPORT_WIN32_11_014: [ If sm_open_begin does not return SM_EXEC_GRANTED, socket_transport_create_from_socket shall fail and return NULL. ]
|
||||
SM_RESULT open_result = sm_open_begin(result->sm);
|
||||
if (open_result == SM_EXEC_GRANTED)
|
||||
{
|
||||
result->type = SOCKET_CLIENT;
|
||||
// Codes_SOCKET_TRANSPORT_LINUX_11_096: [ socket_transport_create_from_socket shall assign the socket_handle to the new allocated socket transport. ]
|
||||
result->socket = socket_handle;
|
||||
sm_open_end(result->sm, true);
|
||||
// Codes_SOCKET_TRANSPORT_LINUX_11_091: [ On success socket_transport_create_from_socket shall return SOCKET_TRANSPORT_HANDLE. ]
|
||||
goto all_ok;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogError("sm_open_begin failed with %" PRI_MU_ENUM " in accept, closing incoming socket.", MU_ENUM_VALUE(SM_RESULT, open_result));
|
||||
}
|
||||
sm_destroy(result->sm);
|
||||
}
|
||||
free(result);
|
||||
}
|
||||
}
|
||||
// Codes_SOCKET_TRANSPORT_LINUX_11_090: [ On any failure socket_transport_create_from_socket shall return NULL. ]
|
||||
result = NULL;
|
||||
all_ok:
|
||||
return result;
|
||||
}
|
||||
|
||||
void socket_transport_destroy(SOCKET_TRANSPORT_HANDLE socket_transport)
|
||||
{
|
||||
// Codes_SOCKET_TRANSPORT_LINUX_11_006: [ If socket_transport is NULL socket_transport_destroy shall return. ]
|
||||
|
@ -245,7 +298,7 @@ int socket_transport_connect(SOCKET_TRANSPORT_HANDLE socket_transport, const cha
|
|||
if (socket_transport->socket == INVALID_SOCKET)
|
||||
{
|
||||
// Codes_SOCKET_TRANSPORT_LINUX_11_019: [ If any failure is encountered, socket_transport_connect shall call sm_open_end with false, fail and return a non-zero value. ]
|
||||
LogError("Failure conneting to client hostname: %s:%" PRIu16 "", hostname, port);
|
||||
LogError("Failure connecting to client hostname: %s:%" PRIu16 "", hostname, port);
|
||||
result = MU_FAILURE;
|
||||
sm_open_end(socket_transport->sm, false);
|
||||
}
|
||||
|
@ -657,7 +710,7 @@ SOCKET_ACCEPT_RESULT socket_transport_accept(SOCKET_TRANSPORT_HANDLE socket_tran
|
|||
}
|
||||
else
|
||||
{
|
||||
accept_result->sm = sm_create("Socket_transport_win32");
|
||||
accept_result->sm = sm_create("Socket_transport_linux");
|
||||
if (accept_result->sm == NULL)
|
||||
{
|
||||
LogError("Failed calling sm_create in accept, closing incoming socket.");
|
||||
|
@ -728,4 +781,27 @@ SOCKET_HANDLE socket_transport_get_underlying_socket(SOCKET_TRANSPORT_HANDLE soc
|
|||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
bool socket_transport_is_valid_socket(SOCKET_TRANSPORT_HANDLE socket_transport_handle)
|
||||
{
|
||||
bool result;
|
||||
if (socket_transport_handle == NULL)
|
||||
{
|
||||
result = false;
|
||||
LogError("Invalid argument: SOCKET_TRANSPORT_HANDLE socket_transport_handle: %p", socket_transport_handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (socket_transport_handle->socket == INVALID_SOCKET)
|
||||
{
|
||||
result = false;
|
||||
LogError("Invalid socket in argument: SOCKET_TRANSPORT_HANDLE socket_transport_handle: %p", socket_transport_handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -1581,4 +1581,131 @@ TEST_FUNCTION(socket_transport_get_underlying_socket_not_open_fail)
|
|||
socket_transport_destroy(socket_handle);
|
||||
}
|
||||
|
||||
// Tests_SOCKET_TRANSPORT_LINUX_11_087: [ socket_transport_create_from_socket shall allocate a new SOCKET_TRANSPORT object. ]
|
||||
// Tests_SOCKET_TRANSPORT_LINUX_11_088: [ socket_transport_create_from_socket shall call sm_create to create a sm_object with the type set to SOCKET_CLIENT. ]
|
||||
// Tests_SOCKET_TRANSPORT_LINUX_11_096: [ socket_transport_create_from_socket shall assign the socket_handle to the new allocated socket transport. ]
|
||||
// Tests_SOCKET_TRANSPORT_LINUX_11_091: [ On success socket_transport_create_from_socket shall return SOCKET_TRANSPORT_HANDLE. ]
|
||||
TEST_FUNCTION(socket_transport_create_from_socket_succeeds)
|
||||
{
|
||||
//arrange
|
||||
umock_c_reset_all_calls();
|
||||
STRICT_EXPECTED_CALL(malloc(IGNORED_ARG));
|
||||
STRICT_EXPECTED_CALL(sm_create(IGNORED_ARG));
|
||||
STRICT_EXPECTED_CALL(sm_open_begin(IGNORED_ARG));
|
||||
STRICT_EXPECTED_CALL(sm_open_end(IGNORED_ARG, true));
|
||||
|
||||
//act
|
||||
SOCKET_TRANSPORT_HANDLE socket_transport = socket_transport_create_from_socket((SOCKET_HANDLE)test_socket);
|
||||
|
||||
//assert
|
||||
ASSERT_IS_NOT_NULL(socket_transport);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
//cleanup
|
||||
socket_transport_destroy(socket_transport);
|
||||
}
|
||||
|
||||
// Tests_SOCKET_TRANSPORT_LINUX_11_086: [ If socket_handle is an INVALID_SOCKET, socket_transport_create_from_socket shall fail and return NULL. ]
|
||||
TEST_FUNCTION(socket_transport_create_from_socket_invalid_input)
|
||||
{
|
||||
//arrange
|
||||
umock_c_reset_all_calls();
|
||||
|
||||
//act
|
||||
SOCKET_TRANSPORT_HANDLE socket_transport = socket_transport_create_from_socket((SOCKET_HANDLE)INVALID_SOCKET);
|
||||
|
||||
//assert
|
||||
ASSERT_IS_NULL(socket_transport);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
}
|
||||
|
||||
// Tests_SOCKET_TRANSPORT_LINUX_11_097: [ If sm_open_begin does not return SM_EXEC_GRANTED, socket_transport_create_from_socket shall fail and return NULL. ]
|
||||
// Tests_SOCKET_TRANSPORT_LINUX_11_090: [ On any failure socket_transport_create_from_socket shall return NULL. ]
|
||||
TEST_FUNCTION(socket_transport_create_from_socket_fail)
|
||||
{
|
||||
//arrange
|
||||
STRICT_EXPECTED_CALL(malloc(IGNORED_ARG));
|
||||
STRICT_EXPECTED_CALL(sm_create(IGNORED_ARG));
|
||||
STRICT_EXPECTED_CALL(sm_open_begin(IGNORED_ARG));
|
||||
STRICT_EXPECTED_CALL(sm_destroy(IGNORED_ARG));
|
||||
umock_c_negative_tests_snapshot();
|
||||
|
||||
for (size_t index = 0; index < umock_c_negative_tests_call_count(); index++)
|
||||
{
|
||||
if (umock_c_negative_tests_can_call_fail(index))
|
||||
{
|
||||
umock_c_negative_tests_reset();
|
||||
umock_c_negative_tests_fail_call(index);
|
||||
|
||||
//act
|
||||
SOCKET_TRANSPORT_HANDLE socket_handle = socket_transport_create_from_socket((SOCKET_HANDLE)test_socket);
|
||||
|
||||
//assert
|
||||
ASSERT_IS_NULL(socket_handle);
|
||||
|
||||
//cleanup
|
||||
socket_transport_destroy(socket_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests_SOCKET_TRANSPORT_LINUX_11_093: [ If socket_transport_handle is NULL, socket_transport_is_valid_socket shall fail and return false. ]
|
||||
TEST_FUNCTION(socket_transport_is_valid_socket_NULL_input)
|
||||
{
|
||||
//arrange
|
||||
umock_c_reset_all_calls();
|
||||
|
||||
//act
|
||||
bool result = socket_transport_is_valid_socket(NULL);
|
||||
|
||||
//assert
|
||||
ASSERT_IS_TRUE(!result);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
}
|
||||
|
||||
// Tests_SOCKET_TRANSPORT_LINUX_11_095: [ On success, socket_transport_is_valid_socket shall return true. ]
|
||||
TEST_FUNCTION(socket_transport_is_valid_socket_succeeds)
|
||||
{
|
||||
//arrange
|
||||
SOCKET_TRANSPORT_HANDLE test_socket_transport = socket_transport_create_client();
|
||||
socket_transport_connect(test_socket_transport, TEST_HOSTNAME, TEST_PORT, TEST_CONNECTION_TIMEOUT);
|
||||
umock_c_reset_all_calls();
|
||||
|
||||
//act
|
||||
bool result = socket_transport_is_valid_socket(test_socket_transport);
|
||||
|
||||
//assert
|
||||
ASSERT_IS_TRUE(result);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
//cleanup
|
||||
socket_transport_disconnect(test_socket_transport);
|
||||
socket_transport_destroy(test_socket_transport);
|
||||
}
|
||||
|
||||
// Tests_SOCKET_TRANSPORT_LINUX_11_094: [ If the socket inside socket_transport_handle is an INVALID_SOCKET, socket_transport_is_valid_socket shall fail and return false. ]
|
||||
TEST_FUNCTION(socket_transport_is_valid_socket_INVALID_SOCKET)
|
||||
{
|
||||
//arrange
|
||||
SOCKET_TRANSPORT_HANDLE test_socket_transport = socket_transport_create_client();
|
||||
umock_c_reset_all_calls();
|
||||
|
||||
STRICT_EXPECTED_CALL(sm_open_begin(IGNORED_ARG));
|
||||
STRICT_EXPECTED_CALL(socket(IGNORED_ARG, IGNORED_ARG, IGNORED_ARG))
|
||||
.SetReturn(INVALID_SOCKET);
|
||||
STRICT_EXPECTED_CALL(sm_open_end(IGNORED_ARG, false));
|
||||
|
||||
//act
|
||||
socket_transport_connect(test_socket_transport, TEST_HOSTNAME, TEST_PORT, TEST_CONNECTION_TIMEOUT);
|
||||
bool result = socket_transport_is_valid_socket(test_socket_transport);
|
||||
|
||||
//assert
|
||||
ASSERT_IS_TRUE(!result);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
//cleanup
|
||||
socket_transport_disconnect(test_socket_transport);
|
||||
socket_transport_destroy(test_socket_transport);
|
||||
}
|
||||
|
||||
END_TEST_SUITE(TEST_SUITE_NAME_FROM_CMAKE)
|
||||
|
|
|
@ -51,6 +51,7 @@ typedef struct SOCKET_BUFFER_TAG
|
|||
|
||||
MOCKABLE_FUNCTION(, SOCKET_TRANSPORT_HANDLE, socket_transport_create_client);
|
||||
MOCKABLE_FUNCTION(, SOCKET_TRANSPORT_HANDLE, socket_transport_create_server);
|
||||
MOCKABLE_FUNCTION(, SOCKET_TRANSPORT_HANDLE, socket_transport_create_from_socket, SOCKET_HANDLE, socket_handle);
|
||||
MOCKABLE_FUNCTION(, void, socket_transport_destroy, SOCKET_TRANSPORT_HANDLE, socket_transport);
|
||||
|
||||
MOCKABLE_FUNCTION(, int, socket_transport_connect, SOCKET_TRANSPORT_HANDLE, socket_transport, const char*, hostname, uint16_t, port, uint32_t, connection_timeout_ms);
|
||||
|
@ -63,6 +64,7 @@ MOCKABLE_FUNCTION(, SOCKET_SEND_RESULT, socket_transport_send, SOCKET_TRANSPORT_
|
|||
MOCKABLE_FUNCTION(, SOCKET_RECEIVE_RESULT, socket_transport_receive, SOCKET_TRANSPORT_HANDLE, socket_transport, SOCKET_BUFFER*, payload, uint32_t, buffer_count, uint32_t*, bytes_recv, uint32_t, flags, void*, data);
|
||||
|
||||
MOCKABLE_FUNCTION(, SOCKET_HANDLE, socket_transport_get_underlying_socket, SOCKET_TRANSPORT_HANDLE, socket_transport);
|
||||
MOCKABLE_FUNCTION(, bool, socket_transport_is_valid_socket, SOCKET_TRANSPORT_HANDLE, socket_transport_handle);
|
||||
```
|
||||
|
||||
### socket_transport_create_client
|
||||
|
@ -97,6 +99,28 @@ MOCKABLE_FUNCTION(, SOCKET_TRANSPORT_HANDLE, socket_transport_create_server);
|
|||
|
||||
**SOCKET_TRANSPORT_WIN32_09_090: [** On success `socket_transport_create_server` shall return `SOCKET_TRANSPORT_HANDLE`. **]**
|
||||
|
||||
### socket_transport_create_from_socket
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, SOCKET_TRANSPORT_HANDLE, socket_transport_create_from_socket, SOCKET_HANDLE, socket_handle);
|
||||
```
|
||||
|
||||
`socket_transport_create_from_socket` creates a client socket transport from a given socket handle.
|
||||
|
||||
**SOCKET_TRANSPORT_WIN32_09_096: [** If socket_handle is an INVALID_SOCKET, `socket_transport_create_from_socket` shall fail and return `NULL`. **]**
|
||||
|
||||
**SOCKET_TRANSPORT_WIN32_09_097: [** `socket_transport_create_from_socket` shall allocate a new SOCKET_TRANSPORT object. **]**
|
||||
|
||||
**SOCKET_TRANSPORT_WIN32_09_098: [** `socket_transport_create_from_socket` shall call sm_create to create a sm_object with the type set to SOCKET_CLIENT. **]**
|
||||
|
||||
**SOCKET_TRANSPORT_WIN32_09_014: [** If `sm_open_begin` does not return `SM_EXEC_GRANTED`, `socket_transport_create_from_socket` shall fail and return `NULL`. **]**
|
||||
|
||||
**SOCKET_TRANSPORT_WIN32_09_099: [** `socket_transport_create_from_socket` shall assign the socket_handle to the new allocated socket transport. **]**
|
||||
|
||||
**SOCKET_TRANSPORT_WIN32_09_100: [** On any failure `socket_transport_create_from_socket` shall return `NULL`. **]**
|
||||
|
||||
**SOCKET_TRANSPORT_WIN32_09_101: [** On success `socket_transport_create_from_socket` shall return SOCKET_TRANSPORT_HANDLE. **]**
|
||||
|
||||
|
||||
### socket_transport_destroy
|
||||
|
||||
|
@ -329,3 +353,17 @@ MOCKABLE_FUNCTION(, SOCKET_HANDLE, socket_transport_get_underlying_socket, SOCKE
|
|||
**SOCKET_TRANSPORT_WIN32_09_081: [** `socket_transport_get_underlying_socket` shall return the SOCKET_TRANSPORT socket value. **]**
|
||||
|
||||
**SOCKET_TRANSPORT_WIN32_09_082: [** `socket_transport_get_underlying_socket` shall call `sm_exec_end`. **]**
|
||||
|
||||
### socket_transport_is_valid_socket
|
||||
|
||||
```c
|
||||
MOCKABLE_FUNCTION(, bool, socket_transport_is_valid_socket, SOCKET_TRANSPORT_HANDLE, socket_transport_handle);
|
||||
```
|
||||
|
||||
**SOCKET_TRANSPORT_WIN32_09_092: [** `socket_transport_is_valid_socket` checks that the internal socket is valid. **]**
|
||||
|
||||
**SOCKET_TRANSPORT_WIN32_09_093: [** If `socket_transport_handle` is `NULL`, `socket_transport_is_valid_socket` shall fail and return false. **]**
|
||||
|
||||
**SOCKET_TRANSPORT_WIN32_09_094: [** If the socket inside `socket_transport_handle` is an `INVALID_SOCKET`, `socket_transport_is_valid_socket` shall fail and return false. **]**
|
||||
|
||||
**SOCKET_TRANSPORT_WIN32_09_095: [** On success, `socket_transport_is_valid_socket` shall return true. **]**
|
||||
|
|
|
@ -240,6 +240,58 @@ all_ok:
|
|||
return result;
|
||||
}
|
||||
|
||||
SOCKET_TRANSPORT_HANDLE socket_transport_create_from_socket(SOCKET_HANDLE socket_handle)
|
||||
{
|
||||
SOCKET_TRANSPORT* result;
|
||||
// Codes_SOCKET_TRANSPORT_WIN32_09_096: [ If socket_handle is an INVALID_SOCKET, socket_transport_create_from_socket shall fail and return NULL. ]
|
||||
if ((SOCKET)socket_handle == INVALID_SOCKET)
|
||||
{
|
||||
LogError("Invalid socket, unable to create socket_transport_handle.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Codes_SOCKET_TRANSPORT_WIN32_09_097: [ socket_transport_create_from_socket shall allocate a new SOCKET_TRANSPORT object. ]
|
||||
result = malloc(sizeof(SOCKET_TRANSPORT));
|
||||
if (result == NULL)
|
||||
{
|
||||
LogError("failure allocating SOCKET_TRANSPORT: %zu", sizeof(SOCKET_TRANSPORT));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Codes_SOCKET_TRANSPORT_WIN32_09_098: [ socket_transport_create_from_socket shall call sm_create to create a sm_object with the type set to SOCKET_CLIENT. ]
|
||||
result->sm = sm_create("Socket_transport_win32");
|
||||
if (result->sm == NULL)
|
||||
{
|
||||
LogError("sm_create failed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Codes_SOCKET_TRANSPORT_WIN32_09_014: [ If sm_open_begin does not return SM_EXEC_GRANTED, socket_transport_create_from_socket shall fail and return NULL. ]
|
||||
SM_RESULT open_result = sm_open_begin(result->sm);
|
||||
if (open_result == SM_EXEC_GRANTED)
|
||||
{
|
||||
result->type = SOCKET_CLIENT;
|
||||
// Codes_SOCKET_TRANSPORT_WIN32_09_099: [ socket_transport_create_from_socket shall assign the socket_handle to the new allocated socket transport. ]
|
||||
result->socket = (SOCKET)socket_handle;
|
||||
sm_open_end(result->sm, true);
|
||||
// Codes_SOCKET_TRANSPORT_WIN32_09_101: [ On success socket_transport_create_from_socket shall return SOCKET_TRANSPORT_HANDLE. ]
|
||||
goto all_ok;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogError("sm_open_begin failed with %" PRI_MU_ENUM " in accept, closing incoming socket.", MU_ENUM_VALUE(SM_RESULT, open_result));
|
||||
}
|
||||
sm_destroy(result->sm);
|
||||
}
|
||||
free(result);
|
||||
}
|
||||
}
|
||||
// Codes_SOCKET_TRANSPORT_WIN32_09_100: [ On any failure socket_transport_create_from_socket shall return NULL. ]
|
||||
result = NULL;
|
||||
all_ok:
|
||||
return result;
|
||||
}
|
||||
|
||||
void socket_transport_destroy(SOCKET_TRANSPORT_HANDLE socket_transport)
|
||||
{
|
||||
// Codes_SOCKET_TRANSPORT_WIN32_09_006: [ If socket_transport is NULL socket_transport_destroy shall return. ]
|
||||
|
@ -760,3 +812,26 @@ SOCKET_HANDLE socket_transport_get_underlying_socket(SOCKET_TRANSPORT_HANDLE soc
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool socket_transport_is_valid_socket(SOCKET_TRANSPORT_HANDLE socket_transport_handle)
|
||||
{
|
||||
bool result;
|
||||
if (socket_transport_handle == NULL)
|
||||
{
|
||||
result = false;
|
||||
LogError("Invalid argument: SOCKET_TRANSPORT_HANDLE socket_transport_handle: %p", socket_transport_handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (socket_transport_handle->socket == INVALID_SOCKET)
|
||||
{
|
||||
result = false;
|
||||
LogError("Invalid socket in argument: SOCKET_TRANSPORT_HANDLE socket_transport_handle: %p", socket_transport_handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -1837,4 +1837,131 @@ TEST_FUNCTION(socket_transport_get_underlying_socket_NULL_input_fail)
|
|||
//cleanup
|
||||
}
|
||||
|
||||
// Tests_SOCKET_TRANSPORT_WIN32_09_098: [ socket_transport_create_from_socket shall call sm_create to create a sm_object with the type set to SOCKET_CLIENT. ]
|
||||
// Tests_SOCKET_TRANSPORT_WIN32_09_097: [ socket_transport_create_from_socket shall allocate a new SOCKET_TRANSPORT object. ]
|
||||
// Tests_SOCKET_TRANSPORT_WIN32_09_099: [ socket_transport_create_from_socket shall assign the socket_handle to the new allocated socket transport. ]
|
||||
// Tests_SOCKET_TRANSPORT_WIN32_09_101: [ On success socket_transport_create_from_socket shall return SOCKET_TRANSPORT_HANDLE. ]
|
||||
TEST_FUNCTION(socket_transport_create_from_socket_succeeds)
|
||||
{
|
||||
//arrange
|
||||
umock_c_reset_all_calls();
|
||||
STRICT_EXPECTED_CALL(malloc(IGNORED_ARG));
|
||||
STRICT_EXPECTED_CALL(sm_create(IGNORED_ARG));
|
||||
STRICT_EXPECTED_CALL(sm_open_begin(IGNORED_ARG));
|
||||
STRICT_EXPECTED_CALL(sm_open_end(IGNORED_ARG, true));
|
||||
|
||||
//act
|
||||
SOCKET_TRANSPORT_HANDLE socket_transport = socket_transport_create_from_socket((SOCKET_HANDLE)test_socket);
|
||||
|
||||
//assert
|
||||
ASSERT_IS_NOT_NULL(socket_transport);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
//cleanup
|
||||
socket_transport_destroy(socket_transport);
|
||||
}
|
||||
|
||||
// Tests_SOCKET_TRANSPORT_WIN32_09_096: [ If socket_handle is an INVALID_SOCKET, socket_transport_create_from_socket shall fail and return NULL. ]
|
||||
TEST_FUNCTION(socket_transport_create_from_socket_invalid_input)
|
||||
{
|
||||
//arrange
|
||||
umock_c_reset_all_calls();
|
||||
|
||||
//act
|
||||
SOCKET_TRANSPORT_HANDLE socket_transport = socket_transport_create_from_socket((SOCKET_HANDLE)INVALID_SOCKET);
|
||||
|
||||
//assert
|
||||
ASSERT_IS_NULL(socket_transport);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
}
|
||||
|
||||
// Tests_SOCKET_TRANSPORT_WIN32_09_014: [ If sm_open_begin does not return SM_EXEC_GRANTED, socket_transport_create_from_socket shall fail and return NULL. ]
|
||||
// Tests_SOCKET_TRANSPORT_WIN32_09_102: [ On any failure socket_transport_create_from_socket shall return NULL. ]
|
||||
TEST_FUNCTION(socket_transport_create_from_socket_fail)
|
||||
{
|
||||
//arrange
|
||||
STRICT_EXPECTED_CALL(malloc(IGNORED_ARG));
|
||||
STRICT_EXPECTED_CALL(sm_create(IGNORED_ARG));
|
||||
STRICT_EXPECTED_CALL(sm_open_begin(IGNORED_ARG));
|
||||
STRICT_EXPECTED_CALL(sm_destroy(IGNORED_ARG));
|
||||
umock_c_negative_tests_snapshot();
|
||||
|
||||
for (size_t index = 0; index < umock_c_negative_tests_call_count(); index++)
|
||||
{
|
||||
if (umock_c_negative_tests_can_call_fail(index))
|
||||
{
|
||||
umock_c_negative_tests_reset();
|
||||
umock_c_negative_tests_fail_call(index);
|
||||
|
||||
//act
|
||||
SOCKET_TRANSPORT_HANDLE socket_handle = socket_transport_create_from_socket((SOCKET_HANDLE)test_socket);
|
||||
|
||||
//assert
|
||||
ASSERT_IS_NULL(socket_handle);
|
||||
|
||||
//cleanup
|
||||
socket_transport_destroy(socket_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests_SOCKET_TRANSPORT_WIN32_09_093: [ If socket_transport_handle is NULL, socket_transport_is_valid_socket shall fail and return false. ]
|
||||
TEST_FUNCTION(socket_transport_is_valid_socket_NULL_input)
|
||||
{
|
||||
//arrange
|
||||
umock_c_reset_all_calls();
|
||||
|
||||
//act
|
||||
bool result = socket_transport_is_valid_socket(NULL);
|
||||
|
||||
//assert
|
||||
ASSERT_IS_TRUE(!result);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
}
|
||||
|
||||
// Tests_SOCKET_TRANSPORT_WIN32_09_095: [ On success, socket_transport_is_valid_socket shall return true.
|
||||
TEST_FUNCTION(socket_transport_is_valid_socket_succeeds)
|
||||
{
|
||||
//arrange
|
||||
SOCKET_TRANSPORT_HANDLE test_socket_transport = socket_transport_create_client();
|
||||
socket_transport_connect(test_socket_transport, TEST_HOSTNAME, TEST_PORT, TEST_CONNECTION_TIMEOUT);
|
||||
umock_c_reset_all_calls();
|
||||
|
||||
//act
|
||||
bool result = socket_transport_is_valid_socket(test_socket_transport);
|
||||
|
||||
//assert
|
||||
ASSERT_IS_TRUE(result);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
//cleanup
|
||||
socket_transport_disconnect(test_socket_transport);
|
||||
socket_transport_destroy(test_socket_transport);
|
||||
}
|
||||
|
||||
// Tests_SOCKET_TRANSPORT_WIN32_09_094: [ If the socket inside socket_transport_handle is an INVALID_SOCKET, socket_transport_is_valid_socket shall fail and return false. ]
|
||||
TEST_FUNCTION(socket_transport_is_valid_socket_INVALID_SOCKET)
|
||||
{
|
||||
//arrange
|
||||
SOCKET_TRANSPORT_HANDLE test_socket_transport = socket_transport_create_client();
|
||||
umock_c_reset_all_calls();
|
||||
|
||||
STRICT_EXPECTED_CALL(sm_open_begin(IGNORED_ARG));
|
||||
STRICT_EXPECTED_CALL(socket(IGNORED_ARG, IGNORED_ARG, IGNORED_ARG))
|
||||
.SetReturn(INVALID_SOCKET);
|
||||
STRICT_EXPECTED_CALL(sm_open_end(IGNORED_ARG, false));
|
||||
|
||||
//act
|
||||
socket_transport_connect(test_socket_transport, TEST_HOSTNAME, TEST_PORT, TEST_CONNECTION_TIMEOUT);
|
||||
bool result = socket_transport_is_valid_socket(test_socket_transport);
|
||||
|
||||
//assert
|
||||
ASSERT_IS_TRUE(!result);
|
||||
ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
|
||||
|
||||
//cleanup
|
||||
socket_transport_disconnect(test_socket_transport);
|
||||
socket_transport_destroy(test_socket_transport);
|
||||
}
|
||||
|
||||
END_TEST_SUITE(TEST_SUITE_NAME_FROM_CMAKE)
|
||||
|
|
Загрузка…
Ссылка в новой задаче