1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-22 21:23:07 +03:00

mock: addrList fix (#6248)

* improve mock tcp write
* mock addrlist
* add a single mock build in travis
This commit is contained in:
david gauchard 2019-07-03 09:49:03 +02:00 committed by GitHub
parent 5a47cab77d
commit 6272e897ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 154 additions and 20 deletions

View File

@ -93,6 +93,10 @@ jobs:
script: $TRAVIS_BUILD_DIR/tests/ci/style_check.sh
install: tests/ci/install_astyle.sh
- name: "Mock trivial test"
stage: build
script: $TRAVIS_BUILD_DIR/tests/buildm.sh
- name: "Boards"
stage: build
script: $TRAVIS_BUILD_DIR/tests/ci/build_boards.sh

View File

@ -25,6 +25,7 @@
#include <arch/cc.h>
#include <sys/time.h>
#include <IPAddress.h>
#include <AddrList.h>
#include <lwip/ip_addr.h>
#include <WString.h>
#include <cstdint>

7
tests/buildm.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/sh
set -e
cd $(cd ${0%/*}; pwd)/host
make -j ../../libraries/ESP8266WebServer/examples/FSBrowser/FSBrowser

View File

@ -2,3 +2,117 @@
// TODO
// mock AddrList with POSIX mock API
// later: real AddrList will work with lwIP API
// mock is IPv4 only
#ifndef __ADDRLISTX_H
#define __ADDRLISTX_H
#include <ESP8266WiFi.h>
namespace esp8266
{
namespace AddressListImplementation
{
struct netifWrapper
{
netifWrapper (bool netif) : _netif(netif) {}
netifWrapper (const netifWrapper& o) : _netif(o._netif) {}
netifWrapper& operator= (const netifWrapper& o)
{
_netif = o._netif;
return *this;
}
bool equal(const netifWrapper& o)
{
return _netif == o._netif;
}
// address properties
IPAddress addr () const { return WiFi.localIP(); }
bool isLegacy () const { return true; }
bool isLocal () const { return false; }
bool isV4 () const { return addr().isV4(); }
bool isV6 () const { return !addr().isV4(); }
String toString() const { return addr().toString(); }
// related to legacy address (_num=0, ipv4)
IPAddress ipv4 () const { ip_info info; wifi_get_ip_info(0, &info); return info.ip; }
IPAddress netmask () const { ip_info info; wifi_get_ip_info(0, &info); return info.netmask; }
IPAddress gw () const { ip_info info; wifi_get_ip_info(0, &info); return info.gw; }
// common to all addresses of this interface
String ifname () const { return "st"; }
const char* ifhostname () const { return wifi_station_get_hostname(); }
String ifmac () const { uint8_t mac[20]; WiFi.macAddress(mac); return String((char*)mac); }
int ifnumber () const { return 0; }
bool ifUp () const { return true; }
bool _netif;
};
class AddressListIterator
{
public:
AddressListIterator (const netifWrapper& o) : netIf(o) {}
AddressListIterator (bool netif) : netIf(netif)
{
// This constructor is called with lwIP's global netif_list, or
// nullptr. operator++() is designed to loop through _configured_
// addresses. That's why netIf's _num is initialized to -1 to allow
// returning the first usable address to AddressList::begin().
(void)operator++();
}
const netifWrapper& operator* () const { return netIf; }
const netifWrapper* operator-> () const { return &netIf; }
bool operator== (AddressListIterator& o) { return netIf.equal(*o); }
bool operator!= (AddressListIterator& o) { return !netIf.equal(*o); }
AddressListIterator& operator= (const AddressListIterator& o) { netIf = o.netIf; return *this; }
AddressListIterator operator++ (int)
{
AddressListIterator ret = *this;
(void)operator++();
return ret;
}
AddressListIterator& operator++ ()
{
netIf._netif = !netIf._netif;
return *this;
}
netifWrapper netIf;
};
class AddressList
{
public:
using const_iterator = const AddressListIterator;
const_iterator begin () const { return const_iterator(true); }
const_iterator end () const { return const_iterator(false); }
};
inline AddressList::const_iterator begin (const AddressList& a) { return a.begin(); }
inline AddressList::const_iterator end (const AddressList& a) { return a.end(); }
} // AddressListImplementation
} // esp8266
extern esp8266::AddressListImplementation::AddressList addrList;
#endif

View File

@ -136,7 +136,11 @@ ssize_t mockPeekBytes (int sock, char* dst, size_t usersize, int timeout_ms, cha
p.events = POLLIN;
} while (poll(&p, 1, timeout_ms) == 1);
memcpy(dst, ccinbuf, retsize);
if (dst)
{
memcpy(dst, ccinbuf, retsize);
}
return retsize;
}
@ -153,32 +157,36 @@ ssize_t mockRead (int sock, char* dst, size_t size, int timeout_ms, char* ccinbu
ssize_t mockWrite (int sock, const uint8_t* data, size_t size, int timeout_ms)
{
struct pollfd p;
p.fd = sock;
p.events = POLLOUT;
int ret = poll(&p, 1, timeout_ms);
if (ret == -1)
size_t sent = 0;
while (sent < size)
{
fprintf(stderr, MOCK "ClientContext::write: poll(%d): %s\n", sock, strerror(errno));
return 0;
}
if (ret)
{
#ifndef MSG_NOSIGNAL
ret = ::write(sock, data, size);
#else
ret = ::send(sock, data, size, MSG_NOSIGNAL);
#endif
struct pollfd p;
p.fd = sock;
p.events = POLLOUT;
int ret = poll(&p, 1, timeout_ms);
if (ret == -1)
{
fprintf(stderr, MOCK "ClientContext::write(%d): %s\n", sock, strerror(errno));
return -1;
}
if (ret != (int)size)
if (ret)
{
fprintf(stderr, MOCK "ClientContext::write: short write (%d < %zd) (FIXME poll loop TODO)\n", ret, size);
exit(EXIT_FAILURE);
#ifndef MSG_NOSIGNAL
ret = ::write(sock, data + sent, size - sent);
#else
ret = ::send(sock, data + sent, size - sent, MSG_NOSIGNAL);
#endif
if (ret == -1)
{
fprintf(stderr, MOCK "ClientContext::read: write(%d): %s\n", sock, strerror(errno));
return -1;
}
sent += ret;
if (sent < size)
fprintf(stderr, MOCK "ClientContext::write: sent %d bytes (%zd / %zd)\n", ret, sent, size);
}
}
return ret;
fprintf(stderr, MOCK "ClientContext::write: total sent %zd bytes\n", sent);
return sent;
}