Skip to content

Commit 21b4eca

Browse files
author
Cruz Monrreal
authored
Merge pull request #8316 from michalpasztamobica/master
unittests: Add tests for netsocket classes
2 parents 1eaa8a5 + 5b4634a commit 21b4eca

File tree

14 files changed

+662
-28
lines changed

14 files changed

+662
-28
lines changed
Lines changed: 287 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,287 @@
1+
/*
2+
* Copyright (c) 2018, Arm Limited and affiliates
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#include "gtest/gtest.h"
19+
#include "gmock/gmock.h"
20+
#include "features/netsocket/EthernetInterface.h"
21+
#include <iostream>
22+
23+
class MockEMAC : public EMAC {
24+
public:
25+
MOCK_METHOD0(power_up, bool());
26+
MOCK_METHOD0(power_down, void());
27+
MOCK_CONST_METHOD0(get_mtu_size, uint32_t());
28+
MOCK_CONST_METHOD0(get_align_preference, uint32_t());
29+
MOCK_CONST_METHOD2(get_ifname, void(char *name, uint8_t size));
30+
MOCK_CONST_METHOD0(get_hwaddr_size, uint8_t());
31+
MOCK_CONST_METHOD1(get_hwaddr, bool(uint8_t *addr));
32+
MOCK_METHOD1(set_hwaddr, void(const uint8_t *));
33+
MOCK_METHOD1(link_out, bool(emac_mem_buf_t *buf));
34+
MOCK_METHOD1(set_link_input_cb, void(emac_link_input_cb_t input_cb));
35+
MOCK_METHOD1(set_link_state_cb, void(emac_link_state_change_cb_t state_cb));
36+
MOCK_METHOD1(add_multicast_group, void(const uint8_t *address));
37+
MOCK_METHOD1(remove_multicast_group, void(const uint8_t *address));
38+
MOCK_METHOD1(set_all_multicast, void(bool all));
39+
MOCK_METHOD1(set_memory_manager, void(EMACMemoryManager &mem_mngr));
40+
41+
static MockEMAC &get_instance()
42+
{
43+
static MockEMAC emacMock1;
44+
return emacMock1;
45+
}
46+
};
47+
48+
MBED_WEAK EMAC &EMAC::get_default_instance()
49+
{
50+
return MockEMAC::get_instance();
51+
}
52+
53+
class EmacNetworkStackMock : public OnboardNetworkStack {
54+
public:
55+
MOCK_METHOD3(gethostbyname, nsapi_error_t(const char *host, SocketAddress *address, nsapi_version_t version));
56+
MOCK_METHOD1(add_dns_server, nsapi_error_t(const SocketAddress &address));
57+
MOCK_METHOD2(call_in, nsapi_error_t(int delay, mbed::Callback<void()> func));
58+
MOCK_METHOD2(socket_open, nsapi_error_t(nsapi_socket_t *handle, nsapi_protocol_t proto));
59+
MOCK_METHOD1(socket_close, nsapi_error_t(nsapi_socket_t handle));
60+
MOCK_METHOD2(socket_bind, nsapi_error_t(nsapi_socket_t handle, const SocketAddress &address));
61+
MOCK_METHOD2(socket_listen, nsapi_error_t(nsapi_socket_t handle, int backlog));
62+
MOCK_METHOD2(socket_connect, nsapi_error_t(nsapi_socket_t handle, const SocketAddress &address));
63+
MOCK_METHOD3(socket_accept, nsapi_error_t(nsapi_socket_t server, nsapi_socket_t *handle, SocketAddress *address));
64+
MOCK_METHOD3(socket_send, nsapi_error_t(nsapi_socket_t handle, const void *data, nsapi_size_t size));
65+
MOCK_METHOD3(socket_recv, nsapi_error_t(nsapi_socket_t handle, void *data, nsapi_size_t size));
66+
MOCK_METHOD4(socket_sendto, nsapi_error_t(nsapi_socket_t handle, const SocketAddress &address, const void *data, nsapi_size_t size));
67+
MOCK_METHOD4(socket_recvfrom, nsapi_error_t(nsapi_socket_t handle, SocketAddress *address, void *data, nsapi_size_t size));
68+
MOCK_METHOD5(setsockopt, nsapi_error_t(nsapi_socket_t handle, int level, int optname, const void *optval, unsigned optlen));
69+
MOCK_METHOD5(getsockopt, nsapi_error_t(nsapi_socket_t handle, int level, int optname, const void *optval, unsigned *optlen));
70+
MOCK_METHOD3(socket_attach, void(nsapi_socket_t handle, void (*callback)(void *), void *data));
71+
MOCK_METHOD3(add_ethernet_interface, nsapi_error_t(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out));
72+
73+
static EmacNetworkStackMock &get_instance()
74+
{
75+
static EmacNetworkStackMock stackMock1;
76+
return stackMock1;
77+
}
78+
79+
class InterfaceMock : public OnboardNetworkStack::Interface {
80+
public:
81+
82+
static InterfaceMock &get_instance()
83+
{
84+
static InterfaceMock test_interface;
85+
return test_interface;
86+
}
87+
MOCK_METHOD6(bringup, nsapi_error_t(bool dhcp, const char *ip,
88+
const char *netmask, const char *gw,
89+
nsapi_ip_stack_t stack,
90+
bool blocking
91+
));
92+
MOCK_METHOD0(bringdown, nsapi_error_t());
93+
MOCK_METHOD1(attach, void(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb));
94+
MOCK_CONST_METHOD0(get_connection_status, nsapi_connection_status_t());
95+
MOCK_METHOD2(get_mac_address, char *(char *buf, nsapi_size_t buflen));
96+
MOCK_METHOD2(get_ip_address, char *(char *buf, nsapi_size_t buflen));
97+
MOCK_METHOD2(get_netmask, char *(char *buf, nsapi_size_t buflen));
98+
MOCK_METHOD2(get_gateway, char *(char *buf, nsapi_size_t buflen));
99+
};
100+
};
101+
102+
OnboardNetworkStack &OnboardNetworkStack::get_default_instance()
103+
{
104+
return EmacNetworkStackMock::get_instance();
105+
}
106+
107+
// Implementaion in in NetworkInterfaceDefaults.cpp
108+
MBED_WEAK EthInterface *EthInterface::get_default_instance()
109+
{
110+
return get_target_default_instance();
111+
}
112+
113+
using ::testing::_;
114+
using ::testing::Return;
115+
using ::testing::ReturnArg;
116+
using ::testing::SaveArg;
117+
using ::testing::SaveArgPointee;
118+
using ::testing::SetArrayArgument;
119+
using ::testing::SetArgPointee;
120+
using ::testing::SetArgReferee;
121+
122+
class TestEthernetInterface: public testing::Test {
123+
protected:
124+
EthernetInterface *iface;
125+
EmacNetworkStackMock *stackMock;
126+
MockEMAC *emacMock;
127+
EmacNetworkStackMock::InterfaceMock *netStackIface;
128+
virtual void SetUp()
129+
{
130+
stackMock = &EmacNetworkStackMock::get_instance();
131+
emacMock = &MockEMAC::get_instance();
132+
netStackIface = &EmacNetworkStackMock::InterfaceMock::get_instance();
133+
iface = new EthernetInterface(MockEMAC::get_instance(), EmacNetworkStackMock::get_instance());
134+
}
135+
136+
virtual void TearDown()
137+
{
138+
// Do not delete the mocks pointers, as they point to statically allocated singletons.
139+
delete iface;
140+
}
141+
142+
/* Enclose the heavily-used connection procedure to improve code redability */
143+
void doConnect(bool dhcp = true, bool blocking = true)
144+
{
145+
EXPECT_CALL(*stackMock, add_ethernet_interface(testing::Ref(*emacMock), true, _))
146+
.Times(1)
147+
.WillOnce(DoAll(SetArgPointee<2>(netStackIface), Return(NSAPI_ERROR_OK)));
148+
EXPECT_CALL(*netStackIface, attach(_))
149+
.Times(1)
150+
.RetiresOnSaturation();;
151+
EXPECT_CALL(*netStackIface, bringup(dhcp, NULL, NULL, NULL, DEFAULT_STACK, blocking))
152+
.Times(1)
153+
.WillOnce(Return(NSAPI_ERROR_OK));
154+
EXPECT_EQ(NSAPI_ERROR_OK, iface->connect());
155+
}
156+
157+
static void cb(nsapi_event_t ev, intptr_t ptr)
158+
{
159+
160+
}
161+
};
162+
163+
TEST_F(TestEthernetInterface, constructor_default)
164+
{
165+
EXPECT_TRUE(iface);
166+
}
167+
168+
TEST_F(TestEthernetInterface, constructor_getter)
169+
{
170+
EthInterface *eth = EthInterface::get_default_instance();
171+
}
172+
173+
174+
175+
TEST_F(TestEthernetInterface, connect)
176+
{
177+
doConnect();
178+
}
179+
180+
TEST_F(TestEthernetInterface, connect_failure)
181+
{
182+
EXPECT_CALL(*stackMock, add_ethernet_interface(testing::Ref(*emacMock), true, _))
183+
.Times(1)
184+
.WillOnce(DoAll(SetArgPointee<2>(netStackIface), Return(NSAPI_ERROR_NO_MEMORY)));
185+
EXPECT_EQ(NSAPI_ERROR_NO_MEMORY, iface->connect());
186+
}
187+
188+
TEST_F(TestEthernetInterface, disconnect_without_connecting)
189+
{
190+
EXPECT_EQ(NSAPI_ERROR_NO_CONNECTION, iface->disconnect());
191+
}
192+
193+
TEST_F(TestEthernetInterface, disconnect)
194+
{
195+
doConnect();
196+
197+
EXPECT_CALL(*netStackIface, bringdown())
198+
.Times(1)
199+
.WillOnce(Return(NSAPI_ERROR_OK));
200+
EXPECT_EQ(NSAPI_ERROR_OK, iface->disconnect());
201+
}
202+
203+
TEST_F(TestEthernetInterface, set_network)
204+
{
205+
char ipAddress[NSAPI_IPv4_SIZE] = "127.0.0.1";
206+
char netmask[NSAPI_IPv4_SIZE] = "255.255.0.0";
207+
char gateway[NSAPI_IPv4_SIZE] = "127.0.0.2";
208+
209+
const char *ipAddressArg;
210+
const char *netmaskArg;
211+
const char *gatewayArg;
212+
213+
EXPECT_EQ(0, iface->get_ip_address());
214+
EXPECT_EQ(0, iface->get_netmask());
215+
EXPECT_EQ(0, iface->get_gateway());
216+
217+
// Set the network data
218+
EXPECT_EQ(NSAPI_ERROR_OK, iface->set_network(ipAddress, netmask, gateway));
219+
220+
// Now the bringup should have different arguments. We can't use doConnect method.
221+
EXPECT_CALL(*stackMock, add_ethernet_interface(testing::Ref(*emacMock), true, _))
222+
.Times(1)
223+
.WillOnce(DoAll(SetArgPointee<2>(netStackIface), Return(NSAPI_ERROR_OK)));
224+
EXPECT_CALL(*netStackIface, attach(_))
225+
.Times(1)
226+
.RetiresOnSaturation();
227+
// Do not put the expected char * arguments, as they are pointers and would not match
228+
EXPECT_CALL(*netStackIface, bringup(false, _, _, _, DEFAULT_STACK, true))
229+
.Times(1)
230+
.WillOnce(DoAll(SaveArg<1>(&ipAddressArg),
231+
SaveArg<2>(&netmaskArg),
232+
SaveArg<3>(&gatewayArg),
233+
Return(NSAPI_ERROR_OK)));
234+
EXPECT_EQ(NSAPI_ERROR_OK, iface->connect());
235+
// Check the contents of the stored pointer arguments.
236+
EXPECT_TRUE(0 == strcmp(ipAddress, ipAddressArg));
237+
EXPECT_TRUE(0 == strcmp(netmask, netmaskArg));
238+
EXPECT_TRUE(0 == strcmp(gateway, gatewayArg));
239+
240+
// Testing the getters makes sense now.
241+
EXPECT_CALL(*netStackIface, get_ip_address(_, _))
242+
.Times(1)
243+
.WillOnce(DoAll(SetArgPointee<0>(*ipAddress), Return(ipAddress)));
244+
EXPECT_EQ(std::string(ipAddress), std::string(iface->get_ip_address()));
245+
246+
EXPECT_CALL(*netStackIface, get_netmask(_, _))
247+
.Times(1)
248+
.WillOnce(DoAll(SetArgPointee<0>(*netmask), Return(netmask)));
249+
EXPECT_EQ(std::string(netmask), std::string(iface->get_netmask()));
250+
251+
EXPECT_CALL(*netStackIface, get_gateway(_, _))
252+
.Times(1)
253+
.WillOnce(DoAll(SetArgPointee<0>(*gateway), Return(gateway)));
254+
EXPECT_EQ(std::string(gateway), std::string(iface->get_gateway()));
255+
}
256+
257+
TEST_F(TestEthernetInterface, get_connection_status)
258+
{
259+
EXPECT_EQ(NSAPI_STATUS_DISCONNECTED, iface->get_connection_status());
260+
261+
doConnect();
262+
263+
EXPECT_CALL(*netStackIface, get_connection_status())
264+
.Times(1)
265+
.WillOnce(Return(NSAPI_STATUS_LOCAL_UP));
266+
EXPECT_EQ(NSAPI_STATUS_LOCAL_UP, iface->get_connection_status());
267+
}
268+
269+
TEST_F(TestEthernetInterface, attach)
270+
{
271+
doConnect();
272+
EXPECT_CALL(*netStackIface, attach(_)) // TODO: check that the correct function is passed.
273+
.Times(1);
274+
iface->attach(cb);
275+
}
276+
277+
TEST_F(TestEthernetInterface, set_dhcp)
278+
{
279+
EXPECT_EQ(NSAPI_ERROR_OK, iface->set_dhcp(false));
280+
doConnect(false, true);
281+
}
282+
283+
TEST_F(TestEthernetInterface, set_blocking)
284+
{
285+
EXPECT_EQ(NSAPI_ERROR_OK, iface->set_blocking(false));
286+
doConnect(true, false);
287+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
####################
3+
# UNIT TESTS
4+
####################
5+
6+
# Unit test suite name
7+
set(TEST_SUITE_NAME "features_netsocket_EthernetInterface")
8+
9+
# Source files
10+
set(unittest-sources
11+
../features/netsocket/SocketAddress.cpp
12+
../features/netsocket/EthernetInterface.cpp
13+
../features/netsocket/EMACInterface.cpp
14+
../features/netsocket/NetworkInterface.cpp
15+
../features/netsocket/NetworkStack.cpp
16+
../features/frameworks/nanostack-libservice/source/libip4string/ip4tos.c
17+
../features/frameworks/nanostack-libservice/source/libip4string/stoip4.c
18+
)
19+
20+
# Test files
21+
set(unittest-test-sources
22+
features/netsocket/EthernetInterface/test_EthernetInterface.cpp
23+
stubs/Mutex_stub.cpp
24+
stubs/mbed_assert_stub.c
25+
stubs/equeue_stub.c
26+
stubs/EventQueue_stub.cpp
27+
stubs/mbed_shared_queues_stub.cpp
28+
stubs/nsapi_dns_stub.cpp
29+
stubs/EventFlags_stub.cpp
30+
stubs/stoip4_stub.c
31+
stubs/ip4tos_stub.c
32+
stubs/NetworkStack_stub.cpp
33+
)

UNITTESTS/features/netsocket/InternetSocket/test_InternetSocket.cpp

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,30 @@ class stubInternetSocket : public InternetSocket {
5858
}
5959

6060
// Testing functions
61-
void add_reader (void) { _readers++;}
62-
void rem_reader (void) { _readers--;}
63-
void add_writer (void) { _writers++;}
64-
void rem_writer (void) { _writers--;}
65-
void add_pending (void) { _pending++;}
66-
void rem_pending (void) { _pending--;}
61+
void add_reader(void)
62+
{
63+
_readers++;
64+
}
65+
void rem_reader(void)
66+
{
67+
_readers--;
68+
}
69+
void add_writer(void)
70+
{
71+
_writers++;
72+
}
73+
void rem_writer(void)
74+
{
75+
_writers--;
76+
}
77+
void add_pending(void)
78+
{
79+
_pending++;
80+
}
81+
void rem_pending(void)
82+
{
83+
_pending--;
84+
}
6785

6886
protected:
6987
virtual nsapi_protocol_t get_proto()

0 commit comments

Comments
 (0)