Skip to content

Commit 6272e89

Browse files
authored
mock: addrList fix (#6248)
* improve mock tcp write * mock addrlist * add a single mock build in travis
1 parent 5a47cab commit 6272e89

File tree

5 files changed

+154
-20
lines changed

5 files changed

+154
-20
lines changed

.travis.yml

+4
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ jobs:
9393
script: $TRAVIS_BUILD_DIR/tests/ci/style_check.sh
9494
install: tests/ci/install_astyle.sh
9595

96+
- name: "Mock trivial test"
97+
stage: build
98+
script: $TRAVIS_BUILD_DIR/tests/buildm.sh
99+
96100
- name: "Boards"
97101
stage: build
98102
script: $TRAVIS_BUILD_DIR/tests/ci/build_boards.sh

libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <arch/cc.h>
2626
#include <sys/time.h>
2727
#include <IPAddress.h>
28+
#include <AddrList.h>
2829
#include <lwip/ip_addr.h>
2930
#include <WString.h>
3031
#include <cstdint>

tests/buildm.sh

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/sh
2+
3+
set -e
4+
5+
cd $(cd ${0%/*}; pwd)/host
6+
7+
make -j ../../libraries/ESP8266WebServer/examples/FSBrowser/FSBrowser

tests/host/common/AddrList.h

+114
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,117 @@
22
// TODO
33
// mock AddrList with POSIX mock API
44
// later: real AddrList will work with lwIP API
5+
6+
// mock is IPv4 only
7+
8+
#ifndef __ADDRLISTX_H
9+
#define __ADDRLISTX_H
10+
11+
#include <ESP8266WiFi.h>
12+
13+
namespace esp8266
14+
{
15+
16+
namespace AddressListImplementation
17+
{
18+
19+
20+
struct netifWrapper
21+
{
22+
netifWrapper (bool netif) : _netif(netif) {}
23+
netifWrapper (const netifWrapper& o) : _netif(o._netif) {}
24+
25+
netifWrapper& operator= (const netifWrapper& o)
26+
{
27+
_netif = o._netif;
28+
return *this;
29+
}
30+
31+
bool equal(const netifWrapper& o)
32+
{
33+
return _netif == o._netif;
34+
}
35+
36+
// address properties
37+
IPAddress addr () const { return WiFi.localIP(); }
38+
bool isLegacy () const { return true; }
39+
bool isLocal () const { return false; }
40+
bool isV4 () const { return addr().isV4(); }
41+
bool isV6 () const { return !addr().isV4(); }
42+
String toString() const { return addr().toString(); }
43+
44+
// related to legacy address (_num=0, ipv4)
45+
IPAddress ipv4 () const { ip_info info; wifi_get_ip_info(0, &info); return info.ip; }
46+
IPAddress netmask () const { ip_info info; wifi_get_ip_info(0, &info); return info.netmask; }
47+
IPAddress gw () const { ip_info info; wifi_get_ip_info(0, &info); return info.gw; }
48+
49+
// common to all addresses of this interface
50+
String ifname () const { return "st"; }
51+
const char* ifhostname () const { return wifi_station_get_hostname(); }
52+
String ifmac () const { uint8_t mac[20]; WiFi.macAddress(mac); return String((char*)mac); }
53+
int ifnumber () const { return 0; }
54+
bool ifUp () const { return true; }
55+
56+
bool _netif;
57+
};
58+
59+
60+
class AddressListIterator
61+
{
62+
public:
63+
AddressListIterator (const netifWrapper& o) : netIf(o) {}
64+
AddressListIterator (bool netif) : netIf(netif)
65+
{
66+
// This constructor is called with lwIP's global netif_list, or
67+
// nullptr. operator++() is designed to loop through _configured_
68+
// addresses. That's why netIf's _num is initialized to -1 to allow
69+
// returning the first usable address to AddressList::begin().
70+
(void)operator++();
71+
}
72+
73+
const netifWrapper& operator* () const { return netIf; }
74+
const netifWrapper* operator-> () const { return &netIf; }
75+
76+
bool operator== (AddressListIterator& o) { return netIf.equal(*o); }
77+
bool operator!= (AddressListIterator& o) { return !netIf.equal(*o); }
78+
79+
AddressListIterator& operator= (const AddressListIterator& o) { netIf = o.netIf; return *this; }
80+
81+
AddressListIterator operator++ (int)
82+
{
83+
AddressListIterator ret = *this;
84+
(void)operator++();
85+
return ret;
86+
}
87+
88+
AddressListIterator& operator++ ()
89+
{
90+
netIf._netif = !netIf._netif;
91+
return *this;
92+
}
93+
94+
netifWrapper netIf;
95+
};
96+
97+
98+
class AddressList
99+
{
100+
public:
101+
using const_iterator = const AddressListIterator;
102+
103+
const_iterator begin () const { return const_iterator(true); }
104+
const_iterator end () const { return const_iterator(false); }
105+
106+
};
107+
108+
inline AddressList::const_iterator begin (const AddressList& a) { return a.begin(); }
109+
inline AddressList::const_iterator end (const AddressList& a) { return a.end(); }
110+
111+
112+
} // AddressListImplementation
113+
114+
} // esp8266
115+
116+
extern esp8266::AddressListImplementation::AddressList addrList;
117+
118+
#endif

tests/host/common/ClientContextSocket.cpp

+28-20
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,11 @@ ssize_t mockPeekBytes (int sock, char* dst, size_t usersize, int timeout_ms, cha
136136
p.events = POLLIN;
137137
} while (poll(&p, 1, timeout_ms) == 1);
138138

139-
memcpy(dst, ccinbuf, retsize);
139+
if (dst)
140+
{
141+
memcpy(dst, ccinbuf, retsize);
142+
}
143+
140144
return retsize;
141145
}
142146

@@ -153,32 +157,36 @@ ssize_t mockRead (int sock, char* dst, size_t size, int timeout_ms, char* ccinbu
153157

154158
ssize_t mockWrite (int sock, const uint8_t* data, size_t size, int timeout_ms)
155159
{
156-
struct pollfd p;
157-
p.fd = sock;
158-
p.events = POLLOUT;
159-
int ret = poll(&p, 1, timeout_ms);
160-
if (ret == -1)
161-
{
162-
fprintf(stderr, MOCK "ClientContext::write: poll(%d): %s\n", sock, strerror(errno));
163-
return 0;
164-
}
165-
if (ret)
160+
size_t sent = 0;
161+
while (sent < size)
166162
{
167-
#ifndef MSG_NOSIGNAL
168-
ret = ::write(sock, data, size);
169-
#else
170-
ret = ::send(sock, data, size, MSG_NOSIGNAL);
171-
#endif
163+
164+
struct pollfd p;
165+
p.fd = sock;
166+
p.events = POLLOUT;
167+
int ret = poll(&p, 1, timeout_ms);
172168
if (ret == -1)
173169
{
174170
fprintf(stderr, MOCK "ClientContext::write(%d): %s\n", sock, strerror(errno));
175171
return -1;
176172
}
177-
if (ret != (int)size)
173+
if (ret)
178174
{
179-
fprintf(stderr, MOCK "ClientContext::write: short write (%d < %zd) (FIXME poll loop TODO)\n", ret, size);
180-
exit(EXIT_FAILURE);
175+
#ifndef MSG_NOSIGNAL
176+
ret = ::write(sock, data + sent, size - sent);
177+
#else
178+
ret = ::send(sock, data + sent, size - sent, MSG_NOSIGNAL);
179+
#endif
180+
if (ret == -1)
181+
{
182+
fprintf(stderr, MOCK "ClientContext::read: write(%d): %s\n", sock, strerror(errno));
183+
return -1;
184+
}
185+
sent += ret;
186+
if (sent < size)
187+
fprintf(stderr, MOCK "ClientContext::write: sent %d bytes (%zd / %zd)\n", ret, sent, size);
181188
}
182189
}
183-
return ret;
190+
fprintf(stderr, MOCK "ClientContext::write: total sent %zd bytes\n", sent);
191+
return sent;
184192
}

0 commit comments

Comments
 (0)