From caf01479ea7abb49113f40cb9fd4b83892851959 Mon Sep 17 00:00:00 2001 From: Michal Paszta Date: Fri, 8 Nov 2019 08:46:32 +0200 Subject: [PATCH] Improve doxygen and unittest coverage for API Mainly focusing on hardening the tests for return values. --- .../test_EthernetInterface.cpp | 51 +++ .../test_NetworkInterface.cpp | 6 + .../PPPInterface/test_PPPInterface.cpp | 293 ++++++++++++++++++ .../netsocket/PPPInterface/unittest.cmake | 41 +++ .../netsocket/TCPSocket/test_TCPSocket.cpp | 9 +- .../test_TLSSocketWrapper.cpp | 24 +- .../WiFiAccessPoint/test_WiFiAccessPoint.cpp | 1 + UNITTESTS/stubs/OnboardNetworkStack_mock.h | 6 + features/netsocket/EMACInterface.h | 70 +---- features/netsocket/InternetDatagramSocket.h | 4 +- features/netsocket/NetworkInterface.h | 10 +- features/netsocket/NetworkStack.h | 5 +- features/netsocket/PPPInterface.h | 63 +--- features/netsocket/SocketAddress.h | 2 + features/netsocket/TCPSocket.h | 5 +- features/netsocket/TLSSocketWrapper.h | 3 + features/netsocket/nsapi_dns.h | 11 +- 17 files changed, 480 insertions(+), 124 deletions(-) create mode 100644 UNITTESTS/features/netsocket/PPPInterface/test_PPPInterface.cpp create mode 100644 UNITTESTS/features/netsocket/PPPInterface/unittest.cmake diff --git a/UNITTESTS/features/netsocket/EthernetInterface/test_EthernetInterface.cpp b/UNITTESTS/features/netsocket/EthernetInterface/test_EthernetInterface.cpp index 6580c404d6..7f8e670c71 100644 --- a/UNITTESTS/features/netsocket/EthernetInterface/test_EthernetInterface.cpp +++ b/UNITTESTS/features/netsocket/EthernetInterface/test_EthernetInterface.cpp @@ -117,6 +117,15 @@ protected: TEST_F(TestEthernetInterface, constructor_default) { EXPECT_TRUE(iface); + + // Test that this clas presents itself correctly + EXPECT_NE(nullptr, iface->ethInterface()); + EXPECT_NE(nullptr, iface->emacInterface()); + + EXPECT_EQ(nullptr, iface->wifiInterface()); + EXPECT_EQ(nullptr, iface->cellularBase()); + EXPECT_EQ(nullptr, iface->cellularInterface()); + EXPECT_EQ(nullptr, iface->meshInterface()); } TEST_F(TestEthernetInterface, constructor_getter) @@ -164,6 +173,9 @@ TEST_F(TestEthernetInterface, set_network) SocketAddress netmaskArg; SocketAddress gatewayArg; + // Before connecting return NULL + EXPECT_EQ(NULL, iface->get_mac_address()); + SocketAddress tmp; EXPECT_EQ(NSAPI_ERROR_NO_CONNECTION, iface->get_ip_address(&tmp)); EXPECT_EQ(NSAPI_ERROR_NO_CONNECTION, iface->get_netmask(&tmp)); @@ -229,6 +241,45 @@ TEST_F(TestEthernetInterface, attach) iface->attach(cb); } + +TEST_F(TestEthernetInterface, get_interface_name) +{ + char name[100] = "eth0"; + EXPECT_EQ(NULL, iface->get_interface_name(name)); + + doConnect(); + + // The parameter will be an internal variable. + EXPECT_CALL(*netStackIface, get_interface_name(_)) + .Times(1) + .WillOnce(Return(name)); + EXPECT_EQ(std::string(name), std::string(iface->get_interface_name(name))); +} + +TEST_F(TestEthernetInterface, get_ipv6_link_local_address) +{ + SocketAddress addr("4.3.2.1"); + EXPECT_EQ(NSAPI_ERROR_NO_CONNECTION, iface->get_ipv6_link_local_address(&addr)); + EXPECT_EQ(std::string(addr.get_ip_address()), std::string("4.3.2.1")); + doConnect(); + + // The parameter will be an internal variable. + EXPECT_CALL(*netStackIface, get_ipv6_link_local_address(&addr)) + .Times(1) + .WillOnce(Return(NSAPI_ERROR_OK)); + EXPECT_EQ(NSAPI_ERROR_OK, iface->get_ipv6_link_local_address(&addr)); +} + +TEST_F(TestEthernetInterface, set_as_default) +{ + doConnect(); + + EXPECT_CALL(*stackMock, set_default_interface(netStackIface)) + .Times(1); + iface->set_as_default(); +} + + TEST_F(TestEthernetInterface, set_dhcp) { EXPECT_EQ(NSAPI_ERROR_OK, iface->set_dhcp(false)); diff --git a/UNITTESTS/features/netsocket/NetworkInterface/test_NetworkInterface.cpp b/UNITTESTS/features/netsocket/NetworkInterface/test_NetworkInterface.cpp index b89e503617..dc8bd968b1 100644 --- a/UNITTESTS/features/netsocket/NetworkInterface/test_NetworkInterface.cpp +++ b/UNITTESTS/features/netsocket/NetworkInterface/test_NetworkInterface.cpp @@ -148,6 +148,12 @@ TEST_F(TestNetworkInterface, set_blocking) EXPECT_EQ(iface->set_blocking(true), NSAPI_ERROR_UNSUPPORTED); } +TEST_F(TestNetworkInterface, get_ipv6_link_local_address) +{ + SocketAddress a; + EXPECT_EQ(iface->get_ipv6_link_local_address(&a), NSAPI_ERROR_UNSUPPORTED); +} + void my_iface_callback(nsapi_event_t e, intptr_t i) { (void)e; diff --git a/UNITTESTS/features/netsocket/PPPInterface/test_PPPInterface.cpp b/UNITTESTS/features/netsocket/PPPInterface/test_PPPInterface.cpp new file mode 100644 index 0000000000..cab12b275a --- /dev/null +++ b/UNITTESTS/features/netsocket/PPPInterface/test_PPPInterface.cpp @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates + * SPDX-License-Identifier: Apache-2.0 + * + * 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 "gtest/gtest.h" +#include "gmock/gmock.h" + +#include "OnboardNetworkStack_mock.h" + +#include "features/netsocket/PPPInterface.h" +#include +#include "FileHandle_stub.h" + + +OnboardNetworkStack &OnboardNetworkStack::get_default_instance() +{ + return OnboardNetworkStackMock::get_instance(); +} + +using ::testing::_; +using ::testing::Return; +using ::testing::ReturnArg; +using ::testing::SaveArg; +using ::testing::SaveArgPointee; +using ::testing::SetArrayArgument; +using ::testing::SetArgPointee; +using ::testing::SetArgReferee; + +class MockPPP : public PPP { +public: + MOCK_METHOD0(power_up, bool()); + MOCK_METHOD0(power_down, void()); + MOCK_METHOD0(get_mtu_size, uint32_t()); + MOCK_CONST_METHOD0(get_align_preference, uint32_t()); + MOCK_CONST_METHOD2(get_ifname, void(char *name, uint8_t size)); + MOCK_METHOD2(link_out, bool(net_stack_mem_buf_t *buf, nsapi_ip_stack_t ip_stack)); + MOCK_METHOD1(set_stream, void(mbed::FileHandle *stream)); + MOCK_METHOD1(set_ip_stack, void(nsapi_ip_stack_t ip_stack)); + MOCK_METHOD2(set_credentials, void(const char *uname, const char *password)); + MOCK_METHOD1(get_ip_address, const nsapi_addr_t *(nsapi_version_t version)); + MOCK_METHOD0(get_netmask, const nsapi_addr_t *()); + MOCK_METHOD0(get_gateway, const nsapi_addr_t *()); + MOCK_METHOD1(get_dns_server, const nsapi_addr_t *(uint8_t index)); + MOCK_METHOD1(set_link_input_cb, void(ppp_link_input_cb_t input_cb)); + MOCK_METHOD1(set_link_state_cb, void(ppp_link_state_change_cb_t state_cb)); + MOCK_METHOD1(set_memory_manager, void(NetStackMemoryManager &mem_mngr)); + + static MockPPP &get_instance() + { + static MockPPP pppMock1; + return pppMock1; + } +}; + +MBED_WEAK PPP &PPP::get_default_instance() +{ + return MockPPP::get_instance(); +} + +class TestPPPInterface: public testing::Test { +protected: + PPPInterface *iface; + OnboardNetworkStackMock *stackMock; + MockPPP *pppMock; + OnboardNetworkStackMock::InterfaceMock *netStackIface; + virtual void SetUp() + { + stackMock = &OnboardNetworkStackMock::get_instance(); + pppMock = &MockPPP::get_instance(); + netStackIface = &OnboardNetworkStackMock::InterfaceMock::get_instance(); + iface = new PPPInterface(MockPPP::get_instance(), OnboardNetworkStackMock::get_instance()); + } + + virtual void TearDown() + { + // Do not delete the mocks pointers, as they point to statically allocated singletons. + delete iface; + } + + /* Enclose the heavily-used connection procedure to improve code redability */ + void doConnect(bool blocking = true) + { + EXPECT_CALL(*pppMock, set_stream(_)); + EXPECT_CALL(*pppMock, set_ip_stack(_)); + EXPECT_CALL(*pppMock, set_credentials(_, _)); + EXPECT_CALL(*stackMock, add_ppp_interface(testing::Ref(*pppMock), true, _)) + .Times(1) + .WillOnce(DoAll(SetArgPointee<2>(netStackIface), Return(NSAPI_ERROR_OK))); + EXPECT_CALL(*netStackIface, attach(_)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*netStackIface, bringup(false, NULL, NULL, NULL, DEFAULT_STACK, blocking)) + .Times(1) + .WillOnce(Return(NSAPI_ERROR_OK)); + EXPECT_EQ(NSAPI_ERROR_OK, iface->connect()); + } + + static void cb(nsapi_event_t ev, intptr_t ptr) + { + + } +}; + +TEST_F(TestPPPInterface, constructor_default) +{ + EXPECT_TRUE(iface); + // Test that this clas presents itself correctly + EXPECT_NE(nullptr, iface->pppInterface()); + + EXPECT_EQ(nullptr, iface->emacInterface()); + EXPECT_EQ(nullptr, iface->ethInterface()); + EXPECT_EQ(nullptr, iface->wifiInterface()); + EXPECT_EQ(nullptr, iface->cellularBase()); + EXPECT_EQ(nullptr, iface->cellularInterface()); + EXPECT_EQ(nullptr, iface->meshInterface()); +} + +TEST_F(TestPPPInterface, connect) +{ + mbed::FileHandle_stub handle; + nsapi_ip_stack_t stack = IPV4_STACK; + iface->set_credentials("uname", "passwd"); + iface->set_stream(&handle); + iface->set_ip_stack(stack); + + EXPECT_CALL(*pppMock, set_stream(&handle)); + EXPECT_CALL(*pppMock, set_ip_stack(stack)); + EXPECT_CALL(*pppMock, set_credentials("uname", "passwd")); + EXPECT_CALL(*stackMock, add_ppp_interface(testing::Ref(*pppMock), true, _)) + .Times(1) + .WillOnce(DoAll(SetArgPointee<2>(netStackIface), Return(NSAPI_ERROR_OK))); + EXPECT_CALL(*netStackIface, attach(_)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*netStackIface, bringup(false, NULL, NULL, NULL, stack, true)) + .Times(1) + .WillOnce(Return(NSAPI_ERROR_OK)); + EXPECT_EQ(NSAPI_ERROR_OK, iface->connect()); +} + +TEST_F(TestPPPInterface, connect_failure) +{ + EXPECT_CALL(*pppMock, set_stream(_)); + EXPECT_CALL(*pppMock, set_ip_stack(_)); + EXPECT_CALL(*pppMock, set_credentials(_, _)); + EXPECT_CALL(*stackMock, add_ppp_interface(testing::Ref(*pppMock), true, _)) + .Times(1) + .WillOnce(DoAll(SetArgPointee<2>(netStackIface), Return(NSAPI_ERROR_NO_MEMORY))); + EXPECT_EQ(NSAPI_ERROR_NO_MEMORY, iface->connect()); +} + +TEST_F(TestPPPInterface, disconnect_without_connecting) +{ + EXPECT_EQ(NSAPI_ERROR_NO_CONNECTION, iface->disconnect()); +} + +TEST_F(TestPPPInterface, disconnect) +{ + doConnect(); + + EXPECT_CALL(*netStackIface, bringdown()) + .Times(1) + .WillOnce(Return(NSAPI_ERROR_OK)); + EXPECT_EQ(NSAPI_ERROR_OK, iface->disconnect()); +} + +TEST_F(TestPPPInterface, set_network) +{ + char ipAddress[NSAPI_IPv4_SIZE] = "127.0.0.1"; + char netmask[NSAPI_IPv4_SIZE] = "255.255.0.0"; + char gateway[NSAPI_IPv4_SIZE] = "127.0.0.2"; + + const char *ipAddressArg; + const char *netmaskArg; + const char *gatewayArg; + + EXPECT_EQ(0, iface->get_ip_address()); + EXPECT_EQ(0, iface->get_netmask()); + EXPECT_EQ(0, iface->get_gateway()); + + EXPECT_CALL(*pppMock, set_stream(_)); + EXPECT_CALL(*pppMock, set_ip_stack(_)); + EXPECT_CALL(*pppMock, set_credentials(_, _)); + + // Set the network data + EXPECT_EQ(NSAPI_ERROR_OK, iface->set_network(ipAddress, netmask, gateway)); + + // Now the bringup should have different arguments. We can't use doConnect method. + EXPECT_CALL(*stackMock, add_ppp_interface(testing::Ref(*pppMock), true, _)) + .Times(1) + .WillOnce(DoAll(SetArgPointee<2>(netStackIface), Return(NSAPI_ERROR_OK))); + EXPECT_CALL(*netStackIface, attach(_)) + .Times(1) + .RetiresOnSaturation(); + // Do not put the expected char * arguments, as they are pointers and would not match + EXPECT_CALL(*netStackIface, bringup(false, _, _, _, DEFAULT_STACK, true)) + .Times(1) + .WillOnce(DoAll(SaveArg<1>(&ipAddressArg), + SaveArg<2>(&netmaskArg), + SaveArg<3>(&gatewayArg), + Return(NSAPI_ERROR_OK))); + EXPECT_EQ(NSAPI_ERROR_OK, iface->connect()); + // Check the contents of the stored pointer arguments. + EXPECT_TRUE(0 == strcmp(ipAddress, ipAddressArg)); + EXPECT_TRUE(0 == strcmp(netmask, netmaskArg)); + EXPECT_TRUE(0 == strcmp(gateway, gatewayArg)); + + // Testing the getters makes sense now. + EXPECT_CALL(*netStackIface, get_ip_address(_, _)) + .Times(1) + .WillOnce(DoAll(SetArgPointee<0>(*ipAddress), Return(ipAddress))); + EXPECT_EQ(std::string(ipAddress), std::string(iface->get_ip_address())); + + EXPECT_CALL(*netStackIface, get_netmask(_, _)) + .Times(1) + .WillOnce(DoAll(SetArgPointee<0>(*netmask), Return(netmask))); + EXPECT_EQ(std::string(netmask), std::string(iface->get_netmask())); + + EXPECT_CALL(*netStackIface, get_gateway(_, _)) + .Times(1) + .WillOnce(DoAll(SetArgPointee<0>(*gateway), Return(gateway))); + EXPECT_EQ(std::string(gateway), std::string(iface->get_gateway())); +} + +TEST_F(TestPPPInterface, get_connection_status) +{ + EXPECT_EQ(NSAPI_STATUS_DISCONNECTED, iface->get_connection_status()); + + doConnect(); + + EXPECT_CALL(*netStackIface, get_connection_status()) + .Times(1) + .WillOnce(Return(NSAPI_STATUS_LOCAL_UP)); + EXPECT_EQ(NSAPI_STATUS_LOCAL_UP, iface->get_connection_status()); +} + +TEST_F(TestPPPInterface, get_interface_name) +{ + char name[100]; + memset(name, '\0', 100); + EXPECT_EQ(NULL, iface->get_interface_name(name)); + + doConnect(); + + EXPECT_EQ(NULL, iface->get_interface_name(name)); + + EXPECT_CALL(*netStackIface, get_interface_name(name)) + .Times(1) + .WillOnce(Return(name)); + EXPECT_EQ(name, iface->get_interface_name(name)); +} + +TEST_F(TestPPPInterface, set_as_default) +{ + doConnect(); + + EXPECT_CALL(*stackMock, set_default_interface(netStackIface)) + .Times(1); + iface->set_as_default(); +} + +TEST_F(TestPPPInterface, attach) +{ + doConnect(); + EXPECT_CALL(*netStackIface, attach(_)) // TODO: check that the correct function is passed. + .Times(1); + iface->attach(cb); +} + +TEST_F(TestPPPInterface, set_dhcp) +{ + EXPECT_EQ(NSAPI_ERROR_UNSUPPORTED, iface->set_dhcp(false)); + doConnect(true); +} + +TEST_F(TestPPPInterface, set_blocking) +{ + EXPECT_EQ(NSAPI_ERROR_OK, iface->set_blocking(false)); + doConnect(false); +} diff --git a/UNITTESTS/features/netsocket/PPPInterface/unittest.cmake b/UNITTESTS/features/netsocket/PPPInterface/unittest.cmake new file mode 100644 index 0000000000..2fd80777d6 --- /dev/null +++ b/UNITTESTS/features/netsocket/PPPInterface/unittest.cmake @@ -0,0 +1,41 @@ + +#################### +# UNIT TESTS +#################### + +# Unit test suite name +set(TEST_SUITE_NAME "features_netsocket_PPPInterface") + +# Source files +set(unittest-sources + ../features/netsocket/SocketAddress.cpp + ../features/netsocket/PPPInterface.cpp + ../features/netsocket/EMACInterface.cpp + ../features/netsocket/NetworkInterface.cpp + ../features/netsocket/NetworkStack.cpp + ../features/frameworks/nanostack-libservice/source/libip4string/ip4tos.c + ../features/frameworks/nanostack-libservice/source/libip6string/ip6tos.c + ../features/frameworks/nanostack-libservice/source/libip4string/stoip4.c + ../features/frameworks/nanostack-libservice/source/libip6string/stoip6.c + ../features/frameworks/nanostack-libservice/source/libBits/common_functions.c + ../features/frameworks/nanostack-libservice/source/libList/ns_list.c +) + +# Test files +set(unittest-test-sources + features/netsocket/PPPInterface/test_PPPInterface.cpp + stubs/Mutex_stub.cpp + stubs/mbed_assert_stub.c + stubs/equeue_stub.c + stubs/EventQueue_stub.cpp + stubs/FileHandle_stub.cpp + stubs/mbed_shared_queues_stub.cpp + stubs/nsapi_dns_stub.cpp + stubs/EventFlags_stub.cpp + stubs/stoip4_stub.c + stubs/ip4tos_stub.c + stubs/NetworkStack_stub.cpp + stubs/NetworkInterfaceDefaults_stub.cpp + stubs/SocketStats_Stub.cpp + stubs/mbed_error.c +) diff --git a/UNITTESTS/features/netsocket/TCPSocket/test_TCPSocket.cpp b/UNITTESTS/features/netsocket/TCPSocket/test_TCPSocket.cpp index 5a2da649ab..a49c7809fa 100644 --- a/UNITTESTS/features/netsocket/TCPSocket/test_TCPSocket.cpp +++ b/UNITTESTS/features/netsocket/TCPSocket/test_TCPSocket.cpp @@ -110,10 +110,11 @@ TEST_F(TestTCPSocket, connect_with_timeout) TEST_F(TestTCPSocket, connect_error_is_connected) { socket->open((NetworkStack *)&stack); - stack.return_values.push_back(NSAPI_ERROR_ALREADY); stack.return_values.push_back(NSAPI_ERROR_IS_CONNECTED); + stack.return_values.push_back(NSAPI_ERROR_ALREADY); const SocketAddress a("127.0.0.1", 1024); socket->set_timeout(1); + EXPECT_EQ(socket->connect(a), NSAPI_ERROR_IS_CONNECTED); EXPECT_EQ(socket->connect(a), NSAPI_ERROR_OK); } @@ -278,3 +279,9 @@ TEST_F(TestTCPSocket, accept_would_block) EXPECT_EQ(socket->accept(&error), static_cast(NULL)); EXPECT_EQ(error, NSAPI_ERROR_WOULD_BLOCK); } + +TEST_F(TestTCPSocket, unsupported_api) +{ + SocketAddress addr; + EXPECT_EQ(socket->join_multicast_group(addr), NSAPI_ERROR_UNSUPPORTED); +} diff --git a/UNITTESTS/features/netsocket/TLSSocketWrapper/test_TLSSocketWrapper.cpp b/UNITTESTS/features/netsocket/TLSSocketWrapper/test_TLSSocketWrapper.cpp index 1de1e86bac..740d6eba9a 100644 --- a/UNITTESTS/features/netsocket/TLSSocketWrapper/test_TLSSocketWrapper.cpp +++ b/UNITTESTS/features/netsocket/TLSSocketWrapper/test_TLSSocketWrapper.cpp @@ -213,6 +213,11 @@ TEST_F(TestTLSSocketWrapper, connect_handshake_fail_ssl_handshake_in_progress) mbedtls_stub.retArray[3] = MBEDTLS_ERR_SSL_WANT_READ; // mbedtls_ssl_handshake error eventFlagsStubNextRetval.push_back(osFlagsError); // Break the wait loop EXPECT_EQ(wrapper->send(dataBuf, dataSize), NSAPI_ERROR_WOULD_BLOCK); + + // Check that recv will fail in this situation. + mbedtls_stub.retArray[4] = MBEDTLS_ERR_SSL_WANT_READ; // mbedtls_ssl_handshake error + eventFlagsStubNextRetval.push_back(osFlagsError); // Break the wait loop + EXPECT_EQ(wrapper->recv(dataBuf, dataSize), NSAPI_ERROR_WOULD_BLOCK); } TEST_F(TestTLSSocketWrapper, connect_handshake_fail_ssl_get_verify_result) @@ -296,7 +301,7 @@ TEST_F(TestTLSSocketWrapper, recv_all_data) { transport->open((NetworkStack *)&stack); mbedtls_stub.useCounter = true; - mbedtls_stub.retArray[3] = dataSize; // mbedtls_ssl_write + mbedtls_stub.retArray[3] = dataSize; // mbedtls_ssl_read const SocketAddress a("127.0.0.1", 1024); EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK); EXPECT_EQ(wrapper->recv(dataBuf, dataSize), dataSize); @@ -307,7 +312,7 @@ TEST_F(TestTLSSocketWrapper, recv_less_than_expected) transport->open((NetworkStack *)&stack); unsigned int lessThanDataSize = dataSize - 1; mbedtls_stub.useCounter = true; - mbedtls_stub.retArray[3] = lessThanDataSize; // mbedtls_ssl_write + mbedtls_stub.retArray[3] = lessThanDataSize; // mbedtls_ssl_read const SocketAddress a("127.0.0.1", 1024); EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK); EXPECT_EQ(wrapper->recv(dataBuf, dataSize), lessThanDataSize); @@ -317,7 +322,7 @@ TEST_F(TestTLSSocketWrapper, recv_would_block) { transport->open((NetworkStack *)&stack); mbedtls_stub.useCounter = true; - mbedtls_stub.retArray[3] = MBEDTLS_ERR_SSL_WANT_WRITE; // mbedtls_ssl_write + mbedtls_stub.retArray[3] = MBEDTLS_ERR_SSL_WANT_WRITE; // mbedtls_ssl_read const SocketAddress a("127.0.0.1", 1024); EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK); eventFlagsStubNextRetval.push_back(osFlagsError); // Break the wait loop @@ -328,13 +333,24 @@ TEST_F(TestTLSSocketWrapper, recv_device_error) { transport->open((NetworkStack *)&stack); mbedtls_stub.useCounter = true; - mbedtls_stub.retArray[3] = MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE; // mbedtls_ssl_write + mbedtls_stub.retArray[3] = MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE; // mbedtls_ssl_read const SocketAddress a("127.0.0.1", 1024); EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK); eventFlagsStubNextRetval.push_back(osFlagsError); // Break the wait loop EXPECT_EQ(wrapper->recv(dataBuf, dataSize), NSAPI_ERROR_DEVICE_ERROR); } +TEST_F(TestTLSSocketWrapper, recv_peer_clode_notify) +{ + transport->open((NetworkStack *)&stack); + mbedtls_stub.useCounter = true; + mbedtls_stub.retArray[3] = MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY; // mbedtls_ssl_read + const SocketAddress a("127.0.0.1", 1024); + EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK); + eventFlagsStubNextRetval.push_back(osFlagsError); // Break the wait loop + EXPECT_EQ(wrapper->recv(dataBuf, dataSize), 0); +} + TEST_F(TestTLSSocketWrapper, recv_from_no_socket) { SocketAddress a("127.0.0.1", 1024); diff --git a/UNITTESTS/features/netsocket/WiFiAccessPoint/test_WiFiAccessPoint.cpp b/UNITTESTS/features/netsocket/WiFiAccessPoint/test_WiFiAccessPoint.cpp index 959332832c..b20ae83776 100644 --- a/UNITTESTS/features/netsocket/WiFiAccessPoint/test_WiFiAccessPoint.cpp +++ b/UNITTESTS/features/netsocket/WiFiAccessPoint/test_WiFiAccessPoint.cpp @@ -17,6 +17,7 @@ #include "gtest/gtest.h" #include "features/netsocket/WiFiAccessPoint.h" +#include "features/netsocket/NetworkInterface.h" #include class TestWiFiAccessPoint : public testing::Test { diff --git a/UNITTESTS/stubs/OnboardNetworkStack_mock.h b/UNITTESTS/stubs/OnboardNetworkStack_mock.h index 02a91c5f3c..e85d731d92 100644 --- a/UNITTESTS/stubs/OnboardNetworkStack_mock.h +++ b/UNITTESTS/stubs/OnboardNetworkStack_mock.h @@ -47,6 +47,8 @@ public: MOCK_METHOD5(getsockopt, nsapi_error_t(nsapi_socket_t handle, int level, int optname, const void *optval, unsigned *optlen)); MOCK_METHOD3(socket_attach, void(nsapi_socket_t handle, void (*callback)(void *), void *data)); MOCK_METHOD3(add_ethernet_interface, nsapi_error_t(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out)); + MOCK_METHOD3(add_ppp_interface, nsapi_error_t(PPP &ppp, bool default_if, OnboardNetworkStack::Interface **interface_out)); + MOCK_METHOD1(set_default_interface, void (OnboardNetworkStack::Interface *interface)); static OnboardNetworkStackMock &get_instance() { @@ -70,11 +72,15 @@ public: MOCK_METHOD0(bringdown, nsapi_error_t()); MOCK_METHOD1(attach, void(mbed::Callback status_cb)); MOCK_CONST_METHOD0(get_connection_status, nsapi_connection_status_t()); + MOCK_METHOD1(get_interface_name, char *(char *buf)); MOCK_METHOD2(get_mac_address, char *(char *buf, nsapi_size_t buflen)); MOCK_METHOD2(get_ip_address, char *(char *buf, nsapi_size_t buflen)); + MOCK_METHOD1(get_ip_address, nsapi_error_t (SocketAddress *address)); MOCK_METHOD1(get_ipv6_link_local_address, nsapi_error_t(SocketAddress *address)); MOCK_METHOD2(get_netmask, char *(char *buf, nsapi_size_t buflen)); + MOCK_METHOD1(get_netmask, nsapi_error_t (SocketAddress *address)); MOCK_METHOD2(get_gateway, char *(char *buf, nsapi_size_t buflen)); + MOCK_METHOD1(get_gateway, nsapi_error_t (SocketAddress *address)); }; }; diff --git a/features/netsocket/EMACInterface.h b/features/netsocket/EMACInterface.h index 1e493ea3a4..bdcaadc965 100644 --- a/features/netsocket/EMACInterface.h +++ b/features/netsocket/EMACInterface.h @@ -74,96 +74,54 @@ public: * Requires that the network is disconnected * * @param dhcp False to disable dhcp (defaults to enabled) - * @return 0 on success, negative error code on failure + * @retval NSAPI_ERROR_OK on success. + * @retval NSAPI_ERROR_UNSUPPORTED if operation is not supported. */ virtual nsapi_error_t set_dhcp(bool dhcp); - /** Start the interface - * @return 0 on success, negative on failure - */ + /** @copydoc NetworkInterface::connect */ virtual nsapi_error_t connect(); - /** Stop the interface - * @return 0 on success, negative on failure - */ + /** @copydoc NetworkInterface::disconnect */ virtual nsapi_error_t disconnect(); - /** Get the local MAC address - * - * Provided MAC address is intended for info or debug purposes and - * may not be provided if the underlying network interface does not - * provide a MAC address - * - * @return Null-terminated representation of the local MAC address - * or null if no MAC address is available - */ + /** @copydoc NetworkInterface::get_mac_address */ virtual const char *get_mac_address(); - /** Get the local IP address - * - * @return Null-terminated representation of the local IP address - * or null if no IP address has been received - */ + /** @copydoc NetworkInterface::get_ip_address */ virtual nsapi_error_t get_ip_address(SocketAddress *address); MBED_DEPRECATED_SINCE("mbed-os-5.15", "String-based APIs are deprecated") virtual const char *get_ip_address(); - /** Get the IPv6 link local address - * - * @address SocketAddress representation of the link local IPv6 address - * @return 0 on success, negative error code on failure - */ + /** @copydoc NetworkInterface::get_ipv6_link_local_address */ virtual nsapi_error_t get_ipv6_link_local_address(SocketAddress *address); - /** Get the local network mask - * - * @return Null-terminated representation of the local network mask - * or null if no network mask has been received - */ + /** @copydoc NetworkInterface::get_netmask */ virtual nsapi_error_t get_netmask(SocketAddress *address); MBED_DEPRECATED_SINCE("mbed-os-5.15", "String-based APIs are deprecated") virtual const char *get_netmask(); - /** Get the local gateways - * - * @return Null-terminated representation of the local gateway - * or null if no network mask has been received - */ + /** @copydoc NetworkInterface::get_gateway */ virtual nsapi_error_t get_gateway(SocketAddress *address); MBED_DEPRECATED_SINCE("mbed-os-5.15", "String-based APIs are deprecated") virtual const char *get_gateway(); - /** Get the network interface name - * - * @return Null-terminated representation of the network interface name - * or null if interface not exists - */ + /** @copydoc NetworkInterface::get_interface_name */ virtual char *get_interface_name(char *interface_name); - /** Set the network interface as default one - */ + /** @copydoc NetworkInterface::set_as_default */ virtual void set_as_default(); - /** Register callback for status reporting - * - * @param status_cb The callback for status changes - */ + /** @copydoc NetworkInterface::attach */ virtual void attach(mbed::Callback status_cb); - /** Get the connection status - * - * @return The connection status according to nsapi_connection_status_t - */ + /** @copydoc NetworkInterface::get_connection_status */ virtual nsapi_connection_status_t get_connection_status() const; - /** Set blocking status of connect() which by default should be blocking - * - * @param blocking true if connect is blocking - * @return 0 on success, negative error code on failure - */ + /** @copydoc NetworkInterface::set_blocking */ virtual nsapi_error_t set_blocking(bool blocking); /** Provide access to the EMAC diff --git a/features/netsocket/InternetDatagramSocket.h b/features/netsocket/InternetDatagramSocket.h index 060521f98f..cc9e40197f 100644 --- a/features/netsocket/InternetDatagramSocket.h +++ b/features/netsocket/InternetDatagramSocket.h @@ -42,6 +42,7 @@ public: * @param size Size of the buffer in bytes. * @retval int Number of sent bytes on success. * @retval NSAPI_ERROR_NO_SOCKET in case socket was not created correctly. + * @retval NSAPI_ERROR_DNS_FAILURE if the DNS address of host could not be resolved * @retval NSAPI_ERROR_WOULD_BLOCK in case non-blocking mode is enabled * and send cannot be performed immediately. * @retval int Other negative error codes for stack-related failures. @@ -60,8 +61,6 @@ public: * @param address The SocketAddress of the remote host. * @param data Buffer of data to send to the host. * @param size Size of the buffer in bytes. - * @retval NSAPI_ERROR_DNS_FAILURE in case the address parameter cannot - * be resolved. * @retval NSAPI_ERROR_NO_SOCKET in case socket was not created correctly. * @retval NSAPI_ERROR_WOULD_BLOCK in case non-blocking mode is enabled * and send cannot be performed immediately. @@ -120,6 +119,7 @@ public: * @retval NSAPI_ERROR_NO_SOCKET in case socket was not created correctly. * @retval NSAPI_ERROR_WOULD_BLOCK in case non-blocking mode is enabled * and send cannot be performed immediately. + * #retval NSAPI_ERROR_NO_ADDRESS if the address was not set with connect(). * @retval int Other negative error codes for stack-related failures. * See \ref NetworkStack::socket_send. */ diff --git a/features/netsocket/NetworkInterface.h b/features/netsocket/NetworkInterface.h index a03909d795..6c1f605335 100644 --- a/features/netsocket/NetworkInterface.h +++ b/features/netsocket/NetworkInterface.h @@ -162,7 +162,8 @@ public: * @param ip_address SocketAddress object containing the local IP address * @param netmask SocketAddress object containing the local network mask * @param gateway SocketAddress object containing the local gateway - * @return NSAPI_ERROR_OK on success, negative error code on failure + * @retval NSAPI_ERROR_OK on success + * @retval NSAPI_ERROR_UNSUPPORTED if this function is unsupported */ virtual nsapi_error_t set_network(const SocketAddress &ip_address, const SocketAddress &netmask, const SocketAddress &gateway); @@ -175,7 +176,8 @@ public: * that the network is disconnected. * * @param dhcp True to enable DHCP. - * @return NSAPI_ERROR_OK on success, negative error code on failure. + * @retval NSAPI_ERROR_OK on success. + * @retval NSAPI_ERROR_UNSUPPORTED if operation is not supported. */ virtual nsapi_error_t set_dhcp(bool dhcp); @@ -228,7 +230,9 @@ public: * @param version IP version of address to resolve, NSAPI_UNSPEC indicates * version is chosen by the stack (defaults to NSAPI_UNSPEC). * @param interface_name Network interface name - * @return NSAPI_ERROR_OK on success, negative error code on failure. + * @retval NSAPI_ERROR_OK on success + * @retval int Negative error code on failure. + * See @ref NetworkStack::gethostbyname */ virtual nsapi_error_t gethostbyname(const char *host, SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC, const char *interface_name = NULL); diff --git a/features/netsocket/NetworkStack.h b/features/netsocket/NetworkStack.h index 4fbd23b341..3b0f30867f 100644 --- a/features/netsocket/NetworkStack.h +++ b/features/netsocket/NetworkStack.h @@ -90,7 +90,10 @@ public: * @param version IP version of address to resolve, NSAPI_UNSPEC indicates * version is chosen by the stack (defaults to NSAPI_UNSPEC) * @param interface_name Network interface_name - * @return NSAPI_ERROR_OK on success, negative error code on failure + * @retval NSAPI_ERROR_OK on success + * @retval NSAPI_ERROR_PARAMETER if invalid (null) name is provided + * @retval NSAPI_ERROR_DNS_FAILURE if DNS resolution fails + * @retval int other negative errors, see @ref nsapi_dns_query */ virtual nsapi_error_t gethostbyname(const char *host, SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC, const char *interface_name = NULL); diff --git a/features/netsocket/PPPInterface.h b/features/netsocket/PPPInterface.h index dd5dde3747..a98c409d93 100644 --- a/features/netsocket/PPPInterface.h +++ b/features/netsocket/PPPInterface.h @@ -50,34 +50,16 @@ public: OnboardNetworkStack &stack = OnboardNetworkStack::get_default_instance()); virtual ~PPPInterface(); - /** Set a static IP address - * - * Configures this network interface to use a static IP address. - * Implicitly disables DHCP, which can be enabled in set_dhcp. - * Requires that the network is disconnected. - * - * @param ip_address Null-terminated representation of the local IP address - * @param netmask Null-terminated representation of the local network mask - * @param gateway Null-terminated representation of the local gateway - * @return 0 on success, negative error code on failure - */ + /** @copydoc NetworkInterface::set_network */ virtual nsapi_error_t set_network(const char *ip_address, const char *netmask, const char *gateway); - /** Start the interface - * @return 0 on success, negative on failure - */ + /** @copydoc NetworkInterface::connect */ virtual nsapi_error_t connect(); - /** Stop the interface - * @return 0 on success, negative on failure - */ + /** @copydoc NetworkInterface::disconnect */ virtual nsapi_error_t disconnect(); - /** Get the local IP address - * - * @return Null-terminated representation of the local IP address - * or null if no IP address has been received - */ + /** @copydoc NetworkInterface::get_ip_address */ virtual const char *get_ip_address(); /** @copydoc NetworkInterface::get_ip_address */ @@ -89,48 +71,25 @@ public: /** @copydoc NetworkInterface::get_gateway */ virtual nsapi_error_t get_gateway(SocketAddress *address); - /** Get the local network mask - * - * @return Null-terminated representation of the local network mask - * or null if no network mask has been received - */ + /** @copydoc NetworkInterface::get_netmask */ virtual const char *get_netmask(); - /** Get the local gateways - * - * @return Null-terminated representation of the local gateway - * or null if no network mask has been received - */ + /** @copydoc NetworkInterface::get_gateway */ virtual const char *get_gateway(); - /** Get the network interface name - * - * @return Null-terminated representation of the network interface name - * or null if interface not exists - */ + /** @copydoc NetworkInterface::get_interface_name */ virtual char *get_interface_name(char *interface_name); - /** Set the network interface as default one - */ + /** @copydoc NetworkInterface::set_as_default */ virtual void set_as_default(); - /** Register callback for status reporting - * - * @param status_cb The callback for status changes - */ + /** @copydoc NetworkInterface::attach */ virtual void attach(mbed::Callback status_cb); - /** Get the connection status - * - * @return The connection status according to nsapi_connection_status_t - */ + /** @copydoc NetworkInterface::get_connection_status */ virtual nsapi_connection_status_t get_connection_status() const; - /** Set blocking status of connect() which by default should be blocking - * - * @param blocking true if connect is blocking - * @return 0 on success, negative error code on failure - */ + /** @copydoc NetworkInterface::set_blocking */ virtual nsapi_error_t set_blocking(bool blocking); /** Sets file stream used to communicate with modem diff --git a/features/netsocket/SocketAddress.h b/features/netsocket/SocketAddress.h index e0b2e1f6bb..5310ba4d64 100644 --- a/features/netsocket/SocketAddress.h +++ b/features/netsocket/SocketAddress.h @@ -160,6 +160,8 @@ public: /** Copy address from another SocketAddress * * @param addr SocketAddress to copy + * + * @retval SocketAddress reference to this address */ SocketAddress &operator=(const SocketAddress &addr); diff --git a/features/netsocket/TCPSocket.h b/features/netsocket/TCPSocket.h index 0da69761ab..113581190c 100644 --- a/features/netsocket/TCPSocket.h +++ b/features/netsocket/TCPSocket.h @@ -197,7 +197,10 @@ public: * By default, accept blocks until incoming connection occurs. If socket is set to * non-blocking or times out, error is set to NSAPI_ERROR_WOULD_BLOCK. * - * @param error pointer to storage of the error value or NULL + * @param error pointer to storage of the error value or NULL: + * NSAPI_ERROR_OK on success + * NSAPI_ERROR_WOULD_BLOCK if socket is set to non-blocking and would block + * NSAPI_ERROR_NO_SOCKET if the socket was not open * @return pointer to a socket */ virtual TCPSocket *accept(nsapi_error_t *error = NULL); diff --git a/features/netsocket/TLSSocketWrapper.h b/features/netsocket/TLSSocketWrapper.h index 2a3e03e567..bc4cf9ddf9 100644 --- a/features/netsocket/TLSSocketWrapper.h +++ b/features/netsocket/TLSSocketWrapper.h @@ -92,6 +92,9 @@ public: * @note Must be called before calling connect() * * @param root_ca_pem Root CA Certificate in PEM format. + * @retval NSAPI_ERROR_OK on success. + * @retval NSAPI_ERROR_NO_MEMORY in case there is not enough memory to allocate certificate. + * @retval NSAPI_ERROR_PARAMETER in case the provided root_ca parameter failed parsing. */ nsapi_error_t set_root_ca_cert(const char *root_ca_pem); diff --git a/features/netsocket/nsapi_dns.h b/features/netsocket/nsapi_dns.h index 1870c82f8c..5e4f003708 100644 --- a/features/netsocket/nsapi_dns.h +++ b/features/netsocket/nsapi_dns.h @@ -85,8 +85,7 @@ nsapi_error_t nsapi_dns_query(NetworkStack *stack, const char *host, * @param addr Destination for the host address * @param interface_name Network interface name * @param version IP version to resolve (defaults to NSAPI_IPv4) - * @return 0 on success, negative error code on failure - * NSAPI_ERROR_DNS_FAILURE indicates the host could not be found + * @return See @ref nsapi_dns_query_multiple */ nsapi_error_t nsapi_dns_query(NetworkStack *stack, const char *host, SocketAddress *addr, const char *interface_name, nsapi_version_t version = NSAPI_IPv4); @@ -156,8 +155,12 @@ nsapi_error_t nsapi_dns_query(S *stack, const char *host, * @param addr Array for the host addresses * @param addr_count Number of addresses allocated in the array * @param version IP version to resolve (defaults to NSAPI_IPv4) - * @return Number of addresses found on success, negative error code on failure - * NSAPI_ERROR_DNS_FAILURE indicates the host could not be found + * @return Positive number of addresses found on success + * @retval NSAPI_ERROR_PARAMETER if provided parameters are invalid + * @retval NSAPI_ERROR_NO_MEMORY if allocation fails due to lack of memory + * @retval NSAPI_ERROR_DNS_FAILURE if DNS resolution fails + * @retval NSAPI_ERROR_WOULD_BLOCK in case non-blocking mode is enabled and + * DNS cannot be resolved immediately. */ nsapi_size_or_error_t nsapi_dns_query_multiple(NetworkStack *stack, const char *host, SocketAddress *addr, nsapi_size_t addr_count, const char *interface_name, nsapi_version_t version = NSAPI_IPv4);