Skip to content

mock: addrList fix #6248

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions libraries/ESP8266mDNS/src/LEAmDNS_Control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
7 changes: 7 additions & 0 deletions tests/buildm.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/sh

set -e

cd $(cd ${0%/*}; pwd)/host

make -j ../../libraries/ESP8266WebServer/examples/FSBrowser/FSBrowser
114 changes: 114 additions & 0 deletions tests/host/common/AddrList.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
48 changes: 28 additions & 20 deletions tests/host/common/ClientContextSocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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)
{
fprintf(stderr, MOCK "ClientContext::write: poll(%d): %s\n", sock, strerror(errno));
return 0;
}
if (ret)
size_t sent = 0;
while (sent < size)
{
#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;
}