From 6272e897ca959694d2dbb410eb5e11127bcfca73 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Wed, 3 Jul 2019 09:49:03 +0200 Subject: [PATCH] mock: addrList fix (#6248) * improve mock tcp write * mock addrlist * add a single mock build in travis --- .travis.yml | 4 + libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp | 1 + tests/buildm.sh | 7 ++ tests/host/common/AddrList.h | 114 ++++++++++++++++++ tests/host/common/ClientContextSocket.cpp | 48 +++++--- 5 files changed, 154 insertions(+), 20 deletions(-) create mode 100755 tests/buildm.sh diff --git a/.travis.yml b/.travis.yml index b0f716f1d..498739f1c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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 diff --git a/libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp b/libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp index 64a670f4a..b00a84f73 100644 --- a/libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp +++ b/libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/tests/buildm.sh b/tests/buildm.sh new file mode 100755 index 000000000..1b973a59f --- /dev/null +++ b/tests/buildm.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +set -e + +cd $(cd ${0%/*}; pwd)/host + +make -j ../../libraries/ESP8266WebServer/examples/FSBrowser/FSBrowser diff --git a/tests/host/common/AddrList.h b/tests/host/common/AddrList.h index 260a301ab..0da63bc7f 100644 --- a/tests/host/common/AddrList.h +++ b/tests/host/common/AddrList.h @@ -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 + +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 diff --git a/tests/host/common/ClientContextSocket.cpp b/tests/host/common/ClientContextSocket.cpp index 30ba39038..b2366fa72 100644 --- a/tests/host/common/ClientContextSocket.cpp +++ b/tests/host/common/ClientContextSocket.cpp @@ -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; }