diff --git a/tests/device/test_ClientContext/test_ClientContext.ino b/tests/device/test_ClientContext/test_ClientContext.ino new file mode 100644 index 0000000000..ea6ea015dc --- /dev/null +++ b/tests/device/test_ClientContext/test_ClientContext.ino @@ -0,0 +1,94 @@ +#include +#include +#include +#include + +extern "C" { +#include "user_interface.h" +} + +BS_ENV_DECLARE(); + +// no need for #include +struct tcp_pcb; +extern struct tcp_pcb* tcp_tw_pcbs; +extern "C" void tcp_abort (struct tcp_pcb* pcb); + +void tcpCleanup (void) +{ + while (tcp_tw_pcbs) + tcp_abort(tcp_tw_pcbs); +} + +void setup() +{ + Serial.begin(115200); + Serial.setDebugOutput(true); + WiFi.persistent(false); + WiFi.mode(WIFI_STA); + WiFi.begin(STA_SSID, STA_PASS); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + } + BS_RUN(Serial); +} + +TEST_CASE("WiFi release ClientContext", "[clientcontext]") +{ + #define MAXLOOPS 50 + #define SUCCESS_GOAL 10 + #define srv SERVER_IP + + WiFiClient client; + + Serial.print(srv); + + // look for reachable port on gateway + int port; + for (port = 8266; port <= 8285; port++) + if (client.connect(srv, port)) + { + client.stop(); + break; + } + if (port > 8285) + port = 0; + + Serial.printf(":%d\r\n", port); + + int loops = 0; + int success = 0; + + if (port) + { + tcpCleanup(); + int heapStart = ESP.getFreeHeap(); + int minHeap = heapStart / 2; + int heap = heapStart; + Serial.printf("heap: %d\r\n", heap); + + while (success < SUCCESS_GOAL && ++loops <= MAXLOOPS && (int)ESP.getFreeHeap() > minHeap) + if (client.connect(srv, port)) + { + client.stop(); + tcpCleanup(); + int newHeap = (int)ESP.getFreeHeap(); + Serial.printf("%03d %5d %d\r\n", loops, newHeap, newHeap - heap); + if (newHeap - heap == 0) + success++; + heap = newHeap; + } + + Serial.printf("heap: %d\r\n" + "loops: %d\r\nstable-loops: %d\r\n", + ESP.getFreeHeap(), + loops, + success); + } + + REQUIRE(success >= SUCCESS_GOAL); +} + +void loop() +{ +} diff --git a/tests/device/test_ClientContext/test_ClientContext.py b/tests/device/test_ClientContext/test_ClientContext.py new file mode 100644 index 0000000000..ae29bcd2fe --- /dev/null +++ b/tests/device/test_ClientContext/test_ClientContext.py @@ -0,0 +1,60 @@ +from mock_decorators import setup, teardown +from flask import Flask, request +from threading import Thread +import socket +import select +import sys +import os + +@setup('WiFi release ClientContext') +def setup_tcpsrv(e): + + global thread + + app = Flask(__name__) + + def run(): + + global running + + running = False + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + for port in range(8266, 8285 + 1): + try: + print >>sys.stderr, 'trying port', port + server_address = ("0.0.0.0", port) + sock.bind(server_address) + sock.listen(1) + running = True + break + except Exception: + print >>sys.stderr, 'busy' + if not running: + return + print >>sys.stderr, 'starting up on %s port %s' % server_address + print >>sys.stderr, 'waiting for connections' + while running: + print >>sys.stderr, 'loop' + readable, writable, errored = select.select([sock], [], [], 1.0) + if readable: + connection, client_address = sock.accept() + try: + print >>sys.stderr, 'client connected:', client_address + finally: + print >>sys.stderr, 'close' + connection.shutdown(socket.SHUT_RDWR) + connection.close() + + thread = Thread(target=run) + thread.start() + +@teardown('WiFi release ClientContext') +def teardown_tcpsrv(e): + + global thread + global running + + print >>sys.stderr, 'closing' + running = False + thread.join() + return 0