From fd46af67c6f9b8b59011ddd5b87279e8d434ac8a Mon Sep 17 00:00:00 2001 From: Michal Paszta Date: Thu, 31 Oct 2019 09:31:52 +0200 Subject: [PATCH] Modify nsapi_dns tests to be module tests The nsapi_dns tests were cross-class tests anyway, going through nsapi_dns and UDPSocket. Now they also include EthernetInterface and only mock the NetworkStack, which makes them the most cross-class module test we could think of in netsocket module. --- .../IfaceDnsSocket/test_IfaceDnsSocket.cpp} | 357 +++++++----------- .../netsocket/IfaceDnsSocket/unittest.cmake | 47 +++ .../test_EthernetInterface.cpp | 38 +- .../netsocket/nsapi_dns/unittest.cmake | 46 --- UNITTESTS/stubs/CellularInterface_stub.cpp | 24 ++ UNITTESTS/stubs/EMAC_mock.h | 55 +++ UNITTESTS/stubs/MeshInterface_stub.cpp | 24 ++ UNITTESTS/stubs/OnboardNetworkStack_mock.h | 10 +- features/netsocket/EMACInterface.h | 1 + 9 files changed, 304 insertions(+), 298 deletions(-) rename UNITTESTS/{features/netsocket/nsapi_dns/test_nsapi_dns.cpp => MODULETESTS/features/netsocket/IfaceDnsSocket/test_IfaceDnsSocket.cpp} (50%) create mode 100644 UNITTESTS/MODULETESTS/features/netsocket/IfaceDnsSocket/unittest.cmake delete mode 100644 UNITTESTS/features/netsocket/nsapi_dns/unittest.cmake create mode 100644 UNITTESTS/stubs/CellularInterface_stub.cpp create mode 100644 UNITTESTS/stubs/EMAC_mock.h create mode 100644 UNITTESTS/stubs/MeshInterface_stub.cpp diff --git a/UNITTESTS/features/netsocket/nsapi_dns/test_nsapi_dns.cpp b/UNITTESTS/MODULETESTS/features/netsocket/IfaceDnsSocket/test_IfaceDnsSocket.cpp similarity index 50% rename from UNITTESTS/features/netsocket/nsapi_dns/test_nsapi_dns.cpp rename to UNITTESTS/MODULETESTS/features/netsocket/IfaceDnsSocket/test_IfaceDnsSocket.cpp index d0256c05f1..1280732e3c 100644 --- a/UNITTESTS/features/netsocket/nsapi_dns/test_nsapi_dns.cpp +++ b/UNITTESTS/MODULETESTS/features/netsocket/IfaceDnsSocket/test_IfaceDnsSocket.cpp @@ -18,10 +18,10 @@ #include "gtest/gtest.h" #include "gmock/gmock.h" #include "nsapi_dns.h" -#include "NetworkInterface.h" +#include "features/netsocket/EthernetInterface.h" #include "SocketAddress.h" -#include "EMAC.h" -#include "OnboardNetworkStack.h" +#include "EMAC_mock.h" +#include "OnboardNetworkStack_mock.h" #include "EventQueue.h" #include #include @@ -31,121 +31,6 @@ // Control the rtos EventFlags stub. See EventFlags_stub.cpp extern std::list eventFlagsStubNextRetval; -// This has been copied from test_EthernetInterface -// with one modification: we don't need to mock add_ethernet_interface -class NetworkStackMock : public OnboardNetworkStack { -public: - MOCK_METHOD3(gethostbyname, nsapi_error_t(const char *host, SocketAddress *address, nsapi_version_t version)); - MOCK_METHOD1(add_dns_server, nsapi_error_t(const SocketAddress &address)); - MOCK_METHOD3(get_dns_server, nsapi_error_t(int index, SocketAddress *address, const char *interface_name)); - MOCK_METHOD2(call_in, nsapi_error_t(int delay, mbed::Callback func)); - MOCK_METHOD2(socket_open, nsapi_error_t(nsapi_socket_t *handle, nsapi_protocol_t proto)); - // No need to mock socket_close really. - nsapi_error_t socket_close(nsapi_socket_t handle) - { - return 0; - }; - MOCK_METHOD2(socket_bind, nsapi_error_t(nsapi_socket_t handle, const SocketAddress &address)); - MOCK_METHOD2(socket_listen, nsapi_error_t(nsapi_socket_t handle, int backlog)); - MOCK_METHOD2(socket_connect, nsapi_error_t(nsapi_socket_t handle, const SocketAddress &address)); - MOCK_METHOD3(socket_accept, nsapi_error_t(nsapi_socket_t server, nsapi_socket_t *handle, SocketAddress *address)); - MOCK_METHOD3(socket_send, nsapi_error_t(nsapi_socket_t handle, const void *data, nsapi_size_t size)); - MOCK_METHOD3(socket_recv, nsapi_error_t(nsapi_socket_t handle, void *data, nsapi_size_t size)); - MOCK_METHOD4(socket_sendto, nsapi_error_t(nsapi_socket_t handle, const SocketAddress &address, const void *data, nsapi_size_t size)); - MOCK_METHOD4(socket_recvfrom, nsapi_error_t(nsapi_socket_t handle, SocketAddress *address, void *data, nsapi_size_t size)); - MOCK_METHOD5(setsockopt, nsapi_error_t(nsapi_socket_t handle, int level, int optname, const void *optval, unsigned optlen)); - MOCK_METHOD5(getsockopt, nsapi_error_t(nsapi_socket_t handle, int level, int optname, const void *optval, unsigned *optlen)); - void *socket_cb; - // No need to mock socket_attach really. - void socket_attach(nsapi_socket_t handle, void (*callback)(void *), void *data) - { - socket_cb = data; - }; - nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out) - { - return NSAPI_ERROR_OK; - } - - static NetworkStackMock &get_instance() - { - static NetworkStackMock stackMock1; - return stackMock1; - } - - class InterfaceMock : public OnboardNetworkStack::Interface { - public: - - static InterfaceMock &get_instance() - { - static InterfaceMock test_interface; - return test_interface; - } - MOCK_METHOD6(bringup, nsapi_error_t(bool dhcp, const char *ip, - const char *netmask, const char *gw, - nsapi_ip_stack_t stack, - bool blocking - )); - 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_METHOD2(get_mac_address, char *(char *buf, nsapi_size_t buflen)); - MOCK_METHOD1(get_ip_address, nsapi_error_t(SocketAddress *address)); - MOCK_METHOD2(get_ip_address, char *(char *buf, nsapi_size_t buflen)); - MOCK_METHOD1(get_netmask, nsapi_error_t(SocketAddress *address)); - MOCK_METHOD2(get_netmask, char *(char *buf, nsapi_size_t buflen)); - MOCK_METHOD1(get_gateway, nsapi_error_t(SocketAddress *address)); - MOCK_METHOD2(get_gateway, char *(char *buf, nsapi_size_t buflen)); - }; -}; - -class NetworkInterfaceMock: public NetworkInterface { -public: - virtual ~NetworkInterfaceMock() {}; - MOCK_METHOD0(set_as_default, void()); - MOCK_METHOD0(get_mac_address, const char *()); - MOCK_METHOD0(get_ip_address, const char *()); - MOCK_METHOD0(get_netmask, const char *()); - MOCK_METHOD0(get_gateway, const char *()); - MOCK_METHOD1(get_interface_name, char *(char *interface_name)); - MOCK_METHOD3(set_network, nsapi_error_t(const char *ip_address, const char *netmask, const char *gateway)); - MOCK_METHOD1(set_dhcp, nsapi_error_t(bool dhcp)); - MOCK_METHOD0(connect, nsapi_error_t()); - MOCK_METHOD0(disconnect, nsapi_error_t()); - MOCK_METHOD4(gethostbyname, nsapi_error_t(const char *host, SocketAddress *address, nsapi_version_t version, const char *interface_name)); - typedef mbed::Callback hostbyname_cb_t; - MOCK_METHOD4(gethostbyname_async, nsapi_value_or_error_t(const char *host, hostbyname_cb_t callback, nsapi_version_t version, const char *interface_name)); - MOCK_METHOD1(gethostbyname_async_cancel, nsapi_error_t(int id)); - MOCK_METHOD2(add_dns_server, nsapi_error_t(const SocketAddress &address, const char *interface_name)); - MOCK_METHOD1(attach, void(mbed::Callback status_cb)); - MOCK_METHOD1(add_event_listener, void(mbed::Callback status_cb)); - MOCK_METHOD1(remove_event_listener, void(mbed::Callback status_cb)); - MOCK_METHOD0(get_connection_status, nsapi_connection_status_t()); - MOCK_METHOD1(set_blocking, nsapi_error_t(bool blocking)); - MOCK_METHOD0(ethInterface, EthInterface * ()); - MOCK_METHOD0(wifiInterface, WiFiInterface * ()); - MOCK_METHOD0(meshInterface, MeshInterface * ()); - MOCK_METHOD0(emacInterface, EMACInterface * ()); - - static NetworkInterfaceMock &get_default_instance() - { - static NetworkInterfaceMock stackMock1; - return stackMock1; - } - - static NetworkInterfaceMock &get_target_default_instance() - { - static NetworkInterfaceMock stackMock1; - return stackMock1; - } - -public: - NetworkStack *get_stack() - { - return &NetworkStackMock::get_instance(); - } - MOCK_METHOD0(set_default_parameters, void()); -}; - using ::testing::_; using ::testing::Return; using ::testing::ReturnArg; @@ -156,7 +41,19 @@ using ::testing::SetArgPointee; using ::testing::SetArgReferee; using ::testing::DoAll; -class Test_nsapi_dns : public testing::Test { +// This is the bottom layer, that goes outside of module's scope. +// This would be implemented by LWIPInterface, NanostackInterface, or board-specific stack. +OnboardNetworkStack &OnboardNetworkStack::get_default_instance() +{ + return OnboardNetworkStackMock::get_instance(); +} + +// Wrapper to avoid calling OnboardNetworkStack::get_default_instance() everywhere +static OnboardNetworkStackMock &stackMock() { + return OnboardNetworkStackMock::get_instance(); +} + +class Test_IfaceDnsSocket : public testing::Test { public: static nsapi_error_t call_in(int delay, mbed::Callback func) { @@ -165,11 +62,11 @@ public: return NSAPI_ERROR_OK; } protected: - NetworkInterfaceMock *iface; + EthernetInterface *iface; virtual void SetUp() { - iface = &NetworkInterfaceMock::get_default_instance(); + iface = new EthernetInterface(MockEMAC::get_instance(), OnboardNetworkStackMock::get_instance());; nsapi_dns_reset(); eventQueue.clear(); hostname_cb_result = NSAPI_ERROR_DEVICE_ERROR; @@ -178,6 +75,7 @@ protected: virtual void TearDown() { + delete iface; } @@ -216,13 +114,13 @@ protected: static const unsigned char packet_ip4_3addresses[packet_ip4_3addresses_size]; }; -std::list> Test_nsapi_dns::eventQueue; -nsapi_error_t Test_nsapi_dns::hostname_cb_result = NSAPI_ERROR_DEVICE_ERROR; -SocketAddress *Test_nsapi_dns::hostname_cb_address = NULL; -int Test_nsapi_dns::query_id = 1; // Default after nsapi_dns_reset() +std::list> Test_IfaceDnsSocket::eventQueue; +nsapi_error_t Test_IfaceDnsSocket::hostname_cb_result = NSAPI_ERROR_DEVICE_ERROR; +SocketAddress *Test_IfaceDnsSocket::hostname_cb_address = NULL; +int Test_IfaceDnsSocket::query_id = 1; // Default after nsapi_dns_reset() // An actual google.com DNS resolution packet captured using a greentea test. -const unsigned char Test_nsapi_dns::packet_ip4[Test_nsapi_dns::packet_ip4_size] = { +const unsigned char Test_IfaceDnsSocket::packet_ip4[Test_IfaceDnsSocket::packet_ip4_size] = { 0x00, 0x01, // ID 0x81, 0x80, // Flags 0x00, 0x01, // qdcount @@ -248,7 +146,7 @@ const unsigned char Test_nsapi_dns::packet_ip4[Test_nsapi_dns::packet_ip4_size] }; // Same as previous packet, but with a fake IPv6 address instead of the IPv4 one -const unsigned char Test_nsapi_dns::packet_ip6[Test_nsapi_dns::packet_ip6_size] = { +const unsigned char Test_IfaceDnsSocket::packet_ip6[Test_IfaceDnsSocket::packet_ip6_size] = { 0x00, 0x01, // ID 0x81, 0x80, // Flags 0x00, 0x01, // qdcount @@ -275,7 +173,7 @@ const unsigned char Test_nsapi_dns::packet_ip6[Test_nsapi_dns::packet_ip6_size] }; // Same as packet_ipv4, but with two fake ipv4 appended at the end. -const unsigned char Test_nsapi_dns::packet_ip4_3addresses[Test_nsapi_dns::packet_ip4_3addresses_size] = { +const unsigned char Test_IfaceDnsSocket::packet_ip4_3addresses[Test_IfaceDnsSocket::packet_ip4_3addresses_size] = { 0x00, 0x01, // ID 0x81, 0x80, // Flags 0x00, 0x01, // qdcount @@ -325,25 +223,27 @@ ACTION_P2(SetArg2ToCharPtr, value, size) } } -TEST_F(Test_nsapi_dns, single_query) +TEST_F(Test_IfaceDnsSocket, single_query) { SocketAddress addr; // Make sure socket opens successfully - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_open(_, NSAPI_UDP)) + EXPECT_CALL(stackMock(), socket_open(_, NSAPI_UDP)) .Times(1) - .WillOnce(DoAll(SetArgPointee<0>((void **)&NetworkStackMock::get_instance()), Return(NSAPI_ERROR_OK))); + .WillOnce(DoAll(SetArgPointee<0>((void **)&stackMock()), Return(NSAPI_ERROR_OK))); // Returning UNSUPPORTED will cause the nsapi_dns addresses to be used. - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), get_dns_server(_, _, _)) + EXPECT_CALL(stackMock(), get_dns_server(_, _, _)) .Times(1) .WillOnce(DoAll(SetArgPointee<1>(SocketAddress("1.2.3.4", 53)), Return(NSAPI_ERROR_OK))); - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_sendto(_, _, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_OK)); + EXPECT_CALL(stackMock(), socket_sendto(_, _, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_OK)); // Return a predefined google.com resolution packet. - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_recvfrom(_, _, _, _)) + EXPECT_CALL(stackMock(), socket_recvfrom(_, _, _, _)) .Times(1) - .WillOnce(DoAll(SetArg2ToCharPtr(Test_nsapi_dns::packet_ip4, Test_nsapi_dns::packet_ip4_size), Return(Test_nsapi_dns::packet_ip4_size))); + .WillOnce(DoAll(SetArg2ToCharPtr(Test_IfaceDnsSocket::packet_ip4, Test_IfaceDnsSocket::packet_ip4_size), Return(Test_IfaceDnsSocket::packet_ip4_size))); + + EXPECT_CALL(stackMock(), socket_close(_)).Times(1).WillOnce(Return(NSAPI_ERROR_OK)); EXPECT_EQ(NSAPI_ERROR_OK, nsapi_dns_query(iface, "www.google.com", &addr)); EXPECT_EQ(addr.get_ip_version(), NSAPI_IPv4); @@ -355,25 +255,27 @@ TEST_F(Test_nsapi_dns, single_query) EXPECT_FALSE(strncmp(addr.get_ip_address(), "216.58.207.238", sizeof("216.58.207.238"))); } -TEST_F(Test_nsapi_dns, single_query_ip6) +TEST_F(Test_IfaceDnsSocket, single_query_ip6) { SocketAddress addr; // Make sure socket opens successfully - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_open(_, NSAPI_UDP)) + EXPECT_CALL(stackMock(), socket_open(_, NSAPI_UDP)) .Times(1) - .WillOnce(DoAll(SetArgPointee<0>((void **)&NetworkStackMock::get_instance()), Return(NSAPI_ERROR_OK))); + .WillOnce(DoAll(SetArgPointee<0>((void **)&stackMock()), Return(NSAPI_ERROR_OK))); // Returning UNSUPPORTED will cause the nsapi_dns addresses to be used. - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), get_dns_server(_, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_UNSUPPORTED)); + EXPECT_CALL(stackMock(), get_dns_server(_, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_UNSUPPORTED)); // We want to send one query to the DNS server. - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_sendto(_, _, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_OK)); + EXPECT_CALL(stackMock(), socket_sendto(_, _, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_OK)); // Return a predefined google.com resolution packet. - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_recvfrom(_, _, _, _)) + EXPECT_CALL(stackMock(), socket_recvfrom(_, _, _, _)) .Times(1) - .WillOnce(DoAll(SetArg2ToCharPtr(Test_nsapi_dns::packet_ip6, Test_nsapi_dns::packet_ip6_size), Return(Test_nsapi_dns::packet_ip6_size))); + .WillOnce(DoAll(SetArg2ToCharPtr(Test_IfaceDnsSocket::packet_ip6, Test_IfaceDnsSocket::packet_ip6_size), Return(Test_IfaceDnsSocket::packet_ip6_size))); + + EXPECT_CALL(stackMock(), socket_close(_)).Times(1).WillOnce(Return(NSAPI_ERROR_OK)); EXPECT_EQ(NSAPI_ERROR_OK, nsapi_dns_query(iface, "www.google.com", &addr, NSAPI_IPv6)); EXPECT_EQ(addr.get_ip_version(), NSAPI_IPv6); @@ -398,25 +300,27 @@ int getaddrinfo(NetworkStack *stack, const char *hostname, SocketAddress hints, return num; } -TEST_F(Test_nsapi_dns, multiple_queries) +TEST_F(Test_IfaceDnsSocket, multiple_queries) { // Make sure socket opens successfully - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_open(_, NSAPI_UDP)) + EXPECT_CALL(stackMock(), socket_open(_, NSAPI_UDP)) .Times(1) - .WillOnce(DoAll(SetArgPointee<0>((void **)&NetworkStackMock::get_instance()), Return(NSAPI_ERROR_OK))); + .WillOnce(DoAll(SetArgPointee<0>((void **)&stackMock()), Return(NSAPI_ERROR_OK))); - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), get_dns_server(_, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_UNSUPPORTED)); + EXPECT_CALL(stackMock(), get_dns_server(_, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_UNSUPPORTED)); - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_sendto(_, _, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_OK)); + EXPECT_CALL(stackMock(), socket_sendto(_, _, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_OK)); // Return a predefined google.com resolution packet. - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_recvfrom(_, _, _, _)) + EXPECT_CALL(stackMock(), socket_recvfrom(_, _, _, _)) .Times(1) - .WillOnce(DoAll(SetArg2ToCharPtr(Test_nsapi_dns::packet_ip4_3addresses, Test_nsapi_dns::packet_ip4_3addresses_size), Return(Test_nsapi_dns::packet_ip4_3addresses_size))); + .WillOnce(DoAll(SetArg2ToCharPtr(Test_IfaceDnsSocket::packet_ip4_3addresses, Test_IfaceDnsSocket::packet_ip4_3addresses_size), Return(Test_IfaceDnsSocket::packet_ip4_3addresses_size))); + + EXPECT_CALL(stackMock(), socket_close(_)).Times(1).WillOnce(Return(NSAPI_ERROR_OK)); SocketAddress *addr; SocketAddress hints{{NSAPI_UNSPEC}, 443}; - EXPECT_EQ(3, getaddrinfo((NetworkStackMock *)iface->get_stack(), "www.google.com", hints, &addr)); + EXPECT_EQ(3, getaddrinfo(&stackMock(), "www.google.com", hints, &addr)); EXPECT_EQ(addr[0].get_ip_version(), NSAPI_IPv4); EXPECT_FALSE(strncmp(addr[0].get_ip_address(), "216.58.207.238", sizeof("216.58.207.238"))); @@ -428,7 +332,7 @@ TEST_F(Test_nsapi_dns, multiple_queries) SocketAddress *addr_cache; // Cache will only raturn one address. - EXPECT_EQ(Test_nsapi_dns::query_id, getaddrinfo((NetworkStackMock *)iface->get_stack(), "www.google.com", hints, &addr_cache)); + EXPECT_EQ(Test_IfaceDnsSocket::query_id, getaddrinfo(&stackMock(), "www.google.com", hints, &addr_cache)); // This is a bug which will be fixed in EXPECT_EQ(addr_cache[0].get_ip_version(), NSAPI_IPv4); @@ -436,160 +340,164 @@ TEST_F(Test_nsapi_dns, multiple_queries) delete[] addr_cache; } -TEST_F(Test_nsapi_dns, single_query_errors) +TEST_F(Test_IfaceDnsSocket, single_query_errors) { testing::InSequence s; SocketAddress addr {}; // Error - empty host name EXPECT_EQ(NSAPI_ERROR_PARAMETER, nsapi_dns_query(iface, "", &addr)); - EXPECT_EQ(NSAPI_ERROR_PARAMETER, nsapi_dns_query_multiple_async((NetworkStackMock *)iface->get_stack(), "", &Test_nsapi_dns::hostbyname_cb, 5, &Test_nsapi_dns::call_in, NULL)); + EXPECT_EQ(NSAPI_ERROR_PARAMETER, nsapi_dns_query_multiple_async(&stackMock(), "", &Test_IfaceDnsSocket::hostbyname_cb, 5, &Test_IfaceDnsSocket::call_in, NULL)); // Error - socket_open failing // Make sure socket opens successfully - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_open(_, NSAPI_UDP)) + EXPECT_CALL(stackMock(), socket_open(_, NSAPI_UDP)) .Times(1) .WillOnce(DoAll(SetArgPointee<0>((void **)NULL), Return(NSAPI_ERROR_DEVICE_ERROR))); EXPECT_EQ(NSAPI_ERROR_DEVICE_ERROR, nsapi_dns_query(iface, "www.google.com", &addr)); } -TEST_F(Test_nsapi_dns, simultaneous_query_async) +TEST_F(Test_IfaceDnsSocket, simultaneous_query_async) { // Make sure socket opens successfully - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_open(_, NSAPI_UDP)) + EXPECT_CALL(stackMock(), socket_open(_, NSAPI_UDP)) .Times(1) - .WillOnce(DoAll(SetArgPointee<0>((void **)&NetworkStackMock::get_instance()), Return(NSAPI_ERROR_OK))); + .WillOnce(DoAll(SetArgPointee<0>((void **)&stackMock()), Return(NSAPI_ERROR_OK))); - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), get_dns_server(_, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_UNSUPPORTED)); + EXPECT_CALL(stackMock(), get_dns_server(_, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_UNSUPPORTED)); - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_sendto(_, _, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_OK)); + EXPECT_CALL(stackMock(), socket_sendto(_, _, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_OK)); { testing::InSequence s; // Return a predefined google.com resolution packet. - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_recvfrom(_, _, _, _)) + EXPECT_CALL(stackMock(), socket_recvfrom(_, _, _, _)) .Times(1) - .WillOnce(DoAll(SetArg2ToCharPtr(Test_nsapi_dns::packet_ip4, Test_nsapi_dns::packet_ip4_size), Return(Test_nsapi_dns::packet_ip4_size))); + .WillOnce(DoAll(SetArg2ToCharPtr(Test_IfaceDnsSocket::packet_ip4, Test_IfaceDnsSocket::packet_ip4_size), Return(Test_IfaceDnsSocket::packet_ip4_size))); // There will be another try to recv from the socket, return 0, to show that no data is pending. - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_recvfrom(_, _, _, _)) + EXPECT_CALL(stackMock(), socket_recvfrom(_, _, _, _)) .Times(1) .WillOnce(Return(0)); } - EXPECT_EQ(Test_nsapi_dns::query_id, nsapi_dns_query_async((NetworkStackMock *)iface->get_stack(), "www.google.com", &Test_nsapi_dns::hostbyname_cb, Test_nsapi_dns::call_in, NSAPI_IPv4)); + EXPECT_CALL(stackMock(), socket_close(_)).Times(1).WillOnce(Return(NSAPI_ERROR_OK)); + + EXPECT_EQ(Test_IfaceDnsSocket::query_id, nsapi_dns_query_async(&stackMock(), "www.google.com", &Test_IfaceDnsSocket::hostbyname_cb, Test_IfaceDnsSocket::call_in, NSAPI_IPv4)); // Let another query to be stored in the queue. - EXPECT_EQ(Test_nsapi_dns::query_id + 1, nsapi_dns_query_async((NetworkStackMock *)iface->get_stack(), "www.amazon.com", &Test_nsapi_dns::hostbyname_cb, Test_nsapi_dns::call_in, NSAPI_IPv4)); + EXPECT_EQ(Test_IfaceDnsSocket::query_id + 1, nsapi_dns_query_async(&stackMock(), "www.amazon.com", &Test_IfaceDnsSocket::hostbyname_cb, Test_IfaceDnsSocket::call_in, NSAPI_IPv4)); executeEventQueueCallbacks(); // This will register the socket_callback. - reinterpret_cast *>(((NetworkStackMock *)iface->get_stack())->socket_cb)->call((void *)packet_ip4); + reinterpret_cast *>((&stackMock())->socket_cb)->call((void *)packet_ip4); // Run through registered callbacks again, to execute socket_callback_handle executeEventQueueCallbacks(); // Run again to execute response_handler executeEventQueueCallbacks(); - EXPECT_EQ(NSAPI_ERROR_OK, Test_nsapi_dns::hostname_cb_result); - EXPECT_EQ(Test_nsapi_dns::hostname_cb_address[0].get_ip_version(), NSAPI_IPv4); - EXPECT_FALSE(strncmp(Test_nsapi_dns::hostname_cb_address[0].get_ip_address(), "216.58.207.238", sizeof("216.58.207.238"))); + EXPECT_EQ(NSAPI_ERROR_OK, Test_IfaceDnsSocket::hostname_cb_result); + EXPECT_EQ(Test_IfaceDnsSocket::hostname_cb_address[0].get_ip_version(), NSAPI_IPv4); + EXPECT_FALSE(strncmp(Test_IfaceDnsSocket::hostname_cb_address[0].get_ip_address(), "216.58.207.238", sizeof("216.58.207.238"))); - delete[] Test_nsapi_dns::hostname_cb_address; + delete[] Test_IfaceDnsSocket::hostname_cb_address; // Second call should use cache. - EXPECT_EQ(NSAPI_ERROR_OK, nsapi_dns_query_async((NetworkStackMock *)iface->get_stack(), "www.google.com", &Test_nsapi_dns::hostbyname_cb, Test_nsapi_dns::call_in, NSAPI_IPv4)); - EXPECT_EQ(Test_nsapi_dns::hostname_cb_address[0].get_ip_version(), NSAPI_IPv4); - EXPECT_FALSE(strncmp(Test_nsapi_dns::hostname_cb_address[0].get_ip_address(), "216.58.207.238", sizeof("216.58.207.238"))); + EXPECT_EQ(NSAPI_ERROR_OK, nsapi_dns_query_async(&stackMock(), "www.google.com", &Test_IfaceDnsSocket::hostbyname_cb, Test_IfaceDnsSocket::call_in, NSAPI_IPv4)); + EXPECT_EQ(Test_IfaceDnsSocket::hostname_cb_address[0].get_ip_version(), NSAPI_IPv4); + EXPECT_FALSE(strncmp(Test_IfaceDnsSocket::hostname_cb_address[0].get_ip_address(), "216.58.207.238", sizeof("216.58.207.238"))); - delete[] Test_nsapi_dns::hostname_cb_address; + delete[] Test_IfaceDnsSocket::hostname_cb_address; - EXPECT_EQ(NSAPI_ERROR_OK, nsapi_dns_query_async_cancel((intptr_t)Test_nsapi_dns::query_id + 1)); + EXPECT_EQ(NSAPI_ERROR_OK, nsapi_dns_query_async_cancel((intptr_t)Test_IfaceDnsSocket::query_id + 1)); } // Imitate the getaddrinfo to make the example more real-life. int getaddrinfo_async(NetworkStack *stack, const char *hostname, NetworkStack::hostbyname_cb_t cb) { - return nsapi_dns_query_multiple_async(stack, hostname, cb, 5, &Test_nsapi_dns::call_in, NULL); + return nsapi_dns_query_multiple_async(stack, hostname, cb, 5, &Test_IfaceDnsSocket::call_in, NULL); } -TEST_F(Test_nsapi_dns, single_query_async_multiple) +TEST_F(Test_IfaceDnsSocket, single_query_async_multiple) { // Make sure socket opens successfully - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_open(_, NSAPI_UDP)) + EXPECT_CALL(stackMock(), socket_open(_, NSAPI_UDP)) .Times(1) - .WillOnce(DoAll(SetArgPointee<0>((void **)&NetworkStackMock::get_instance()), Return(NSAPI_ERROR_OK))); + .WillOnce(DoAll(SetArgPointee<0>((void **)&stackMock()), Return(NSAPI_ERROR_OK))); - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), get_dns_server(_, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_UNSUPPORTED)); + EXPECT_CALL(stackMock(), get_dns_server(_, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_UNSUPPORTED)); - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_sendto(_, _, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_OK)); + EXPECT_CALL(stackMock(), socket_sendto(_, _, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_OK)); { testing::InSequence s; // Return a predefined google.com resolution packet. - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_recvfrom(_, _, _, _)) + EXPECT_CALL(stackMock(), socket_recvfrom(_, _, _, _)) .Times(1) - .WillOnce(DoAll(SetArg2ToCharPtr(Test_nsapi_dns::packet_ip4_3addresses, Test_nsapi_dns::packet_ip4_3addresses_size), Return(Test_nsapi_dns::packet_ip4_3addresses_size))); + .WillOnce(DoAll(SetArg2ToCharPtr(Test_IfaceDnsSocket::packet_ip4_3addresses, Test_IfaceDnsSocket::packet_ip4_3addresses_size), Return(Test_IfaceDnsSocket::packet_ip4_3addresses_size))); // There will be another try to recv from the socket, return 0, to show that no data is pending. - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_recvfrom(_, _, _, _)) + EXPECT_CALL(stackMock(), socket_recvfrom(_, _, _, _)) .Times(1) .WillOnce(Return(0)); } - EXPECT_EQ(Test_nsapi_dns::query_id, getaddrinfo_async((NetworkStackMock *)iface->get_stack(), "www.google.com", &Test_nsapi_dns::hostbyname_cb)); + EXPECT_CALL(stackMock(), socket_close(_)).Times(1).WillOnce(Return(NSAPI_ERROR_OK)); + + EXPECT_EQ(Test_IfaceDnsSocket::query_id, getaddrinfo_async(&stackMock(), "www.google.com", &Test_IfaceDnsSocket::hostbyname_cb)); executeEventQueueCallbacks(); // This will register the socket_callback. - reinterpret_cast *>(((NetworkStackMock *)iface->get_stack())->socket_cb)->call((void *)packet_ip4); + reinterpret_cast *>((&stackMock())->socket_cb)->call((void *)packet_ip4); // Run through registered callbacks again, to execute socket_callback_handle executeEventQueueCallbacks(); // Run again to execute response_handler executeEventQueueCallbacks(); - EXPECT_EQ(3, Test_nsapi_dns::hostname_cb_result); - EXPECT_EQ(Test_nsapi_dns::hostname_cb_address[0].get_ip_version(), NSAPI_IPv4); - EXPECT_EQ(Test_nsapi_dns::hostname_cb_address[1].get_ip_version(), NSAPI_IPv4); - EXPECT_EQ(Test_nsapi_dns::hostname_cb_address[2].get_ip_version(), NSAPI_IPv4); - EXPECT_FALSE(strncmp(Test_nsapi_dns::hostname_cb_address[0].get_ip_address(), "216.58.207.238", sizeof("216.58.207.238"))); - EXPECT_FALSE(strncmp(Test_nsapi_dns::hostname_cb_address[1].get_ip_address(), "222.173.190.239", sizeof("222.173.190.239"))); - EXPECT_FALSE(strncmp(Test_nsapi_dns::hostname_cb_address[2].get_ip_address(), "1.2.3.4", sizeof("1.2.3.4"))); + EXPECT_EQ(3, Test_IfaceDnsSocket::hostname_cb_result); + EXPECT_EQ(Test_IfaceDnsSocket::hostname_cb_address[0].get_ip_version(), NSAPI_IPv4); + EXPECT_EQ(Test_IfaceDnsSocket::hostname_cb_address[1].get_ip_version(), NSAPI_IPv4); + EXPECT_EQ(Test_IfaceDnsSocket::hostname_cb_address[2].get_ip_version(), NSAPI_IPv4); + EXPECT_FALSE(strncmp(Test_IfaceDnsSocket::hostname_cb_address[0].get_ip_address(), "216.58.207.238", sizeof("216.58.207.238"))); + EXPECT_FALSE(strncmp(Test_IfaceDnsSocket::hostname_cb_address[1].get_ip_address(), "222.173.190.239", sizeof("222.173.190.239"))); + EXPECT_FALSE(strncmp(Test_IfaceDnsSocket::hostname_cb_address[2].get_ip_address(), "1.2.3.4", sizeof("1.2.3.4"))); - delete[] Test_nsapi_dns::hostname_cb_address; - Test_nsapi_dns::hostname_cb_result = NSAPI_ERROR_DEVICE_ERROR; + delete[] Test_IfaceDnsSocket::hostname_cb_address; + Test_IfaceDnsSocket::hostname_cb_result = NSAPI_ERROR_DEVICE_ERROR; // Do not set any return values. Second call should use cache. // Cache will only return one address! - EXPECT_EQ(0, getaddrinfo_async((NetworkStackMock *)iface->get_stack(), "www.google.com", &Test_nsapi_dns::hostbyname_cb)); - EXPECT_EQ(NSAPI_ERROR_OK, Test_nsapi_dns::hostname_cb_result); - EXPECT_EQ(Test_nsapi_dns::hostname_cb_address[0].get_ip_version(), NSAPI_IPv4); - EXPECT_FALSE(strncmp(Test_nsapi_dns::hostname_cb_address[0].get_ip_address(), "216.58.207.238", sizeof("216.58.207.238"))); + EXPECT_EQ(0, getaddrinfo_async(&stackMock(), "www.google.com", &Test_IfaceDnsSocket::hostbyname_cb)); + EXPECT_EQ(NSAPI_ERROR_OK, Test_IfaceDnsSocket::hostname_cb_result); + EXPECT_EQ(Test_IfaceDnsSocket::hostname_cb_address[0].get_ip_version(), NSAPI_IPv4); + EXPECT_FALSE(strncmp(Test_IfaceDnsSocket::hostname_cb_address[0].get_ip_address(), "216.58.207.238", sizeof("216.58.207.238"))); - delete[] Test_nsapi_dns::hostname_cb_address; + delete[] Test_IfaceDnsSocket::hostname_cb_address; } -TEST_F(Test_nsapi_dns, async_cancel) +TEST_F(Test_IfaceDnsSocket, async_cancel) { - EXPECT_EQ(Test_nsapi_dns::query_id, nsapi_dns_query_async((NetworkStackMock *)iface->get_stack(), "www.google.com", &Test_nsapi_dns::hostbyname_cb, Test_nsapi_dns::call_in, NSAPI_IPv4)); + EXPECT_EQ(Test_IfaceDnsSocket::query_id, nsapi_dns_query_async(&stackMock(), "www.google.com", &Test_IfaceDnsSocket::hostbyname_cb, Test_IfaceDnsSocket::call_in, NSAPI_IPv4)); EXPECT_EQ(NSAPI_ERROR_OK, nsapi_dns_query_async_cancel((intptr_t)1)); executeEventQueueCallbacks(); - EXPECT_EQ(NSAPI_ERROR_DEVICE_ERROR, Test_nsapi_dns::hostname_cb_result); - EXPECT_EQ(NULL, Test_nsapi_dns::hostname_cb_address); + EXPECT_EQ(NSAPI_ERROR_DEVICE_ERROR, Test_IfaceDnsSocket::hostname_cb_result); + EXPECT_EQ(NULL, Test_IfaceDnsSocket::hostname_cb_address); // Try to cancel twice - should return error EXPECT_EQ(NSAPI_ERROR_PARAMETER, nsapi_dns_query_async_cancel((intptr_t)1)); } -TEST_F(Test_nsapi_dns, add_server) +TEST_F(Test_IfaceDnsSocket, add_server) { SocketAddress server_address("1.2.3.4", 8000); EXPECT_EQ(NSAPI_ERROR_OK, nsapi_dns_add_server(server_address, NULL)); @@ -597,25 +505,27 @@ TEST_F(Test_nsapi_dns, add_server) SocketAddress addr; // Make sure socket opens successfully - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_open(_, NSAPI_UDP)) + EXPECT_CALL(stackMock(), socket_open(_, NSAPI_UDP)) .Times(1) - .WillOnce(DoAll(SetArgPointee<0>((void **)&NetworkStackMock::get_instance()), Return(NSAPI_ERROR_OK))); + .WillOnce(DoAll(SetArgPointee<0>((void **)&stackMock()), Return(NSAPI_ERROR_OK))); - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), get_dns_server(_, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_UNSUPPORTED)); + EXPECT_CALL(stackMock(), get_dns_server(_, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_UNSUPPORTED)); - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_sendto(_, server_address, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_OK)); + EXPECT_CALL(stackMock(), socket_sendto(_, server_address, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_OK)); + + EXPECT_CALL(stackMock(), socket_close(_)).Times(1).WillOnce(Return(NSAPI_ERROR_OK)); // Return a predefined google.com resolution packet. - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_recvfrom(_, _, _, _)) + EXPECT_CALL(stackMock(), socket_recvfrom(_, _, _, _)) .Times(1) - .WillOnce(DoAll(SetArg2ToCharPtr(Test_nsapi_dns::packet_ip4, Test_nsapi_dns::packet_ip4_size), Return(Test_nsapi_dns::packet_ip4_size))); + .WillOnce(DoAll(SetArg2ToCharPtr(Test_IfaceDnsSocket::packet_ip4, Test_IfaceDnsSocket::packet_ip4_size), Return(Test_IfaceDnsSocket::packet_ip4_size))); EXPECT_EQ(NSAPI_ERROR_OK, nsapi_dns_query(iface, "www.google.com", &addr)); EXPECT_EQ(addr.get_ip_version(), NSAPI_IPv4); EXPECT_FALSE(strncmp(addr.get_ip_address(), "216.58.207.238", sizeof("216.58.207.238"))); } -TEST_F(Test_nsapi_dns, attempts) +TEST_F(Test_IfaceDnsSocket, attempts) { constexpr int DNS_SERVER_SIZE = 5; // This must be kept equal to DNS_SERVER_SIZE macro define in nsapi_dns.cpp @@ -632,15 +542,15 @@ TEST_F(Test_nsapi_dns, attempts) testing::InSequence s; // Make sure socket opens successfully - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_open(_, NSAPI_UDP)) + EXPECT_CALL(stackMock(), socket_open(_, NSAPI_UDP)) .Times(1) - .WillOnce(DoAll(SetArgPointee<0>((void **)&NetworkStackMock::get_instance()), Return(NSAPI_ERROR_OK))); + .WillOnce(DoAll(SetArgPointee<0>((void **)&stackMock()), Return(NSAPI_ERROR_OK))); - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), get_dns_server(_, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_UNSUPPORTED)); + EXPECT_CALL(stackMock(), get_dns_server(_, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_UNSUPPORTED)); int attempt = 0; while (attempt < DNS_SERVER_SIZE) { - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_sendto(_, known_server_address[attempt % DNS_SERVER_SIZE], _, _)) + EXPECT_CALL(stackMock(), socket_sendto(_, known_server_address[attempt % DNS_SERVER_SIZE], _, _)) .Times(1) .WillRepeatedly(Return(NSAPI_ERROR_DEVICE_ERROR)); @@ -649,10 +559,13 @@ TEST_F(Test_nsapi_dns, attempts) break; } } + + EXPECT_CALL(stackMock(), socket_close(_)).Times(1).WillOnce(Return(NSAPI_ERROR_OK)); + EXPECT_EQ(NSAPI_ERROR_DNS_FAILURE, nsapi_dns_query(iface, "www.google.com", &addr)); } -TEST_F(Test_nsapi_dns, retries_attempts) +TEST_F(Test_IfaceDnsSocket, retries_attempts) { constexpr int DNS_SERVER_SIZE = 5; // This must be kept equal to DNS_SERVER_SIZE macro define in nsapi_dns.cpp @@ -669,11 +582,11 @@ TEST_F(Test_nsapi_dns, retries_attempts) testing::InSequence s; // Make sure socket opens successfully - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_open(_, NSAPI_UDP)) + EXPECT_CALL(stackMock(), socket_open(_, NSAPI_UDP)) .Times(1) - .WillOnce(DoAll(SetArgPointee<0>((void **)&NetworkStackMock::get_instance()), Return(NSAPI_ERROR_OK))); + .WillOnce(DoAll(SetArgPointee<0>((void **)&stackMock()), Return(NSAPI_ERROR_OK))); - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), get_dns_server(_, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_UNSUPPORTED)); + EXPECT_CALL(stackMock(), get_dns_server(_, _, _)).Times(1).WillOnce(Return(NSAPI_ERROR_UNSUPPORTED)); // Set up all the expectation: sendto and recvfrom should come one after another, untill dns runs out of attempts. int attempt = 0; @@ -682,14 +595,14 @@ TEST_F(Test_nsapi_dns, retries_attempts) int retry = 0; while (retry < MBED_CONF_NSAPI_DNS_RETRIES + 1) { int server_idx = attempt / (MBED_CONF_NSAPI_DNS_RETRIES + 1); - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_sendto(_, known_server_address[server_idx % DNS_SERVER_SIZE], _, _)) + EXPECT_CALL(stackMock(), socket_sendto(_, known_server_address[server_idx % DNS_SERVER_SIZE], _, _)) .Times(1) .WillRepeatedly(Return(NSAPI_ERROR_OK)); eventFlagsStubNextRetval.push_back(osFlagsError); // Break the wait loop // Make sure the retries will be necessary. - EXPECT_CALL(*((NetworkStackMock *)iface->get_stack()), socket_recvfrom(_, _, _, _)) + EXPECT_CALL(stackMock(), socket_recvfrom(_, _, _, _)) .Times(1) .WillRepeatedly(Return(NSAPI_ERROR_WOULD_BLOCK)); @@ -701,5 +614,7 @@ TEST_F(Test_nsapi_dns, retries_attempts) } } + EXPECT_CALL(stackMock(), socket_close(_)).Times(1).WillOnce(Return(NSAPI_ERROR_OK)); + EXPECT_EQ(NSAPI_ERROR_DNS_FAILURE, nsapi_dns_query(iface, "www.google.com", &addr)); } diff --git a/UNITTESTS/MODULETESTS/features/netsocket/IfaceDnsSocket/unittest.cmake b/UNITTESTS/MODULETESTS/features/netsocket/IfaceDnsSocket/unittest.cmake new file mode 100644 index 0000000000..a53fbd2437 --- /dev/null +++ b/UNITTESTS/MODULETESTS/features/netsocket/IfaceDnsSocket/unittest.cmake @@ -0,0 +1,47 @@ + +#################### +# UNIT TESTS +#################### + +set(unittest-sources + ../features/netsocket/SocketAddress.cpp + ../features/netsocket/NetworkInterface.cpp + ../features/netsocket/NetworkInterfaceDefaults.cpp + ../features/netsocket/NetworkStack.cpp #nsapi_create_stack + ../features/netsocket/InternetSocket.cpp + ../features/netsocket/TCPSocket.cpp + ../features/netsocket/InternetDatagramSocket.cpp + ../features/netsocket/UDPSocket.cpp + ../features/netsocket/SocketStats.cpp + ../features/netsocket/EthernetInterface.cpp + ../features/netsocket/EMACInterface.cpp + ../features/netsocket/nsapi_dns.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/libBits/common_functions.c + ../features/frameworks/nanostack-libservice/source/libList/ns_list.c +) + +set(unittest-test-sources + MODULETESTS/features/netsocket/IfaceDnsSocket/test_IfaceDnsSocket.cpp + stubs/MeshInterface_stub.cpp + stubs/CellularInterface_stub.cpp + stubs/Mutex_stub.cpp + stubs/mbed_assert_stub.cpp + stubs/mbed_atomic_stub.c + stubs/mbed_critical_stub.c + stubs/mbed_rtos_rtx_stub.c + stubs/equeue_stub.c + stubs/EventQueue_stub.cpp + stubs/Kernel_stub.cpp + stubs/mbed_error.c + stubs/mbed_shared_queues_stub.cpp + stubs/rtx_mutex_stub.c + stubs/EventFlags_stub.cpp +) + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDEVICE_EMAC -DMBED_CONF_TARGET_NETWORK_DEFAULT_INTERFACE_TYPE=ETHERNET -DMBED_CONF_NSAPI_DNS_RESPONSE_WAIT_TIME=10000 -DMBED_CONF_NSAPI_DNS_RETRIES=1 -DMBED_CONF_NSAPI_DNS_TOTAL_ATTEMPTS=10 -DMBED_CONF_NSAPI_DNS_CACHE_SIZE=5") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DDEVICE_EMAC -DMBED_CONF_TARGET_NETWORK_DEFAULT_INTERFACE_TYPE=ETHERNET -DMBED_CONF_NSAPI_DNS_RESPONSE_WAIT_TIME=10000 -DMBED_CONF_NSAPI_DNS_RETRIES=1 -DMBED_CONF_NSAPI_DNS_TOTAL_ATTEMPTS=10 -DMBED_CONF_NSAPI_DNS_CACHE_SIZE=5") \ No newline at end of file diff --git a/UNITTESTS/features/netsocket/EthernetInterface/test_EthernetInterface.cpp b/UNITTESTS/features/netsocket/EthernetInterface/test_EthernetInterface.cpp index 7f8e670c71..ca6522b1b8 100644 --- a/UNITTESTS/features/netsocket/EthernetInterface/test_EthernetInterface.cpp +++ b/UNITTESTS/features/netsocket/EthernetInterface/test_EthernetInterface.cpp @@ -22,36 +22,7 @@ #include "features/netsocket/EthernetInterface.h" #include - -class MockEMAC : public EMAC { -public: - MOCK_METHOD0(power_up, bool()); - MOCK_METHOD0(power_down, void()); - MOCK_CONST_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_CONST_METHOD0(get_hwaddr_size, uint8_t()); - MOCK_CONST_METHOD1(get_hwaddr, bool(uint8_t *addr)); - MOCK_METHOD1(set_hwaddr, void(const uint8_t *)); - MOCK_METHOD1(link_out, bool(emac_mem_buf_t *buf)); - MOCK_METHOD1(set_link_input_cb, void(emac_link_input_cb_t input_cb)); - MOCK_METHOD1(set_link_state_cb, void(emac_link_state_change_cb_t state_cb)); - MOCK_METHOD1(add_multicast_group, void(const uint8_t *address)); - MOCK_METHOD1(remove_multicast_group, void(const uint8_t *address)); - MOCK_METHOD1(set_all_multicast, void(bool all)); - MOCK_METHOD1(set_memory_manager, void(EMACMemoryManager &mem_mngr)); - - static MockEMAC &get_instance() - { - static MockEMAC emacMock1; - return emacMock1; - } -}; - -MBED_WEAK EMAC &EMAC::get_default_instance() -{ - return MockEMAC::get_instance(); -} +#include "EMAC_mock.h" OnboardNetworkStack &OnboardNetworkStack::get_default_instance() { @@ -168,6 +139,8 @@ TEST_F(TestEthernetInterface, set_network) SocketAddress ipAddress("127.0.0.1"); SocketAddress netmask("255.255.0.0"); SocketAddress gateway("127.0.0.2"); + char macAddress[NSAPI_MAC_SIZE]; + memset(macAddress, '\0', NSAPI_MAC_SIZE); SocketAddress ipAddressArg; SocketAddress netmaskArg; @@ -205,6 +178,11 @@ TEST_F(TestEthernetInterface, set_network) EXPECT_EQ(gateway, gatewayArg); // Testing the getters makes sense now. + EXPECT_CALL(*netStackIface, get_mac_address(_, _)) + .Times(1) + .WillOnce(DoAll(SetArrayArgument<0>(macAddress, macAddress+NSAPI_MAC_SIZE), Return(macAddress))); + EXPECT_EQ(std::string(macAddress), std::string(iface->get_mac_address())); + EXPECT_CALL(*netStackIface, get_ip_address(_)) .Times(1) .WillOnce(DoAll(SetArgPointee<0>(ipAddress), Return(NSAPI_ERROR_OK))); diff --git a/UNITTESTS/features/netsocket/nsapi_dns/unittest.cmake b/UNITTESTS/features/netsocket/nsapi_dns/unittest.cmake deleted file mode 100644 index 63980cb611..0000000000 --- a/UNITTESTS/features/netsocket/nsapi_dns/unittest.cmake +++ /dev/null @@ -1,46 +0,0 @@ - -#################### -# UNIT TESTS -#################### - -# Unit test suite name -set(TEST_SUITE_NAME "features_netsocket_nsapi_dns") - -# Source files -set(unittest-sources - ../features/netsocket/nsapi_dns.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 - stubs/Mutex_stub.cpp - ../features/netsocket/SocketAddress.cpp - stubs/mbed_assert_stub.cpp - stubs/NetworkStack_stub.cpp - stubs/NetworkInterfaceDefaults_stub.cpp - stubs/mbed_atomic_stub.c - stubs/mbed_critical_stub.c - stubs/mbed_rtos_rtx_stub.c - stubs/Kernel_stub.cpp - stubs/EventFlags_stub.cpp - stubs/rtx_mutex_stub.c - stubs/SocketStats_Stub.cpp - features/netsocket/nsapi_dns/test_nsapi_dns.cpp - ../features/netsocket/NetworkInterface.cpp - ../features/netsocket/InternetSocket.cpp - ../features/netsocket/InternetDatagramSocket.cpp - ../features/netsocket/UDPSocket.cpp -) - -set(unittest-test-flags - -DMBED_CONF_NSAPI_DNS_RESPONSE_WAIT_TIME=10000 - -DMBED_CONF_NSAPI_DNS_RETRIES=1 - -DMBED_CONF_NSAPI_DNS_TOTAL_ATTEMPTS=10 - -DMBED_CONF_NSAPI_DNS_CACHE_SIZE=5 -) diff --git a/UNITTESTS/stubs/CellularInterface_stub.cpp b/UNITTESTS/stubs/CellularInterface_stub.cpp new file mode 100644 index 0000000000..aea3e9671d --- /dev/null +++ b/UNITTESTS/stubs/CellularInterface_stub.cpp @@ -0,0 +1,24 @@ +/* Socket + * Copyright (c) 2019 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 "CellularInterface.h" + +MBED_WEAK CellularInterface *CellularInterface::get_target_default_instance() +{ + return NULL; +} + + diff --git a/UNITTESTS/stubs/EMAC_mock.h b/UNITTESTS/stubs/EMAC_mock.h new file mode 100644 index 0000000000..f41ae8021f --- /dev/null +++ b/UNITTESTS/stubs/EMAC_mock.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2019, 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. + */ + +#ifndef EMACMOCK_H +#define EMACMOCK_H + +#include "gtest/gtest.h" +#include "gmock/gmock.h" +#include "features/netsocket/EMAC.h" + +class MockEMAC : public EMAC { +public: + MOCK_METHOD0(power_up, bool()); + MOCK_METHOD0(power_down, void()); + MOCK_CONST_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_CONST_METHOD0(get_hwaddr_size, uint8_t()); + MOCK_CONST_METHOD1(get_hwaddr, bool(uint8_t *addr)); + MOCK_METHOD1(set_hwaddr, void(const uint8_t *)); + MOCK_METHOD1(link_out, bool(emac_mem_buf_t *buf)); + MOCK_METHOD1(set_link_input_cb, void(emac_link_input_cb_t input_cb)); + MOCK_METHOD1(set_link_state_cb, void(emac_link_state_change_cb_t state_cb)); + MOCK_METHOD1(add_multicast_group, void(const uint8_t *address)); + MOCK_METHOD1(remove_multicast_group, void(const uint8_t *address)); + MOCK_METHOD1(set_all_multicast, void(bool all)); + MOCK_METHOD1(set_memory_manager, void(EMACMemoryManager &mem_mngr)); + + static MockEMAC &get_instance() + { + static MockEMAC emacMock1; + return emacMock1; + } +}; + +MBED_WEAK EMAC &EMAC::get_default_instance() +{ + return MockEMAC::get_instance(); +} + +#endif // EMACMOCK_H diff --git a/UNITTESTS/stubs/MeshInterface_stub.cpp b/UNITTESTS/stubs/MeshInterface_stub.cpp new file mode 100644 index 0000000000..039ba866f1 --- /dev/null +++ b/UNITTESTS/stubs/MeshInterface_stub.cpp @@ -0,0 +1,24 @@ +/* Socket + * Copyright (c) 2019 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 "MeshInterface.h" + +MBED_WEAK MeshInterface *MeshInterface::get_target_default_instance() +{ + return NULL; +} + + diff --git a/UNITTESTS/stubs/OnboardNetworkStack_mock.h b/UNITTESTS/stubs/OnboardNetworkStack_mock.h index e85d731d92..57d5b506f3 100644 --- a/UNITTESTS/stubs/OnboardNetworkStack_mock.h +++ b/UNITTESTS/stubs/OnboardNetworkStack_mock.h @@ -32,6 +32,7 @@ class OnboardNetworkStackMock : public OnboardNetworkStack { public: MOCK_METHOD3(gethostbyname, nsapi_error_t(const char *host, SocketAddress *address, nsapi_version_t version)); MOCK_METHOD1(add_dns_server, nsapi_error_t(const SocketAddress &address)); + MOCK_METHOD3(get_dns_server, nsapi_error_t(int index, SocketAddress *address, const char *interface_name)); MOCK_METHOD2(call_in, nsapi_error_t(int delay, mbed::Callback func)); MOCK_METHOD2(socket_open, nsapi_error_t(nsapi_socket_t *handle, nsapi_protocol_t proto)); MOCK_METHOD1(socket_close, nsapi_error_t(nsapi_socket_t handle)); @@ -45,10 +46,17 @@ public: MOCK_METHOD4(socket_recvfrom, nsapi_error_t(nsapi_socket_t handle, SocketAddress *address, void *data, nsapi_size_t size)); MOCK_METHOD5(setsockopt, nsapi_error_t(nsapi_socket_t handle, int level, int optname, const void *optval, unsigned optlen)); 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(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)); + void *socket_cb; + // No need to mock socket_attach really. + void socket_attach(nsapi_socket_t handle, void (*callback)(void *), void *data) + { + socket_cb = data; + }; + static OnboardNetworkStackMock &get_instance() { diff --git a/features/netsocket/EMACInterface.h b/features/netsocket/EMACInterface.h index bdcaadc965..70e6aef12a 100644 --- a/features/netsocket/EMACInterface.h +++ b/features/netsocket/EMACInterface.h @@ -106,6 +106,7 @@ public: /** @copydoc NetworkInterface::get_gateway */ virtual nsapi_error_t get_gateway(SocketAddress *address); + /** @copydoc NetworkInterface::get_gateway */ MBED_DEPRECATED_SINCE("mbed-os-5.15", "String-based APIs are deprecated") virtual const char *get_gateway();