name: nginx Tests

on:
  workflow_call:

jobs:
  build_wolfssl:
    name: Build wolfSSL
    # Just to keep it the same as the testing target
    runs-on: ubuntu-latest
    # This should be a safe limit for the tests to run.
    timeout-minutes: 4
    steps:
      - if: ${{ runner.debug }}
        name: Enable wolfSSL debug logging
        run: |
          # We don't use --enable-debug since it makes the logs too loud
          echo "wolf_debug_flags= CFLAGS='-g3 -O0'" >> $GITHUB_ENV

      - name: Build wolfSSL
        uses: wolfSSL/actions-build-autotools-project@v1
        with:
          path: wolfssl
          configure: --enable-nginx ${{ env.wolf_debug_flags }}
          install: true

      - name: Upload built lib
        uses: actions/upload-artifact@v3
        with:
          name: wolf-install-nginx
          path: build-dir
          retention-days: 1

  nginx_check:
    strategy:
      fail-fast: false
      matrix:
        include:
          # in general we want to pass all tests that match *ssl*
          - ref: 1.25.0
            test-ref: 5b2894ea1afd01a26c589ce11f310df118e42592
            # Following tests pass with sanitizer on
            sanitize-ok: >-
              h2_ssl_proxy_cache.t h2_ssl.t h2_ssl_variables.t h2_ssl_verify_client.t
              mail_imap_ssl.t mail_ssl_conf_command.t mail_ssl_session_reuse.t
              mail_ssl.t proxy_ssl_certificate_empty.t proxy_ssl_certificate.t
              proxy_ssl_certificate_vars.t proxy_ssl_conf_command.t proxy_ssl_name.t
              ssl_certificate_chain.t ssl_certificate_perl.t ssl_certificates.t
              ssl_certificate.t ssl_client_escaped_cert.t ssl_conf_command.t
              ssl_crl.t ssl_curve.t ssl_engine_keys.t ssl_ocsp.t ssl_password_file.t
              ssl_proxy_protocol.t ssl_proxy_upgrade.t ssl_reject_handshake.t
              ssl_session_reuse.t ssl_session_ticket_key.t ssl_sni_reneg.t
              ssl_sni_sessions.t ssl_sni.t ssl_stapling.t ssl.t ssl_verify_client.t
              ssl_verify_depth.t stream_proxy_ssl_certificate.t stream_proxy_ssl_certificate_vars.t
              stream_proxy_ssl_conf_command.t stream_proxy_ssl_name_complex.t
              stream_proxy_ssl_name.t stream_ssl_certificate.t stream_ssl_conf_command.t
              stream_ssl_preread_alpn.t stream_ssl_preread_protocol.t stream_ssl_preread.t
              stream_ssl_realip.t stream_ssl_session_reuse.t stream_ssl.t stream_ssl_variables.t
              stream_ssl_verify_client.t stream_upstream_zone_ssl.t upstream_zone_ssl.t
              uwsgi_ssl_certificate.t uwsgi_ssl_certificate_vars.t uwsgi_ssl.t
              uwsgi_ssl_verify.t
            # Following tests do not pass with sanitizer on (with OpenSSL too)
            sanitize-not-ok: >-
              grpc_ssl.t h2_proxy_request_buffering_ssl.t h2_proxy_ssl.t
              proxy_request_buffering_ssl.t proxy_ssl_keepalive.t proxy_ssl.t
              proxy_ssl_verify.t stream_proxy_protocol_ssl.t stream_proxy_ssl.t
              stream_proxy_ssl_verify.t stream_ssl_alpn.t
          - ref: 1.24.0
            test-ref: 212d9d003886e3a24542855fb60355a417f037de
            # Following tests pass with sanitizer on
            sanitize-ok: >-
              h2_ssl_proxy_cache.t h2_ssl.t h2_ssl_variables.t h2_ssl_verify_client.t
              mail_imap_ssl.t mail_ssl_conf_command.t mail_ssl_session_reuse.t mail_ssl.t
              proxy_ssl_certificate_empty.t proxy_ssl_certificate.t proxy_ssl_certificate_vars.t
              proxy_ssl_name.t ssl_certificate_chain.t ssl_certificate_perl.t ssl_certificates.t
              ssl_certificate.t ssl_client_escaped_cert.t ssl_conf_command.t ssl_crl.t
              ssl_engine_keys.t ssl_ocsp.t ssl_password_file.t ssl_proxy_protocol.t
              ssl_proxy_upgrade.t ssl_reject_handshake.t ssl_session_reuse.t
              ssl_session_ticket_key.t ssl_sni_reneg.t ssl_sni_sessions.t ssl_sni.t
              ssl_stapling.t ssl.t ssl_verify_client.t stream_proxy_ssl_certificate.t
              stream_proxy_ssl_certificate_vars.t stream_proxy_ssl_name_complex.t
              stream_proxy_ssl_name.t stream_ssl_alpn.t stream_ssl_certificate.t
              stream_ssl_conf_command.t stream_ssl_preread_alpn.t stream_ssl_preread_protocol.t
              stream_ssl_preread.t stream_ssl_realip.t stream_ssl_session_reuse.t stream_ssl.t
              stream_ssl_variables.t stream_ssl_verify_client.t stream_upstream_zone_ssl.t
              upstream_zone_ssl.t uwsgi_ssl_certificate.t uwsgi_ssl_certificate_vars.t
              uwsgi_ssl.t uwsgi_ssl_verify.t 
            # Following tests do not pass with sanitizer on (with OpenSSL too)
            sanitize-not-ok: >-
              grpc_ssl.t h2_proxy_request_buffering_ssl.t h2_proxy_ssl.t
              proxy_request_buffering_ssl.t proxy_ssl_conf_command.t proxy_ssl_keepalive.t
              proxy_ssl.t proxy_ssl_verify.t ssl_curve.t ssl_verify_depth.t
              stream_proxy_protocol_ssl.t stream_proxy_ssl_conf_command.t stream_proxy_ssl.t
              stream_proxy_ssl_verify.t
    name: ${{ matrix.ref }}
    runs-on: ubuntu-latest
    # This should be a safe limit for the tests to run.
    timeout-minutes: 6
    needs: build_wolfssl
    steps:
      - name: Download lib
        uses: actions/download-artifact@v3
        with:
          name: wolf-install-nginx
          path: build-dir

      - name: Install dependencies
        run: |
          sudo cpan -iT Proc::Find Net::SSLeay IO::Socket::SSL

      - name: Checkout wolfssl-nginx
        uses: actions/checkout@v3
        with:
          repository: wolfssl/wolfssl-nginx
          path: wolfssl-nginx

      - name: Checkout nginx
        uses: actions/checkout@v3
        with:
          repository: nginx/nginx
          path: nginx
          ref: release-${{ matrix.ref }}

      - name: Apply nginx patch
        working-directory: nginx
        run: patch -p1 < ../wolfssl-nginx/nginx-${{ matrix.ref }}-wolfssl.patch

      - if: ${{ runner.debug }}
        name: Apply nginx debug patch
        working-directory: nginx
        run: patch -p1 < ../wolfssl-nginx/nginx-${{ matrix.ref }}-wolfssl-debug.patch

      - name: Checkout nginx-tests
        uses: actions/checkout@v3
        with:
          repository: nginx/nginx-tests
          path: nginx-tests
          ref: ${{ matrix.test-ref }}

      - name: Apply nginx-tests patch
        working-directory: nginx-tests
        run: patch -p1 < ../wolfssl-nginx/nginx-tests-patches/*${{ matrix.test-ref }}.patch

      - name: Build nginx without sanitizer
        working-directory: nginx
        run: |
          ./auto/configure --with-wolfssl=$GITHUB_WORKSPACE/build-dir --with-http_ssl_module \
            --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module \
            --with-http_v2_module --with-mail --with-mail_ssl_module
          make -j

      - name: Confirm nginx built with wolfSSL
        working-directory: nginx
        run: ldd objs/nginx | grep wolfssl

      - if: ${{ runner.debug }}
        name: Run nginx-tests without sanitizer (debug)
        working-directory: nginx-tests
        run: |
          LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$GITHUB_WORKSPACE/build-dir/lib \
            TMPDIR=$GITHUB_WORKSPACE TEST_NGINX_VERBOSE=y TEST_NGINX_CATLOG=y \
            TEST_NGINX_BINARY=../nginx/objs/nginx prove -v ${{ matrix.sanitize-not-ok }}

      - if: ${{ !runner.debug }}
        name: Run nginx-tests without sanitizer
        working-directory: nginx-tests
        run: |
          LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$GITHUB_WORKSPACE/build-dir/lib \
            TMPDIR=$GITHUB_WORKSPACE TEST_NGINX_BINARY=../nginx/objs/nginx \
            prove ${{ matrix.sanitize-not-ok }}

      - if: ${{ runner.debug }}
        name: Enable wolfSSL debug logging
        run: |
          echo "nginx_c_flags=-O0" >> $GITHUB_ENV

      - name: Build nginx with sanitizer
        working-directory: nginx
        run: |
          ./auto/configure --with-wolfssl=$GITHUB_WORKSPACE/build-dir --with-http_ssl_module \
            --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module \
            --with-http_v2_module --with-mail --with-mail_ssl_module \
            --with-cc-opt='-fsanitize=address -DNGX_DEBUG_PALLOC=1 -g3 ${{ env.nginx_c_flags }}' \
            --with-ld-opt='-fsanitize=address ${{ env.nginx_c_flags }}'
          make -j

      - name: Confirm nginx built with wolfSSL
        working-directory: nginx
        run: ldd objs/nginx | grep wolfssl

      - if: ${{ runner.debug }}
        name: Run nginx-tests with sanitizer (debug)
        working-directory: nginx-tests
        run: |
          LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$GITHUB_WORKSPACE/build-dir/lib \
          TMPDIR=$GITHUB_WORKSPACE TEST_NGINX_VERBOSE=y TEST_NGINX_CATLOG=y \
          TEST_NGINX_BINARY=../nginx/objs/nginx prove -v ${{ matrix.sanitize-ok }}

      - if: ${{ !runner.debug }}
        name: Run nginx-tests with sanitizer
        working-directory: nginx-tests
        run: |
          LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$GITHUB_WORKSPACE/build-dir/lib \
            TMPDIR=$GITHUB_WORKSPACE TEST_NGINX_BINARY=../nginx/objs/nginx \
            prove ${{ matrix.sanitize-ok }}
 