Add socketstats stub functions for unittest and addressed reviews

pull/8592/head
deepikabhavnani 2018-11-18 20:41:03 -06:00
parent f6c1a40b29
commit 117eb0bc87
17 changed files with 151 additions and 62 deletions

View File

@ -183,18 +183,26 @@ void UDPSOCKET_ECHOTEST_NONBLOCK()
}
free(stack_mem);
#ifdef MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
TEST_ASSERT_EQUAL(1, fetch_stats());
TEST_ASSERT_EQUAL(NSAPI_UDP, udp_stats[0].proto);
TEST_ASSERT(udp_stats[0].sent_bytes != 0);
TEST_ASSERT(udp_stats[0].recv_bytes != 0);
#endif
// Packet loss up to 30% tolerated
if (packets_sent > 0) {
double loss_ratio = 1 - ((double)packets_recv / (double)packets_sent);
printf("Packets sent: %d, packets received %d, loss ratio %.2lf\r\n", packets_sent, packets_recv, loss_ratio);
TEST_ASSERT_DOUBLE_WITHIN(TOLERATED_LOSS_RATIO, EXPECTED_LOSS_RATIO, loss_ratio);
#ifdef MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
count = fetch_stats();
for (j = 0; j < count; j++) {
if ((NSAPI_UDP == udp_stats[j].proto) && (SOCK_OPEN == udp_stats[j].state)) {
TEST_ASSERT(udp_stats[j].sent_bytes != 0);
TEST_ASSERT(udp_stats[j].recv_bytes != 0);
break;
}
}
loss_ratio = 1 - ((double)udp_stats[j].recv_bytes / (double)udp_stats[j].sent_bytes);
printf("Bytes sent: %d, bytes received %d, loss ratio %.2lf\r\n", udp_stats[j].sent_bytes, udp_stats[j].recv_bytes, loss_ratio);
TEST_ASSERT_DOUBLE_WITHIN(TOLERATED_LOSS_RATIO, EXPECTED_LOSS_RATIO, loss_ratio);
#endif
}
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
}

View File

@ -33,4 +33,5 @@ set(unittest-test-sources
stubs/stoip4_stub.c
stubs/ip4tos_stub.c
stubs/NetworkStack_stub.cpp
stubs/SocketStats_Stub.cpp
)

View File

@ -25,4 +25,5 @@ set(unittest-test-sources
stubs/EventFlags_stub.cpp
stubs/stoip4_stub.c
stubs/ip4tos_stub.c
stubs/SocketStats_Stub.cpp
)

View File

@ -25,4 +25,5 @@ set(unittest-test-sources
stubs/nsapi_dns_stub.cpp
stubs/EventFlags_stub.cpp
features/netsocket/NetworkInterface/test_NetworkInterface.cpp
stubs/SocketStats_Stub.cpp
)

View File

@ -28,4 +28,5 @@ set(unittest-test-sources
stubs/nsapi_dns_stub.cpp
stubs/EventFlags_stub.cpp
features/netsocket/NetworkStack/test_NetworkStack.cpp
stubs/SocketStats_Stub.cpp
)

View File

@ -28,4 +28,5 @@ set(unittest-test-sources
stubs/nsapi_dns_stub.cpp
stubs/EventFlags_stub.cpp
features/netsocket/TCPServer/test_TCPServer.cpp
stubs/SocketStats_Stub.cpp
)

View File

@ -26,4 +26,5 @@ set(unittest-test-sources
stubs/EventFlags_stub.cpp
stubs/stoip4_stub.c
stubs/ip4tos_stub.c
stubs/SocketStats_Stub.cpp
)

View File

@ -26,4 +26,5 @@ set(unittest-test-sources
stubs/nsapi_dns_stub.cpp
stubs/stoip4_stub.c
stubs/ip4tos_stub.c
stubs/SocketStats_Stub.cpp
)

View File

@ -0,0 +1,61 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "SocketStats.h"
int SocketStats::get_entry_position(const Socket *const reference_id)
{
return 0;
}
size_t SocketStats::mbed_stats_socket_get_each(mbed_stats_socket_t *stats, size_t count)
{
return 0;
}
SocketStats::SocketStats()
{
}
void SocketStats::stats_new_socket_entry(const Socket *const reference_id)
{
return;
}
void SocketStats::stats_update_socket_state(const Socket *const reference_id, socket_state state)
{
return;
}
void SocketStats::stats_update_peer(const Socket *const reference_id, const SocketAddress &peer)
{
return;
}
void SocketStats::stats_update_proto(const Socket *const reference_id, nsapi_protocol_t proto)
{
return;
}
void SocketStats::stats_update_sent_bytes(const Socket *const reference_id, size_t sent_bytes)
{
return;
}
void SocketStats::stats_update_recv_bytes(const Socket *const reference_id, size_t recv_bytes)
{
return;
}

