Skip to content

Commit

Permalink
CI: test OpenBSD + FreeBSD + illumos in Linux VM
Browse files Browse the repository at this point in the history
workaround greenlet installation on OmniOS v11:
libev assumes inotify.h must be Linux. make autoconf stop offering it.
  • Loading branch information
pajod committed Sep 8, 2024
1 parent 1e78b91 commit 0d03ef2
Show file tree
Hide file tree
Showing 5 changed files with 549 additions and 11 deletions.
67 changes: 67 additions & 0 deletions .github/workflows/bsd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: bsd
on:
push:
branches:
- master
paths:
- '*.py'
- 'tox.ini'
- '.github/workflows/bsd.yml'
pull_request:
branches:
- master
permissions:
# BOLD WARNING: do not add permissions, this workflow executes remote code
contents: read
env:
FORCE_COLOR: 1
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
freebsd:
name: freebsd
timeout-minutes: 20
runs-on: ubuntu-latest
strategy:
fail-fast: true
steps:
- uses: actions/checkout@v4
- uses: vmactions/freebsd-vm@v1
with:
prepare: pkg install -y nginx python311 py311-pip py311-tox py311-sqlite3
usesh: true
copyback: false
# not a typo: "openssl --version" != "openssl version"
run: |
uname -a \
&& python3.11 --version \
&& python3.11 -m tox --version \
&& openssl version \
&& pkg info nginx \
&& python3.11 -m tox -e run-module \
&& python3.11 -m tox -e run-entrypoint \
&& python3.11 -m tox -e py
openbsd:
name: openbsd
timeout-minutes: 20
runs-on: ubuntu-latest
strategy:
fail-fast: true
steps:
- uses: actions/checkout@v4
- uses: vmactions/openbsd-vm@v1
with:
prepare: pkg_add python py3-pip py3-tox py3-sqlite3 nginx
usesh: true
copyback: false
run: |
uname -a \
&& python3 --version \
&& python3 -m tox --version \
&& openssl version \
&& pkg_info nginx \
&& python3 -m tox -e run-module \
&& python3 -m tox -e run-entrypoint \
&& python3 -m tox -e py
52 changes: 52 additions & 0 deletions .github/workflows/illumos.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: illumos
on:
push:
branches:
- master
paths:
- '*.py'
- 'tox.ini'
- '.github/workflows/illumos.yml'
pull_request:
branches:
- master
permissions:
# BOLD WARNING: do not add permissions, this workflow executes remote code
contents: read
env:
FORCE_COLOR: 1
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
omnios:
name: illumos
timeout-minutes: 20
runs-on: ubuntu-latest
strategy:
fail-fast: true
steps:
- uses: actions/checkout@v4
- uses: vmactions/omnios-vm@v1
with:
# need gcc: compile greenlet from source
# autoconf must pretend inotify unavail: libev FTBFS
# /tmp/.nginx must exist because nginx will not create configured tmp
prepare: |
pkg install pip-311 python-311 sqlite-3 nginx gcc13
usesh: true
copyback: false
run: |
cat /etc/release \
&& uname -a \
&& python3 --version \
&& openssl version \
&& pkg info nginx \
&& gcc -dM -E - </dev/null \
&& ac_cv_header_sys_inotify_h=no ac_cv_func_inotify_init=no python3 -m pip install gevent \
&& mkdir -p /tmp/.nginx \
&& python3 -m pip install tox \
&& python3 -m tox --version \
&& python3 -m tox -e run-module \
&& python3 -m tox -e run-entrypoint \
&& python3 -m tox -e py
8 changes: 7 additions & 1 deletion .github/workflows/tox.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
name: tox
on: [push, pull_request]
on:
push:
branches:
- master
pull_request:
branches:
- master
permissions:
contents: read # to fetch code (actions/checkout)
env:
Expand Down
27 changes: 17 additions & 10 deletions tests/test_nginx.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,28 @@
import shutil
import signal
import subprocess
import shutil
import sys
import time
from itertools import chain
from pathlib import Path
from tempfile import TemporaryDirectory
from typing import TYPE_CHECKING
from filelock import FileLock

import pytest

if TYPE_CHECKING:
import http.client
from typing import Any, NamedTuple, Self

CMD_OPENSSL = Path("/usr/bin/openssl")
CMD_NGINX = Path("/usr/sbin/nginx")
# test runner may not be system administrator. not needed here, to run nginx
PATH = "/usr/sbin:/usr/local/sbin:"+os.environ.get("PATH", "/usr/local/bin:/usr/bin")
CMD_OPENSSL = shutil.which("openssl", path=PATH)
CMD_NGINX = shutil.which("nginx", path=PATH)

pytestmark = pytest.mark.skipif(
not CMD_OPENSSL.is_file() or not CMD_NGINX.is_file(),
reason="need %s and %s" % (CMD_OPENSSL, CMD_NGINX),
CMD_OPENSSL is None or CMD_NGINX is None,
reason="need nginx and openssl binaries",
)

STDOUT = 0
Expand All @@ -51,6 +53,8 @@
] # type: list[str|NamedTuple]

WORKER_DEPENDS = {
"sync": [],
"gthread": [],
"aiohttp.GunicornWebWorker": ["aiohttp"],
"aiohttp.GunicornUVLoopWebWorker": ["aiohttp", "uvloop"],
"uvicorn.workers.UvicornWorker": ["uvicorn"], # deprecated
Expand All @@ -65,6 +69,7 @@
}
DEP_WANTED = set(chain(*WORKER_DEPENDS.values())) # type: set[str]
DEP_INSTALLED = set() # type: set[str]
WORKER_ORDER = list(WORKER_DEPENDS.keys())

for dependency in DEP_WANTED:
try:
Expand Down Expand Up @@ -306,9 +311,9 @@ def dummy_ssl_cert(tmp_path_factory):
key = base_tmp_dir / "dummy.key"
print(crt, key)
# generate once, reuse for all tests
with FileLock("%s.lock" % crt):
if not crt.is_file():
generate_dummy_ssl_cert(crt, key)
# with FileLock("%s.lock" % crt):
if not crt.is_file():
generate_dummy_ssl_cert(crt, key)
return crt, key


Expand Down Expand Up @@ -345,7 +350,7 @@ def __init__(
"gunicorn",
"--config=%s" % self.conf_path,
"--log-level=debug",
"--worker-class=%s" % worker_class,
"--worker-class=%s" % (worker_class, ),
"--workers=%d" % WORKER_COUNT,
# unsupported at the time this test was submitted
# "--buf-read-size=%d" % read_size,
Expand Down Expand Up @@ -387,7 +392,9 @@ def get(self, path):
@pytest.mark.parametrize("worker_class", TEST_SIMPLE)
def test_nginx_proxy(*, ssl, worker_class, dummy_ssl_cert, read_size=1024):
# avoid ports <= 6144 which may be in use by CI runner
fixed_port = 1024 * 6 + secrets.randbelow(1024 * 9)
# avoid quickly reusing ports as they might not be cleared immediately on BSD
worker_index = WORKER_ORDER.index(worker_class)
fixed_port = 1024 * 6 + (2 if ssl else 0) + (4 * worker_index)
# FIXME: should also test inherited socket (LISTEN_FDS)
# FIXME: should also test non-inherited (named) UNIX socket
gunicorn_bind = "[::1]:%d" % fixed_port
Expand Down
Loading

0 comments on commit 0d03ef2

Please sign in to comment.