mirror of
https://github.com/espressif/esp-lwip.git
synced 2026-08-21 09:20:09 +00:00
ci: Add simple CI test
with relaxed criteria on the lingering test, as the fix is not added yet
This commit is contained in:
@@ -1,32 +1,31 @@
|
|||||||
name: CI
|
name: CI
|
||||||
|
|
||||||
on:
|
on: [push, pull_request]
|
||||||
push:
|
|
||||||
branches: [master]
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build-and-test:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
compiler: [gcc, clang]
|
compiler: [gcc, clang]
|
||||||
env:
|
env:
|
||||||
CC: ${{ matrix.compiler }}
|
CC: ${{ matrix.compiler }}
|
||||||
LSAN_OPTIONS: verbosity=1:log_threads=1
|
LSAN_OPTIONS: verbosity=1:log_threads=1
|
||||||
|
WGET_CHECK2JUNIT_PY: https://raw.githubusercontent.com/gsauthof/utility/42792030/check2junit.py
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
run: sudo apt-get install check ninja-build doxygen
|
run: |
|
||||||
|
sudo apt-get install check ninja-build doxygen
|
||||||
|
python -m pip install lxml junit-xml
|
||||||
|
wget --no-verbose ${WGET_CHECK2JUNIT_PY}
|
||||||
|
|
||||||
|
- name: Build and Run unit tests with make and cmake
|
||||||
|
run: ./test/ci/unit_tests.sh
|
||||||
|
|
||||||
- name: Copy lwipcfg.h for example app
|
- name: Copy lwipcfg.h for example app
|
||||||
run: cp contrib/examples/example_app/lwipcfg.h.ci contrib/examples/example_app/lwipcfg.h
|
run: cp contrib/examples/example_app/lwipcfg.h.ci contrib/examples/example_app/lwipcfg.h
|
||||||
|
|
||||||
- name: Build unit tests with make
|
|
||||||
run: make -C contrib/ports/unix/check
|
|
||||||
- name: Run unit tests
|
|
||||||
run: make -C contrib/ports/unix/check check
|
|
||||||
|
|
||||||
- name: Run cmake
|
- name: Run cmake
|
||||||
run: mkdir build && cd build && cmake .. -G Ninja
|
run: mkdir build && cd build && cmake .. -G Ninja
|
||||||
- name: Build with cmake
|
- name: Build with cmake
|
||||||
@@ -35,9 +34,32 @@ jobs:
|
|||||||
run: cd build && cmake --build . --target lwipdocs
|
run: cd build && cmake --build . --target lwipdocs
|
||||||
|
|
||||||
- name: Validate combinations of options
|
- name: Validate combinations of options
|
||||||
run: cd contrib/ports/unix/example_app && ./iteropts.sh
|
run: ./test/ci/validate_opts.sh
|
||||||
|
|
||||||
- name: Build the default example app
|
- name: Build and run test apps
|
||||||
run: |
|
run: ./test/ci/test_apps.sh
|
||||||
cp contrib/examples/example_app/lwipcfg.h.example contrib/examples/example_app/lwipcfg.h
|
|
||||||
make -C contrib/ports/unix/example_app TESTFLAGS="-Wno-documentation" -j 4
|
- name: Upload Test Results
|
||||||
|
if: always()
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Test Results ${{ matrix.compiler }}
|
||||||
|
path: "*.xml"
|
||||||
|
|
||||||
|
publish-test-results:
|
||||||
|
name: "Publish Tests Results"
|
||||||
|
needs: build-and-test
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
checks: write
|
||||||
|
if: always()
|
||||||
|
steps:
|
||||||
|
- name: Download Artifacts
|
||||||
|
uses: actions/download-artifact@v2
|
||||||
|
with:
|
||||||
|
path: artifacts
|
||||||
|
|
||||||
|
- name: Publish Test Results
|
||||||
|
uses: EnricoMi/publish-unit-test-result-action@v2
|
||||||
|
with:
|
||||||
|
junit_files: "artifacts/**/*.xml"
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
stages:
|
||||||
|
- host_test
|
||||||
|
- deploy
|
||||||
|
|
||||||
|
image: ${CI_DOCKER_REGISTRY}/esp-env-v5.0:2
|
||||||
|
|
||||||
|
variables:
|
||||||
|
CMAKE_SH: cmake-3.22.3-linux-x86_64.sh
|
||||||
|
CC: cc
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
# Use CI Tools
|
||||||
|
- curl -sSL ${CIT_LOADER_URL} | sh
|
||||||
|
- source citools/import_functions
|
||||||
|
|
||||||
|
.get_cmake: &get_cmake |
|
||||||
|
wget -q https://github.com/Kitware/CMake/releases/download/v3.22.3/${CMAKE_SH}
|
||||||
|
mkdir -p /opt/cmake && sh ${CMAKE_SH} --prefix=/opt/cmake --skip-license
|
||||||
|
export PATH=/opt/cmake/bin:$PATH
|
||||||
|
|
||||||
|
run_unittests:
|
||||||
|
stage: host_test
|
||||||
|
tags:
|
||||||
|
- host_test
|
||||||
|
dependencies: []
|
||||||
|
script:
|
||||||
|
- ./test/ci/unit_tests.sh
|
||||||
|
|
||||||
|
build_all:
|
||||||
|
stage: host_test
|
||||||
|
tags:
|
||||||
|
- host_test
|
||||||
|
script:
|
||||||
|
- cp contrib/examples/example_app/lwipcfg.h.ci contrib/examples/example_app/lwipcfg.h
|
||||||
|
- mkdir build && cd build && cmake .. -G Ninja
|
||||||
|
- cmake --build .
|
||||||
|
- cmake --build . --target lwipdocs
|
||||||
|
|
||||||
|
validate_opts:
|
||||||
|
stage: host_test
|
||||||
|
tags:
|
||||||
|
- host_test
|
||||||
|
script:
|
||||||
|
- ./test/ci/validate_opts.sh
|
||||||
|
|
||||||
|
run_test_apps:
|
||||||
|
stage: host_test
|
||||||
|
tags:
|
||||||
|
- host_test
|
||||||
|
script:
|
||||||
|
- *get_cmake
|
||||||
|
- ./test/ci/test_apps.sh
|
||||||
|
|
||||||
|
.add_gh_key_remote: &add_gh_key_remote |
|
||||||
|
command -v ssh-agent >/dev/null || exit 1
|
||||||
|
eval $(ssh-agent -s)
|
||||||
|
printf '%s\n' "${GH_PUSH_KEY}" | tr -d '\r' | ssh-add - > /dev/null
|
||||||
|
mkdir -p ~/.ssh && chmod 700 ~/.ssh
|
||||||
|
[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config || ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
|
||||||
|
git remote remove github || true
|
||||||
|
git remote add github ${GH_PUSH_REPO}
|
||||||
|
|
||||||
|
push_master_to_github:
|
||||||
|
stage: deploy
|
||||||
|
only:
|
||||||
|
- 2.1.2-esp
|
||||||
|
- 2.1.3-esp
|
||||||
|
when: on_success
|
||||||
|
variables:
|
||||||
|
GIT_STRATEGY: clone
|
||||||
|
script:
|
||||||
|
- *add_gh_key_remote
|
||||||
|
- "[ -n \"${CI_COMMIT_TAG:-}\" ] && git push github ${CI_COMMIT_TAG}"
|
||||||
|
- "[ -z \"${CI_COMMIT_TAG:-}\" ] && git push github ${CI_COMMIT_SHA}:refs/heads/${CI_COMMIT_REF_NAME}"
|
||||||
|
|
||||||
@@ -76,6 +76,8 @@ if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
|||||||
list(APPEND LWIP_COMPILER_FLAGS_GNU_CLANG
|
list(APPEND LWIP_COMPILER_FLAGS_GNU_CLANG
|
||||||
-Wlogical-op
|
-Wlogical-op
|
||||||
-Wtrampolines
|
-Wtrampolines
|
||||||
|
-fno-stack-clash-protection
|
||||||
|
-Wno-error=format-extra-args
|
||||||
)
|
)
|
||||||
|
|
||||||
if (NOT LWIP_HAVE_MBEDTLS)
|
if (NOT LWIP_HAVE_MBEDTLS)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ include(${LWIP_DIR}/contrib/ports/CMakeCommon.cmake)
|
|||||||
|
|
||||||
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||||
# check.h causes 'error: token pasting of ',' and __VA_ARGS__ is a GNU extension' with clang 9.0.0
|
# check.h causes 'error: token pasting of ',' and __VA_ARGS__ is a GNU extension' with clang 9.0.0
|
||||||
list(LWIP_COMPILER_FLAGS APPEND -Wno-gnu-zero-variadic-macro-arguments)
|
list(APPEND LWIP_COMPILER_FLAGS -Wno-gnu-zero-variadic-macro-arguments)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set (LWIP_DEFINITIONS -DLWIP_DEBUG -DLWIP_NOASSERT_ON_ERROR)
|
set (LWIP_DEFINITIONS -DLWIP_DEBUG -DLWIP_NOASSERT_ON_ERROR)
|
||||||
|
|||||||
@@ -45,7 +45,6 @@
|
|||||||
* leaking messages.
|
* leaking messages.
|
||||||
*/
|
*/
|
||||||
#define _GNU_SOURCE /* pull in pthread_setname_np() on Linux */
|
#define _GNU_SOURCE /* pull in pthread_setname_np() on Linux */
|
||||||
|
|
||||||
#include "lwip/debug.h"
|
#include "lwip/debug.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ PROJECT_NAME = "lwIP"
|
|||||||
# could be handy for archiving the generated documentation or if some version
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = "2.2.0.esp"
|
PROJECT_NUMBER = "2.2.0.dev"
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer a
|
# for a project that appears at the top of each page and should give viewer a
|
||||||
|
|||||||
+1
-1
@@ -983,7 +983,7 @@ lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM)
|
|||||||
err = ERR_OK;
|
err = ERR_OK;
|
||||||
/* linger enabled/required at all? (i.e. is there untransmitted data left?) */
|
/* linger enabled/required at all? (i.e. is there untransmitted data left?) */
|
||||||
if ((conn->linger >= 0) && (conn->pcb.tcp->unsent || conn->pcb.tcp->unacked)) {
|
if ((conn->linger >= 0) && (conn->pcb.tcp->unsent || conn->pcb.tcp->unacked)) {
|
||||||
if ((conn->linger == 0)) {
|
if (conn->linger == 0) {
|
||||||
/* data left but linger prevents waiting */
|
/* data left but linger prevents waiting */
|
||||||
tcp_abort(tpcb);
|
tcp_abort(tpcb);
|
||||||
tpcb = NULL;
|
tpcb = NULL;
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ extern "C" {
|
|||||||
#if LWIP_VERSION_IS_RELEASE
|
#if LWIP_VERSION_IS_RELEASE
|
||||||
#define LWIP_VERSION_STRING_SUFFIX ""
|
#define LWIP_VERSION_STRING_SUFFIX ""
|
||||||
#elif LWIP_VERSION_IS_DEVELOPMENT
|
#elif LWIP_VERSION_IS_DEVELOPMENT
|
||||||
#define LWIP_VERSION_STRING_SUFFIX "esp"
|
#define LWIP_VERSION_STRING_SUFFIX "d"
|
||||||
#else
|
#else
|
||||||
#define LWIP_VERSION_STRING_SUFFIX "rc" LWIP_VERSTR(LWIP_VERSION_RC)
|
#define LWIP_VERSION_STRING_SUFFIX "rc" LWIP_VERSTR(LWIP_VERSION_RC)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.8)
|
||||||
|
|
||||||
|
project(lwip_test_apps C)
|
||||||
|
|
||||||
|
if (NOT CMAKE_SYSTEM_NAME STREQUAL Linux AND NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
|
||||||
|
message(FATAL_ERROR "Unit test are currently only working on Linux or Darwin")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT LWIP_DIR OR NOT LWIP_CONTRIB_DIR)
|
||||||
|
set(LWIP_DIR "$ENV{LWIP_DIR}")
|
||||||
|
set(LWIP_CONTRIB_DIR "$ENV{LWIP_CONTRIB_DIR}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT CI_BUILD)
|
||||||
|
set(LWIP_USE_SANITIZERS true)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(${LWIP_CONTRIB_DIR}/ports/CMakeCommon.cmake)
|
||||||
|
|
||||||
|
if(CMAKE_C_COMPILER_ID STREQUAL Clang)
|
||||||
|
# check.h causes 'error: token pasting of ',' and __VA_ARGS__ is a GNU extension' with clang 9.0.0
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set (LWIP_DEFINITIONS -DLWIP_DEBUG -DLWIP_NOASSERT_ON_ERROR -DLWIP_OPTTEST_FILE)
|
||||||
|
set (LWIP_INCLUDE_DIRS
|
||||||
|
"${LWIP_DIR}/test/apps"
|
||||||
|
"${LWIP_DIR}/test/unix"
|
||||||
|
"${LWIP_CONTRIB_DIR}/ports/unix/port/include"
|
||||||
|
"${LWIP_DIR}/test/unit"
|
||||||
|
"${LWIP_DIR}/src/include"
|
||||||
|
"${LWIP_CONTRIB_DIR}/"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/${TEST_CONFIG}"
|
||||||
|
)
|
||||||
|
|
||||||
|
include(${LWIP_CONTRIB_DIR}/ports/unix/Filelists.cmake)
|
||||||
|
include(${LWIP_DIR}/src/Filelists.cmake)
|
||||||
|
include(${LWIP_DIR}/test/apps/Filelists.cmake)
|
||||||
|
|
||||||
|
add_executable(lwip_test_apps ${LWIP_TESTFILES})
|
||||||
|
target_include_directories(lwip_test_apps PRIVATE ${LWIP_INCLUDE_DIRS})
|
||||||
|
target_compile_options(lwip_test_apps PRIVATE ${LWIP_COMPILER_FLAGS})
|
||||||
|
target_compile_definitions(lwip_test_apps PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
|
||||||
|
|
||||||
|
find_library(LIBCHECK check)
|
||||||
|
find_library(LIBM m)
|
||||||
|
target_link_libraries(lwip_test_apps ${LWIP_SANITIZER_LIBS} lwipallapps lwipcore ${LIBCHECK} ${LIBM})
|
||||||
|
|
||||||
|
if (NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
|
||||||
|
# check installed via brew on Darwin doesn't have a separate subunit library (must be statically linked)
|
||||||
|
find_library(LIBSUBUNIT subunit)
|
||||||
|
target_link_libraries(lwip_test_apps ${LIBSUBUNIT})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (CMAKE_SYSTEM_NAME STREQUAL Linux)
|
||||||
|
find_library(LIBUTIL util)
|
||||||
|
find_library(LIBPTHREAD pthread)
|
||||||
|
find_library(LIBRT rt)
|
||||||
|
target_link_libraries(lwip_test_apps ${LIBUTIL} ${LIBPTHREAD} ${LIBRT})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (CMAKE_SYSTEM_NAME STREQUAL Darwin)
|
||||||
|
# Darwin doesn't have pthreads or POSIX real-time extensions libs
|
||||||
|
find_library(LIBUTIL util)
|
||||||
|
target_link_libraries(lwip_test_apps ${LIBUTIL})
|
||||||
|
endif()
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
# This file is indended to be included in end-user CMakeLists.txt
|
||||||
|
# include(/path/to/Filelists.cmake)
|
||||||
|
# It assumes the variable LWIP_DIR is defined pointing to the
|
||||||
|
# root path of lwIP sources.
|
||||||
|
#
|
||||||
|
# This file is NOT designed (on purpose) to be used as cmake
|
||||||
|
# subdir via add_subdirectory()
|
||||||
|
# The intention is to provide greater flexibility to users to
|
||||||
|
# create their own targets using the *_SRCS variables.
|
||||||
|
|
||||||
|
set(LWIP_TESTDIR ${LWIP_DIR}/test/apps)
|
||||||
|
set(LWIP_TESTFILES
|
||||||
|
${LWIP_TESTDIR}/test_apps.c
|
||||||
|
${LWIP_TESTDIR}/test_sockets.c
|
||||||
|
${LWIP_CONTRIB_DIR}/ports/unix/port/sys_arch.c
|
||||||
|
)
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
#ifndef LWIP_HDR_LWIP_CHECK_CONFIG_H
|
||||||
|
#define LWIP_HDR_LWIP_CHECK_CONFIG_H
|
||||||
|
|
||||||
|
#endif /* LWIP_TEST_APPS_CONFIG_H */
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#ifndef LWIP_HDR_TEST_APPS_LWIPOPTS_TEST_H
|
||||||
|
#define LWIP_HDR_TEST_APPS_LWIPOPTS_TEST_H
|
||||||
|
|
||||||
|
#define LWIP_SO_LINGER 1
|
||||||
|
|
||||||
|
#ifdef LWIP_DEBUG
|
||||||
|
|
||||||
|
#define LWIP_DBG_MIN_LEVEL 0
|
||||||
|
#define PPP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define MEM_DEBUG LWIP_DBG_OFF
|
||||||
|
#define MEMP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define PBUF_DEBUG LWIP_DBG_OFF
|
||||||
|
#define API_LIB_DEBUG LWIP_DBG_OFF
|
||||||
|
#define API_MSG_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCPIP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define NETIF_DEBUG LWIP_DBG_OFF
|
||||||
|
#define SOCKETS_DEBUG LWIP_DBG_OFF
|
||||||
|
#define DNS_DEBUG LWIP_DBG_OFF
|
||||||
|
#define AUTOIP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define DHCP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define IP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define IP_REASS_DEBUG LWIP_DBG_OFF
|
||||||
|
#define ICMP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define IGMP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define UDP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_RTO_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_CWND_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_WND_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_FR_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_RST_DEBUG LWIP_DBG_OFF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_TEST_APPS_LWIPOPTS_TEST_H */
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#ifndef LWIP_HDR_TEST_APPS_LWIPOPTS_TEST_H
|
||||||
|
#define LWIP_HDR_TEST_APPS_LWIPOPTS_TEST_H
|
||||||
|
|
||||||
|
#define LWIP_SO_LINGER 1
|
||||||
|
#define SO_REUSE 1
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_TEST_APPS_LWIPOPTS_TEST_H */
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#ifndef LWIP_HDR_TEST_APPS_LWIPOPTS_TEST_H
|
||||||
|
#define LWIP_HDR_TEST_APPS_LWIPOPTS_TEST_H
|
||||||
|
|
||||||
|
#define LWIP_SO_LINGER 0
|
||||||
|
|
||||||
|
#ifdef LWIP_DEBUG
|
||||||
|
|
||||||
|
#define LWIP_DBG_MIN_LEVEL 0
|
||||||
|
#define PPP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define MEM_DEBUG LWIP_DBG_OFF
|
||||||
|
#define MEMP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define PBUF_DEBUG LWIP_DBG_OFF
|
||||||
|
#define API_LIB_DEBUG LWIP_DBG_OFF
|
||||||
|
#define API_MSG_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCPIP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define NETIF_DEBUG LWIP_DBG_OFF
|
||||||
|
#define SOCKETS_DEBUG LWIP_DBG_OFF
|
||||||
|
#define DNS_DEBUG LWIP_DBG_OFF
|
||||||
|
#define AUTOIP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define DHCP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define IP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define IP_REASS_DEBUG LWIP_DBG_OFF
|
||||||
|
#define ICMP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define IGMP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define UDP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_RTO_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_CWND_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_WND_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_FR_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
|
||||||
|
#define TCP_RST_DEBUG LWIP_DBG_OFF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_TEST_APPS_LWIPOPTS_TEST_H */
|
||||||
@@ -0,0 +1,310 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Adam Dunkels <[email protected]>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_LWIPOPTS_H
|
||||||
|
#define LWIP_LWIPOPTS_H
|
||||||
|
|
||||||
|
#ifdef LWIP_OPTTEST_FILE
|
||||||
|
#include "lwipopts_test.h"
|
||||||
|
#endif /* LWIP_OPTTEST_FILE */
|
||||||
|
|
||||||
|
#define LWIP_IPV4 1
|
||||||
|
#define LWIP_IPV6 0
|
||||||
|
#define LWIP_ND6 0
|
||||||
|
#define LWIP_IPV6_REASS 0
|
||||||
|
|
||||||
|
#define NO_SYS 0
|
||||||
|
#define LWIP_SOCKET (NO_SYS==0)
|
||||||
|
#define LWIP_NETCONN (NO_SYS==0)
|
||||||
|
#define LWIP_NETIF_API (NO_SYS==0)
|
||||||
|
|
||||||
|
#define LWIP_IGMP LWIP_IPV4
|
||||||
|
#define LWIP_ICMP LWIP_IPV4
|
||||||
|
|
||||||
|
#define LWIP_SNMP LWIP_UDP
|
||||||
|
#define MIB2_STATS LWIP_SNMP
|
||||||
|
#ifdef LWIP_HAVE_MBEDTLS
|
||||||
|
#define LWIP_SNMP_V3 (LWIP_SNMP)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LWIP_DNS LWIP_UDP
|
||||||
|
#define LWIP_MDNS_RESPONDER LWIP_UDP
|
||||||
|
|
||||||
|
#define LWIP_NUM_NETIF_CLIENT_DATA (LWIP_MDNS_RESPONDER)
|
||||||
|
|
||||||
|
#define LWIP_HAVE_LOOPIF 1
|
||||||
|
#define LWIP_NETIF_LOOPBACK 1
|
||||||
|
#define LWIP_LOOPBACK_MAX_PBUFS 10
|
||||||
|
|
||||||
|
#define TCP_LISTEN_BACKLOG 1
|
||||||
|
|
||||||
|
#define LWIP_COMPAT_SOCKETS 1
|
||||||
|
#define LWIP_SO_RCVTIMEO 1
|
||||||
|
#define LWIP_SO_RCVBUF 1
|
||||||
|
|
||||||
|
#define LWIP_TCPIP_CORE_LOCKING 0
|
||||||
|
|
||||||
|
#define LWIP_NETIF_LINK_CALLBACK 1
|
||||||
|
#define LWIP_NETIF_STATUS_CALLBACK 1
|
||||||
|
#define LWIP_NETIF_EXT_STATUS_CALLBACK 1
|
||||||
|
|
||||||
|
|
||||||
|
#define LWIP_DBG_TYPES_ON (LWIP_DBG_ON|LWIP_DBG_TRACE|LWIP_DBG_STATE|LWIP_DBG_FRESH|LWIP_DBG_HALT)
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Memory options ---------- */
|
||||||
|
/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
|
||||||
|
lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
|
||||||
|
byte alignment -> define MEM_ALIGNMENT to 2. */
|
||||||
|
/* MSVC port: intel processors don't need 4-byte alignment,
|
||||||
|
but are faster that way! */
|
||||||
|
#define MEM_ALIGNMENT 4U
|
||||||
|
|
||||||
|
/* MEM_SIZE: the size of the heap memory. If the application will send
|
||||||
|
a lot of data that needs to be copied, this should be set high. */
|
||||||
|
#define MEM_SIZE 16000
|
||||||
|
|
||||||
|
|
||||||
|
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
|
||||||
|
sends a lot of data out of ROM (or other static memory), this
|
||||||
|
should be set high. */
|
||||||
|
#define MEMP_NUM_PBUF 16
|
||||||
|
/* MEMP_NUM_RAW_PCB: the number of UDP protocol control blocks. One
|
||||||
|
per active RAW "connection". */
|
||||||
|
#define MEMP_NUM_RAW_PCB 3
|
||||||
|
/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
|
||||||
|
per active UDP "connection". */
|
||||||
|
#define MEMP_NUM_UDP_PCB 4
|
||||||
|
/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
|
||||||
|
connections. */
|
||||||
|
#define MEMP_NUM_TCP_PCB 5
|
||||||
|
/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
|
||||||
|
connections. */
|
||||||
|
#define MEMP_NUM_TCP_PCB_LISTEN 8
|
||||||
|
/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
|
||||||
|
segments. */
|
||||||
|
#define MEMP_NUM_TCP_SEG 16
|
||||||
|
/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
|
||||||
|
timeouts. */
|
||||||
|
#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 8)
|
||||||
|
|
||||||
|
/* The following four are used only with the sequential API and can be
|
||||||
|
set to 0 if the application only will use the raw API. */
|
||||||
|
/* MEMP_NUM_NETBUF: the number of struct netbufs. */
|
||||||
|
#define MEMP_NUM_NETBUF 2
|
||||||
|
/* MEMP_NUM_NETCONN: the number of struct netconns. */
|
||||||
|
#define MEMP_NUM_NETCONN 10
|
||||||
|
/* MEMP_NUM_TCPIP_MSG_*: the number of struct tcpip_msg, which is used
|
||||||
|
for sequential API communication and incoming packets. Used in
|
||||||
|
src/api/tcpip.c. */
|
||||||
|
#define MEMP_NUM_TCPIP_MSG_API 16
|
||||||
|
#define MEMP_NUM_TCPIP_MSG_INPKT 16
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Pbuf options ---------- */
|
||||||
|
/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
|
||||||
|
#define PBUF_POOL_SIZE 120
|
||||||
|
|
||||||
|
/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
|
||||||
|
#define PBUF_POOL_BUFSIZE 256
|
||||||
|
|
||||||
|
/** SYS_LIGHTWEIGHT_PROT
|
||||||
|
* define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection
|
||||||
|
* for certain critical regions during buffer allocation, deallocation and memory
|
||||||
|
* allocation and deallocation.
|
||||||
|
*/
|
||||||
|
#define SYS_LIGHTWEIGHT_PROT (NO_SYS==0)
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- TCP options ---------- */
|
||||||
|
#define LWIP_TCP 1
|
||||||
|
#define TCP_TTL 255
|
||||||
|
|
||||||
|
#define LWIP_ALTCP 0
|
||||||
|
|
||||||
|
|
||||||
|
/* Controls if TCP should queue segments that arrive out of
|
||||||
|
order. Define to 0 if your device is low on memory. */
|
||||||
|
#define TCP_QUEUE_OOSEQ 1
|
||||||
|
|
||||||
|
/* TCP Maximum segment size. */
|
||||||
|
#define TCP_MSS 1024
|
||||||
|
|
||||||
|
/* TCP sender buffer space (bytes). */
|
||||||
|
#define TCP_SND_BUF 2048
|
||||||
|
|
||||||
|
/* TCP sender buffer space (pbufs). This must be at least = 2 *
|
||||||
|
TCP_SND_BUF/TCP_MSS for things to work. */
|
||||||
|
#define TCP_SND_QUEUELEN (4 * TCP_SND_BUF/TCP_MSS)
|
||||||
|
|
||||||
|
/* TCP writable space (bytes). This must be less than or equal
|
||||||
|
to TCP_SND_BUF. It is the amount of space which must be
|
||||||
|
available in the tcp snd_buf for select to return writable */
|
||||||
|
#define TCP_SNDLOWAT (TCP_SND_BUF/2)
|
||||||
|
|
||||||
|
/* TCP receive window. */
|
||||||
|
#define TCP_WND (20 * 1024)
|
||||||
|
|
||||||
|
/* Maximum number of retransmissions of data segments. */
|
||||||
|
#define TCP_MAXRTX 12
|
||||||
|
|
||||||
|
/* Maximum number of retransmissions of SYN segments. */
|
||||||
|
#define TCP_SYNMAXRTX 4
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- ARP options ---------- */
|
||||||
|
#define LWIP_ARP 1
|
||||||
|
#define ARP_TABLE_SIZE 10
|
||||||
|
#define ARP_QUEUEING 1
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- IP options ---------- */
|
||||||
|
/* Define IP_FORWARD to 1 if you wish to have the ability to forward
|
||||||
|
IP packets across network interfaces. If you are going to run lwIP
|
||||||
|
on a device with only one network interface, define this to 0. */
|
||||||
|
#define IP_FORWARD 0
|
||||||
|
|
||||||
|
/* IP reassembly and segmentation.These are orthogonal even
|
||||||
|
* if they both deal with IP fragments */
|
||||||
|
#define IP_REASSEMBLY 1
|
||||||
|
#define IP_REASS_MAX_PBUFS (10 * ((1500 + PBUF_POOL_BUFSIZE - 1) / PBUF_POOL_BUFSIZE))
|
||||||
|
#define MEMP_NUM_REASSDATA IP_REASS_MAX_PBUFS
|
||||||
|
#define IP_FRAG 1
|
||||||
|
#define IPV6_FRAG_COPYHEADER 1
|
||||||
|
|
||||||
|
/* ---------- ICMP options ---------- */
|
||||||
|
#define ICMP_TTL 255
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- DHCP options ---------- */
|
||||||
|
/* Define LWIP_DHCP to 1 if you want DHCP configuration of
|
||||||
|
interfaces. */
|
||||||
|
#define LWIP_DHCP LWIP_UDP
|
||||||
|
|
||||||
|
/* 1 if you want to do an ARP check on the offered address
|
||||||
|
(recommended). */
|
||||||
|
#define DHCP_DOES_ARP_CHECK (LWIP_DHCP)
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- AUTOIP options ------- */
|
||||||
|
#define LWIP_AUTOIP (LWIP_DHCP)
|
||||||
|
#define LWIP_DHCP_AUTOIP_COOP (LWIP_DHCP && LWIP_AUTOIP)
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- UDP options ---------- */
|
||||||
|
#define LWIP_UDP 1
|
||||||
|
#define LWIP_UDPLITE LWIP_UDP
|
||||||
|
#define UDP_TTL 255
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- RAW options ---------- */
|
||||||
|
#define LWIP_RAW 1
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- Statistics options ---------- */
|
||||||
|
|
||||||
|
#define LWIP_STATS 1
|
||||||
|
#define LWIP_STATS_DISPLAY 1
|
||||||
|
|
||||||
|
#if LWIP_STATS
|
||||||
|
#define LINK_STATS 1
|
||||||
|
#define IP_STATS 1
|
||||||
|
#define ICMP_STATS 1
|
||||||
|
#define IGMP_STATS 1
|
||||||
|
#define IPFRAG_STATS 1
|
||||||
|
#define UDP_STATS 1
|
||||||
|
#define TCP_STATS 1
|
||||||
|
#define MEM_STATS 1
|
||||||
|
#define MEMP_STATS 1
|
||||||
|
#define PBUF_STATS 1
|
||||||
|
#define SYS_STATS 1
|
||||||
|
#endif /* LWIP_STATS */
|
||||||
|
|
||||||
|
/* ---------- NETBIOS options ---------- */
|
||||||
|
#define LWIP_NETBIOS_RESPOND_NAME_QUERY 1
|
||||||
|
|
||||||
|
/* ---------- PPP options ---------- */
|
||||||
|
|
||||||
|
#define PPP_SUPPORT 1 /* Set > 0 for PPP */
|
||||||
|
|
||||||
|
#if PPP_SUPPORT
|
||||||
|
|
||||||
|
#define NUM_PPP 1 /* Max PPP sessions. */
|
||||||
|
|
||||||
|
|
||||||
|
/* Select modules to enable. Ideally these would be set in the makefile but
|
||||||
|
* we're limited by the command line length so you need to modify the settings
|
||||||
|
* in this file.
|
||||||
|
*/
|
||||||
|
#define PPPOE_SUPPORT 1
|
||||||
|
#define PPPOS_SUPPORT 1
|
||||||
|
|
||||||
|
#define PAP_SUPPORT 1 /* Set > 0 for PAP. */
|
||||||
|
#define CHAP_SUPPORT 1 /* Set > 0 for CHAP. */
|
||||||
|
#define MSCHAP_SUPPORT 0 /* Set > 0 for MSCHAP */
|
||||||
|
#define CBCP_SUPPORT 0 /* Set > 0 for CBCP (NOT FUNCTIONAL!) */
|
||||||
|
#define CCP_SUPPORT 0 /* Set > 0 for CCP */
|
||||||
|
#define VJ_SUPPORT 1 /* Set > 0 for VJ header compression. */
|
||||||
|
#define MD5_SUPPORT 1 /* Set > 0 for MD5 (see also CHAP) */
|
||||||
|
|
||||||
|
#endif /* PPP_SUPPORT */
|
||||||
|
|
||||||
|
|
||||||
|
/* The following defines must be done even in OPTTEST mode: */
|
||||||
|
|
||||||
|
void sys_check_core_locking(void);
|
||||||
|
struct sys_sem;
|
||||||
|
typedef struct sys_sem * sys_sem_t;
|
||||||
|
sys_sem_t* sys_thread_sem_get(void);
|
||||||
|
void sys_thread_sem_init(void);
|
||||||
|
void sys_thread_sem_deinit(void);
|
||||||
|
|
||||||
|
#define ESP_LWIP 1
|
||||||
|
#define LWIP_NETCONN_FULLDUPLEX 1
|
||||||
|
#define LWIP_NETCONN_SEM_PER_THREAD 1
|
||||||
|
|
||||||
|
#define ESP_LWIP_IGMP_TIMERS_ONDEMAND 1
|
||||||
|
#define ESP_LWIP_DHCP_FINE_TIMERS_ONDEMAND 1
|
||||||
|
#define ESP_LWIP_DNS_TIMERS_ONDEMAND 1
|
||||||
|
#define ESP_LWIP_MLD6_TIMERS_ONDEMAND 1
|
||||||
|
#if IP_REASSEMBLY
|
||||||
|
#define ESP_LWIP_IP4_REASSEMBLY_TIMERS_ONDEMAND 1
|
||||||
|
#endif /* IP_REASSEMBLY */
|
||||||
|
#if LWIP_IPV6_REASS
|
||||||
|
#define ESP_LWIP_IP6_REASSEMBLY_TIMERS_ONDEMAND 1
|
||||||
|
#endif /* LWIP_IPV6_REASS */
|
||||||
|
#define ESP_DNS 1
|
||||||
|
#define ESP_LWIP_ARP 1
|
||||||
|
#define LWIP_AUTOIP_MAX_CONFLICTS 10
|
||||||
|
#define LWIP_AUTOIP_RATE_LIMIT_INTERVAL 60
|
||||||
|
#define DNS_FALLBACK_SERVER_INDEX (DNS_MAX_SERVERS - 1)
|
||||||
|
|
||||||
|
#endif /* LWIP_LWIPOPTS_H */
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
try:
|
||||||
|
import sys
|
||||||
|
from junit_xml import TestSuite as ts, TestCase as tc
|
||||||
|
|
||||||
|
t=tc("lingering close stress test")
|
||||||
|
if len(sys.argv) > 1 and sys.argv[1] == "failed":
|
||||||
|
t.add_failure_info("test got stuck when closing clients socket")
|
||||||
|
print(ts.to_xml_string([ts("SOCKET SO_LINGER stress test", [t])]))
|
||||||
|
|
||||||
|
except ImportError:
|
||||||
|
print()
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
#include "lwip_check.h"
|
||||||
|
|
||||||
|
#include "api/test_sockets.h"
|
||||||
|
|
||||||
|
#include "lwip/init.h"
|
||||||
|
#include "lwip/tcpip.h"
|
||||||
|
|
||||||
|
Suite* create_suite(const char* name, testfunc *tests, size_t num_tests, SFun setup, SFun teardown)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
Suite *s = suite_create(name);
|
||||||
|
|
||||||
|
for(i = 0; i < num_tests; i++) {
|
||||||
|
TCase *tc_core = tcase_create(name);
|
||||||
|
if ((setup != NULL) || (teardown != NULL)) {
|
||||||
|
tcase_add_checked_fixture(tc_core, setup, teardown);
|
||||||
|
}
|
||||||
|
tcase_add_named_test(tc_core, tests[i]);
|
||||||
|
suite_add_tcase(s, tc_core);
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lwip_check_ensure_no_alloc(unsigned int skip)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned int mask;
|
||||||
|
for (i = 0, mask = 1; i < MEMP_MAX; i++, mask <<= 1) {
|
||||||
|
if (!(skip & mask)) {
|
||||||
|
fail_unless(lwip_stats.memp[i]->used == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
int number_failed;
|
||||||
|
SRunner *sr;
|
||||||
|
size_t i;
|
||||||
|
suite_getter_fn* suites[] = {
|
||||||
|
sockets_suite,
|
||||||
|
};
|
||||||
|
size_t num = sizeof(suites)/sizeof(void*);
|
||||||
|
LWIP_ASSERT("No suites defined", num > 0);
|
||||||
|
|
||||||
|
tcpip_init(NULL, NULL);
|
||||||
|
|
||||||
|
sr = srunner_create((suites[0])());
|
||||||
|
srunner_set_xml(sr, "lwip_test_apps.xml");
|
||||||
|
for(i = 1; i < num; i++) {
|
||||||
|
srunner_add_suite(sr, ((suite_getter_fn*)suites[i])());
|
||||||
|
}
|
||||||
|
|
||||||
|
srunner_set_fork_status(sr, CK_NOFORK);
|
||||||
|
|
||||||
|
srunner_run_all(sr, CK_NORMAL);
|
||||||
|
number_failed = srunner_ntests_failed(sr);
|
||||||
|
srunner_free(sr);
|
||||||
|
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
|
}
|
||||||
@@ -0,0 +1,249 @@
|
|||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include "lwip_check.h"
|
||||||
|
|
||||||
|
#include "lwip/mem.h"
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
#include "lwip/sockets.h"
|
||||||
|
#include "lwip/priv/sockets_priv.h"
|
||||||
|
#include "lwip/priv/tcp_priv.h"
|
||||||
|
#include "lwip/api.h"
|
||||||
|
|
||||||
|
Suite *sockets_suite(void);
|
||||||
|
|
||||||
|
static int
|
||||||
|
test_sockets_get_used_count(void)
|
||||||
|
{
|
||||||
|
int used = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_SOCKETS; i++) {
|
||||||
|
struct lwip_sock* s = lwip_socket_dbg_get_socket(i);
|
||||||
|
if (s != NULL) {
|
||||||
|
if (s->fd_used) {
|
||||||
|
used++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return used;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !SO_REUSE
|
||||||
|
static int
|
||||||
|
wait_for_pcbs_to_cleanup(void)
|
||||||
|
{
|
||||||
|
struct tcp_pcb *pcb = tcp_active_pcbs;
|
||||||
|
while (pcb != NULL) {
|
||||||
|
if (pcb->state == TIME_WAIT || pcb->state == LAST_ACK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
pcb = pcb->next;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* Setups/teardown functions */
|
||||||
|
static void
|
||||||
|
sockets_setup(void)
|
||||||
|
{
|
||||||
|
fail_unless(test_sockets_get_used_count() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sockets_teardown(void)
|
||||||
|
{
|
||||||
|
fail_unless(test_sockets_get_used_count() == 0);
|
||||||
|
/* poll until all memory is released... */
|
||||||
|
while (tcp_tw_pcbs) {
|
||||||
|
tcp_abort(tcp_tw_pcbs);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct test_params {
|
||||||
|
int listener;
|
||||||
|
size_t tx_buffer_size;
|
||||||
|
struct linger so_linger;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void *
|
||||||
|
server_thread(void *arg)
|
||||||
|
{
|
||||||
|
struct test_params *params = (struct test_params *)arg;
|
||||||
|
int srv;
|
||||||
|
int err;
|
||||||
|
int ret;
|
||||||
|
struct sockaddr_storage source_addr;
|
||||||
|
socklen_t addr_len = sizeof(source_addr);
|
||||||
|
char rxbuf[16];
|
||||||
|
|
||||||
|
/* accept the connection */
|
||||||
|
srv = lwip_accept(params->listener, (struct sockaddr *)&source_addr, &addr_len);
|
||||||
|
/* accepted, so won't need the listener socket anymore, close it */
|
||||||
|
ret = lwip_close(params->listener);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
|
||||||
|
#if LWIP_SO_LINGER
|
||||||
|
/* if we linger with timout=0, we might not be able to even accept */
|
||||||
|
if (params->so_linger.l_linger == 0 && srv < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
fail_unless(srv >= 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if !LWIP_SO_LINGER
|
||||||
|
/* check that we received exactly the amount of bytes that we sent */
|
||||||
|
ret = lwip_recv(srv, rxbuf, params->tx_buffer_size, 0);
|
||||||
|
err = errno;
|
||||||
|
fail_unless(ret == (int)params->tx_buffer_size);
|
||||||
|
/* check that we received exactly 0, i.e. EOF, connection closed cleanly */
|
||||||
|
ret = lwip_recv(srv, rxbuf, sizeof(rxbuf), 0);
|
||||||
|
err = errno;
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
/* check that we could receive no longer */
|
||||||
|
ret = lwip_recv(srv, rxbuf, sizeof(rxbuf), 0);
|
||||||
|
err = errno;
|
||||||
|
fail_unless(ret == -1);
|
||||||
|
fail_unless(err == ENOTCONN || err == ECONNRESET);
|
||||||
|
#else
|
||||||
|
/* try to receive (could be data or EOF if the client lingers on closing) */
|
||||||
|
ret = lwip_recv(srv, rxbuf, sizeof(rxbuf), 0);
|
||||||
|
err = errno;
|
||||||
|
fail_unless(ret >= 0);
|
||||||
|
fail_unless(err == 0);
|
||||||
|
|
||||||
|
if (params->so_linger.l_onoff == 1 && params->so_linger.l_linger > 0) {
|
||||||
|
/* if lingering enabled with a non-zero timeout, let's just close
|
||||||
|
* (connection could be closed both cleanly and abruptly) */
|
||||||
|
ret = lwip_close(srv);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* otherwise, check that we could receive no longer */
|
||||||
|
ret = lwip_recv(srv, rxbuf, sizeof(rxbuf), 0);
|
||||||
|
err = errno;
|
||||||
|
if (params->so_linger.l_onoff == 0 || params->so_linger.l_linger > 0) {
|
||||||
|
/* if lingering disabled or timeout nonzero, we should get a clean exit */
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
} else {
|
||||||
|
/* linger with timeout=0, expect an abrupt closure */
|
||||||
|
fail_unless(ret == -1);
|
||||||
|
fail_unless(err == ENOTCONN || err == ECONNRESET);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* close server socket */
|
||||||
|
ret = lwip_close(srv);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_socket_close_linger(int l_onoff, int l_linger)
|
||||||
|
{
|
||||||
|
int client;
|
||||||
|
int ret;
|
||||||
|
struct sockaddr_in sa_listen;
|
||||||
|
const u16_t port = 1234;
|
||||||
|
static const char txbuf[] = "something";
|
||||||
|
struct test_params params;
|
||||||
|
int err;
|
||||||
|
pthread_t srv_thread;
|
||||||
|
|
||||||
|
/* set test parameters */
|
||||||
|
params.so_linger.l_onoff = l_onoff;
|
||||||
|
params.so_linger.l_linger = l_linger;
|
||||||
|
params.tx_buffer_size = sizeof(txbuf);
|
||||||
|
|
||||||
|
fail_unless(test_sockets_get_used_count() == 0);
|
||||||
|
/* set up the listener */
|
||||||
|
memset(&sa_listen, 0, sizeof(sa_listen));
|
||||||
|
sa_listen.sin_family = AF_INET;
|
||||||
|
sa_listen.sin_port = PP_HTONS(port);
|
||||||
|
sa_listen.sin_addr.s_addr = PP_HTONL(INADDR_LOOPBACK);
|
||||||
|
params.listener = lwip_socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
fail_unless(params.listener >= 0);
|
||||||
|
#if SO_REUSE
|
||||||
|
ret = 1;
|
||||||
|
fail_unless(setsockopt(params.listener, SOL_SOCKET, SO_REUSEADDR, &ret, sizeof(ret)) == 0);
|
||||||
|
#endif
|
||||||
|
ret = lwip_bind(params.listener, (struct sockaddr *)&sa_listen, sizeof(sa_listen));
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
ret = lwip_listen(params.listener, 1);
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
|
||||||
|
/* continue to serve connections in a separate thread*/
|
||||||
|
err = pthread_create(&srv_thread, NULL, server_thread, ¶ms);
|
||||||
|
fail_unless(err == 0);
|
||||||
|
|
||||||
|
/* set up the client */
|
||||||
|
client = lwip_socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
/* connect */
|
||||||
|
ret = lwip_connect(client, (struct sockaddr *) &sa_listen, sizeof(sa_listen));
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
|
||||||
|
/* set socket to enable SO_LINGER option */
|
||||||
|
ret = lwip_setsockopt(client, SOL_SOCKET, SO_LINGER, ¶ms.so_linger, sizeof(params.so_linger));
|
||||||
|
#if LWIP_SO_LINGER
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
#else
|
||||||
|
/* If not enabled, just expect No Such Option error */
|
||||||
|
err = errno;
|
||||||
|
fail_unless(ret == -1);
|
||||||
|
fail_unless(err == ENOPROTOOPT);
|
||||||
|
#endif /* LWIP_SO_LINGER */
|
||||||
|
|
||||||
|
ret = lwip_send(client, txbuf, sizeof(txbuf), 0);
|
||||||
|
fail_unless(ret == sizeof(txbuf));
|
||||||
|
|
||||||
|
/* close from client's side */
|
||||||
|
ret = lwip_close(client);
|
||||||
|
#if !LWIP_SO_LINGER
|
||||||
|
err = errno;
|
||||||
|
fail_unless(ret == 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pthread_join(srv_thread, NULL);
|
||||||
|
#if !SO_REUSE
|
||||||
|
while (wait_for_pcbs_to_cleanup() != 0) {
|
||||||
|
usleep(1000);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
START_TEST(test_sockets_close_state_machine_linger_off)
|
||||||
|
{
|
||||||
|
LWIP_UNUSED_ARG(_i);
|
||||||
|
test_socket_close_linger(0, 0);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_sockets_close_state_machine_linger_on)
|
||||||
|
{
|
||||||
|
LWIP_UNUSED_ARG(_i);
|
||||||
|
test_socket_close_linger(1, 1);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_sockets_close_state_machine_linger_on_timeout_0)
|
||||||
|
{
|
||||||
|
LWIP_UNUSED_ARG(_i);
|
||||||
|
test_socket_close_linger(1, 0);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
/** Create the suite including all tests for this module */
|
||||||
|
Suite *
|
||||||
|
sockets_suite(void)
|
||||||
|
{
|
||||||
|
testfunc tests[] = {
|
||||||
|
TESTFUNC(test_sockets_close_state_machine_linger_off),
|
||||||
|
TESTFUNC(test_sockets_close_state_machine_linger_on),
|
||||||
|
TESTFUNC(test_sockets_close_state_machine_linger_on_timeout_0),
|
||||||
|
};
|
||||||
|
return create_suite("SOCKETS", tests, sizeof(tests)/sizeof(testfunc), sockets_setup, sockets_teardown);
|
||||||
|
}
|
||||||
Executable
+20
@@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
export LWIP_DIR=`pwd`
|
||||||
|
export LWIP_CONTRIB_DIR=`pwd`/contrib
|
||||||
|
|
||||||
|
cd test/apps
|
||||||
|
# Prepare a failing report in case we get stuck (check in no-fork mode)
|
||||||
|
python socket_linger_stress_test.py failed > ${LWIP_DIR}/socket_linger_stress_test.xml
|
||||||
|
for cfg in config_no_linger config_linger config_linger_reuse; do
|
||||||
|
cmake -DCI_BUILD=1 -DTEST_CONFIG=${cfg} -B ${cfg} -G Ninja .
|
||||||
|
cmake --build ${cfg}/
|
||||||
|
timeout 10 ./${cfg}/lwip_test_apps
|
||||||
|
[ -f check2junit.py ] &&
|
||||||
|
python ${LWIP_DIR}/check2junit.py lwip_test_apps.xml > ${LWIP_DIR}/${cfg}.xml
|
||||||
|
done
|
||||||
|
# Run the lingering test multiple times
|
||||||
|
for run in {1..10}; do ( timeout 10 ./config_linger/lwip_test_apps ) || exit 1 ; done
|
||||||
|
# All good, regenerate the stress test-report, since the test succeeded
|
||||||
|
python socket_linger_stress_test.py > ${LWIP_DIR}/socket_linger_stress_test.xml
|
||||||
Executable
+43
@@ -0,0 +1,43 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
export CI_ROOT_DIR=`pwd`
|
||||||
|
export LWIPDIR=../../../../src
|
||||||
|
export ORIG_CC=${CC}
|
||||||
|
pushd `pwd`
|
||||||
|
cd contrib/ports/unix/check
|
||||||
|
|
||||||
|
### with GNU Make
|
||||||
|
|
||||||
|
# build and run default lwip tests (ESP_LWIP=0!)
|
||||||
|
make clean
|
||||||
|
make -j 4 check
|
||||||
|
# retest with ESP_LWIP patches
|
||||||
|
make clean
|
||||||
|
export EXTRA_CFLAGS="-DESP_LWIP=1" && export CC="${ORIG_CC} ${EXTRA_CFLAGS}"
|
||||||
|
make -j 4 check
|
||||||
|
# retest with IP_FORWARD enabled
|
||||||
|
make clean
|
||||||
|
export EXTRA_CFLAGS="-DESP_LWIP=1 -DIP_FORWARD=1" && export CC="${ORIG_CC} ${EXTRA_CFLAGS}"
|
||||||
|
make -j 4 check
|
||||||
|
# retest with IP_FORWARD and IP_NAPT enabled
|
||||||
|
make clean
|
||||||
|
export EXTRA_CFLAGS="-DESP_LWIP=1 -DIP_FORWARD=1 -DIP_NAPT=1" && export CC="${ORIG_CC} ${EXTRA_CFLAGS}"
|
||||||
|
make -j 4 check
|
||||||
|
# Please uncomment the below to test IP_FORWARD/IP_NAPT tests with debug output (only ip4_route test suite will be executed)
|
||||||
|
make clean
|
||||||
|
export EXTRA_CFLAGS="-DESP_LWIP=1 -DIP_FORWARD=1 -DESP_TEST_DEBUG=1 -DIP_NAPT=1" && export CC="${ORIG_CC} ${EXTRA_CFLAGS}"
|
||||||
|
make -j 4 check
|
||||||
|
|
||||||
|
|
||||||
|
### with CMake
|
||||||
|
cd ${CI_ROOT_DIR}/contrib/ports/unix/check
|
||||||
|
rm -rf build
|
||||||
|
export EXTRA_CFLAGS=""
|
||||||
|
export CC="${ORIG_CC}"
|
||||||
|
mkdir build && cd build && cmake -DLWIP_DIR=`pwd`/../../../../.. .. -G Ninja
|
||||||
|
cmake --build . && ./lwip_unittests
|
||||||
|
[ -f ${CI_ROOT_DIR}/check2junit.py ] &&
|
||||||
|
python ${CI_ROOT_DIR}/check2junit.py lwip_unittests.xml > ${CI_ROOT_DIR}/unit_tests.xml
|
||||||
|
|
||||||
|
popd
|
||||||
Executable
+11
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
export CFLAGS="-I../../../../test/unix -include esp_lwipopts.h"
|
||||||
|
export LWIPDIR=../../../../src/
|
||||||
|
cp contrib/examples/example_app/lwipcfg.h.example contrib/examples/example_app/lwipcfg.h
|
||||||
|
cd contrib/ports/unix/example_app
|
||||||
|
|
||||||
|
make TESTFLAGS="-Wno-documentation" -j 4
|
||||||
|
chmod +x iteropts.sh
|
||||||
|
./iteropts.sh
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#define ESP_LWIP LWIP_NETCONN_FULLDUPLEX
|
||||||
|
#define ESP_LWIP_IP4_REASSEMBLY_TIMERS_ONDEMAND ESP_LWIP
|
||||||
|
#define ESP_LWIP_IP6_REASSEMBLY_TIMERS_ONDEMAND ESP_LWIP
|
||||||
|
#define ESP_LWIP_DNS_TIMERS_ONDEMAND ESP_LWIP
|
||||||
|
#define ESP_LWIP_DHCP_FINE_TIMERS_ONDEMAND ESP_LWIP
|
||||||
|
#define ESP_LWIP_IGMP_TIMERS_ONDEMAND ESP_LWIP
|
||||||
|
#define ESP_LWIP_MLD6_TIMERS_ONDEMAND ESP_LWIP
|
||||||
|
#define ESP_DNS ESP_LWIP
|
||||||
|
#define ESP_LWIP_ARP ESP_LWIP
|
||||||
Reference in New Issue
Block a user