]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
CI: add pytest github workflow to CI test/tests-httpd on a HTTP/3 setup
authorStefan Eissing <stefan@eissing.org>
Wed, 18 Jan 2023 10:11:41 +0000 (11:11 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 31 Jan 2023 11:04:23 +0000 (12:04 +0100)
Closes #10317

.github/workflows/pytest.yml [new file with mode: 0644]
lib/vquic/curl_ngtcp2.c
tests/tests-httpd/test_04_stuttered.py
tests/tests-httpd/testenv/curl.py
tests/tests-httpd/testenv/httpd.py

diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml
new file mode 100644 (file)
index 0000000..eac6ed1
--- /dev/null
@@ -0,0 +1,103 @@
+# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
+#
+# SPDX-License-Identifier: curl
+
+name: pytest
+
+on:
+  push:
+    branches:
+    - master
+    - '*/ci'
+    paths-ignore:
+    - '**/*.md'
+  pull_request:
+    branches:
+    - master
+    paths-ignore:
+    - '**/*.md'
+
+concurrency:
+  # Hardcoded workflow filename as workflow name above is just Linux again
+  group: pytest-openssl-${{ github.event.pull_request.number || github.sha }}
+  cancel-in-progress: true
+
+jobs:
+  autotools:
+    name: ${{ matrix.build.name }}
+    runs-on: 'ubuntu-latest'
+    timeout-minutes: 60
+    strategy:
+      fail-fast: false
+      matrix:
+        build:
+        - name: quictls
+          install: >-
+            libpsl-dev libbrotli-dev libzstd-dev zlib1g-dev libev-dev libc-ares-dev
+          configure: >-
+            PKG_CONFIG_PATH="$HOME/all/lib/pkgconfig" LDFLAGS="-Wl,-rpath,$HOME/all/lib"
+            --with-ngtcp2=$HOME/all --enable-warnings --enable-werror --enable-debug
+            --with-test-nghttpx="$HOME/all/bin/nghttpx"
+          ngtcp2-configure: >-
+            --prefix=$HOME/all PKG_CONFIG_PATH="$HOME/all/lib/pkgconfig" --enable-lib-only
+
+    steps:
+    - run: |
+        sudo apt-get update
+        sudo apt-get install libtool autoconf automake pkg-config stunnel4 ${{ matrix.build.install }}
+        sudo apt-get install apache2 apache2-dev
+        sudo python3 -m pip install impacket pytest cryptography
+      name: 'install prereqs and impacket, pytest, crypto'
+
+    - run: |
+        git clone --depth=1 -b openssl-3.0.7+quic https://github.com/quictls/openssl
+        cd openssl
+        ./config --prefix=$HOME/all --libdir=$HOME/all/lib
+        make install_sw
+      name: 'install quictls'
+
+    - run: |
+        git clone --depth=1 -b v0.8.0 https://github.com/ngtcp2/nghttp3
+        cd nghttp3
+        autoreconf -fi
+        ./configure --prefix=$HOME/all PKG_CONFIG_PATH="$HOME/all/lib/pkgconfig" --enable-lib-only
+        make install
+      name: 'install nghttp3'
+
+    - run: |
+        git clone --depth=1 -b v0.12.1 https://github.com/ngtcp2/ngtcp2
+        cd ngtcp2
+        autoreconf -fi
+        ./configure ${{ matrix.build.ngtcp2-configure }} --with-openssl
+        make install
+      name: 'install ngtcp2'
+
+    - run: |
+        git clone --depth=1 -b v1.51.0 https://github.com/nghttp2/nghttp2
+        cd nghttp2
+        autoreconf -fi
+        ./configure --prefix=$HOME/all PKG_CONFIG_PATH="$HOME/all/lib/pkgconfig" --enable-http3
+        make install
+      name: 'install nghttp2'
+
+    - uses: actions/checkout@v3
+
+    - run: autoreconf -fi
+      name: 'autoreconf'
+
+    - run: ./configure --with-openssl=$HOME/all ${{ matrix.build.configure }}
+      name: 'configure'
+
+    - run: make V=1
+      name: 'make'
+
+    - run: make V=1 examples
+      name: 'make examples'
+
+    - run: make V=1 -C tests
+      name: 'make tests'
+
+    - run: pytest -v
+      name: 'run pytest'
+      env:
+        TFLAGS: "${{ matrix.build.tflags }}"
index dd694805f8ae0db1bf32c5bab76d220267132bda..c76d1234538774aa47e211c20ca81f9d0128cd20 100644 (file)
@@ -1472,6 +1472,8 @@ static CURLcode h3_stream_open(struct Curl_cfilter *cf,
 
   infof(data, "Using HTTP/3 Stream ID: %" PRIx64 " (easy handle %p)",
         stream3_id, (void *)data);
+  DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRIx64 "] opened for %s",
+                stream3_id, data->state.url));
 
   Curl_pseudo_free(hreq);
   return CURLE_OK;
