diff --git a/.github/workflows/build_and_test_with_resty_events.yml b/.github/workflows/build_and_test_with_resty_events.yml new file mode 100644 index 00000000..c2d4c73f --- /dev/null +++ b/.github/workflows/build_and_test_with_resty_events.yml @@ -0,0 +1,136 @@ +name: Build and test + +on: [push, pull_request] + +jobs: + build: + name: CI using lua-resty-events + runs-on: ubuntu-20.04 + strategy: + matrix: + openresty-version: [1.15.8.3, 1.17.8.2, 1.19.9.1, 1.21.4.1] + + steps: + - name: Update and install OS dependencies + run: | + sudo apt-get update && sudo apt-get install -y libssl-dev ssl-cert + sudo systemctl disable nginx + sudo systemctl stop nginx + + + - name: Set environment variables + env: + OPENRESTY_VER: ${{ matrix.openresty-version }} + RESTY_EVENTS_VER: 0.1.0 + LUAROCKS_VER: 3.9.0 + OPENSSL_VER: 1.1.1o + PCRE_VER: 8.45 + run: | + echo "INSTALL_ROOT=$HOME/install-root" >> $GITHUB_ENV + echo "DOWNLOAD_ROOT=$HOME/download-root" >> $GITHUB_ENV + echo "OPENRESTY=$OPENRESTY_VER" >> $GITHUB_ENV + echo "LUAROCKS=$LUAROCKS_VER" >> $GITHUB_ENV + echo "OPENSSL=$OPENSSL_VER" >> $GITHUB_ENV + echo "PCRE=$PCRE_VER" >> $GITHUB_ENV + echo "RESTY_EVENTS=$RESTY_EVENTS_VER" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=$HOME/install-root/lib:$LD_LIBRARY_PATH" >> $GITHUB_ENV + + - name: Checkout lua-resty-healthcheck + uses: actions/checkout@v3 + + - name: Lookup build cache + uses: actions/cache@v3 + id: cache-deps + with: + path: ${{ env.GITHUB_WORKSPACE }}/ + key: ${{ runner.os }}-${{ hashFiles('**/.github/workflows/build_and_test_with_resty_events.yml') }}-${{ matrix.openresty-version }} + + - name: Add to Path + if: steps.cache-deps.outputs.cache-hit != 'true' + run: echo "$INSTALL_ROOT/bin:$INSTALL_ROOT/nginx/sbin:$INSTALL_ROOT/luajit/bin:/usr/bin" >> $GITHUB_PATH + + - name: Build and install OpenSSL + if: steps.cache-deps.outputs.cache-hit != 'true' + run: | + curl -sSLO https://www.openssl.org/source/openssl-$OPENSSL.tar.gz + tar -xzf openssl-$OPENSSL.tar.gz + cd openssl-$OPENSSL + ./config -g shared -DPURIFY no-threads --prefix=$INSTALL_ROOT --openssldir=$INSTALL_ROOT no-unit-test + make + make install_sw + + - name: Checkout lua-resty-events + uses: actions/checkout@v3 + if: steps.cache-deps.outputs.cache-hit != 'true' + with: + repository: Kong/lua-resty-events + ref: refs/tags/0.1.0 + path: lua-resty-events + + - name: Build and install OpenResty + if: steps.cache-deps.outputs.cache-hit != true + run: | + curl -sSLO https://openresty.org/download/openresty-$OPENRESTY.tar.gz + tar -xzf openresty-$OPENRESTY.tar.gz + cd openresty-$OPENRESTY + ./configure \ + --prefix=$INSTALL_ROOT \ + --with-cc-opt='-I$INSTALL_ROOT/include' \ + --with-ld-opt='-L$INSTALL_ROOT/lib -Wl,-rpath,$INSTALL_ROOT/lib' \ + --with-pcre-jit \ + --with-http_ssl_module \ + --with-http_realip_module \ + --with-http_stub_status_module \ + --with-http_v2_module \ + --without-http_encrypted_session_module \ + --with-stream_realip_module \ + --with-stream_ssl_preread_module \ + --add-module=../lua-resty-events \ + --with-pcre + make + make install + make install LUA_LIBDIR=$INSTALL_ROOT/lualib + + - name: Install LuaRocks + if: steps.cache-deps.outputs.cache-hit != 'true' + run: | + curl -sSLO https://luarocks.org/releases/luarocks-$LUAROCKS.tar.gz + tar -xzf luarocks-$LUAROCKS.tar.gz + cd luarocks-$LUAROCKS + ./configure \ + --prefix=$INSTALL_ROOT \ + --lua-suffix=jit \ + --with-lua=$INSTALL_ROOT/luajit \ + --with-lua-include=$INSTALL_ROOT/luajit/include/luajit-2.1 + make build + make install + + - name: Install manual dependencies + if: steps.cache-deps.outputs.cache-hit != 'true' + run: | + luarocks install luacheck + + - name: Install Test::NGINX + if: steps.cache-deps.outputs.cache-hit != 'true' + run: | + sudo apt-get install cpanminus + cpanm --notest --local-lib=$HOME/perl5 local::lib && eval $(perl -I $HOME/perl5/lib/perl5/ -Mlocal::lib) + cpanm --notest Test::Nginx + + - name: Install lua-resty-events + if: steps.cache-deps.outputs.cache-hit != 'true' + run: | + cd lua-resty-events + OPENRESTY_PREFIX=$INSTALL_ROOT PREFIX=$INSTALL_ROOT LUA_LIB_DIR=$INSTALL_ROOT/lualib make install + + - name: Install lua-resty-healthcheck + run: luarocks make + + - name: Run tests + env: + PATH: ${{ env.INSTALL_ROOT }}/bin:${{ env.INSTALL_ROOT }}/nginx/sbin:${{ env.INSTALL_ROOT }}/luajit/bin:/usr/bin + TEST_NGINX_BINARY: ${{ env.INSTALL_ROOT }}/nginx/sbin/nginx + run: | + eval `luarocks path` + eval $(perl -I $HOME/perl5/lib/perl5/ -Mlocal::lib) + TEST_NGINX_RANDOMIZE=1 prove -I. -r t/with_resty-events diff --git a/.github/workflows/build_and_test_with_worker_events.yml b/.github/workflows/build_and_test_with_worker_events.yml new file mode 100644 index 00000000..d8a45c6f --- /dev/null +++ b/.github/workflows/build_and_test_with_worker_events.yml @@ -0,0 +1,64 @@ +name: Build and test + +on: [push, pull_request] + +jobs: + build: + name: CI using lua-resty-worker-events + runs-on: ubuntu-20.04 + strategy: + matrix: + openresty-version: [1.15.8.3, 1.17.8.2, 1.19.9.1, 1.21.4.1] + + steps: + - name: Update and install OS dependencies + run: | + sudo apt-get update && sudo apt-get install -y libssl-dev ssl-cert + sudo systemctl disable nginx + sudo systemctl stop nginx + + + - name: Set environment variables + env: + OPENRESTY_VER: ${{ matrix.openresty-version }} + run: | + echo "/usr/local/openresty/nginx/sbin" >> $GITHUB_PATH + + - name: Checkout lua-resty-healthcheck + uses: actions/checkout@v3 + + - name: Install OpenResty ${{ matrix.openresty-version }} + env: + OPENRESTY_VER: ${{ matrix.openresty-version }} + run: | + sudo apt-get -y install --no-install-recommends wget gnupg ca-certificates + wget -O - https://openresty.org/package/pubkey.gpg | sudo apt-key add - + echo "deb http://openresty.org/package/ubuntu $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/openresty.list + sudo apt-get update + sudo apt-get -y install openresty=$OPENRESTY_VER-1~focal1 + + - name: Install LuaRocks + run: sudo apt-get install -y luarocks + + - name: Install manual dependencies + run: | + sudo luarocks install luacheck + sudo luarocks install lua-resty-worker-events 1.0.0 + + - name: Install Test::NGINX + run: | + sudo apt-get install cpanminus + cpanm --notest --local-lib=$HOME/perl5 local::lib && eval $(perl -I $HOME/perl5/lib/perl5/ -Mlocal::lib) + cpanm --notest Test::Nginx + + - name: Checkout lua-resty-healthcheck + uses: actions/checkout@v3 + + - name: Install lua-resty-healthcheck + run: sudo luarocks make + + - name: Run tests + run: | + eval `luarocks path` + eval $(perl -I $HOME/perl5/lib/perl5/ -Mlocal::lib) + TEST_NGINX_RANDOMIZE=1 prove -I. -r t/with_worker-events diff --git a/.github/workflows/latest_os_resty_events.yml b/.github/workflows/latest_os_resty_events.yml deleted file mode 100644 index 2963d8ea..00000000 --- a/.github/workflows/latest_os_resty_events.yml +++ /dev/null @@ -1,190 +0,0 @@ -name: Build and test for Ubuntu latest using lua-resty-events - -on: [push, pull_request] - -jobs: - build: - name: Build and install dependencies - runs-on: ubuntu-latest - strategy: - matrix: - openresty-version: [1.21.4.1] - luarocks-version: [3.8.0] - - steps: - - name: Update and install OS dependencies - run: sudo apt-get update && sudo apt-get install -y libssl-dev ssl-cert - - - name: Set environment variables - env: - LUAROCKS_VER: ${{ matrix.luarocks-version }} - OPENRESTY_VER: ${{ matrix.openresty-version }} - run: | - echo "DOWNLOAD_PATH=$HOME/download-root" >> $GITHUB_ENV - export DOWNLOAD_PATH=$HOME/download-root - echo "INSTALL_PATH=$HOME/install-root" >> $GITHUB_ENV - export INSTALL_PATH=$HOME/install-root - echo "LUAROCKS_VER=$LUAROCKS_VER" >> $GITHUB_ENV - echo "OPENRESTY_VER=$OPENRESTY_VER" >> $GITHUB_ENV - export LUAROCKS_PREFIX=$INSTALL_PATH/luarocks-$LUAROCKS_VER - echo "LUAROCKS_PREFIX=$LUAROCKS_PREFIX" >> $GITHUB_ENV - export OPENRESTY_PREFIX=$INSTALL_PATH/openresty-$OPENRESTY_VER - echo "OPENRESTY_PREFIX=$OPENRESTY_PREFIX" >> $GITHUB_ENV - echo "PATH=$DOWNLOAD_PATH:$LUAROCKS_PREFIX/bin:$OPENRESTY_PREFIX/nginx/sbin:$DOWNLOAD_PATH/cpanm:$PATH" >> $GITHUB_ENV - - - name: Checkout lua-resty-healthcheck - uses: actions/checkout@v2 - - - name: Lookup build cache - uses: actions/cache@v2 - id: cache-deps - with: - path: | - ${{ env.INSTALL_PATH }} - ~/perl5 - key: ${{ runner.os }}-${{ hashFiles('.github/workflows/latest_os.yml') }} - - - name: Create needed paths - if: steps.cache-deps.outputs.cache-hit != 'true' - run: | - mkdir -p $DOWNLOAD_PATH - mkdir -p $INSTALL_PATH - - - name: Build and install OpenResty ${{ matrix.openresty-version }} - if: steps.cache-deps.outputs.cache-hit != 'true' - run: | - if [ ! -d $INSTALL_PATH/openresty-$OPENRESTY_VER ]; - then - pushd $DOWNLOAD_PATH - echo "Downloading from http://openresty.org/download/openresty-$OPENRESTY_VER.tar.gz" - wget -O $DOWNLOAD_PATH/openresty-$OPENRESTY_VER.tar.gz http://openresty.org/download/openresty-$OPENRESTY_VER.tar.gz - echo "tar -zxf $DOWNLOAD_PATH/openresty-$OPENRESTY_VER.tar.gz" - tar -zxf $DOWNLOAD_PATH/openresty-$OPENRESTY_VER.tar.gz - echo "result: $?" - pushd openresty-$OPENRESTY_VER - ./configure --prefix=$OPENRESTY_PREFIX - make - make install - popd - popd - fi - - - name: Build and install LuaRocks ${{ matrix.luarocks-version }} - if: steps.cache-deps.outputs.cache-hit != 'true' - run: | - if [ ! -d $INSTALL_PATH/luarocks-$LUAROCKS_VER ]; - then - pushd $DOWNLOAD_PATH - echo "Downloading from https://luarocks.github.io/luarocks/releases/luarocks-$LUAROCKS_VER.tar.gz" - wget -O $DOWNLOAD_PATH/luarocks-$LUAROCKS_VER.tar.gz https://luarocks.github.io/luarocks/releases/luarocks-$LUAROCKS_VER.tar.gz - tar -zxf $DOWNLOAD_PATH/luarocks-$LUAROCKS_VER.tar.gz - pushd luarocks-$LUAROCKS_VER - ./configure --prefix=$LUAROCKS_PREFIX --with-lua=$OPENRESTY_PREFIX/luajit --with-lua-include=$OPENRESTY_PREFIX/luajit/include/luajit-2.1 --lua-suffix=jit - make build - make install - popd - luarocks install luacheck - luarocks install lua-resty-events 0.1.0 - popd - fi - - - name: Install Test::NGINX - if: steps.cache-deps.outputs.cache-hit != 'true' - run: | - if [ ! -f $DOWNLOAD_PATH/cpanm ]; - then - wget -O $DOWNLOAD_PATH/cpanm https://cpanmin.us/ - chmod +x $DOWNLOAD_PATH/cpanm - cpanm --notest --local-lib=$HOME/perl5 local::lib && eval $(perl -I $HOME/perl5/lib/perl5/ -Mlocal::lib) - cpanm --notest Test::Nginx - fi - - lint: - name: Static code analysis - runs-on: ubuntu-latest - needs: build - strategy: - matrix: - openresty-version: [1.21.4.1] - luarocks-version: [3.8.0] - steps: - - name: Checkout lua-resty-healthcheck - uses: actions/checkout@v2 - - - name: Set environment variables - env: - LUAROCKS_VER: ${{ matrix.luarocks-version }} - OPENRESTY_VER: ${{ matrix.openresty-version }} - run: | - echo "DOWNLOAD_PATH=$HOME/download-root" >> $GITHUB_ENV - export DOWNLOAD_PATH=$HOME/download-root - echo "INSTALL_PATH=$HOME/install-root" >> $GITHUB_ENV - export INSTALL_PATH=$HOME/install-root - echo "LUAROCKS_VER=$LUAROCKS_VER" >> $GITHUB_ENV - echo "OPENRESTY_VER=$OPENRESTY_VER" >> $GITHUB_ENV - export LUAROCKS_PREFIX=$INSTALL_PATH/luarocks-$LUAROCKS_VER - echo "LUAROCKS_PREFIX=$LUAROCKS_PREFIX" >> $GITHUB_ENV - export OPENRESTY_PREFIX=$INSTALL_PATH/openresty-$OPENRESTY_VER - echo "OPENRESTY_PREFIX=$OPENRESTY_PREFIX" >> $GITHUB_ENV - echo "PATH=$DOWNLOAD_PATH:$LUAROCKS_PREFIX/bin:$OPENRESTY_PREFIX/nginx/sbin:$DOWNLOAD_PATH/cpanm:$PATH" >> $GITHUB_ENV - - - name: Lookup build cache - uses: actions/cache@v2 - id: cache-deps - with: - path: | - ${{ env.INSTALL_PATH }} - ~/perl5 - key: ${{ runner.os }}-${{ hashFiles('.github/workflows/latest_os.yml') }} - - - name: Lint code - run: | - eval `luarocks path` - luacheck lib - - install-and-test: - name: Test lua-resty-healthcheck - runs-on: ubuntu-latest - needs: build - strategy: - matrix: - openresty-version: [1.21.4.1] - luarocks-version: [3.8.0] - steps: - - name: Checkout lua-resty-healthcheck - uses: actions/checkout@v2 - - - name: Set environment variables - env: - LUAROCKS_VER: ${{ matrix.luarocks-version }} - OPENRESTY_VER: ${{ matrix.openresty-version }} - run: | - echo "DOWNLOAD_PATH=$HOME/download-root" >> $GITHUB_ENV - export DOWNLOAD_PATH=$HOME/download-root - echo "INSTALL_PATH=$HOME/install-root" >> $GITHUB_ENV - export INSTALL_PATH=$HOME/install-root - echo "LUAROCKS_VER=$LUAROCKS_VER" >> $GITHUB_ENV - echo "OPENRESTY_VER=$OPENRESTY_VER" >> $GITHUB_ENV - export LUAROCKS_PREFIX=$INSTALL_PATH/luarocks-$LUAROCKS_VER - echo "LUAROCKS_PREFIX=$LUAROCKS_PREFIX" >> $GITHUB_ENV - export OPENRESTY_PREFIX=$INSTALL_PATH/openresty-$OPENRESTY_VER - echo "OPENRESTY_PREFIX=$OPENRESTY_PREFIX" >> $GITHUB_ENV - echo "PATH=$DOWNLOAD_PATH:$LUAROCKS_PREFIX/bin:$OPENRESTY_PREFIX/nginx/sbin:$DOWNLOAD_PATH/cpanm:$PATH" >> $GITHUB_ENV - - - name: Lookup build cache - uses: actions/cache@v2 - id: cache-deps - with: - path: | - ${{ env.INSTALL_PATH }} - ~/perl5 - key: ${{ runner.os }}-${{ hashFiles('.github/workflows/latest_os.yml') }} - - - name: Install lua-resty-healthcheck - run: luarocks make - - - name: Run tests - run: | - eval `luarocks path` - eval $(perl -I $HOME/perl5/lib/perl5/ -Mlocal::lib) - TEST_NGINX_RANDOMIZE=1 prove -I. -r t diff --git a/.github/workflows/latest_os_worker_events.yml b/.github/workflows/latest_os_worker_events.yml deleted file mode 100644 index ecd824eb..00000000 --- a/.github/workflows/latest_os_worker_events.yml +++ /dev/null @@ -1,190 +0,0 @@ -name: Build and test for Ubuntu latest using lua-resty-worker-events - -on: [push, pull_request] - -jobs: - build: - name: Build and install dependencies - runs-on: ubuntu-latest - strategy: - matrix: - openresty-version: [1.21.4.1] - luarocks-version: [3.8.0] - - steps: - - name: Update and install OS dependencies - run: sudo apt-get update && sudo apt-get install -y libssl-dev ssl-cert - - - name: Set environment variables - env: - LUAROCKS_VER: ${{ matrix.luarocks-version }} - OPENRESTY_VER: ${{ matrix.openresty-version }} - run: | - echo "DOWNLOAD_PATH=$HOME/download-root" >> $GITHUB_ENV - export DOWNLOAD_PATH=$HOME/download-root - echo "INSTALL_PATH=$HOME/install-root" >> $GITHUB_ENV - export INSTALL_PATH=$HOME/install-root - echo "LUAROCKS_VER=$LUAROCKS_VER" >> $GITHUB_ENV - echo "OPENRESTY_VER=$OPENRESTY_VER" >> $GITHUB_ENV - export LUAROCKS_PREFIX=$INSTALL_PATH/luarocks-$LUAROCKS_VER - echo "LUAROCKS_PREFIX=$LUAROCKS_PREFIX" >> $GITHUB_ENV - export OPENRESTY_PREFIX=$INSTALL_PATH/openresty-$OPENRESTY_VER - echo "OPENRESTY_PREFIX=$OPENRESTY_PREFIX" >> $GITHUB_ENV - echo "PATH=$DOWNLOAD_PATH:$LUAROCKS_PREFIX/bin:$OPENRESTY_PREFIX/nginx/sbin:$DOWNLOAD_PATH/cpanm:$PATH" >> $GITHUB_ENV - - - name: Checkout lua-resty-healthcheck - uses: actions/checkout@v2 - - - name: Lookup build cache - uses: actions/cache@v2 - id: cache-deps - with: - path: | - ${{ env.INSTALL_PATH }} - ~/perl5 - key: ${{ runner.os }}-${{ hashFiles('.github/workflows/latest_os.yml') }} - - - name: Create needed paths - if: steps.cache-deps.outputs.cache-hit != 'true' - run: | - mkdir -p $DOWNLOAD_PATH - mkdir -p $INSTALL_PATH - - - name: Build and install OpenResty ${{ matrix.openresty-version }} - if: steps.cache-deps.outputs.cache-hit != 'true' - run: | - if [ ! -d $INSTALL_PATH/openresty-$OPENRESTY_VER ]; - then - pushd $DOWNLOAD_PATH - echo "Downloading from http://openresty.org/download/openresty-$OPENRESTY_VER.tar.gz" - wget -O $DOWNLOAD_PATH/openresty-$OPENRESTY_VER.tar.gz http://openresty.org/download/openresty-$OPENRESTY_VER.tar.gz - echo "tar -zxf $DOWNLOAD_PATH/openresty-$OPENRESTY_VER.tar.gz" - tar -zxf $DOWNLOAD_PATH/openresty-$OPENRESTY_VER.tar.gz - echo "result: $?" - pushd openresty-$OPENRESTY_VER - ./configure --prefix=$OPENRESTY_PREFIX - make - make install - popd - popd - fi - - - name: Build and install LuaRocks ${{ matrix.luarocks-version }} - if: steps.cache-deps.outputs.cache-hit != 'true' - run: | - if [ ! -d $INSTALL_PATH/luarocks-$LUAROCKS_VER ]; - then - pushd $DOWNLOAD_PATH - echo "Downloading from https://luarocks.github.io/luarocks/releases/luarocks-$LUAROCKS_VER.tar.gz" - wget -O $DOWNLOAD_PATH/luarocks-$LUAROCKS_VER.tar.gz https://luarocks.github.io/luarocks/releases/luarocks-$LUAROCKS_VER.tar.gz - tar -zxf $DOWNLOAD_PATH/luarocks-$LUAROCKS_VER.tar.gz - pushd luarocks-$LUAROCKS_VER - ./configure --prefix=$LUAROCKS_PREFIX --with-lua=$OPENRESTY_PREFIX/luajit --with-lua-include=$OPENRESTY_PREFIX/luajit/include/luajit-2.1 --lua-suffix=jit - make build - make install - popd - luarocks install luacheck - luarocks install lua-resty-worker-events 1.0.0 - popd - fi - - - name: Install Test::NGINX - if: steps.cache-deps.outputs.cache-hit != 'true' - run: | - if [ ! -f $DOWNLOAD_PATH/cpanm ]; - then - wget -O $DOWNLOAD_PATH/cpanm https://cpanmin.us/ - chmod +x $DOWNLOAD_PATH/cpanm - cpanm --notest --local-lib=$HOME/perl5 local::lib && eval $(perl -I $HOME/perl5/lib/perl5/ -Mlocal::lib) - cpanm --notest Test::Nginx - fi - - lint: - name: Static code analysis - runs-on: ubuntu-latest - needs: build - strategy: - matrix: - openresty-version: [1.21.4.1] - luarocks-version: [3.8.0] - steps: - - name: Checkout lua-resty-healthcheck - uses: actions/checkout@v2 - - - name: Set environment variables - env: - LUAROCKS_VER: ${{ matrix.luarocks-version }} - OPENRESTY_VER: ${{ matrix.openresty-version }} - run: | - echo "DOWNLOAD_PATH=$HOME/download-root" >> $GITHUB_ENV - export DOWNLOAD_PATH=$HOME/download-root - echo "INSTALL_PATH=$HOME/install-root" >> $GITHUB_ENV - export INSTALL_PATH=$HOME/install-root - echo "LUAROCKS_VER=$LUAROCKS_VER" >> $GITHUB_ENV - echo "OPENRESTY_VER=$OPENRESTY_VER" >> $GITHUB_ENV - export LUAROCKS_PREFIX=$INSTALL_PATH/luarocks-$LUAROCKS_VER - echo "LUAROCKS_PREFIX=$LUAROCKS_PREFIX" >> $GITHUB_ENV - export OPENRESTY_PREFIX=$INSTALL_PATH/openresty-$OPENRESTY_VER - echo "OPENRESTY_PREFIX=$OPENRESTY_PREFIX" >> $GITHUB_ENV - echo "PATH=$DOWNLOAD_PATH:$LUAROCKS_PREFIX/bin:$OPENRESTY_PREFIX/nginx/sbin:$DOWNLOAD_PATH/cpanm:$PATH" >> $GITHUB_ENV - - - name: Lookup build cache - uses: actions/cache@v2 - id: cache-deps - with: - path: | - ${{ env.INSTALL_PATH }} - ~/perl5 - key: ${{ runner.os }}-${{ hashFiles('.github/workflows/latest_os.yml') }} - - - name: Lint code - run: | - eval `luarocks path` - luacheck lib - - install-and-test: - name: Test lua-resty-healthcheck - runs-on: ubuntu-latest - needs: build - strategy: - matrix: - openresty-version: [1.21.4.1] - luarocks-version: [3.8.0] - steps: - - name: Checkout lua-resty-healthcheck - uses: actions/checkout@v2 - - - name: Set environment variables - env: - LUAROCKS_VER: ${{ matrix.luarocks-version }} - OPENRESTY_VER: ${{ matrix.openresty-version }} - run: | - echo "DOWNLOAD_PATH=$HOME/download-root" >> $GITHUB_ENV - export DOWNLOAD_PATH=$HOME/download-root - echo "INSTALL_PATH=$HOME/install-root" >> $GITHUB_ENV - export INSTALL_PATH=$HOME/install-root - echo "LUAROCKS_VER=$LUAROCKS_VER" >> $GITHUB_ENV - echo "OPENRESTY_VER=$OPENRESTY_VER" >> $GITHUB_ENV - export LUAROCKS_PREFIX=$INSTALL_PATH/luarocks-$LUAROCKS_VER - echo "LUAROCKS_PREFIX=$LUAROCKS_PREFIX" >> $GITHUB_ENV - export OPENRESTY_PREFIX=$INSTALL_PATH/openresty-$OPENRESTY_VER - echo "OPENRESTY_PREFIX=$OPENRESTY_PREFIX" >> $GITHUB_ENV - echo "PATH=$DOWNLOAD_PATH:$LUAROCKS_PREFIX/bin:$OPENRESTY_PREFIX/nginx/sbin:$DOWNLOAD_PATH/cpanm:$PATH" >> $GITHUB_ENV - - - name: Lookup build cache - uses: actions/cache@v2 - id: cache-deps - with: - path: | - ${{ env.INSTALL_PATH }} - ~/perl5 - key: ${{ runner.os }}-${{ hashFiles('.github/workflows/latest_os.yml') }} - - - name: Install lua-resty-healthcheck - run: luarocks make - - - name: Run tests - run: | - eval `luarocks path` - eval $(perl -I $HOME/perl5/lib/perl5/ -Mlocal::lib) - TEST_NGINX_RANDOMIZE=1 prove -I. -r t diff --git a/.github/workflows/old_os.yml b/.github/workflows/old_os.yml deleted file mode 100644 index 57f98293..00000000 --- a/.github/workflows/old_os.yml +++ /dev/null @@ -1,189 +0,0 @@ -name: Build and test for Ubuntu 18.04 - -on: [push, pull_request] - -jobs: - build: - name: Build and install dependencies - runs-on: ubuntu-18.04 - strategy: - matrix: - openresty-version: [1.13.6.2, 1.15.8.3, 1.17.8.2, 1.19.9.1, 1.21.4.1] - luarocks-version: [3.8.0] - - steps: - - name: Update and install OS dependencies - run: sudo apt-get update && sudo apt-get install -y libssl-dev ssl-cert - - - name: Set environment variables - env: - LUAROCKS_VER: ${{ matrix.luarocks-version }} - OPENRESTY_VER: ${{ matrix.openresty-version }} - run: | - echo "DOWNLOAD_PATH=$HOME/download-root" >> $GITHUB_ENV - export DOWNLOAD_PATH=$HOME/download-root - echo "INSTALL_PATH=$HOME/install-root" >> $GITHUB_ENV - export INSTALL_PATH=$HOME/install-root - echo "LUAROCKS_VER=$LUAROCKS_VER" >> $GITHUB_ENV - echo "OPENRESTY_VER=$OPENRESTY_VER" >> $GITHUB_ENV - export LUAROCKS_PREFIX=$INSTALL_PATH/luarocks-$LUAROCKS_VER - echo "LUAROCKS_PREFIX=$LUAROCKS_PREFIX" >> $GITHUB_ENV - export OPENRESTY_PREFIX=$INSTALL_PATH/openresty-$OPENRESTY_VER - echo "OPENRESTY_PREFIX=$OPENRESTY_PREFIX" >> $GITHUB_ENV - echo "PATH=$DOWNLOAD_PATH:$LUAROCKS_PREFIX/bin:$OPENRESTY_PREFIX/nginx/sbin:$DOWNLOAD_PATH/cpanm:$PATH" >> $GITHUB_ENV - - - name: Checkout lua-resty-healthcheck - uses: actions/checkout@v2 - - - name: Lookup build cache - uses: actions/cache@v2 - id: cache-deps - with: - path: | - ${{ env.INSTALL_PATH }} - ~/perl5 - key: ${{ runner.os }}-${{ matrix.openresty-version }}-${{ hashFiles('.github/workflows/old_os.yml') }} - - - name: Create needed paths - if: steps.cache-deps.outputs.cache-hit != 'true' - run: | - mkdir -p $DOWNLOAD_PATH - mkdir -p $INSTALL_PATH - - - name: Build and install OpenResty ${{ matrix.openresty-version }} - if: steps.cache-deps.outputs.cache-hit != 'true' - run: | - if [ ! -d $INSTALL_PATH/openresty-$OPENRESTY_VER ]; - then - pushd $DOWNLOAD_PATH - echo "Downloading from http://openresty.org/download/openresty-$OPENRESTY_VER.tar.gz" - wget -O $DOWNLOAD_PATH/openresty-$OPENRESTY_VER.tar.gz http://openresty.org/download/openresty-$OPENRESTY_VER.tar.gz - echo "tar -zxf $DOWNLOAD_PATH/openresty-$OPENRESTY_VER.tar.gz" - tar -zxf $DOWNLOAD_PATH/openresty-$OPENRESTY_VER.tar.gz - echo "result: $?" - pushd openresty-$OPENRESTY_VER - ./configure --prefix=$OPENRESTY_PREFIX - make - make install - popd - popd - fi - - - name: Build and install LuaRocks ${{ matrix.luarocks-version }} - if: steps.cache-deps.outputs.cache-hit != 'true' - run: | - if [ ! -d $INSTALL_PATH/luarocks-$LUAROCKS_VER ]; - then - pushd $DOWNLOAD_PATH - echo "Downloading from https://luarocks.github.io/luarocks/releases/luarocks-$LUAROCKS_VER.tar.gz" - wget -O $DOWNLOAD_PATH/luarocks-$LUAROCKS_VER.tar.gz https://luarocks.github.io/luarocks/releases/luarocks-$LUAROCKS_VER.tar.gz - tar -zxf $DOWNLOAD_PATH/luarocks-$LUAROCKS_VER.tar.gz - pushd luarocks-$LUAROCKS_VER - ./configure --prefix=$LUAROCKS_PREFIX --with-lua=$OPENRESTY_PREFIX/luajit --with-lua-include=$OPENRESTY_PREFIX/luajit/include/luajit-2.1 --lua-suffix=jit - make build - make install - popd - luarocks install luacheck - popd - fi - - - name: Install Test::NGINX - if: steps.cache-deps.outputs.cache-hit != 'true' - run: | - if [ ! -f $DOWNLOAD_PATH/cpanm ]; - then - wget -O $DOWNLOAD_PATH/cpanm https://cpanmin.us/ - chmod +x $DOWNLOAD_PATH/cpanm - cpanm --notest --local-lib=$HOME/perl5 local::lib && eval $(perl -I $HOME/perl5/lib/perl5/ -Mlocal::lib) - cpanm --notest Test::Nginx - fi - - lint: - name: Static code analysis - runs-on: ubuntu-18.04 - needs: build - strategy: - matrix: - openresty-version: [1.13.6.2, 1.15.8.3, 1.17.8.2, 1.19.9.1, 1.21.4.1] - luarocks-version: [3.8.0] - steps: - - name: Checkout lua-resty-healthcheck - uses: actions/checkout@v2 - - - name: Set environment variables - env: - LUAROCKS_VER: ${{ matrix.luarocks-version }} - OPENRESTY_VER: ${{ matrix.openresty-version }} - run: | - echo "DOWNLOAD_PATH=$HOME/download-root" >> $GITHUB_ENV - export DOWNLOAD_PATH=$HOME/download-root - echo "INSTALL_PATH=$HOME/install-root" >> $GITHUB_ENV - export INSTALL_PATH=$HOME/install-root - echo "LUAROCKS_VER=$LUAROCKS_VER" >> $GITHUB_ENV - echo "OPENRESTY_VER=$OPENRESTY_VER" >> $GITHUB_ENV - export LUAROCKS_PREFIX=$INSTALL_PATH/luarocks-$LUAROCKS_VER - echo "LUAROCKS_PREFIX=$LUAROCKS_PREFIX" >> $GITHUB_ENV - export OPENRESTY_PREFIX=$INSTALL_PATH/openresty-$OPENRESTY_VER - echo "OPENRESTY_PREFIX=$OPENRESTY_PREFIX" >> $GITHUB_ENV - echo "PATH=$DOWNLOAD_PATH:$LUAROCKS_PREFIX/bin:$OPENRESTY_PREFIX/nginx/sbin:$DOWNLOAD_PATH/cpanm:$PATH" >> $GITHUB_ENV - - - name: Lookup build cache - uses: actions/cache@v2 - id: cache-deps - with: - path: | - ${{ env.INSTALL_PATH }} - ~/perl5 - key: ${{ runner.os }}-${{ matrix.openresty-version }}-${{ hashFiles('.github/workflows/old_os.yml') }} - - - name: Lint code - run: | - eval `luarocks path` - luacheck lib - - install-and-test: - name: Test lua-resty-healthcheck - runs-on: ubuntu-18.04 - needs: build - strategy: - matrix: - openresty-version: [1.13.6.2, 1.15.8.3, 1.17.8.2, 1.19.9.1, 1.21.4.1] - luarocks-version: [3.8.0] - steps: - - name: Checkout lua-resty-healthcheck - uses: actions/checkout@v2 - - - name: Set environment variables - env: - LUAROCKS_VER: ${{ matrix.luarocks-version }} - OPENRESTY_VER: ${{ matrix.openresty-version }} - run: | - echo "DOWNLOAD_PATH=$HOME/download-root" >> $GITHUB_ENV - export DOWNLOAD_PATH=$HOME/download-root - echo "INSTALL_PATH=$HOME/install-root" >> $GITHUB_ENV - export INSTALL_PATH=$HOME/install-root - echo "LUAROCKS_VER=$LUAROCKS_VER" >> $GITHUB_ENV - echo "OPENRESTY_VER=$OPENRESTY_VER" >> $GITHUB_ENV - export LUAROCKS_PREFIX=$INSTALL_PATH/luarocks-$LUAROCKS_VER - echo "LUAROCKS_PREFIX=$LUAROCKS_PREFIX" >> $GITHUB_ENV - export OPENRESTY_PREFIX=$INSTALL_PATH/openresty-$OPENRESTY_VER - echo "OPENRESTY_PREFIX=$OPENRESTY_PREFIX" >> $GITHUB_ENV - echo "PATH=$DOWNLOAD_PATH:$LUAROCKS_PREFIX/bin:$OPENRESTY_PREFIX/nginx/sbin:$DOWNLOAD_PATH/cpanm:$PATH" >> $GITHUB_ENV - - - name: Lookup build cache - uses: actions/cache@v2 - id: cache-deps - with: - path: | - ${{ env.INSTALL_PATH }} - ~/perl5 - key: ${{ runner.os }}-${{ matrix.openresty-version }}-${{ hashFiles('.github/workflows/old_os.yml') }} - - - name: Install lua-resty-healthcheck - run: luarocks make - - - name: Run tests - run: | - eval `luarocks path` - eval $(perl -I $HOME/perl5/lib/perl5/ -Mlocal::lib) - TEST_NGINX_RANDOMIZE=1 prove -I. -r t diff --git a/lib/resty/healthcheck.lua b/lib/resty/healthcheck.lua index 16553aa1..d0215be6 100644 --- a/lib/resty/healthcheck.lua +++ b/lib/resty/healthcheck.lua @@ -30,10 +30,8 @@ local DEBUG = ngx.DEBUG local ngx_log = ngx.log local tostring = tostring local ipairs = ipairs -local cjson = require("cjson.safe").new() local table_insert = table.insert local table_remove = table.remove -local worker_events = require("resty.worker.events") local resty_lock = require ("resty.lock") local re_find = ngx.re.find local bit = require("bit") @@ -43,9 +41,15 @@ local ngx_worker_pid = ngx.worker.pid local ssl = require("ngx.ssl") local resty_timer = require "resty.timer" + +local RESTY_EVENTS_VER = "0.1.0" +local RESTY_WORKER_EVENTS_VER = "0.3.3" + + local new_tab local nkeys local is_array +local codec do local pcall = pcall @@ -81,8 +85,39 @@ do return true end end + + ok, codec = pcall(require, "string.buffer") + if not ok then + codec = require("cjson.safe").new() + end end + +local worker_events +--- This function loads the worker events module received as arg. It will throw +-- error() if it is not possible to load the module. +local function load_events_module(self) + if self.events_module == "resty.worker.events" then + worker_events = require("resty.worker.events") + assert(worker_events, "could not load lua-resty-worker-events") + assert(worker_events._VERSION == RESTY_WORKER_EVENTS_VER, + "unsupported lua-resty-worker-events version") + + elseif self.events_module == "resty.events" then + worker_events = require("resty.events.compat") + --assert(self.worker_events, "could not load lua-resty-events") + assert(worker_events._VERSION == RESTY_EVENTS_VER, + "unsupported lua-resty-events version") + + else + error("unknown events module") + end + + assert(worker_events.configured(), "please configure the '" .. + self.events_module .. "' module before using 'lua-resty-healthcheck'") +end + + -- constants local EVENT_SOURCE_PREFIX = "lua-resty-healthcheck" local LOG_PREFIX = "[healthcheck] " @@ -196,17 +231,12 @@ local hcs = setmetatable({}, { local active_check_timer --- TODO: improve serialization speed -- serialize a table to a string -local function serialize(t) - return cjson.encode(t) -end +local serialize = codec.encode -- deserialize a string to a table -local function deserialize(s) - return cjson.decode(s) -end +local deserialize = codec.decode local function key_for(key_prefix, ip, port, hostname) @@ -1334,6 +1364,7 @@ local defaults = { name = NO_DEFAULT, shm_name = NO_DEFAULT, type = NO_DEFAULT, + events_module = "resty.worker.events", checks = { active = { type = "http", @@ -1437,14 +1468,14 @@ end -- @return checker object, or `nil + error` function _M.new(opts) - assert(worker_events.configured(), "please configure the " .. - "'lua-resty-worker-events' module before using 'lua-resty-healthcheck'") - + opts = opts or {} local active_type = (((opts or EMPTY).checks or EMPTY).active or EMPTY).type local passive_type = (((opts or EMPTY).checks or EMPTY).passive or EMPTY).type local self = fill_in_settings(opts, defaults) + load_events_module(self) + -- If using deprecated self.type, that takes precedence over -- a default value. TODO: remove this in a future version if self.type then diff --git a/lua-resty-healthcheck-scm-1.rockspec b/lua-resty-healthcheck-scm-1.rockspec index ff1f299b..d9172229 100644 --- a/lua-resty-healthcheck-scm-1.rockspec +++ b/lua-resty-healthcheck-scm-1.rockspec @@ -14,7 +14,6 @@ description = { homepage = "https://github.com/Kong/lua-resty-healthcheck" } dependencies = { - "lua-resty-worker-events == 1.0.0", "penlight >= 1.9.2", "lua-resty-timer ~> 1", } diff --git a/t/with_resty-events/00-new.t b/t/with_resty-events/00-new.t new file mode 100644 index 00000000..03bc1f97 --- /dev/null +++ b/t/with_resty-events/00-new.t @@ -0,0 +1,229 @@ +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +workers(1); + +plan tests => repeat_each() * (blocks() * 3) - 2; + +my $pwd = cwd(); +$ENV{TEST_NGINX_SERVROOT} = server_root(); + +our $HttpConfig = qq{ + lua_package_path "$pwd/lib/?.lua;;"; + lua_shared_dict test_shm 8m; + + server { + server_name kong_worker_events; + listen unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock; + access_log off; + location / { + content_by_lua_block { + require("resty.events.compat").run() + } + } + } +}; + +run_tests(); + +__DATA__ + +=== TEST 1: new() requires worker_events to be configured +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local ok, err = pcall(healthcheck.new, { + events_module = "resty.events", + }) + ngx.log(ngx.ERR, err) + } + } +--- request +GET /t +--- response_body + +--- error_log +please configure + +=== TEST 2: new() requires 'name' +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ unique_timeout = 5, broker_id = 0, listening = "unix:" .. ngx.config.prefix() .. "worker_events.sock" })) + local healthcheck = require("resty.healthcheck") + local ok, err = pcall(healthcheck.new, { + events_module = "resty.events", + shm_name = "test_shm", + }) + ngx.log(ngx.ERR, err) + } + } +--- request +GET /t +--- response_body + +--- error_log +required option 'name' is missing + +=== TEST 3: new() fails with invalid shm +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ unique_timeout = 5, broker_id = 0, listening = "unix:" .. ngx.config.prefix() .. "worker_events.sock" })) + local healthcheck = require("resty.healthcheck") + local ok, err = pcall(healthcheck.new, { + name = "testing", + shm_name = "invalid_shm", + events_module = "resty.events", + }) + ngx.log(ngx.ERR, err) + } + } +--- request +GET /t +--- response_body + +--- error_log +no shm found by name + +=== TEST 4: new() initializes with default config +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ unique_timeout = 5, broker_id = 0, listening = "unix:" .. ngx.config.prefix() .. "worker_events.sock" })) + local healthcheck = require("resty.healthcheck") + local ok, err = pcall(healthcheck.new, { + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + }) + } + } +--- request +GET /t +--- response_body + +--- error_log +Healthchecker started! + +=== TEST 5: new() only accepts http or tcp types +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ unique_timeout = 5, broker_id = 0, listening = "unix:" .. ngx.config.prefix() .. "worker_events.sock" })) + local healthcheck = require("resty.healthcheck") + local ok, err = pcall(healthcheck.new, { + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + type = "http", + }) + ngx.say(ok) + local ok, err = pcall(healthcheck.new, { + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + type = "tcp", + }) + ngx.say(ok) + local ok, err = pcall(healthcheck.new, { + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + type = "get lost", + }) + ngx.say(ok) + } + } +--- request +GET /t +--- response_body +true +true +false + +=== TEST 6: new() deals with bad inputs +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ unique_timeout = 5, broker_id = 0, listening = "unix:" .. ngx.config.prefix() .. "worker_events.sock" })) + local healthcheck = require("resty.healthcheck") + + -- tests for failure + local tests = { + { active = { timeout = -1 }}, + { active = { timeout = 1e+42 }}, + { active = { concurrency = -1 }}, + { active = { concurrency = 1e42 }}, + { active = { healthy = { interval = -1 }}}, + { active = { healthy = { interval = 1e42 }}}, + { active = { healthy = { successes = -1 }}}, + { active = { healthy = { successes = 1e42 }}}, + { active = { unhealthy = { interval = -1 }}}, + { active = { unhealthy = { interval = 1e42 }}}, + { active = { unhealthy = { tcp_failures = -1 }}}, + { active = { unhealthy = { tcp_failures = 1e42 }}}, + { active = { unhealthy = { timeouts = -1 }}}, + { active = { unhealthy = { timeouts = 1e42 }}}, + { active = { unhealthy = { http_failures = -1 }}}, + { active = { unhealthy = { http_failures = 1e42 }}}, + { passive = { healthy = { successes = -1 }}}, + { passive = { healthy = { successes = 1e42 }}}, + { passive = { unhealthy = { tcp_failures = -1 }}}, + { passive = { unhealthy = { tcp_failures = 1e42 }}}, + { passive = { unhealthy = { timeouts = -1 }}}, + { passive = { unhealthy = { timeouts = 1e42 }}}, + { passive = { unhealthy = { http_failures = -1 }}}, + { passive = { unhealthy = { http_failures = 1e42 }}}, + } + for _, test in ipairs(tests) do + local ok, err = pcall(healthcheck.new, { + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + type = "http", + checks = test, + }) + ngx.say(ok) + end + } + } +--- request +GET /t +--- response_body +false +false +false +false +false +false +false +false +false +false +false +false +false +false +false +false +false +false +false +false +false +false +false +false diff --git a/t/with_resty-events/01-start-stop.t b/t/with_resty-events/01-start-stop.t new file mode 100644 index 00000000..152355f7 --- /dev/null +++ b/t/with_resty-events/01-start-stop.t @@ -0,0 +1,182 @@ +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +workers(1); + +plan tests => repeat_each() * (blocks() * 3) + 1; + +my $pwd = cwd(); +$ENV{TEST_NGINX_SERVROOT} = server_root(); + +our $HttpConfig = qq{ + lua_package_path "$pwd/lib/?.lua;;"; + lua_shared_dict test_shm 8m; + + init_worker_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ + unique_timeout = 5, + broker_id = 0, + listening = "unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock" + })) + assert(we.configured()) + } + + server { + server_name kong_worker_events; + listen unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock; + access_log off; + location / { + content_by_lua_block { + require("resty.events.compat").run() + } + } + } +}; + +run_tests(); + +__DATA__ + +=== TEST 1: start() can start after stop() +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + checks = { + active = { + healthy = { + interval = 0.1 + }, + unhealthy = { + interval = 0.1 + } + } + } + }) + local ok, err = checker:stop() + ngx.sleep(0.2) -- wait twice the interval + local ok, err = checker:start() + ngx.say(ok) + } + } +--- request +GET /t +--- response_body +true +--- no_error_log +[error] + + +=== TEST 3: start() is a no-op if active intervals are 0 +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + checks = { + active = { + healthy = { + interval = 0 + }, + unhealthy = { + interval = 0 + } + } + } + }) + local ok, err = checker:start() + ngx.say(ok) + local ok, err = checker:start() + ngx.say(ok) + local ok, err = checker:start() + ngx.say(ok) + } + } +--- request +GET /t +--- response_body +true +true +true +--- no_error_log +[error] + +=== TEST 4: stop() stops health checks +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + checks = { + active = { + healthy = { + interval = 0.1 + }, + unhealthy = { + interval = 0.1 + } + } + } + }) + local ok, err = checker:stop() + ngx.say(ok) + } + } +--- request +GET /t +--- response_body +true +--- no_error_log +[error] +checking + +=== TEST 5: start() restarts health checks +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + checks = { + active = { + healthy = { + interval = 0.1 + }, + unhealthy = { + interval = 0.1 + } + } + } + }) + local ok, err = checker:stop() + ngx.say(ok) + ngx.sleep(1) -- active healthchecks might take up to 1s to start + local ok, err = checker:start() + ngx.say(ok) + ngx.sleep(0.2) -- wait twice the interval + } + } +--- request +GET /t +--- response_body +true +true +--- error_log +checking diff --git a/t/with_resty-events/02-add_target.t b/t/with_resty-events/02-add_target.t new file mode 100644 index 00000000..0815f613 --- /dev/null +++ b/t/with_resty-events/02-add_target.t @@ -0,0 +1,183 @@ +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +workers(1); + +plan tests => repeat_each() * (blocks() * 4) + 3; + +my $pwd = cwd(); +$ENV{TEST_NGINX_SERVROOT} = server_root(); + +our $HttpConfig = qq{ + lua_package_path "$pwd/lib/?.lua;;"; + lua_shared_dict test_shm 8m; + + init_worker_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ + unique_timeout = 5, + broker_id = 0, + listening = "unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock" + })) + assert(we.configured()) + } + + server { + server_name kong_worker_events; + listen unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock; + access_log off; + location / { + content_by_lua_block { + require("resty.events.compat").run() + } + } + } +}; + +run_tests(); + +__DATA__ + +=== TEST 1: add_target() adds an unhealthy target +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + checks = { + active = { + healthy = { + interval = 0.1 + }, + unhealthy = { + interval = 0.1 + } + } + } + }) + ngx.sleep(1) -- active healthchecks might take up to 1s to start + local ok, err = checker:add_target("127.0.0.1", 11111, nil, false) + ngx.say(ok) + ngx.sleep(0.5) + } + } +--- request +GET /t +--- response_body +true +--- error_log +checking healthy targets: nothing to do +checking unhealthy targets: #1 + +--- no_error_log +checking healthy targets: #1 + + + +=== TEST 2: add_target() adds a healthy target +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2112; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 0.1 + }, + unhealthy = { + interval = 0.1 + } + } + } + }) + ngx.sleep(1) -- active healthchecks might take up to 1s to start + local ok, err = checker:add_target("127.0.0.1", 2112, nil, true) + ngx.say(ok) + ngx.sleep(0.2) -- wait twice the interval + } + } +--- request +GET /t +--- response_body +true +--- error_log +checking unhealthy targets: nothing to do +checking healthy targets: #1 + +--- no_error_log +checking unhealthy targets: #1 + + + +=== TEST 3: calling add_target() repeatedly does not change status +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2113; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 0.1, + successes = 1, + }, + unhealthy = { + interval = 0.1, + tcp_failures = 1, + http_failures = 1, + } + } + } + }) + ngx.sleep(1) -- active healthchecks might take up to 1s to start + local ok, err = checker:add_target("127.0.0.1", 2113, nil, true) + local ok, err = checker:add_target("127.0.0.1", 2113, nil, false) + ngx.say(ok) + ngx.sleep(0.2) -- wait twice the interval + } + } +--- request +GET /t +--- response_body +true +--- error_log +checking unhealthy targets: nothing to do +checking healthy targets: #1 + +--- no_error_log +checking unhealthy targets: #1 diff --git a/t/with_resty-events/03-get_target_status.t b/t/with_resty-events/03-get_target_status.t new file mode 100644 index 00000000..f85e7d3a --- /dev/null +++ b/t/with_resty-events/03-get_target_status.t @@ -0,0 +1,106 @@ +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +workers(1); + +plan tests => repeat_each() * (blocks() * 4); + +my $pwd = cwd(); +$ENV{TEST_NGINX_SERVROOT} = server_root(); + +our $HttpConfig = qq{ + lua_package_path "$pwd/lib/?.lua;;"; + lua_shared_dict test_shm 8m; + + init_worker_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ + unique_timeout = 5, + broker_id = 0, + listening = "unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock" + })) + assert(we.configured()) + } + + server { + server_name kong_worker_events; + listen unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock; + access_log off; + location / { + content_by_lua_block { + require("resty.events.compat").run() + } + } + } +}; + +run_tests(); + +__DATA__ + +=== TEST 1: get_target_status() reports proper status +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2115; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 999, -- we don't want active checks + successes = 1, + }, + unhealthy = { + interval = 999, -- we don't want active checks + tcp_failures = 1, + http_failures = 1, + } + }, + passive = { + healthy = { + successes = 1, + }, + unhealthy = { + tcp_failures = 1, + http_failures = 1, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2115, nil, true) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2115)) -- true + + checker:report_tcp_failure("127.0.0.1", 2115) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2115)) -- false + + checker:report_success("127.0.0.1", 2115) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2115)) -- true + } + } +--- request +GET /t +--- response_body +true +false +true +--- no_error_log +checking healthy targets: #1 +checking unhealthy targets: #1 diff --git a/t/with_resty-events/04-report_success.t b/t/with_resty-events/04-report_success.t new file mode 100644 index 00000000..06952980 --- /dev/null +++ b/t/with_resty-events/04-report_success.t @@ -0,0 +1,316 @@ +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +workers(1); + +plan tests => repeat_each() * 28; + +my $pwd = cwd(); +$ENV{TEST_NGINX_SERVROOT} = server_root(); + +our $HttpConfig = qq{ + lua_package_path "$pwd/lib/?.lua;;"; + lua_shared_dict test_shm 8m; + + init_worker_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ + unique_timeout = 5, + broker_id = 0, + listening = "unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock" + })) + assert(we.configured()) + } + + server { + server_name kong_worker_events; + listen unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock; + access_log off; + location / { + content_by_lua_block { + require("resty.events.compat").run() + } + } + } +}; + +run_tests(); + +__DATA__ + + + +=== TEST 1: report_success() recovers HTTP active + passive +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2116; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "http", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 999, -- we don't want active checks + successes = 3, + }, + unhealthy = { + interval = 999, -- we don't want active checks + tcp_failures = 3, + http_failures = 3, + } + }, + passive = { + healthy = { + successes = 3, + }, + unhealthy = { + tcp_failures = 3, + http_failures = 3, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2116, nil, false) + local ok, err = checker:add_target("127.0.0.1", 2118, nil, false) + ngx.sleep(0.01) + checker:report_success("127.0.0.1", 2116, nil, "active") + checker:report_success("127.0.0.1", 2118, nil, "passive") + checker:report_success("127.0.0.1", 2116, nil, "active") + checker:report_success("127.0.0.1", 2118, nil, "passive") + checker:report_success("127.0.0.1", 2116, nil, "active") + checker:report_success("127.0.0.1", 2118, nil, "passive") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2116)) -- true + ngx.say(checker:get_target_status("127.0.0.1", 2118)) -- true + } + } +--- request +GET /t +--- response_body +true +true +--- error_log +healthy SUCCESS increment (1/3) for '(127.0.0.1:2116)' +healthy SUCCESS increment (2/3) for '(127.0.0.1:2116)' +healthy SUCCESS increment (3/3) for '(127.0.0.1:2116)' +event: target status '(127.0.0.1:2116)' from 'false' to 'true' +healthy SUCCESS increment (1/3) for '(127.0.0.1:2116)' +healthy SUCCESS increment (2/3) for '(127.0.0.1:2116)' +healthy SUCCESS increment (3/3) for '(127.0.0.1:2116)' +event: target status '(127.0.0.1:2118)' from 'false' to 'true' + + +=== TEST 2: report_success() recovers TCP active = passive +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2116; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "tcp", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 999, -- we don't want active checks + successes = 3, + }, + unhealthy = { + interval = 999, -- we don't want active checks + tcp_failures = 3, + http_failures = 3, + } + }, + passive = { + healthy = { + successes = 3, + }, + unhealthy = { + tcp_failures = 3, + http_failures = 3, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2116, nil, false) + local ok, err = checker:add_target("127.0.0.1", 2118, nil, false) + ngx.sleep(0.01) + checker:report_success("127.0.0.1", 2116, nil, "active") + checker:report_success("127.0.0.1", 2118, nil, "passive") + checker:report_success("127.0.0.1", 2116, nil, "active") + checker:report_success("127.0.0.1", 2118, nil, "passive") + checker:report_success("127.0.0.1", 2116, nil, "active") + checker:report_success("127.0.0.1", 2118, nil, "passive") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2116)) -- true + ngx.say(checker:get_target_status("127.0.0.1", 2118)) -- true + } + } +--- request +GET /t +--- response_body +true +true +--- error_log +healthy SUCCESS increment (1/3) for '(127.0.0.1:2116)' +healthy SUCCESS increment (2/3) for '(127.0.0.1:2116)' +healthy SUCCESS increment (3/3) for '(127.0.0.1:2116)' +event: target status '(127.0.0.1:2116)' from 'false' to 'true' +healthy SUCCESS increment (1/3) for '(127.0.0.1:2116)' +healthy SUCCESS increment (2/3) for '(127.0.0.1:2116)' +healthy SUCCESS increment (3/3) for '(127.0.0.1:2116)' +event: target status '(127.0.0.1:2118)' from 'false' to 'true' + +=== TEST 3: report_success() is a nop when active.healthy.sucesses == 0 +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2116; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "tcp", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 999, -- we don't want active checks + successes = 0, + }, + unhealthy = { + interval = 999, -- we don't want active checks + tcp_failures = 3, + http_failures = 3, + } + }, + passive = { + healthy = { + successes = 3, + }, + unhealthy = { + tcp_failures = 3, + http_failures = 3, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2116, nil, false) + ngx.sleep(0.01) + checker:report_success("127.0.0.1", 2116, nil, "active") + checker:report_success("127.0.0.1", 2116, nil, "active") + checker:report_success("127.0.0.1", 2116, nil, "active") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2116)) -- false + } + } +--- request +GET /t +--- response_body +false +--- no_error_log +healthy SUCCESS increment +event: target status '127.0.0.1 (127.0.0.1:2116)' from 'false' to 'true' + + + +=== TEST 4: report_success() is a nop when passive.healthy.sucesses == 0 +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2118; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "tcp", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 0, -- we don't want active checks + successes = 0, + }, + unhealthy = { + interval = 0, -- we don't want active checks + tcp_failures = 3, + http_failures = 3, + } + }, + passive = { + healthy = { + successes = 0, + }, + unhealthy = { + tcp_failures = 3, + http_failures = 3, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2118, nil, false) + ngx.sleep(0.01) + checker:report_success("127.0.0.1", 2118, nil, "passive") + checker:report_success("127.0.0.1", 2118, nil, "passive") + checker:report_success("127.0.0.1", 2118, nil, "passive") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2118, nil)) -- false + } + } +--- request +GET /t +--- response_body +false +--- no_error_log +healthy SUCCESS increment +event: target status '(127.0.0.1:2118)' from 'false' to 'true' diff --git a/t/with_resty-events/05-report_failure.t b/t/with_resty-events/05-report_failure.t new file mode 100644 index 00000000..229c20a0 --- /dev/null +++ b/t/with_resty-events/05-report_failure.t @@ -0,0 +1,261 @@ +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +workers(1); + +plan tests => repeat_each() * 26; + +my $pwd = cwd(); +$ENV{TEST_NGINX_SERVROOT} = server_root(); + +our $HttpConfig = qq{ + lua_package_path "$pwd/lib/?.lua;;"; + lua_shared_dict test_shm 8m; + + init_worker_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ + unique_timeout = 5, + broker_id = 0, + listening = "unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock" + })) + assert(we.configured()) + } + + server { + server_name kong_worker_events; + listen unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock; + access_log off; + location / { + content_by_lua_block { + require("resty.events.compat").run() + } + } + } +}; + +run_tests(); + +__DATA__ + + + +=== TEST 1: report_failure() fails HTTP active + passive +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2117; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + type = "http", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 999, -- we don't want active checks + successes = 3, + }, + unhealthy = { + interval = 999, -- we don't want active checks + tcp_failures = 2, + http_failures = 3, + } + }, + passive = { + healthy = { + successes = 3, + }, + unhealthy = { + tcp_failures = 2, + http_failures = 3, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2117, nil, true) + local ok, err = checker:add_target("127.0.0.1", 2113, nil, true) + ngx.sleep(0.01) + checker:report_failure("127.0.0.1", 2117, nil, "active") + checker:report_failure("127.0.0.1", 2113, nil, "passive") + checker:report_failure("127.0.0.1", 2117, nil, "active") + checker:report_failure("127.0.0.1", 2113, nil, "passive") + checker:report_failure("127.0.0.1", 2117, nil, "active") + checker:report_failure("127.0.0.1", 2113, nil, "passive") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2117, nil)) -- false + ngx.say(checker:get_target_status("127.0.0.1", 2113, nil)) -- false + } + } +--- request +GET /t +--- response_body +false +false +--- error_log +unhealthy HTTP increment (1/3) for '(127.0.0.1:2117)' +unhealthy HTTP increment (2/3) for '(127.0.0.1:2117)' +unhealthy HTTP increment (3/3) for '(127.0.0.1:2117)' +event: target status '(127.0.0.1:2117)' from 'true' to 'false' +unhealthy HTTP increment (1/3) for '(127.0.0.1:2113)' +unhealthy HTTP increment (2/3) for '(127.0.0.1:2113)' +unhealthy HTTP increment (3/3) for '(127.0.0.1:2113)' +event: target status '(127.0.0.1:2113)' from 'true' to 'false' + + +=== TEST 2: report_failure() fails TCP active + passive +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2117; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + type = "tcp", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 999, -- we don't want active checks + successes = 3, + }, + unhealthy = { + interval = 999, -- we don't want active checks + tcp_failures = 2, + http_failures = 3, + } + }, + passive = { + healthy = { + successes = 3, + }, + unhealthy = { + tcp_failures = 2, + http_failures = 3, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2117, nil, true) + local ok, err = checker:add_target("127.0.0.1", 2113, nil, true) + ngx.sleep(0.01) + checker:report_failure("127.0.0.1", 2117, nil, "active") + checker:report_failure("127.0.0.1", 2113, nil, "passive") + checker:report_failure("127.0.0.1", 2117, nil, "active") + checker:report_failure("127.0.0.1", 2113, nil, "passive") + checker:report_failure("127.0.0.1", 2117, nil, "active") + checker:report_failure("127.0.0.1", 2113, nil, "passive") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2117, nil)) -- false + ngx.say(checker:get_target_status("127.0.0.1", 2113, nil)) -- false + } + } +--- request +GET /t +--- response_body +false +false +--- error_log +unhealthy TCP increment (1/2) for '(127.0.0.1:2117)' +unhealthy TCP increment (2/2) for '(127.0.0.1:2117)' +event: target status '(127.0.0.1:2117)' from 'true' to 'false' +unhealthy TCP increment (1/2) for '(127.0.0.1:2113)' +unhealthy TCP increment (2/2) for '(127.0.0.1:2113)' +event: target status '(127.0.0.1:2113)' from 'true' to 'false' + + +=== TEST 3: report_failure() is a nop when failure counters == 0 +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2117; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + type = "tcp", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 999, -- we don't want active checks + successes = 3, + }, + unhealthy = { + interval = 999, -- we don't want active checks + tcp_failures = 0, + http_failures = 0, + } + }, + passive = { + healthy = { + successes = 3, + }, + unhealthy = { + tcp_failures = 0, + http_failures = 0, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2117, nil, true) + local ok, err = checker:add_target("127.0.0.1", 2113, nil, true) + ngx.sleep(0.01) + checker:report_failure("127.0.0.1", 2117, nil, "active") + checker:report_failure("127.0.0.1", 2113, nil, "passive") + checker:report_failure("127.0.0.1", 2117, nil, "active") + checker:report_failure("127.0.0.1", 2113, nil, "passive") + checker:report_failure("127.0.0.1", 2117, nil, "active") + checker:report_failure("127.0.0.1", 2113, nil, "passive") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2117, nil)) -- true + ngx.say(checker:get_target_status("127.0.0.1", 2113, nil)) -- true + } + } +--- request +GET /t +--- response_body +true +true +--- no_error_log +unhealthy TCP increment (1/2) for '(127.0.0.1:2117)' +unhealthy TCP increment (2/2) for '(127.0.0.1:2117)' +event: target status '(127.0.0.1:2117)' from 'true' to 'false' +unhealthy TCP increment (1/2) for '(127.0.0.1:2113)' +unhealthy TCP increment (2/2) for '(127.0.0.1:2113)' +event: target status '(127.0.0.1:2113)' from 'true' to 'false' diff --git a/t/with_resty-events/06-report_http_status.t b/t/with_resty-events/06-report_http_status.t new file mode 100644 index 00000000..6686682b --- /dev/null +++ b/t/with_resty-events/06-report_http_status.t @@ -0,0 +1,499 @@ +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +workers(1); + +plan tests => repeat_each() * 41; + +my $pwd = cwd(); +$ENV{TEST_NGINX_SERVROOT} = server_root(); + +our $HttpConfig = qq{ + lua_package_path "$pwd/lib/?.lua;;"; + lua_shared_dict test_shm 8m; + + init_worker_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ + unique_timeout = 5, + broker_id = 0, + listening = "unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock" + })) + assert(we.configured()) + } + + server { + server_name kong_worker_events; + listen unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock; + access_log off; + location / { + content_by_lua_block { + require("resty.events.compat").run() + } + } + } +}; + +run_tests(); + +__DATA__ + + + +=== TEST 1: report_http_status() failures active + passive +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2119; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "http", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 999, -- we don't want active checks + successes = 3, + }, + unhealthy = { + interval = 999, -- we don't want active checks + tcp_failures = 2, + http_failures = 3, + } + }, + passive = { + healthy = { + successes = 3, + }, + unhealthy = { + tcp_failures = 2, + http_failures = 3, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2119, nil, true) + local ok, err = checker:add_target("127.0.0.1", 2113, nil, true) + ngx.sleep(0.01) + checker:report_http_status("127.0.0.1", 2119, nil, 500, "active") + checker:report_http_status("127.0.0.1", 2113, nil, 500, "passive") + checker:report_http_status("127.0.0.1", 2119, nil, 500, "active") + checker:report_http_status("127.0.0.1", 2113, nil, 500, "passive") + checker:report_http_status("127.0.0.1", 2119, nil, 500, "active") + checker:report_http_status("127.0.0.1", 2113, nil, 500, "passive") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2119)) -- false + ngx.say(checker:get_target_status("127.0.0.1", 2113)) -- false + } + } +--- request +GET /t +--- response_body +false +false +--- error_log +unhealthy HTTP increment (1/3) for '(127.0.0.1:2119)' +unhealthy HTTP increment (2/3) for '(127.0.0.1:2119)' +unhealthy HTTP increment (3/3) for '(127.0.0.1:2119)' +event: target status '(127.0.0.1:2119)' from 'true' to 'false' +unhealthy HTTP increment (1/3) for '(127.0.0.1:2113)' +unhealthy HTTP increment (2/3) for '(127.0.0.1:2113)' +unhealthy HTTP increment (3/3) for '(127.0.0.1:2113)' +event: target status '(127.0.0.1:2113)' from 'true' to 'false' + + + +=== TEST 2: report_http_status() successes active + passive +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2119; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "http", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 999, -- we don't want active checks + successes = 4, + }, + unhealthy = { + interval = 999, -- we don't want active checks + tcp_failures = 2, + http_failures = 3, + } + }, + passive = { + healthy = { + successes = 4, + }, + unhealthy = { + tcp_failures = 2, + http_failures = 3, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2119, nil, false) + local ok, err = checker:add_target("127.0.0.1", 2113, nil, false) + ngx.sleep(0.01) + checker:report_http_status("127.0.0.1", 2119, nil, 200, "active") + checker:report_http_status("127.0.0.1", 2113, nil, 200, "passive") + checker:report_http_status("127.0.0.1", 2119, nil, 200, "active") + checker:report_http_status("127.0.0.1", 2113, nil, 200, "passive") + checker:report_http_status("127.0.0.1", 2119, nil, 200, "active") + checker:report_http_status("127.0.0.1", 2113, nil, 200, "passive") + checker:report_http_status("127.0.0.1", 2119, nil, 200, "active") + checker:report_http_status("127.0.0.1", 2113, nil, 200, "passive") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2119)) -- true + ngx.say(checker:get_target_status("127.0.0.1", 2113)) -- true + } + } +--- request +GET /t +--- response_body +true +true +--- error_log +healthy SUCCESS increment (1/4) for '(127.0.0.1:2119)' +healthy SUCCESS increment (2/4) for '(127.0.0.1:2119)' +healthy SUCCESS increment (3/4) for '(127.0.0.1:2119)' +healthy SUCCESS increment (4/4) for '(127.0.0.1:2119)' +event: target status '(127.0.0.1:2119)' from 'false' to 'true' +healthy SUCCESS increment (1/4) for '(127.0.0.1:2113)' +healthy SUCCESS increment (2/4) for '(127.0.0.1:2113)' +healthy SUCCESS increment (3/4) for '(127.0.0.1:2113)' +healthy SUCCESS increment (4/4) for '(127.0.0.1:2113)' +event: target status '(127.0.0.1:2113)' from 'false' to 'true' + + +=== TEST 3: report_http_status() with success is a nop when passive.healthy.successes == 0 +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2119; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "http", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 999, -- we don't want active checks + successes = 4, + }, + unhealthy = { + interval = 999, -- we don't want active checks + tcp_failures = 2, + http_failures = 3, + } + }, + passive = { + healthy = { + successes = 0, + }, + unhealthy = { + tcp_failures = 2, + http_failures = 3, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2119, nil, false) + ngx.sleep(0.01) + checker:report_http_status("127.0.0.1", 2119, nil, 200, "passive") + checker:report_http_status("127.0.0.1", 2119, nil, 200, "passive") + checker:report_http_status("127.0.0.1", 2119, nil, 200, "passive") + checker:report_http_status("127.0.0.1", 2119, nil, 200, "passive") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2119, nil)) -- false + } + } +--- request +GET /t +--- response_body +false +--- no_error_log +healthy SUCCESS increment +event: target status '127.0.0.1 (127.0.0.1:2119)' from 'false' to 'true' + + +=== TEST 4: report_http_status() with success is a nop when active.healthy.successes == 0 +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2119; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "http", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 999, -- we don't want active checks + successes = 0, + }, + unhealthy = { + interval = 999, -- we don't want active checks + tcp_failures = 2, + http_failures = 3, + } + }, + passive = { + healthy = { + successes = 4, + }, + unhealthy = { + tcp_failures = 2, + http_failures = 3, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2119, nil, false) + ngx.sleep(0.01) + checker:report_http_status("127.0.0.1", 2119, nil, 200, "active") + checker:report_http_status("127.0.0.1", 2119, nil, 200, "active") + checker:report_http_status("127.0.0.1", 2119, nil, 200, "active") + checker:report_http_status("127.0.0.1", 2119, nil, 200, "active") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2119, nil)) -- false + } + } +--- request +GET /t +--- response_body +false +--- no_error_log +healthy SUCCESS increment +event: target status '127.0.0.1 (127.0.0.1:2119)' from 'false' to 'true' + + +=== TEST 5: report_http_status() with failure is a nop when passive.unhealthy.http_failures == 0 +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2119; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "http", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 999, -- we don't want active checks + successes = 4, + }, + unhealthy = { + interval = 999, -- we don't want active checks + tcp_failures = 2, + http_failures = 3, + } + }, + passive = { + healthy = { + successes = 4, + }, + unhealthy = { + tcp_failures = 2, + http_failures = 0, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2119, nil, true) + ngx.sleep(0.01) + checker:report_http_status("127.0.0.1", 2119, nil, 500, "passive") + checker:report_http_status("127.0.0.1", 2119, nil, 500, "passive") + checker:report_http_status("127.0.0.1", 2119, nil, 500, "passive") + checker:report_http_status("127.0.0.1", 2119, nil, 500, "passive") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2119)) -- true + } + } +--- request +GET /t +--- response_body +true +--- no_error_log +unhealthy HTTP increment +event: target status '127.0.0.1 (127.0.0.1:2119)' from 'true' to 'false' + + +=== TEST 4: report_http_status() with success is a nop when active.unhealthy.http_failures == 0 +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2119; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "http", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 999, -- we don't want active checks + successes = 4, + }, + unhealthy = { + interval = 999, -- we don't want active checks + tcp_failures = 2, + http_failures = 0, + } + }, + passive = { + healthy = { + successes = 4, + }, + unhealthy = { + tcp_failures = 2, + http_failures = 3, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2119, nil, true) + ngx.sleep(0.01) + checker:report_http_status("127.0.0.1", 2119, nil, 500, "active") + checker:report_http_status("127.0.0.1", 2119, nil, 500, "active") + checker:report_http_status("127.0.0.1", 2119, nil, 500, "active") + checker:report_http_status("127.0.0.1", 2119, nil, 500, "active") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2119, nil)) -- true + } + } +--- request +GET /t +--- response_body +true +--- no_error_log +unhealthy HTTP increment +event: target status '(127.0.0.1:2119)' from 'true' to 'false' + + +=== TEST 5: report_http_status() must work in log phase +--- http_config eval +qq{ + $::HttpConfig +} +--- config + location = /t { + content_by_lua_block { + ngx.say("OK") + } + log_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "http", + checks = { + passive = { + healthy = { + successes = 3, + }, + unhealthy = { + tcp_failures = 2, + http_failures = 3, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2119, nil, true) + ngx.sleep(0.01) + checker:report_http_status("127.0.0.1", 2119, nil, 500, "passive") + checker:report_http_status("127.0.0.1", 2119, nil, 500, "passive") + checker:report_http_status("127.0.0.1", 2119, nil, 500, "passive") + checker:report_http_status("127.0.0.1", 2119, nil, 500, "passive") + checker:report_http_status("127.0.0.1", 2119, nil, 500, "passive") + ngx.sleep(0.01) + checker:report_http_status("127.0.0.1", 2119, nil, 500, "passive") + } + } +--- request +GET /t +--- response_body +OK +--- no_error_log +failed to acquire lock: API disabled in the context of log_by_lua diff --git a/t/with_resty-events/07-report_tcp_failure.t b/t/with_resty-events/07-report_tcp_failure.t new file mode 100644 index 00000000..f6dd4898 --- /dev/null +++ b/t/with_resty-events/07-report_tcp_failure.t @@ -0,0 +1,242 @@ +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +workers(1); + +plan tests => repeat_each() * 18; + +my $pwd = cwd(); +$ENV{TEST_NGINX_SERVROOT} = server_root(); + +our $HttpConfig = qq{ + lua_package_path "$pwd/lib/?.lua;;"; + lua_shared_dict test_shm 8m; + + init_worker_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ + unique_timeout = 5, + broker_id = 0, + listening = "unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock" + })) + assert(we.configured()) + } + + server { + server_name kong_worker_events; + listen unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock; + access_log off; + location / { + content_by_lua_block { + require("resty.events.compat").run() + } + } + } +}; + +run_tests(); + +__DATA__ + + + +=== TEST 1: report_tcp_failure() active + passive +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2120; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "http", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 999, -- we don't want active checks + successes = 3, + }, + unhealthy = { + interval = 999, -- we don't want active checks + tcp_failures = 3, + http_failures = 5, + } + }, + passive = { + healthy = { + successes = 3, + }, + unhealthy = { + tcp_failures = 3, + http_failures = 5, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2120, nil, true) + local ok, err = checker:add_target("127.0.0.1", 2113, nil, true) + ngx.sleep(0.01) + checker:report_tcp_failure("127.0.0.1", 2120, nil, nil, "active") + checker:report_tcp_failure("127.0.0.1", 2113, nil, nil, "passive") + checker:report_tcp_failure("127.0.0.1", 2120, nil, nil, "active") + checker:report_tcp_failure("127.0.0.1", 2113, nil, nil, "passive") + checker:report_tcp_failure("127.0.0.1", 2120, nil, nil, "active") + checker:report_tcp_failure("127.0.0.1", 2113, nil, nil, "passive") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2120)) -- false + ngx.say(checker:get_target_status("127.0.0.1", 2113)) -- false + } + } +--- request +GET /t +--- response_body +false +false +--- error_log +unhealthy TCP increment (1/3) for '(127.0.0.1:2120)' +unhealthy TCP increment (2/3) for '(127.0.0.1:2120)' +unhealthy TCP increment (3/3) for '(127.0.0.1:2120)' +event: target status '(127.0.0.1:2120)' from 'true' to 'false' +unhealthy TCP increment (1/3) for '(127.0.0.1:2113)' +unhealthy TCP increment (2/3) for '(127.0.0.1:2113)' +unhealthy TCP increment (3/3) for '(127.0.0.1:2113)' +event: target status '(127.0.0.1:2113)' from 'true' to 'false' + + +=== TEST 2: report_tcp_failure() for active is a nop when active.unhealthy.tcp_failures == 0 +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2120; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "http", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 999, -- we don't want active checks + successes = 3, + }, + unhealthy = { + interval = 999, -- we don't want active checks + tcp_failures = 0, + http_failures = 5, + } + }, + passive = { + healthy = { + successes = 3, + }, + unhealthy = { + tcp_failures = 3, + http_failures = 5, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2120, nil, true) + ngx.sleep(0.01) + checker:report_tcp_failure("127.0.0.1", 2120, nil, nil, "active") + checker:report_tcp_failure("127.0.0.1", 2120, nil, nil, "active") + checker:report_tcp_failure("127.0.0.1", 2120, nil, nil, "active") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2120)) -- true + } + } +--- request +GET /t +--- response_body +true +--- no_error_log +unhealthy TCP increment +event: target status '(127.0.0.1:2120)' from 'true' to 'false' + + + +=== TEST 3: report_tcp_failure() for passive is a nop when passive.unhealthy.tcp_failures == 0 +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2120; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "http", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 999, -- we don't want active checks + successes = 3, + }, + unhealthy = { + interval = 999, -- we don't want active checks + tcp_failures = 3, + http_failures = 5, + } + }, + passive = { + healthy = { + successes = 3, + }, + unhealthy = { + tcp_failures = 0, + http_failures = 5, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2120, nil, true) + ngx.sleep(0.01) + checker:report_tcp_failure("127.0.0.1", 2120, nil, nil, "passive") + checker:report_tcp_failure("127.0.0.1", 2120, nil, nil, "passive") + checker:report_tcp_failure("127.0.0.1", 2120, nil, nil, "passive") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2120)) -- true + } + } +--- request +GET /t +--- response_body +true +--- no_error_log +unhealthy TCP increment +event: target status '(127.0.0.1:2120)' from 'true' to 'false' diff --git a/t/with_resty-events/08-report_timeout.t b/t/with_resty-events/08-report_timeout.t new file mode 100644 index 00000000..b418baa5 --- /dev/null +++ b/t/with_resty-events/08-report_timeout.t @@ -0,0 +1,244 @@ +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +workers(1); + +plan tests => repeat_each() * 16; + +my $pwd = cwd(); +$ENV{TEST_NGINX_SERVROOT} = server_root(); + +our $HttpConfig = qq{ + lua_package_path "$pwd/lib/?.lua;;"; + lua_shared_dict test_shm 8m; + + init_worker_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ + unique_timeout = 5, + broker_id = 0, + listening = "unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock" + })) + assert(we.configured()) + } + + server { + server_name kong_worker_events; + listen unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock; + access_log off; + location / { + content_by_lua_block { + require("resty.events.compat").run() + } + } + } +}; + +run_tests(); + +__DATA__ + + + +=== TEST 1: report_timeout() active + passive +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2122; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "http", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 999, -- we don't want active checks + successes = 3, + }, + unhealthy = { + interval = 999, -- we don't want active checks + tcp_failures = 3, + http_failures = 5, + timeouts = 2, + } + }, + passive = { + healthy = { + successes = 3, + }, + unhealthy = { + tcp_failures = 3, + http_failures = 5, + timeouts = 2, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2122, nil, true) + local ok, err = checker:add_target("127.0.0.1", 2113, nil, true) + ngx.sleep(0.01) + checker:report_timeout("127.0.0.1", 2122, nil, "active") + checker:report_timeout("127.0.0.1", 2113, nil, "passive") + checker:report_timeout("127.0.0.1", 2122, nil, "active") + checker:report_timeout("127.0.0.1", 2113, nil, "passive") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2122)) -- false + ngx.say(checker:get_target_status("127.0.0.1", 2113)) -- false + } + } +--- request +GET /t +--- response_body +false +false +--- error_log +unhealthy TIMEOUT increment (1/2) for '(127.0.0.1:2122)' +unhealthy TIMEOUT increment (2/2) for '(127.0.0.1:2122)' +event: target status '(127.0.0.1:2122)' from 'true' to 'false' +unhealthy TIMEOUT increment (1/2) for '(127.0.0.1:2113)' +unhealthy TIMEOUT increment (2/2) for '(127.0.0.1:2113)' +event: target status '(127.0.0.1:2113)' from 'true' to 'false' + + +=== TEST 2: report_timeout() for active is a nop when active.unhealthy.timeouts == 0 +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2122; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "http", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 999, -- we don't want active checks + successes = 3, + }, + unhealthy = { + interval = 999, -- we don't want active checks + tcp_failures = 3, + http_failures = 5, + timeouts = 0, + } + }, + passive = { + healthy = { + successes = 3, + }, + unhealthy = { + tcp_failures = 3, + http_failures = 5, + timeouts = 2, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2122, nil, true) + ngx.sleep(0.01) + checker:report_timeout("127.0.0.1", 2122, nil, "active") + checker:report_timeout("127.0.0.1", 2122, nil, "active") + checker:report_timeout("127.0.0.1", 2122, nil, "active") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2122)) -- true + } + } +--- request +GET /t +--- response_body +true +--- no_error_log +unhealthy TCP increment +event: target status '(127.0.0.1:2122)' from 'true' to 'false' + + + +=== TEST 3: report_timeout() for passive is a nop when passive.unhealthy.timeouts == 0 +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2122; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "http", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 999, -- we don't want active checks + successes = 3, + }, + unhealthy = { + interval = 999, -- we don't want active checks + tcp_failures = 3, + http_failures = 5, + timeouts = 2, + } + }, + passive = { + healthy = { + successes = 3, + }, + unhealthy = { + tcp_failures = 3, + http_failures = 5, + timeouts = 0, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2122, nil, true) + ngx.sleep(0.01) + checker:report_timeout("127.0.0.1", 2122, nil, "passive") + checker:report_timeout("127.0.0.1", 2122, nil, "passive") + checker:report_timeout("127.0.0.1", 2122, nil, "passive") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2122)) -- true + } + } +--- request +GET /t +--- response_body +true +--- no_error_log +unhealthy TCP increment +event: target status '(127.0.0.1:2122)' from 'true' to 'false' diff --git a/t/with_resty-events/09-active_probes.t b/t/with_resty-events/09-active_probes.t new file mode 100644 index 00000000..1a708205 --- /dev/null +++ b/t/with_resty-events/09-active_probes.t @@ -0,0 +1,536 @@ +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +workers(1); + +plan tests => repeat_each() * 59; + +my $pwd = cwd(); +$ENV{TEST_NGINX_SERVROOT} = server_root(); + +our $HttpConfig = qq{ + lua_package_path "$pwd/lib/?.lua;;"; + lua_shared_dict test_shm 8m; + + init_worker_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ + unique_timeout = 5, + broker_id = 0, + listening = "unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock" + })) + assert(we.configured()) + } + + server { + server_name kong_worker_events; + listen unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock; + access_log off; + location / { + content_by_lua_block { + require("resty.events.compat").run() + } + } + } +}; + +run_tests(); + +__DATA__ + + + +=== TEST 1: active probes, http node failing +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2114; + location = /status { + return 500; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "http", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 0.1, + successes = 3, + }, + unhealthy = { + interval = 0.1, + http_failures = 3, + } + }, + } + }) + ngx.sleep(2) -- active healthchecks might take some time to start + local ok, err = checker:add_target("127.0.0.1", 2114, nil, true) + ngx.sleep(0.6) -- wait for 6x the check interval + ngx.say(checker:get_target_status("127.0.0.1", 2114)) -- false + } + } +--- request +GET /t +--- response_body +false +--- error_log +checking unhealthy targets: nothing to do +unhealthy HTTP increment (1/3) for '127.0.0.1(127.0.0.1:2114)' +unhealthy HTTP increment (2/3) for '127.0.0.1(127.0.0.1:2114)' +unhealthy HTTP increment (3/3) for '127.0.0.1(127.0.0.1:2114)' +event: target status '127.0.0.1(127.0.0.1:2114)' from 'true' to 'false' +checking healthy targets: nothing to do + + + +=== TEST 2: active probes, http node recovering +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2114; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "http", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 0.1, + successes = 3, + }, + unhealthy = { + interval = 0.1, + http_failures = 3, + } + }, + } + }) + local ok, err = checker:add_target("127.0.0.1", 2114, nil, false) + ngx.sleep(1) -- active healthchecks might take up to 1s to start + ngx.sleep(0.6) -- wait for 6x the check interval + ngx.say(checker:get_target_status("127.0.0.1", 2114)) -- true + } + } +--- request +GET /t +--- response_body +true +--- error_log +checking healthy targets: nothing to do +healthy SUCCESS increment (1/3) for '127.0.0.1(127.0.0.1:2114)' +healthy SUCCESS increment (2/3) for '127.0.0.1(127.0.0.1:2114)' +healthy SUCCESS increment (3/3) for '127.0.0.1(127.0.0.1:2114)' +event: target status '127.0.0.1(127.0.0.1:2114)' from 'false' to 'true' +checking unhealthy targets: nothing to do + +=== TEST 3: active probes, custom http status (regression test for pre-filled defaults) +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2114; + location = /status { + return 500; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "http", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 0.1, + successes = 3, + }, + unhealthy = { + interval = 0.1, + http_failures = 3, + http_statuses = { 429 }, + } + }, + } + }) + local ok, err = checker:add_target("127.0.0.1", 2114, nil, true) + ngx.sleep(0.6) -- wait for 6x the check interval + ngx.say(checker:get_target_status("127.0.0.1", 2114)) -- true + } + } +--- request +GET /t +--- response_body +true +--- error_log +checking unhealthy targets: nothing to do +--- no_error_log +checking healthy targets: nothing to do +unhealthy HTTP increment (1/3) for '127.0.0.1(127.0.0.1:2114)' +unhealthy HTTP increment (2/3) for '127.0.0.1(127.0.0.1:2114)' +unhealthy HTTP increment (3/3) for '127.0.0.1(127.0.0.1:2114)' +event: target status '127.0.0.1(127.0.0.1:2114)' from 'true' to 'false' + + +=== TEST 4: active probes, custom http status, node failing +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2114; + location = /status { + return 401; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "http", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 0.1, + successes = 3, + }, + unhealthy = { + interval = 0.1, + http_failures = 3, + http_statuses = { 401 }, + } + }, + } + }) + ngx.sleep(2) -- active healthchecks might take some time to start + local ok, err = checker:add_target("127.0.0.1", 2114, nil, true) + ngx.sleep(0.6) -- wait for 6x the check interval + ngx.say(checker:get_target_status("127.0.0.1", 2114)) -- false + } + } +--- request +GET /t +--- response_body +false +--- error_log +checking unhealthy targets: nothing to do +unhealthy HTTP increment (1/3) for '127.0.0.1(127.0.0.1:2114)' +unhealthy HTTP increment (2/3) for '127.0.0.1(127.0.0.1:2114)' +unhealthy HTTP increment (3/3) for '127.0.0.1(127.0.0.1:2114)' +event: target status '127.0.0.1(127.0.0.1:2114)' from 'true' to 'false' +checking healthy targets: nothing to do + + + +=== TEST 5: active probes, host is correctly set +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2114; + location = /status { + content_by_lua_block { + if ngx.req.get_headers()["Host"] == "example.com" then + ngx.exit(200) + else + ngx.exit(500) + end + } + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "http", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 0.1, + successes = 1, + }, + unhealthy = { + interval = 0.1, + http_failures = 1, + } + }, + } + }) + ngx.sleep(1) -- active healthchecks might take up to 1s to start + local ok, err = checker:add_target("127.0.0.1", 2114, "example.com", false) + ngx.sleep(0.2) -- wait for 2x the check interval + ngx.say(checker:get_target_status("127.0.0.1", 2114, "example.com")) -- true + } + } +--- request +GET /t +--- response_body +true +--- error_log +event: target status 'example.com(127.0.0.1:2114)' from 'false' to 'true' +checking unhealthy targets: #1 + + +=== TEST 6: active probes, tcp node failing +--- http_config eval +qq{ + $::HttpConfig +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "tcp", + checks = { + active = { + healthy = { + interval = 0.1, + successes = 3, + }, + unhealthy = { + interval = 0.1, + tcp_failures = 3, + } + }, + } + }) + ngx.sleep(1) -- active healthchecks might take up to 1s to start + -- Note: no http server configured, so port 2114 remains unanswered + local ok, err = checker:add_target("127.0.0.1", 2114, nil, true) + ngx.sleep(0.6) -- wait for 6x the check interval + ngx.say(checker:get_target_status("127.0.0.1", 2114)) -- false + } + } +--- request +GET /t +--- response_body +false +--- error_log +checking unhealthy targets: nothing to do +unhealthy TCP increment (1/3) for '127.0.0.1(127.0.0.1:2114)' +unhealthy TCP increment (2/3) for '127.0.0.1(127.0.0.1:2114)' +unhealthy TCP increment (3/3) for '127.0.0.1(127.0.0.1:2114)' +event: target status '127.0.0.1(127.0.0.1:2114)' from 'true' to 'false' +checking healthy targets: nothing to do + + + +=== TEST 7: active probes, tcp node recovering +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2114; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "tcp", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 0.1, + successes = 3, + }, + unhealthy = { + interval = 0.1, + tcp_failures = 3, + } + }, + } + }) + ngx.sleep(1) -- active healthchecks might take up to 1s to start + local ok, err = checker:add_target("127.0.0.1", 2114, nil, false) + ngx.sleep(0.6) -- wait for 6x the check interval + ngx.say(checker:get_target_status("127.0.0.1", 2114)) -- true + } + } +--- request +GET /t +--- response_body +true +--- error_log +checking healthy targets: nothing to do +healthy SUCCESS increment (1/3) for '127.0.0.1(127.0.0.1:2114)' +healthy SUCCESS increment (2/3) for '127.0.0.1(127.0.0.1:2114)' +healthy SUCCESS increment (3/3) for '127.0.0.1(127.0.0.1:2114)' +event: target status '127.0.0.1(127.0.0.1:2114)' from 'false' to 'true' +checking unhealthy targets: nothing to do + + + +=== TEST 8: active probes, custom Host header is correctly set +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2114; + location = /status { + content_by_lua_block { + if ngx.req.get_headers()["Host"] == "custom-host.test" then + ngx.exit(200) + else + ngx.exit(500) + end + } + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "http", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 0.1, + successes = 1, + }, + unhealthy = { + interval = 0.1, + http_failures = 1, + } + }, + } + }) + ngx.sleep(1) -- active healthchecks might take up to 1s to start + local ok, err = checker:add_target("127.0.0.1", 2114, "example.com", false, "custom-host.test") + ngx.sleep(0.3) -- wait for 3x the check interval + ngx.say(checker:get_target_status("127.0.0.1", 2114, "example.com")) -- true + } + } +--- request +GET /t +--- response_body +true +--- error_log +event: target status 'example.com(127.0.0.1:2114)' from 'false' to 'true' +checking unhealthy targets: nothing to do + + + +=== TEST 9: active probes, interval is respected +--- http_config eval +qq{ + $::HttpConfig + + # ignore lua tcp socket read timed out + lua_socket_log_errors off; + + server { + listen 2114; + location = /status { + access_by_lua_block { + ngx.sleep(0.3) + ngx.exit(200) + } + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + test = true, + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "http", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 1, + successes = 1, + }, + unhealthy = { + interval = 1, + http_failures = 1, + } + }, + } + }) + ngx.sleep(1) -- active healthchecks might take up to 1s to start + local ok, err = checker:add_target("127.0.0.1", 2114, nil, true) + ngx.sleep(1) -- wait for the check interval + -- checker callback should not be called more than 5 times + if checker.checker_callback_count < 5 then + ngx.say("OK") + else + ngx.say("BAD") + end + } + } +--- request +GET /t +--- response_body +OK +--- no_error_log +[error] diff --git a/t/with_resty-events/10-garbagecollect.t_disabled b/t/with_resty-events/10-garbagecollect.t_disabled new file mode 100644 index 00000000..885e5a48 --- /dev/null +++ b/t/with_resty-events/10-garbagecollect.t_disabled @@ -0,0 +1,105 @@ +# This test is disabled +# +# We need to understand if it is a false-positive or lua-resty-healthcheck is +# actually leaking the event module memory when deleting a checker instance. +# +# Please rename this test if a solution is found or remove it if it is a +# false-positive. + +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +workers(1); + +plan tests => repeat_each() * (blocks() * 3); + +my $pwd = cwd(); +$ENV{TEST_NGINX_SERVROOT} = server_root(); + +our $HttpConfig = qq{ + lua_package_path "$pwd/lib/?.lua;;"; + lua_shared_dict test_shm 8m; + + init_worker_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ + unique_timeout = 5, + broker_id = 0, + listening = "unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock" + })) + assert(we.configured()) + } + + server { + server_name kong_worker_events; + listen unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock; + access_log off; + location / { + content_by_lua_block { + require("resty.events.compat").run() + } + } + } +}; + +run_tests(); + +__DATA__ + + + +=== TEST 1: garbage collect the checker object +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2121; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local dump = function(...) ngx.log(ngx.DEBUG,"\027[31m\n", require("pl.pretty").write({...}),"\027[0m") end + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + type = "http", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 0.1, + successes = 3, + }, + unhealthy = { + interval = 0.1, + http_failures = 3, + } + }, + } + }) + assert(checker:add_target("127.0.0.1", 2121, nil, true)) + local weak_table = setmetatable({ checker },{ + __mode = "v", + }) + checker = nil -- now only anchored in weak table above + collectgarbage() + collectgarbage() + collectgarbage() + collectgarbage() + ngx.sleep(0.5) -- leave room for timers to run (they shouldn't, but we want to be sure) + ngx.say(#weak_table) -- after GC, should be 0 length + } + } +--- request +GET /t +--- response_body +0 +--- no_error_log +checking healthy targets: #1 diff --git a/t/with_resty-events/11-clear.t b/t/with_resty-events/11-clear.t new file mode 100644 index 00000000..6ca929e8 --- /dev/null +++ b/t/with_resty-events/11-clear.t @@ -0,0 +1,298 @@ +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +workers(1); + +plan tests => repeat_each() * 27; + +my $pwd = cwd(); +$ENV{TEST_NGINX_SERVROOT} = server_root(); + +our $HttpConfig = qq{ + lua_package_path "$pwd/lib/?.lua;;"; + lua_shared_dict test_shm 8m; + + init_worker_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ + unique_timeout = 5, + broker_id = 0, + listening = "unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock" + })) + assert(we.configured()) + } + + server { + server_name kong_worker_events; + listen unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock; + access_log off; + location / { + content_by_lua_block { + require("resty.events.compat").run() + } + } + } +}; + +run_tests(); + +__DATA__ + +=== TEST 1: clear() clears the list, new checkers never see it +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local config = { + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + checks = { + active = { + healthy = { + interval = 0.1 + }, + unhealthy = { + interval = 0.1 + } + } + } + } + local checker1 = healthcheck.new(config) + for i = 1, 10 do + checker1:add_target("127.0.0.1", 10000 + i, nil, false) + end + ngx.sleep(0.2) -- wait twice the interval + checker1:clear() + + local checker2 = healthcheck.new(config) + + ngx.say(true) + } + } +--- request +GET /t +--- response_body +true + +--- error_log +initial target list (0 targets) + +--- no_error_log +initial target list (1 targets) +initial target list (2 targets) +initial target list (3 targets) +initial target list (4 targets) +initial target list (5 targets) +initial target list (6 targets) +initial target list (7 targets) +initial target list (8 targets) +initial target list (9 targets) +initial target list (10 targets) +initial target list (11 targets) + +=== TEST 2: clear() clears the list, other checkers get notified and clear too +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local config = { + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + checks = { + active = { + healthy = { + interval = 0.1 + }, + unhealthy = { + interval = 0.1 + } + } + } + } + local checker1 = healthcheck.new(config) + local checker2 = healthcheck.new(config) + for i = 1, 10 do + checker1:add_target("127.0.0.1", 20000 + i, nil, false) + end + checker2:clear() + ngx.sleep(1) + ngx.say(true) + } + } +--- request +GET /t +--- response_body +true + +--- error_log +checking unhealthy targets: nothing to do + +--- no_error_log +checking unhealthy targets: #10 + +=== TEST 3: clear() resets counters +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 21120; + location = /status { + return 503; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local config = { + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 0.2, + }, + unhealthy = { + interval = 0.2, + http_failures = 3, + } + } + } + } + local checker1 = healthcheck.new(config) + checker1:add_target("127.0.0.1", 21120, nil, true) + ngx.sleep(0.5) -- wait 2.5x the interval + checker1:clear() + checker1:add_target("127.0.0.1", 21120, nil, true) + ngx.sleep(0.3) -- wait 1.5x the interval + ngx.say(true) + } + } +--- request +GET /t +--- response_body +true + +--- error_log +unhealthy HTTP increment (1/3) for '127.0.0.1(127.0.0.1:21120)' +unhealthy HTTP increment (2/3) for '127.0.0.1(127.0.0.1:21120)' +--- no_error_log +unhealthy HTTP increment (3/3) for '(127.0.0.1:21120)' + + +=== TEST 4: delayed_clear() clears the list, after interval new checkers don't see it +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local config = { + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + checks = { + active = { + healthy = { + interval = 0.1 + }, + unhealthy = { + interval = 0.1 + } + } + } + } + local checker1 = healthcheck.new(config) + for i = 1, 10 do + checker1:add_target("127.0.0.1", 10000 + i, nil, false) + end + ngx.sleep(0.2) -- wait twice the interval + ngx.say(checker1:get_target_status("127.0.0.1", 10001)) + checker1:delayed_clear(0.2) + + local checker2 = healthcheck.new(config) + ngx.say(checker2:get_target_status("127.0.0.1", 10001)) + ngx.sleep(0.4) -- wait while the targets are cleared + local status, err = checker2:get_target_status("127.0.0.1", 10001) + if status ~= nil then + ngx.say(status) + else + ngx.say(err) + end + } + } +--- request +GET /t +--- response_body +false +false +target not found + +=== TEST 5: delayed_clear() would clear tgt list, but adding again keeps the previous status +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local config = { + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + checks = { + active = { + healthy = { + interval = 0.1 + }, + unhealthy = { + interval = 0.1 + } + } + } + } + local checker1 = healthcheck.new(config) + checker1:add_target("127.0.0.1", 10001, nil, false) + checker1:add_target("127.0.0.1", 10002, nil, false) + checker1:add_target("127.0.0.1", 10003, nil, false) + ngx.sleep(0.2) -- wait twice the interval + ngx.say(checker1:get_target_status("127.0.0.1", 10002)) + checker1:delayed_clear(0.2) + + local checker2 = healthcheck.new(config) + checker2:add_target("127.0.0.1", 10002, nil, true) + ngx.say(checker2:get_target_status("127.0.0.1", 10002)) + ngx.sleep(0.4) -- wait while the targets would be cleared + local status, err = checker2:get_target_status("127.0.0.1", 10001) + if status ~= nil then + ngx.say(status) + else + ngx.say(err) + end + status, err = checker2:get_target_status("127.0.0.1", 10002) + if status ~= nil then + ngx.say(status) + else + ngx.say(err) + end + status, err = checker2:get_target_status("127.0.0.1", 10003) + if status ~= nil then + ngx.say(status) + else + ngx.say(err) + end + } + } +--- request +GET /t +--- response_body +false +false +target not found +false +target not found diff --git a/t/with_resty-events/12-set_target_status.t b/t/with_resty-events/12-set_target_status.t new file mode 100644 index 00000000..9576f7d0 --- /dev/null +++ b/t/with_resty-events/12-set_target_status.t @@ -0,0 +1,207 @@ +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +workers(1); + +plan tests => repeat_each() * blocks() * 2; + +my $pwd = cwd(); +$ENV{TEST_NGINX_SERVROOT} = server_root(); + +our $HttpConfig = qq{ + lua_package_path "$pwd/lib/?.lua;;"; + lua_shared_dict test_shm 8m; + + init_worker_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ + unique_timeout = 5, + broker_id = 0, + listening = "unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock" + })) + assert(we.configured()) + } + + server { + server_name kong_worker_events; + listen unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock; + access_log off; + location / { + content_by_lua_block { + require("resty.events.compat").run() + } + } + } +}; + +run_tests(); + +__DATA__ + +=== TEST 1: set_target_status() updates a status +--- http_config eval +qq{ + $::HttpConfig +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + }) + local ok, err = checker:add_target("127.0.0.1", 2112, nil, true) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2112)) -- true + checker:set_target_status("127.0.0.1", 2112, nil, false) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2112)) -- false + checker:set_target_status("127.0.0.1", 2112, nil, true) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2112)) -- true + } + } +--- request +GET /t +--- response_body +true +false +true + + +=== TEST 2: set_target_status() restores node after passive check disables it +--- http_config eval +qq{ + $::HttpConfig +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + checks = { + passive = { + unhealthy = { + tcp_failures = 2, + http_failures = 2, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2112, nil, true) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2112)) -- true + checker:report_http_status("127.0.0.1", 2112, nil, 500) + checker:report_http_status("127.0.0.1", 2112, nil, 500) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2112)) -- false + checker:set_target_status("127.0.0.1", 2112, nil, true) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2112)) -- true + } + } +--- request +GET /t +--- response_body +true +false +true + + +=== TEST 3: set_target_status() resets the failure counters +--- http_config eval +qq{ + $::HttpConfig +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + checks = { + passive = { + healthy = { + successes = 2, + }, + unhealthy = { + tcp_failures = 2, + http_failures = 2, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2112, nil, true) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2112)) -- true + checker:report_http_status("127.0.0.1", 2112, nil, 500) + checker:set_target_status("127.0.0.1", 2112, nil, true) + checker:report_http_status("127.0.0.1", 2112, nil, 500) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2112)) -- true + checker:report_http_status("127.0.0.1", 2112, nil, 500) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2112)) -- false + } + } +--- request +GET /t +--- response_body +true +true +false + + +=== TEST 3: set_target_status() resets the success counters +--- http_config eval +qq{ + $::HttpConfig +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + checks = { + passive = { + healthy = { + successes = 2, + }, + unhealthy = { + tcp_failures = 2, + http_failures = 2, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2112, nil, true) + ngx.sleep(0.01) + checker:set_target_status("127.0.0.1", 2112, nil, false) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2112)) -- false + checker:report_http_status("127.0.0.1", 2112, nil, 200) + checker:set_target_status("127.0.0.1", 2112, nil, false) + checker:report_http_status("127.0.0.1", 2112, nil, 200) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2112)) -- false + checker:report_http_status("127.0.0.1", 2112, nil, 200) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2112)) -- true + } + } +--- request +GET /t +--- response_body +false +false +true diff --git a/t/with_resty-events/13-integration.t_disabled b/t/with_resty-events/13-integration.t_disabled new file mode 100644 index 00000000..0e7b9274 --- /dev/null +++ b/t/with_resty-events/13-integration.t_disabled @@ -0,0 +1,207 @@ +# This test is disabled +# +# All the test steps used here take longer than the request timeout because of +# all the ngx.sleep needed to synchronize the events. Running them invididually +# seem to work, so the solution is to split the integration test into smaller +# tests. + +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +workers(1); + +plan tests => repeat_each() * 2; + +my $pwd = cwd(); +$ENV{TEST_NGINX_SERVROOT} = server_root(); + +our $HttpConfig = qq{ + lua_package_path "$pwd/lib/?.lua;;"; + lua_shared_dict test_shm 8m; + + init_worker_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ + unique_timeout = 5, + broker_id = 0, + listening = "unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock" + })) + assert(we.configured()) + } + + server { + server_name kong_worker_events; + listen unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock; + access_log off; + location / { + content_by_lua_block { + require("resty.events.compat").run() + } + } + } +}; + +run_tests(); + +__DATA__ + + + +=== TEST 1: ensure counters work properly +--- http_config eval +qq{ + $::HttpConfig +} +--- config eval +qq{ + location = /t { + content_by_lua_block { + local host = "127.0.0.1" + local port = 2112 + + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + test = true, + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + type = "http", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 0, + successes = 4, + }, + unhealthy = { + interval = 0, + tcp_failures = 2, + http_failures = 0, + } + }, + passive = { + healthy = { + successes = 2, + }, + unhealthy = { + tcp_failures = 2, + http_failures = 2, + timeouts = 2, + } + } + } + }) + + local ok, err = checker:add_target(host, port, nil, true) + + -- S = successes counter + -- F = http_failures counter + -- T = tcp_failures counter + -- O = timeouts counter + + local cases = {} + + local function incr(idxs, i, max) + idxs[i] = idxs[i] + 1 + if idxs[i] > max and i > 1 then + idxs[i] = 1 + incr(idxs, i - 1, max) + end + end + + local function add_cases(cases, len, m) + local idxs = {} + for i = 1, len do + idxs[i] = 1 + end + local word = {} + for _ = 1, (#m) ^ len do + for c = 1, len do + word[c] = m[idxs[c]] + end + table.insert(cases, table.concat(word)) + incr(idxs, len, #m) + end + end + + local m = { "S", "F", "T", "O" } + + -- There are 324 (3*3*3*3*4) possible internal states + -- to the above healthcheck configuration where all limits are set to 2. + -- We need at least five events (4*4*4*4) to be able + -- to exercise all of them + for i = 1, 5 do + add_cases(cases, i, m) + end + + -- Brute-force test all combinations of health events up to 5 events + -- and compares the results given by the library with a simple simulation + -- that implements the specified behavior. + local function run_test_case(case) + assert(checker:set_target_status(host, port, nil, true)) + ngx.sleep(0.002) + local i = 1 + local s, f, t, o = 0, 0, 0, 0 + local mode = true + for c in case:gmatch(".") do + if c == "S" then + checker:report_http_status(host, port, nil, 200, "passive") + ngx.sleep(0.002) + s = s + 1 + f, t, o = 0, 0, 0 + if s == 2 then + mode = true + end + elseif c == "F" then + checker:report_http_status(host, port, nil, 500, "passive") + ngx.sleep(0.002) + f = f + 1 + s = 0 + if f == 2 then + mode = false + end + elseif c == "T" then + checker:report_tcp_failure(host, port, nil, "read", "passive") + ngx.sleep(0.002) + t = t + 1 + s = 0 + if t == 2 then + mode = false + end + elseif c == "O" then + checker:report_timeout(host, port, nil, "passive") + ngx.sleep(0.002) + o = o + 1 + s = 0 + if o == 2 then + mode = false + end + end + + --local ctr, state = checker:test_get_counter(host, port, nil) + --ngx.say(case, ": ", c, " ", string.format("%08x", ctr), " ", state) + --ngx.log(ngx.DEBUG, case, ": ", c, " ", string.format("%08x", ctr), " ", state) + + if checker:get_target_status(host, port, nil) ~= mode then + ngx.say("failed: ", case, " step ", i, " expected ", mode) + return false + end + i = i + 1 + end + return true + end + + for _, case in ipairs(cases) do + ngx.log(ngx.ERR, "Case: ", case) + run_test_case(case) + end + ngx.say("all ok!") + } + } +} +--- request +GET /t +--- response_body +all ok! +--- error_log +--- no_error_log diff --git a/t/with_resty-events/14-tls_active_probes.t b/t/with_resty-events/14-tls_active_probes.t new file mode 100644 index 00000000..d9e44902 --- /dev/null +++ b/t/with_resty-events/14-tls_active_probes.t @@ -0,0 +1,155 @@ +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +workers(1); + +plan tests => blocks() * 2; + +my $pwd = cwd(); +$ENV{TEST_NGINX_SERVROOT} = server_root(); + +our $HttpConfig = qq{ + lua_package_path "$pwd/lib/?.lua;;"; + lua_shared_dict test_shm 8m; + + server { + server_name kong_worker_events; + listen unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock; + access_log off; + location / { + content_by_lua_block { + require("resty.events.compat").run() + } + } + } +}; + +run_tests(); + +__DATA__ + + + +=== TEST 1: active probes, valid https +--- http_config eval: $::HttpConfig +--- config + location = /t { + lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt; + lua_ssl_verify_depth 2; + content_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ unique_timeout = 5, broker_id = 0, listening = "unix:" .. ngx.config.prefix() .. "worker_events.sock" })) + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + checks = { + active = { + type = "https", + http_path = "/", + healthy = { + interval = 2, + successes = 2, + }, + unhealthy = { + interval = 2, + tcp_failures = 2, + } + }, + } + }) + local ok, err = checker:add_target("104.154.89.105", 443, "badssl.com", false) + ngx.sleep(8) -- wait for 4x the check interval + ngx.say(checker:get_target_status("104.154.89.105", 443, "badssl.com")) -- true + } + } +--- request +GET /t +--- response_body +true +--- timeout +15 + +=== TEST 2: active probes, invalid cert +--- http_config eval: $::HttpConfig +--- config + location = /t { + lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt; + lua_ssl_verify_depth 2; + content_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ unique_timeout = 5, broker_id = 0, listening = "unix:" .. ngx.config.prefix() .. "worker_events.sock" })) + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + checks = { + active = { + type = "https", + http_path = "/", + healthy = { + interval = 2, + successes = 2, + }, + unhealthy = { + interval = 2, + tcp_failures = 2, + } + }, + } + }) + local ok, err = checker:add_target("104.154.89.105", 443, "wrong.host.badssl.com", true) + ngx.sleep(8) -- wait for 4x the check interval + ngx.say(checker:get_target_status("104.154.89.105", 443, "wrong.host.badssl.com")) -- false + } + } +--- request +GET /t +--- response_body +false +--- timeout +15 + +=== TEST 3: active probes, accept invalid cert when disabling check +--- http_config eval: $::HttpConfig +--- config + location = /t { + lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt; + lua_ssl_verify_depth 2; + content_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ unique_timeout = 5, broker_id = 0, listening = "unix:" .. ngx.config.prefix() .. "worker_events.sock" })) + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + checks = { + active = { + type = "https", + https_verify_certificate = false, + http_path = "/", + healthy = { + interval = 2, + successes = 2, + }, + unhealthy = { + interval = 2, + tcp_failures = 2, + } + }, + } + }) + local ok, err = checker:add_target("104.154.89.105", 443, "wrong.host.badssl.com", false) + ngx.sleep(8) -- wait for 4x the check interval + ngx.say(checker:get_target_status("104.154.89.105", 443, "wrong.host.badssl.com")) -- true + } + } +--- request +GET /t +--- response_body +true +--- timeout +15 diff --git a/t/with_resty-events/15-get_virtualhost_target_status.t b/t/with_resty-events/15-get_virtualhost_target_status.t new file mode 100644 index 00000000..2921a397 --- /dev/null +++ b/t/with_resty-events/15-get_virtualhost_target_status.t @@ -0,0 +1,322 @@ +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +workers(1); + +plan tests => repeat_each() * (blocks() * 5) + 2; + +my $pwd = cwd(); +$ENV{TEST_NGINX_SERVROOT} = server_root(); + +our $HttpConfig = qq{ + lua_package_path "$pwd/lib/?.lua;;"; + lua_shared_dict test_shm 8m; + + init_worker_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ + unique_timeout = 5, + broker_id = 0, + listening = "unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock" + })) + assert(we.configured()) + } + + server { + server_name kong_worker_events; + listen unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock; + access_log off; + location / { + content_by_lua_block { + require("resty.events.compat").run() + } + } + } +}; + +run_tests(); + +__DATA__ + +=== TEST 1: get_target_status() reports proper status for virtualhosts +--- http_config eval +qq{ + $::HttpConfig +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 999, -- we don't want active checks + successes = 1, + }, + unhealthy = { + interval = 999, -- we don't want active checks + tcp_failures = 1, + http_failures = 1, + } + }, + passive = { + healthy = { + successes = 1, + }, + unhealthy = { + tcp_failures = 1, + http_failures = 2, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2115, "ahostname", true) + local ok, err = checker:add_target("127.0.0.1", 2115, "otherhostname", true) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2115, "ahostname")) -- true + ngx.say(checker:get_target_status("127.0.0.1", 2115, "otherhostname")) -- true + checker:report_http_status("127.0.0.1", 2115, "otherhostname", 500, "passive") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2115, "otherhostname")) -- true + checker:report_http_status("127.0.0.1", 2115, "otherhostname", 500, "passive") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2115, "otherhostname")) -- false + checker:report_success("127.0.0.1", 2115, "otherhostname") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2115, "otherhostname")) -- true + checker:report_tcp_failure("127.0.0.1", 2115, "otherhostname") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2115, "otherhostname")) -- false + ngx.say(checker:get_target_status("127.0.0.1", 2115, "ahostname")) -- true + local _, err = checker:get_target_status("127.0.0.1", 2115) + ngx.say(err) -- target not found + } + } +--- request +GET /t +--- response_body +true +true +true +false +true +false +true +target not found +--- error_log +unhealthy HTTP increment (1/2) for 'otherhostname(127.0.0.1:2115)' +unhealthy HTTP increment (2/2) for 'otherhostname(127.0.0.1:2115)' +event: target status 'otherhostname(127.0.0.1:2115)' from 'true' to 'false' + + + +=== TEST 2: get_target_status() reports proper status for mixed targets (with/without hostname) +--- http_config eval +qq{ + $::HttpConfig +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 999, -- we don't want active checks + successes = 1, + }, + unhealthy = { + interval = 999, -- we don't want active checks + tcp_failures = 1, + http_failures = 1, + } + }, + passive = { + healthy = { + successes = 1, + }, + unhealthy = { + tcp_failures = 1, + http_failures = 1, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2116, "ahostname", true) + local ok, err = checker:add_target("127.0.0.1", 2116, nil, true) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2116, "ahostname")) -- true + ngx.say(checker:get_target_status("127.0.0.1", 2116)) -- true + checker:report_http_status("127.0.0.1", 2116, nil, 500, "passive") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2116, "ahostname")) -- true + ngx.say(checker:get_target_status("127.0.0.1", 2116)) -- false + } + } +--- request +GET /t +--- response_body +true +true +true +false +--- error_log +unhealthy HTTP increment (1/1) for '(127.0.0.1:2116)' +event: target status '(127.0.0.1:2116)' from 'true' to 'false' + + + +=== TEST 3: active probe for virtualhosts listening on same port:ip combination +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2117; + server_name healthyserver; + location = /status { + return 200; + } + } + server { + listen 2117; + server_name unhealthyserver; + location = /status { + return 500; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 0.1, + successes = 3, + }, + unhealthy = { + interval = 0.1, + http_failures = 3, + } + }, + } + }) + local ok, err = checker:add_target("127.0.0.1", 2117, "healthyserver", true) + local ok, err = checker:add_target("127.0.0.1", 2117, "unhealthyserver", true) + ngx.sleep(0.6) -- wait for 6x the check interval + ngx.say(checker:get_target_status("127.0.0.1", 2117, "healthyserver")) -- true + ngx.say(checker:get_target_status("127.0.0.1", 2117, "unhealthyserver")) -- false + local _, err = checker:get_target_status("127.0.0.1", 2117) + ngx.say(err) -- target not found + } + } +--- request +GET /t +--- response_body +true +false +target not found +--- error_log +checking unhealthy targets: nothing to do +unhealthy HTTP increment (1/3) for 'unhealthyserver(127.0.0.1:2117)' +unhealthy HTTP increment (2/3) for 'unhealthyserver(127.0.0.1:2117)' +unhealthy HTTP increment (3/3) for 'unhealthyserver(127.0.0.1:2117)' +event: target status 'unhealthyserver(127.0.0.1:2117)' from 'true' to 'false' + + + +=== TEST 4: get_target_status() reports proper status for same target with and without hostname +--- http_config eval +qq{ + $::HttpConfig +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 999, -- we don't want active checks + successes = 1, + }, + unhealthy = { + interval = 999, -- we don't want active checks + tcp_failures = 1, + http_failures = 1, + } + }, + passive = { + healthy = { + successes = 1, + }, + unhealthy = { + tcp_failures = 1, + http_failures = 1, + } + } + } + }) + local ok, err = checker:add_target("127.0.0.1", 2118, "127.0.0.1", true) + local ok, err = checker:add_target("127.0.0.1", 2119, nil, true) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2118, "127.0.0.1")) -- true + ngx.say(checker:get_target_status("127.0.0.1", 2119)) -- true + ngx.say(checker:get_target_status("127.0.0.1", 2118)) -- true + ngx.say(checker:get_target_status("127.0.0.1", 2119, "127.0.0.1")) -- true + checker:report_http_status("127.0.0.1", 2118, nil, 500, "passive") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2118, "127.0.0.1")) -- false + ngx.say(checker:get_target_status("127.0.0.1", 2119)) -- true + ngx.say(checker:get_target_status("127.0.0.1", 2118)) -- false + ngx.say(checker:get_target_status("127.0.0.1", 2119, "127.0.0.1")) -- true + checker:report_http_status("127.0.0.1", 2119, "127.0.0.1", 500, "passive") + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2118, "127.0.0.1")) -- false + ngx.say(checker:get_target_status("127.0.0.1", 2119)) -- false + ngx.say(checker:get_target_status("127.0.0.1", 2118)) -- false + ngx.say(checker:get_target_status("127.0.0.1", 2119, "127.0.0.1")) -- false + } + } +--- request +GET /t +--- response_body +true +true +true +true +false +true +false +true +false +false +false +false +--- error_log +unhealthy HTTP increment (1/1) for '(127.0.0.1:2118)' +event: target status '(127.0.0.1:2118)' from 'true' to 'false' +unhealthy HTTP increment (1/1) for '127.0.0.1(127.0.0.1:2119)' +event: target status '127.0.0.1(127.0.0.1:2119)' from 'true' to 'false' diff --git a/t/with_resty-events/16-set_all_target_statuses_for_hostname.t b/t/with_resty-events/16-set_all_target_statuses_for_hostname.t new file mode 100644 index 00000000..1385e611 --- /dev/null +++ b/t/with_resty-events/16-set_all_target_statuses_for_hostname.t @@ -0,0 +1,233 @@ +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +workers(1); + +plan tests => repeat_each() * blocks() * 2; + +my $pwd = cwd(); +$ENV{TEST_NGINX_SERVROOT} = server_root(); + +our $HttpConfig = qq{ + lua_package_path "$pwd/lib/?.lua;;"; + lua_shared_dict test_shm 8m; + + init_worker_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ + unique_timeout = 5, + broker_id = 0, + listening = "unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock" + })) + assert(we.configured()) + } + + server { + server_name kong_worker_events; + listen unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock; + access_log off; + location / { + content_by_lua_block { + require("resty.events.compat").run() + } + } + } +}; + +run_tests(); + +__DATA__ + +=== TEST 1: set_all_target_statuses_for_hostname() updates statuses +--- http_config eval +qq{ + $::HttpConfig +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + }) + checker:add_target("127.0.0.1", 2112, "rush", true) + checker:add_target("127.0.0.2", 2112, "rush", true) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2112, "rush")) -- true + ngx.say(checker:get_target_status("127.0.0.2", 2112, "rush")) -- true + checker:set_all_target_statuses_for_hostname("rush", 2112, false) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2112, "rush")) -- false + ngx.say(checker:get_target_status("127.0.0.2", 2112, "rush")) -- false + checker:set_all_target_statuses_for_hostname("rush", 2112, true) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2112, "rush")) -- true + ngx.say(checker:get_target_status("127.0.0.2", 2112, "rush")) -- true + } + } +--- request +GET /t +--- response_body +true +true +false +false +true +true + + +=== TEST 2: set_all_target_statuses_for_hostname() restores node after passive check disables it +--- http_config eval +qq{ + $::HttpConfig +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + checks = { + passive = { + unhealthy = { + tcp_failures = 2, + http_failures = 2, + } + } + } + }) + checker:add_target("127.0.0.1", 2112, "rush", true) + checker:add_target("127.0.0.2", 2112, "rush", true) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2112, "rush")) -- true + ngx.say(checker:get_target_status("127.0.0.2", 2112, "rush")) -- true + checker:report_http_status("127.0.0.1", 2112, "rush", 500) + checker:report_http_status("127.0.0.1", 2112, "rush", 500) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2112, "rush")) -- false + checker:set_all_target_statuses_for_hostname("rush", 2112, true) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2112, "rush")) -- true + ngx.say(checker:get_target_status("127.0.0.2", 2112, "rush")) -- true + } + } +--- request +GET /t +--- response_body +true +true +false +true +true + + +=== TEST 3: set_all_target_statuses_for_hostname() resets failure counters +--- http_config eval +qq{ + $::HttpConfig +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", +events_module = "resty.events", + checks = { + passive = { + healthy = { + successes = 2, + }, + unhealthy = { + tcp_failures = 2, + http_failures = 2, + } + } + } + }) + checker:add_target("127.0.0.1", 2112, "rush", true) + checker:add_target("127.0.0.2", 2112, "rush", true) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2112, "rush")) -- true + ngx.say(checker:get_target_status("127.0.0.2", 2112, "rush")) -- true + checker:report_http_status("127.0.0.1", 2112, "rush", 500) + checker:set_all_target_statuses_for_hostname("rush", 2112, true) + checker:report_http_status("127.0.0.1", 2112, "rush", 500) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2112, "rush")) -- true + ngx.say(checker:get_target_status("127.0.0.2", 2112, "rush")) -- true + checker:report_http_status("127.0.0.1", 2112, "rush", 500) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2112, "rush")) -- false + ngx.say(checker:get_target_status("127.0.0.2", 2112, "rush")) -- true + } + } +--- request +GET /t +--- response_body +true +true +true +true +false +true + + +=== TEST 4: set_target_status() resets the success counters +--- http_config eval +qq{ + $::HttpConfig +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + checks = { + passive = { + healthy = { + successes = 2, + }, + unhealthy = { + tcp_failures = 2, + http_failures = 2, + } + } + } + }) + checker:add_target("127.0.0.1", 2112, "rush", true) + checker:add_target("127.0.0.2", 2112, "rush", true) + ngx.sleep(0.01) + checker:set_all_target_statuses_for_hostname("rush", 2112, false) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2112, "rush")) -- false + ngx.say(checker:get_target_status("127.0.0.2", 2112, "rush")) -- false + checker:report_http_status("127.0.0.1", 2112, "rush", 200) + checker:set_all_target_statuses_for_hostname("rush", 2112, false) + checker:report_http_status("127.0.0.1", 2112, "rush", 200) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2112, "rush")) -- false + ngx.say(checker:get_target_status("127.0.0.2", 2112, "rush")) -- false + checker:report_http_status("127.0.0.1", 2112, "rush", 200) + ngx.sleep(0.01) + ngx.say(checker:get_target_status("127.0.0.1", 2112, "rush")) -- true + ngx.say(checker:get_target_status("127.0.0.2", 2112, "rush")) -- false + } + } +--- request +GET /t +--- response_body +false +false +false +false +true +false diff --git a/t/with_resty-events/17-mtls.t b/t/with_resty-events/17-mtls.t new file mode 100644 index 00000000..c0d0afc3 --- /dev/null +++ b/t/with_resty-events/17-mtls.t @@ -0,0 +1,145 @@ +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +workers(1); + +plan tests => repeat_each() * 4; + +my $pwd = cwd(); +$ENV{TEST_NGINX_SERVROOT} = server_root(); + +our $HttpConfig = qq{ + lua_package_path "$pwd/lib/?.lua;;"; + lua_shared_dict test_shm 8m; + + init_worker_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ + unique_timeout = 5, + broker_id = 0, + listening = "unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock" + })) + assert(we.configured()) + } + + server { + server_name kong_worker_events; + listen unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock; + access_log off; + location / { + content_by_lua_block { + require("resty.events.compat").run() + } + } + } +}; + +run_tests(); + +__DATA__ + +=== TEST 1: configure a MTLS probe +--- http_config eval +qq{ + $::HttpConfig +} +--- config + location = /t { + content_by_lua_block { + local pl_file = require "pl.file" + local cert = pl_file.read("t/with_resty-events/util/cert.pem", true) + local key = pl_file.read("t/with_resty-events/util/key.pem", true) + + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing_mtls", + shm_name = "test_shm", + events_module = "resty.events", + type = "http", + ssl_cert = cert, + ssl_key = key, + checks = { + active = { + http_path = "/status", + healthy = { + interval = 999, -- we don't want active checks + successes = 3, + }, + unhealthy = { + interval = 999, -- we don't want active checks + tcp_failures = 3, + http_failures = 3, + } + }, + passive = { + healthy = { + successes = 3, + }, + unhealthy = { + tcp_failures = 3, + http_failures = 3, + } + } + } + }) + ngx.say(checker ~= nil) -- true + } + } +--- request +GET /t +--- response_body +true + + +=== TEST 2: configure a MTLS probe with parsed cert/key +--- http_config eval +qq{ + $::HttpConfig +} +--- config + location = /t { + content_by_lua_block { + local pl_file = require "pl.file" + local ssl = require "ngx.ssl" + local cert = ssl.parse_pem_cert(pl_file.read("t/with_resty-events/util/cert.pem", true)) + local key = ssl.parse_pem_priv_key(pl_file.read("t/with_resty-events/util/key.pem", true)) + + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing_mtls", + shm_name = "test_shm", +events_module = "resty.events", + type = "http", + ssl_cert = cert, + ssl_key = key, + checks = { + active = { + http_path = "/status", + healthy = { + interval = 999, -- we don't want active checks + successes = 3, + }, + unhealthy = { + interval = 999, -- we don't want active checks + tcp_failures = 3, + http_failures = 3, + } + }, + passive = { + healthy = { + successes = 3, + }, + unhealthy = { + tcp_failures = 3, + http_failures = 3, + } + } + } + }) + ngx.say(checker ~= nil) -- true + } + } +--- request +GET /t +--- response_body +true diff --git a/t/with_resty-events/18-req-headers.t b/t/with_resty-events/18-req-headers.t new file mode 100644 index 00000000..7fd69c33 --- /dev/null +++ b/t/with_resty-events/18-req-headers.t @@ -0,0 +1,280 @@ +use Test::Nginx::Socket::Lua 'no_plan'; +use Cwd qw(cwd); + +workers(1); + +my $pwd = cwd(); +$ENV{TEST_NGINX_SERVROOT} = server_root(); + +our $HttpConfig = qq{ + lua_package_path "$pwd/lib/?.lua;;"; + lua_shared_dict test_shm 8m; + + init_worker_by_lua_block { + local we = require "resty.events.compat" + assert(we.configure({ + unique_timeout = 5, + broker_id = 0, + listening = "unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock" + })) + assert(we.configured()) + } + + server { + server_name kong_worker_events; + listen unix:$ENV{TEST_NGINX_SERVROOT}/worker_events.sock; + access_log off; + location / { + content_by_lua_block { + require("resty.events.compat").run() + } + } + } +}; + +run_tests(); + +__DATA__ + +=== TEST 1: headers: {"User-Agent: curl/7.29.0"} +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2112; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 0.1 + }, + headers = {"User-Agent: curl/7.29.0"} + } + } + }) + ngx.sleep(0.2) -- wait twice the interval + local ok, err = checker:add_target("127.0.0.1", 2112, nil, true) + ngx.say(ok) + ngx.sleep(0.2) -- wait twice the interval + } + } +--- request +GET /t +--- response_body +true +--- error_log +checking healthy targets: nothing to do +checking healthy targets: #1 +GET /status HTTP/1.0 +User-Agent: curl/7.29.0 +Host: 127.0.0.1 + + + +=== TEST 2: headers: {"User-Agent: curl"} +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2112; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 0.1 + }, + headers = {"User-Agent: curl"} + } + } + }) + ngx.sleep(0.2) -- wait twice the interval + local ok, err = checker:add_target("127.0.0.1", 2112, nil, true) + ngx.say(ok) + ngx.sleep(0.2) -- wait twice the interval + } + } +--- request +GET /t +--- response_body +true +--- error_log +checking healthy targets: nothing to do +checking healthy targets: #1 +GET /status HTTP/1.0 +User-Agent: curl +Host: 127.0.0.1 + + +=== TEST 3: headers: { ["User-Agent"] = "curl" } +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2112; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 0.1 + }, + headers = { ["User-Agent"] = "curl" } + } + } + }) + ngx.sleep(0.2) -- wait twice the interval + local ok, err = checker:add_target("127.0.0.1", 2112, nil, true) + ngx.say(ok) + ngx.sleep(0.2) -- wait twice the interval + } + } +--- request +GET /t +--- response_body +true +--- error_log +checking healthy targets: nothing to do +checking healthy targets: #1 +GET /status HTTP/1.0 +User-Agent: curl +Host: 127.0.0.1 + + + +=== TEST 4: headers: { ["User-Agent"] = {"curl"} } +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2112; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 0.1 + }, + headers = { ["User-Agent"] = {"curl"} } + } + } + }) + ngx.sleep(0.2) -- wait twice the interval + local ok, err = checker:add_target("127.0.0.1", 2112, nil, true) + ngx.say(ok) + ngx.sleep(0.2) -- wait twice the interval + } + } +--- request +GET /t +--- response_body +true +--- error_log +checking healthy targets: nothing to do +checking healthy targets: #1 +GET /status HTTP/1.0 +User-Agent: curl +Host: 127.0.0.1 + + + +=== TEST 5: headers: { ["User-Agent"] = {"curl", "nginx"} } +--- http_config eval +qq{ + $::HttpConfig + + server { + listen 2112; + location = /status { + return 200; + } + } +} +--- config + location = /t { + content_by_lua_block { + local healthcheck = require("resty.healthcheck") + local checker = healthcheck.new({ + name = "testing", + shm_name = "test_shm", + events_module = "resty.events", + checks = { + active = { + http_path = "/status", + healthy = { + interval = 0.1 + }, + headers = { ["User-Agent"] = {"curl", "nginx"} } + } + } + }) + ngx.sleep(0.2) -- wait twice the interval + local ok, err = checker:add_target("127.0.0.1", 2112, nil, true) + ngx.say(ok) + ngx.sleep(0.2) -- wait twice the interval + } + } +--- request +GET /t +--- response_body +true +--- error_log +checking healthy targets: nothing to do +checking healthy targets: #1 +GET /status HTTP/1.0 +User-Agent: curl +User-Agent: nginx +Host: 127.0.0.1 diff --git a/t/util/cert.pem b/t/with_resty-events/util/cert.pem similarity index 100% rename from t/util/cert.pem rename to t/with_resty-events/util/cert.pem diff --git a/t/util/key.pem b/t/with_resty-events/util/key.pem similarity index 100% rename from t/util/key.pem rename to t/with_resty-events/util/key.pem diff --git a/t/util/reindex b/t/with_resty-events/util/reindex similarity index 100% rename from t/util/reindex rename to t/with_resty-events/util/reindex diff --git a/t/00-new.t b/t/with_worker-events/00-new.t similarity index 100% rename from t/00-new.t rename to t/with_worker-events/00-new.t diff --git a/t/01-start-stop.t b/t/with_worker-events/01-start-stop.t similarity index 100% rename from t/01-start-stop.t rename to t/with_worker-events/01-start-stop.t diff --git a/t/02-add_target.t b/t/with_worker-events/02-add_target.t similarity index 100% rename from t/02-add_target.t rename to t/with_worker-events/02-add_target.t diff --git a/t/03-get_target_status.t b/t/with_worker-events/03-get_target_status.t similarity index 100% rename from t/03-get_target_status.t rename to t/with_worker-events/03-get_target_status.t diff --git a/t/04-report_success.t b/t/with_worker-events/04-report_success.t similarity index 100% rename from t/04-report_success.t rename to t/with_worker-events/04-report_success.t diff --git a/t/05-report_failure.t b/t/with_worker-events/05-report_failure.t similarity index 100% rename from t/05-report_failure.t rename to t/with_worker-events/05-report_failure.t diff --git a/t/06-report_http_status.t b/t/with_worker-events/06-report_http_status.t similarity index 100% rename from t/06-report_http_status.t rename to t/with_worker-events/06-report_http_status.t diff --git a/t/07-report_tcp_failure.t b/t/with_worker-events/07-report_tcp_failure.t similarity index 100% rename from t/07-report_tcp_failure.t rename to t/with_worker-events/07-report_tcp_failure.t diff --git a/t/08-report_timeout.t b/t/with_worker-events/08-report_timeout.t similarity index 100% rename from t/08-report_timeout.t rename to t/with_worker-events/08-report_timeout.t diff --git a/t/09-active_probes.t b/t/with_worker-events/09-active_probes.t similarity index 100% rename from t/09-active_probes.t rename to t/with_worker-events/09-active_probes.t diff --git a/t/10-garbagecollect.t b/t/with_worker-events/10-garbagecollect.t similarity index 100% rename from t/10-garbagecollect.t rename to t/with_worker-events/10-garbagecollect.t diff --git a/t/11-clear.t b/t/with_worker-events/11-clear.t similarity index 100% rename from t/11-clear.t rename to t/with_worker-events/11-clear.t diff --git a/t/12-set_target_status.t b/t/with_worker-events/12-set_target_status.t similarity index 100% rename from t/12-set_target_status.t rename to t/with_worker-events/12-set_target_status.t diff --git a/t/13-integration.t b/t/with_worker-events/13-integration.t similarity index 100% rename from t/13-integration.t rename to t/with_worker-events/13-integration.t diff --git a/t/14-tls_active_probes.t b/t/with_worker-events/14-tls_active_probes.t similarity index 100% rename from t/14-tls_active_probes.t rename to t/with_worker-events/14-tls_active_probes.t diff --git a/t/15-get_virtualhost_target_status.t b/t/with_worker-events/15-get_virtualhost_target_status.t similarity index 100% rename from t/15-get_virtualhost_target_status.t rename to t/with_worker-events/15-get_virtualhost_target_status.t diff --git a/t/16-set_all_target_statuses_for_hostname.t b/t/with_worker-events/16-set_all_target_statuses_for_hostname.t similarity index 100% rename from t/16-set_all_target_statuses_for_hostname.t rename to t/with_worker-events/16-set_all_target_statuses_for_hostname.t diff --git a/t/17-mtls.t b/t/with_worker-events/17-mtls.t similarity index 90% rename from t/17-mtls.t rename to t/with_worker-events/17-mtls.t index 21166d64..5883cc9d 100644 --- a/t/17-mtls.t +++ b/t/with_worker-events/17-mtls.t @@ -29,8 +29,8 @@ qq{ assert(we.configure{ shm = "my_worker_events", interval = 0.1 }) local pl_file = require "pl.file" - local cert = pl_file.read("t/util/cert.pem", true) - local key = pl_file.read("t/util/key.pem", true) + local cert = pl_file.read("t/with_worker-events/util/cert.pem", true) + local key = pl_file.read("t/with_worker-events/util/key.pem", true) local healthcheck = require("resty.healthcheck") local checker = healthcheck.new({ @@ -85,8 +85,8 @@ qq{ local pl_file = require "pl.file" local ssl = require "ngx.ssl" - local cert = ssl.parse_pem_cert(pl_file.read("t/util/cert.pem", true)) - local key = ssl.parse_pem_priv_key(pl_file.read("t/util/key.pem", true)) + local cert = ssl.parse_pem_cert(pl_file.read("t/with_worker-events/util/cert.pem", true)) + local key = ssl.parse_pem_priv_key(pl_file.read("t/with_worker-events/util/key.pem", true)) local healthcheck = require("resty.healthcheck") local checker = healthcheck.new({ diff --git a/t/20-req-headers.t b/t/with_worker-events/18-req-headers.t similarity index 100% rename from t/20-req-headers.t rename to t/with_worker-events/18-req-headers.t diff --git a/t/with_worker-events/util/cert.pem b/t/with_worker-events/util/cert.pem new file mode 100644 index 00000000..2df6a75a --- /dev/null +++ b/t/with_worker-events/util/cert.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDCTCCAfGgAwIBAgIUWWntedJ1yLAJE2baK/Mg06osmGAwDQYJKoZIhvcNAQEL +BQAwFDESMBAGA1UECgwJS29uZyBJbmMuMB4XDTIwMDQyMzIwMjcwMFoXDTMwMDQy +MTIwMjcwMFowFDESMBAGA1UECgwJS29uZyBJbmMuMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAvVBrEH34MzwKlkBapiNyXr9huSShuojy+7i/01BSFng3 +1TiejXJ3pEjykZqt7ENkZ6+BTYUdb9klK221yXiSyX71x97O0WHHuhH/m4XwGiIH +YPBHdg+ExdMRflXgwtlW3of2hTWxkPkPQDPhoSQVMc5DkU7EOgrTxkv1rUWVAed4 +gSK4IT2AkhKwOSkewZANj2bnK5Evf71ACyJd7IQbJAIYoKBwRJAUXJMA7XAreIB+ +nEr9whNYTklhB4aEa2wtOQuiQubIMJzdOryEX5nufH+tL4p1QKhRPFAqqtJ2Czgw +YZY/v9IrThl19r0nL7FIvxFDNIMeOamJxDLQqsh9NwIDAQABo1MwUTAdBgNVHQ4E +FgQU9t6YAdQ5mOXeqvptN5l3yYZGibEwHwYDVR0jBBgwFoAU9t6YAdQ5mOXeqvpt +N5l3yYZGibEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAhi83 +aXsfJGqr9Zb1guWxbI8uKoG6o88ptXjV2c6dJnxXag0A/Rj+bX2bcPkN2kvQksNl +MBUQlniOydZfsBUAoC0V7yyGUv9eO2RIeFnnNpRXNu+n+Kg2bvgvu8BKNNNOASZv ++Vmzvo9lbfhS9MNAxYk9eTiPNUZ3zn2RfFyT6YWWJbRjk//EAlchyud3XGug9/hw +c05dtzWEYT8GdzMd+Y1/2kR5r/CapSj7GEqL5T3+zDIfjbhTokV7WBrw6og2avoZ +vzrF8xWucry5/2mKQbRxMyCtKYUKTcoLzF4HrNQCETm0n9qUODrHER7Wit9fQFZX +1GEA3BkX2tsbIVVaig== +-----END CERTIFICATE----- diff --git a/t/with_worker-events/util/key.pem b/t/with_worker-events/util/key.pem new file mode 100644 index 00000000..ae945f44 --- /dev/null +++ b/t/with_worker-events/util/key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC9UGsQffgzPAqW +QFqmI3Jev2G5JKG6iPL7uL/TUFIWeDfVOJ6NcnekSPKRmq3sQ2Rnr4FNhR1v2SUr +bbXJeJLJfvXH3s7RYce6Ef+bhfAaIgdg8Ed2D4TF0xF+VeDC2Vbeh/aFNbGQ+Q9A +M+GhJBUxzkORTsQ6CtPGS/WtRZUB53iBIrghPYCSErA5KR7BkA2PZucrkS9/vUAL +Il3shBskAhigoHBEkBRckwDtcCt4gH6cSv3CE1hOSWEHhoRrbC05C6JC5sgwnN06 +vIRfme58f60vinVAqFE8UCqq0nYLODBhlj+/0itOGXX2vScvsUi/EUM0gx45qYnE +MtCqyH03AgMBAAECggEAA1hWa/Yt2onnDfyZHXJm5PGwwlq5WNhuorADA7LZoHgD +VIspkgpBvu9jCduX0yLltUdOm5YMjRtjIr9PhP3SaikKIrv3H5AAvXLv90mIko2j +X70fJiDkEbLHDlpqHEdG16vDWVs3hf5AnLvN8tD2ZujkHL8tjHEAiPJyptsh5OSw +XaltCD67U940XXJ89x0zFZ/3RoRk78wX3ELz7/dY0cMnslMavON+LYTq9hQZyVmm +nOhZICWerKjax4t5f9PZ/zM6IhEVrUhw2WrC31tgRo+ITCIA/nkKid8vNhkiLVdw +jTyAYDLgYW7K8/zVrzmV9TOr3CaZHLQxnF/LMpIEAQKBgQDjnA/G4g2mDD7lsqU1 +N3it87v2VBnZPFNW6L17Qig+2BDTXg1kadFBlp8qtEJI+H5axVSmzsrlmATJVhUK +iYOQwiEsQnt4tGmWZI268NAIUtv0TX0i9yscsezmvGABMcyBCF7ZwFhUfhy0pn1t +kzmbYN4AjYdcisCnSusoMD92NwKBgQDU7YVNuieMIZCIuSxG61N1+ZyX3Ul5l6KU +m1xw1PZvugqXnQlOLV/4Iaz86Vvlt2aDqTWO/iv4LU7ixNdhRtxFIU/b2a8DzDOw +ijhzMGRJqJOdi1NfciiIWHyrjRmGbhCgm784vqV7qbQomiIsjgnDvjoZkossZMiJ +63vs7huxAQKBgQDiQjT8w6JFuk6cD+Zi7G2unmfvCtNXO7ys3Fffu3g+YJL5SrmN +ZBN8W7qFvQNXfo48tYTc/Rx8941qh4QLIYAD2rcXRE9xQgbkVbj+aHykiZnVVWJb +69CTidux0vist1BPxH5lf+tOsr7eZdKxpnTRnI2Thx1URSoWI0d4f93WKQKBgBXn +kW0bl3HtCgdmtU1ebCmY0ik1VJezp8AN84aQAgIga3KJbymhtVu7ayZhg1iwc1Vc +FOxu7WsMji75/QY+2e4qrSJ61GxZl3+z2HbRJaAGPZlZeew5vD26jKjBTTztGbzM +CPH3euKr5KLAqH9Y5VxDt4pl7vdULuUxWoBXRnYBAoGAHIFMYiCdXETtrFHKVTzc +vm4P24PnsNHoDTGMXPeRYRKF2+3VEJrwp1Q3fue4Go4zFB8I6nhNVIbh4dIHxFab +hyxZvGWGUgRvTvD4VYn/YHVoSf2/xNZ0r/S2LKomp+jwoWKfukbCoDjAOWvnK5iD +o41Tn0yhzBdnrYguKznGR3g= +-----END PRIVATE KEY----- diff --git a/t/with_worker-events/util/reindex b/t/with_worker-events/util/reindex new file mode 100755 index 00000000..77ae5484 --- /dev/null +++ b/t/with_worker-events/util/reindex @@ -0,0 +1,27 @@ +#!/usr/bin/env lua + +if not arg[1] then + io.stderr:write("Usage: "..arg[0].." t/*.t\n") + os.exit(1) +end + +for _, name in ipairs(arg) do + local i = 1 + local fd = io.open(name, "r") + if fd then + local new = name.."~" + local out = io.open(new, "w") + for line in fd:lines() do + local test, n, desc = line:match("^(===%s*TEST%s*)(%d+)(.*)$") + if test then + out:write(test .. tostring(i) .. desc .. "\n") + i = i + 1 + else + out:write(line .. "\n") + end + end + out:close() + fd:close() + os.execute("mv " .. new .. " " .. name) + end +end