Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding pytest github workflow to CI test/tests-httpd on a HTTP/3 setup. #10317

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
103 changes: 103 additions & 0 deletions .github/workflows/pytest.yml
@@ -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 }}"
2 changes: 2 additions & 0 deletions lib/vquic/curl_ngtcp2.c
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions tests/tests-httpd/test_04_stuttered.py
Expand Up @@ -97,7 +97,7 @@ def test_04_03_1000_10_1(self, env: Env, httpd, nghttpx, repeat, proto):
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
Expand All @@ -122,7 +122,7 @@ def test_04_04_1000_10_1(self, env: Env, httpd, nghttpx, repeat, proto):
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]:
Expand Down
2 changes: 1 addition & 1 deletion tests/tests-httpd/testenv/curl.py
Expand Up @@ -273,7 +273,7 @@ def _complete_args(self, urls, timeout=None, options=None,
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])
Expand Down
13 changes: 12 additions & 1 deletion tests/tests-httpd/testenv/httpd.py
Expand Up @@ -60,6 +60,8 @@ def __init__(self, env: Env):
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')
Expand Down Expand Up @@ -90,9 +92,17 @@ def exists(self):
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(),
Expand All @@ -117,6 +127,7 @@ def start(self):
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):
Expand Down