index 05538403d1709abcec413f3b2e2aa56e8aaf45a3..6a0d799f78788cbc9b02246bd904e517906b080b 100644 (file)
@@ -97,7 +97,7 @@ class TestStuttered:
         r.check_responses(count=warmups+count, exp_status=200)
         assert r.total_connects == 1
         t_avg, i_min, t_min, i_max, t_max = self.stats_spread(r.stats[warmups:], 'time_total')
-        assert t_max < (3 * t_min) and t_min < 2.5, \
+        assert t_max < (2 * t_min), \
             f'avg time of transfer: {t_avg} [{i_min}={t_min}, {i_max}={t_max}]'
 
     # download 50 files in 10000 chunks a 1 byte with 10us delay between
@@ -122,7 +122,7 @@ class TestStuttered:
         r.check_responses(count=warmups+count, exp_status=200)
         assert r.total_connects == 1
         t_avg, i_min, t_min, i_max, t_max = self.stats_spread(r.stats[warmups:], 'time_total')
-        assert t_max < (3 * t_min) and t_min < 3, \
+        assert t_max < (2 * t_min), \
             f'avg time of transfer: {t_avg} [{i_min}={t_min}, {i_max}={t_max}]'
 
     def stats_spread(self, stats: List[Dict], key: str) -> Tuple[float, int, float, int, float]:
index 1000925d7b991a34c1267141cf8b20895a339af9..244479ef76955c9d5838b7e94f0be9e2a4c71dd6 100644 (file)
@@ -273,7 +273,7 @@ class CurlClient:
             self._curl, "-s", "--path-as-is", "-D", self._headerfile,
         ]
         if self.env.verbose > 2:
-            args.extend(['--trace', self._tracefile])
+            args.extend(['--trace', self._tracefile, '--trace-time'])
 
         for url in urls:
             u = urlparse(urls[0])
index 3fb7b4a72b71473250496a17c8e5c7a1b2585a11..47e98a094be8a9c7bba84a3042d88270387e9eff 100644 (file)
@@ -60,6 +60,8 @@ class Httpd:
         self.env = env
         self._cmd = env.apachectl
         self._apache_dir = os.path.join(env.gen_dir, 'apache')
+        self._run_dir = os.path.join(self._apache_dir, 'run')
+        self._lock_dir = os.path.join(self._apache_dir, 'locks')
         self._docs_dir = os.path.join(self._apache_dir, 'docs')
         self._conf_dir = os.path.join(self._apache_dir, 'conf')
         self._conf_file = os.path.join(self._conf_dir, 'test.conf')
@@ -90,9 +92,17 @@ class Httpd:
         return os.path.exists(self._cmd)
 
     def _run(self, args, intext=''):
+        env = {}
+        for key, val in os.environ.items():
+            env[key] = val
+        env['APACHE_RUN_DIR'] = self._run_dir
+        env['APACHE_RUN_USER'] = os.environ['USER']
+        env['APACHE_LOCK_DIR'] = self._lock_dir
+        env['APACHE_CONFDIR'] = self._apache_dir
         p = subprocess.run(args, stderr=subprocess.PIPE, stdout=subprocess.PIPE,
                            cwd=self.env.gen_dir,
-                           input=intext.encode() if intext else None)
+                           input=intext.encode() if intext else None,
+                           env=env)
         start = datetime.now()
         return ExecResult(args=args, exit_code=p.returncode,
                           stdout=p.stdout.decode().splitlines(),
@@ -117,6 +127,7 @@ class Httpd:
         r = self._apachectl('start')
         if r.exit_code != 0:
             log.error(f'failed to start httpd: {r}')
+            return False
         return self.wait_live(timeout=timedelta(seconds=5))
 
     def stop(self):