View File

@ -24,6 +24,7 @@ InternetSocket::InternetSocket()
_readers(0), _writers(0), _pending(0),
_factory_allocated(false)
{
_socket_stats.stats_new_socket_entry(this);
}
InternetSocket::~InternetSocket()
@ -48,6 +49,7 @@ nsapi_error_t InternetSocket::open(NetworkStack *stack)
return err;
}
_socket_stats.stats_update_socket_state(this, SOCK_OPEN);
_socket = socket;
_event = callback(this, &InternetSocket::event);
_stack->socket_attach(_socket, Callback<void()>::thunk, &_event);
@ -72,7 +74,7 @@ nsapi_error_t InternetSocket::close()
_socket = 0;
ret = _stack->socket_close(socket);
_stack = 0; // Invalidate the stack pointer - otherwise open() fails.
_socket_stats.stats_update_socket_state(this, SOCK_CLOSED);
// Wakeup anything in a blocking operation
// on this socket
event();

View File

@ -140,7 +140,7 @@ void SocketStats::stats_update_sent_bytes(const Socket *const reference_id, size
#ifdef MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
_mutex->lock();
int position = get_entry_position(reference_id);
if ((position >= 0) && (sent_bytes > 0)) {
if ((position >= 0) && ((int32_t)sent_bytes > 0)) {
_stats[position].sent_bytes += sent_bytes;
}
_mutex->unlock();
@ -152,7 +152,7 @@ void SocketStats::stats_update_recv_bytes(const Socket *const reference_id, size
#ifdef MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
_mutex->lock();
int position = get_entry_position(reference_id);
if ((position >= 0) && (recv_bytes > 0)) {
if ((position >= 0) && ((int32_t)recv_bytes > 0)) {
_stats[position].recv_bytes += recv_bytes;
}
_mutex->unlock();

View File

@ -27,6 +27,12 @@
#define MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT 10
#endif
/** Enum of socket states
*
* Can be used to specify current state of socket - Open / Close / Connected / Listen
*
* @enum socket_state
*/
typedef enum {
SOCK_CLOSED, /**< Socket is closed and does not exist anymore in the system */
SOCK_OPEN, /**< Socket is open, but not associated to any peer address */
@ -34,6 +40,8 @@ typedef enum {
SOCK_LISTEN, /**< Socket is listening for incoming connections */
} socket_state;
/** Structure to parse socket statistics
*/
typedef struct {
Socket *reference_id; /**< Used for identifying socket */
SocketAddress peer; /**< Last associated peername of this socket (Destination address) */
@ -51,6 +59,7 @@ typedef struct {
class SocketStats {
public:
#if !defined(DOXYGEN_ONLY)
/** Create an socket statictics object
*
* Application users must not create class objects.
@ -62,7 +71,7 @@ public:
virtual ~SocketStats()
{
}
#endif
/**
* Fill the passed array of structures with the socket statistics for each created socket.
*
@ -76,26 +85,62 @@ public:
*/
static size_t mbed_stats_socket_get_each(mbed_stats_socket_t *stats, size_t count);
#if !defined(DOXYGEN_ONLY)
/** Add entry of newly created socket in statistics array.
@Note: Entry in the array will be maintained even after socket is closed.
Entry will be over-written for sockets which were closed first, in case
we socket creation count exceeds `MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT`.
*/
* API used by socket (TCP / UDP) layers only, not to be used by application.
*
* @param reference_id Id to identify socket in data array.
*
* @Note: Entry in the array will be maintained even after socket is closed.
* Entry will be over-written for sockets which were closed first, in case
* we socket creation count exceeds `MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT`.
*
*/
void stats_new_socket_entry(const Socket *const reference_id);
/** Updates the state of socket and along with that records tick_last_change */
/** Updates the state of socket and along with that records tick_last_change.
* API used by socket (TCP / UDP) layers only, not to be used by application.
*
* @param reference_id Id to identify socket in data array.
* @param state Parameter to update current state of socket.
*
*/
void stats_update_socket_state(const Socket *const reference_id, socket_state state);
/** Update the peer information of the socket */
/** Update the peer information of the socket.
* API used by socket (TCP / UDP) layers only, not to be used by application.
*
* @param reference_id Id to identify socket in data array.
* @param peer Parameter to update destination peer information
*
*/
void stats_update_peer(const Socket *const reference_id, const SocketAddress &peer);
/** Update socket protocol */
/** Update socket protocol.
* API used by socket (TCP / UDP) layers only, not to be used by application.
*
* @param reference_id Id to identify socket in data array.
* @param proto Parameter to update the protocol type of socket.
*
*/
void stats_update_proto(const Socket *const reference_id, nsapi_protocol_t proto);
/** Update bytes sent on socket, which is cumulative count per socket */
/** Update bytes sent on socket, which is cumulative count per socket.
* API used by socket (TCP / UDP) layers only, not to be used by application.
*
* @param reference_id Id to identify socket in data array.
* @param sent_bytes Parameter to append bytes sent over the socket.
*
*/
void stats_update_sent_bytes(const Socket *const reference_id, size_t sent_bytes);
/** Update bytes received on socket, which is cumulative count per socket */
/** Update bytes received on socket, which is cumulative count per socket
* API used by socket (TCP / UDP) layers only, not to be used by application.
*
* @param reference_id Id to identify socket in data array.
* @param recv_bytes Parameter to append bytes received by the socket
*
*/
void stats_update_recv_bytes(const Socket *const reference_id, size_t recv_bytes);
#ifdef MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
@ -105,10 +150,13 @@ private:
static uint32_t _size;
/** Internal function to scan the array and get position of element in the list.
This API locks the mutex and the next API call updating the entry in the array
should release the lock */
*
* @param reference_id Id to identify socket in data array.
*
*/
int get_entry_position(const Socket *const reference_id);
#endif
#endif
};
#endif

View File

@ -20,12 +20,11 @@ using mbed::Callback;
TCPServer::TCPServer()
{
_socket_stats.stats_new_socket_entry(this);
_socket_stats.stats_update_proto(this, NSAPI_TCP);
}
TCPServer::~TCPServer()
{
_socket_stats.stats_update_socket_state(this, SOCK_CLOSED);
}
nsapi_error_t TCPServer::accept(TCPSocket *connection, SocketAddress *address)

View File

@ -20,7 +20,7 @@
TCPSocket::TCPSocket()
{
_socket_stats.stats_new_socket_entry(this);
_socket_stats.stats_update_proto(this, NSAPI_TCP);
}
TCPSocket::TCPSocket(TCPSocket *parent, nsapi_socket_t socket, SocketAddress address)
@ -36,19 +36,10 @@ TCPSocket::TCPSocket(TCPSocket *parent, nsapi_socket_t socket, SocketAddress add
TCPSocket::~TCPSocket()
{
_socket_stats.stats_update_socket_state(this, SOCK_CLOSED);
}
nsapi_error_t TCPSocket::close()
{
_socket_stats.stats_update_socket_state(this, SOCK_CLOSED);
return InternetSocket::close();
}
nsapi_protocol_t TCPSocket::get_proto()
{
_socket_stats.stats_update_proto(this, NSAPI_TCP);
_socket_stats.stats_update_socket_state(this, SOCK_OPEN);
return NSAPI_TCP;
}

View File

@ -61,15 +61,6 @@ public:
*/
virtual ~TCPSocket();
/** Close the socket.
*
* Closes any open connection and deallocates any memory associated
* with the socket. Called from destructor if socket is not closed.
*
* @return NSAPI_ERROR_OK on success, negative error code on failure
*/
virtual nsapi_error_t close();
/** Override multicast functions to return error for TCP
*
*/

View File

@ -20,24 +20,15 @@
UDPSocket::UDPSocket()
{
_socket_stats.stats_new_socket_entry(this);
_socket_stats.stats_update_proto(this, NSAPI_UDP);
}
UDPSocket::~UDPSocket()
{
_socket_stats.stats_update_socket_state(this, SOCK_CLOSED);
}
nsapi_error_t UDPSocket::close()
{
_socket_stats.stats_update_socket_state(this, SOCK_CLOSED);
return InternetSocket::close();
}
nsapi_protocol_t UDPSocket::get_proto()
{
_socket_stats.stats_update_proto(this, NSAPI_UDP);
_socket_stats.stats_update_socket_state(this, SOCK_OPEN);
return NSAPI_UDP;
}

View File

@ -59,15 +59,6 @@ public:
*/
virtual ~UDPSocket();
/** Close the socket.
*
* Closes any open connection and deallocates any memory associated
* with the socket. Called from destructor if socket is not closed.
*
* @return NSAPI_ERROR_OK on success, negative error code on failure
*/
virtual nsapi_error_t close();
/** Send data to the specified host and port.
*
* By default, sendto blocks until data is sent. If socket is set to