Skip to content

Commit

Permalink
Add tests to the Python build, wheel, and Mypyc packages.
Browse files Browse the repository at this point in the history
Create shared tests to be used for both unit and integration
testing, and increase the coverage of unit tests to 100%. Additionally,
before publishing the pre-release, run the shared tests against the
build version for each OS supported by the code.

The intention here is to ensure that all build packages are tested
and function correctly for all supported features.

Resolves: #577
  • Loading branch information
nycholas committed Oct 27, 2024
1 parent dd8c991 commit 381229f
Show file tree
Hide file tree
Showing 92 changed files with 5,342 additions and 5,041 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/on_update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
- name: Run tox (Style, Type checker, Security, Docs) | Python 3.12
if: ${{ matrix.platform == 'ubuntu-latest' && matrix.python-version == '3.12' }}
run: |
tox -e style,typing-mypy,typing-pyright,security-safety,security-bandit,docs -p all
tox -e style,typing-mypy,typing-pyright,security-bandit,docs -p all
- name: Run tox (Tests) | ${{ matrix.platform }}
run: |
tox -e py,py-async
8 changes: 8 additions & 0 deletions .github/workflows/pre_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,14 @@ jobs:
steps:
- name: Checkout source at ${{ matrix.platform }}
uses: actions/checkout@v4
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Prepare build
run: |
pip install -U pip tomlkit
python bin/cibw-before-build.py
- name: Build wheels
uses: pypa/[email protected]
with:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ parts/
sdist/
var/
wheels/
wheelhouse/
share/python-wheels/
*.egg-info/
.installed.cfg
Expand Down
5 changes: 3 additions & 2 deletions Dockerfile.it
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ WORKDIR /svc
COPY requirements/tests.txt /svc/
RUN pip install pip setuptools wheel --upgrade \
&& pip wheel --wheel-dir=/svc/wheels -r tests.txt \
poetry-core>=1.0.0
&& pip install poetry-core>=1.0.0

FROM python:3.12-alpine

Expand Down Expand Up @@ -57,6 +57,7 @@ ARG VERSION=1
RUN echo "Version: ${VERSION}"

COPY .docker/* requirements/tests.txt tests/integration/*.py tests/integration/*.ini /app/
COPY tests/integration/shared/*.py tests/shared/ /app/shared/

RUN pip install pip setuptools wheel --upgrade \
&& pip install --no-index --find-links=/svc/wheels -r tests.txt \
Expand All @@ -74,4 +75,4 @@ RUN pip install pip setuptools wheel --upgrade \

USER flask_user

CMD ./wait-for.sh ${SITE_DOMAIN}:${SITE_PORT} -t 600 -- pytest --junitxml=test-results/junit.xml
CMD ./wait-for.sh ${SITE_DOMAIN}:${SITE_PORT} -t 600 -- pytest -n auto --junitxml=test-results/junit.xml
4 changes: 1 addition & 3 deletions Dockerfile.local
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,4 @@ USER flask_user
ARG VERSION=1
RUN echo "Version: ${VERSION}"

COPY .docker/* /app/
COPY tests/test_apps/app/__init__.py /app/app.py
COPY tests/test_apps/async_app/__init__.py /app/async_app.py
COPY .docker/* tests/test_apps/ /app/
2 changes: 1 addition & 1 deletion Dockerfile.py310.test
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ RUN set -ex \
&& pip install -r requirements/base.txt \
&& pip install -r requirements/style.txt \
&& pip install -r requirements/tests.txt \
poetry-core>=1.0.0 \
&& pip install poetry-core>=1.0.0 \
&& apk del .build-deps \
&& addgroup -S kuchulu \
&& adduser \
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.py311.test
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ RUN set -ex \
&& pip install -r requirements/base.txt \
&& pip install -r requirements/style.txt \
&& pip install -r requirements/tests.txt \
poetry-core>=1.0.0 \
&& pip install poetry-core>=1.0.0 \
&& apk del .build-deps \
&& addgroup -S kuchulu \
&& adduser \
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.py312.test
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ RUN set -ex \
&& pip install -r requirements/base.txt \
&& pip install -r requirements/style.txt \
&& pip install -r requirements/tests.txt \
poetry-core>=1.0.0 \
&& pip install poetry-core>=1.0.0 \
&& apk del .build-deps \
&& addgroup -S kuchulu \
&& adduser \
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.py38.test
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ RUN set -ex \
&& pip install -r requirements/base.txt \
&& pip install -r requirements/style.txt \
&& pip install -r requirements/tests.txt \
poetry-core>=1.0.0 \
&& pip install poetry-core>=1.0.0 \
&& apk del .build-deps \
&& addgroup -S kuchulu \
&& adduser \
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.py39.test
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ RUN set -ex \
&& pip install -r requirements/base.txt \
&& pip install -r requirements/style.txt \
&& pip install -r requirements/tests.txt \
poetry-core>=1.0.0 \
&& pip install poetry-core>=1.0.0 \
&& apk del .build-deps \
&& addgroup -S kuchulu \
&& adduser \
Expand Down
2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ graft docs
prune docs/_build
graft examples
graft tests
global-exclude *~ *.py[cod] *.so *.swp *.editorconfig __pycache__
global-exclude *~ *.py[cod] *.so *.swp *.editorconfig __pycache__ .tox **/.tox venv .venv .venv.* **/venv **/.venv **/.venv.*
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ all: clean test

clean:
@find {src,examples,tests} -regex ".*\.\(so\|pyc\)" | xargs rm -rf
@find {src,examples,tests} -name "__pycache__" -o -name ".coverage" -o -name ".tox" -o -name ".pytest_cache" -o -name ".ruff_cache" -o -name ".pkg" -o -name ".tmp" | xargs rm -rf
@find {src,examples,tests} -name "__pycache__" -o -name ".coverage" -o -name "junit" -o -name "coverage.lcov" -o -name "htmlcov" -o -name ".tox" -o -name ".pytest_cache" -o -name ".ruff_cache" -o -name ".pkg" -o -name ".tmp" | xargs rm -rf
@rm -rf .coverage coverage.* .eggs/ .mypy_cache/ .pytype/ .ruff_cache/ .pytest_cache/ .tox/ src/*.egg-info/ htmlcov/ junit/ htmldoc/ build/ dist/ wheelhouse/

style:
Expand All @@ -33,6 +33,7 @@ release: test
@python -m pip install --upgrade -r requirements/cbuild.txt
@python -m build
@MYPYC_ENABLE=1 python setup.py bdist_wheel
@cibuildwheel --config-file pyproject.mypyc.toml

publish-test: release
@python -m pip install --upgrade twine
Expand Down
39 changes: 39 additions & 0 deletions bin/cibw-before-build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env python
# Copyright (c) 2024-2024, Cenobit Technologies, Inc. http://cenobit.es/
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of the Cenobit Technologies nor the names of
# its contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
import tomllib

from tomlkit import dumps

with open('pyproject.toml', 'rb') as fp:
pyproject = tomllib.load(fp)

pyproject['build-system']['requires'] = ['setuptools>=61.0', 'wheel>=0.42', 'mypy', 'pydantic']
pyproject['build-system']['build-backend'] = 'setuptools.build_meta'

with open('pyproject.toml', 'w') as fp:
fp.write(dumps(pyproject))
8 changes: 5 additions & 3 deletions docker-compose.it.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ services:
- FLASK_SERVER_NAME=app:5000
user: ${UID:-0}:${GID:-0}
command: >
python app.py
python -m app
ports:
- '5000:5000'
networks:
Expand All @@ -45,6 +45,8 @@ services:
- API_URL=https://async-app.flask-jsonrpc.cenobit.es/api
- BROWSABLE_API_URL=https://async-app.flask-jsonrpc.cenobit.es/api/browse
user: ${UID:-0}:${GID:-0}
command: >
./wait-for.sh async-app.flask-jsonrpc.cenobit.es:80 -t 600 -- pytest -n auto --junitxml=test-results/junit.xml test_async_app.py
volumes:
- .pytest_cache/test-results/async-app:/app/test-results
- .pytest_cache/screnshots/async-app:/app/.pytest_cache/screnshots
Expand All @@ -63,7 +65,7 @@ services:
- FLASK_SERVER_NAME=async-app:5000
user: ${UID:-0}:${GID:-0}
command: >
python async-app.py
python -m async_app
ports:
- '5001:5000'
networks:
Expand Down Expand Up @@ -99,7 +101,7 @@ services:
- FLASK_SERVER_NAME=mypyc-app:5000
user: ${UID:-0}:${GID:-0}
command: >
python app.py
python -m app
ports:
- '5002:5000'
networks:
Expand Down
8 changes: 6 additions & 2 deletions examples/javascript/tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ envtmpdir = {toxworkdir}/tmp/{envname}
constrain_package_deps = true
use_frozen_constraints = true
deps =
pytest
pytest==8.3.3
pytest-cov==5.0.0
pytest-xdist==3.6.1
pytest-sugar==1.0.0
pytest-env==1.1.5
async: Flask[async]>=3.0.0,<4.0
commands =
pytest -vv --tb=short --basetemp={envtmpdir} {posargs}
pytest -n auto -vv --tb=short --basetemp={envtmpdir} {posargs}
2 changes: 1 addition & 1 deletion examples/minimal-async/tests/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ def test_multi_decorators(client: 'FlaskClient') -> None:
'id': 1,
'jsonrpc': '2.0',
'result': {
'headers': 'User-Agent: Werkzeug/3.0.4\r\n'
'headers': 'User-Agent: Werkzeug/3.0.6\r\n'
'Host: localhost\r\n'
'Content-Type: application/json\r\n'
'Content-Length: 78\r\n'
Expand Down
8 changes: 6 additions & 2 deletions examples/minimal-async/tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ envtmpdir = {toxworkdir}/tmp/{envname}
constrain_package_deps = true
use_frozen_constraints = true
deps =
pytest
pytest==8.3.3
pytest-cov==5.0.0
pytest-xdist==3.6.1
pytest-sugar==1.0.0
pytest-env==1.1.5
async: Flask[async]>=3.0.0,<4.0
commands =
pytest -vv --tb=short --basetemp={envtmpdir} {posargs}
pytest -n auto -vv --tb=short --basetemp={envtmpdir} {posargs}
2 changes: 1 addition & 1 deletion examples/minimal/tests/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ def test_multi_decorators(client: 'FlaskClient') -> None:
'id': 1,
'jsonrpc': '2.0',
'result': {
'headers': 'User-Agent: Werkzeug/3.0.4\r\n'
'headers': 'User-Agent: Werkzeug/3.0.6\r\n'
'Host: localhost\r\n'
'Content-Type: application/json\r\n'
'Content-Length: 78\r\n'
Expand Down
8 changes: 6 additions & 2 deletions examples/minimal/tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ envtmpdir = {toxworkdir}/tmp/{envname}
constrain_package_deps = true
use_frozen_constraints = true
deps =
pytest
pytest==8.3.3
pytest-cov==5.0.0
pytest-xdist==3.6.1
pytest-sugar==1.0.0
pytest-env==1.1.5
async: Flask[async]>=3.0.0,<4.0
commands =
pytest -vv --tb=short --basetemp={envtmpdir} {posargs}
pytest -n auto -vv --tb=short --basetemp={envtmpdir} {posargs}
8 changes: 6 additions & 2 deletions examples/modular/tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ envtmpdir = {toxworkdir}/tmp/{envname}
constrain_package_deps = true
use_frozen_constraints = true
deps =
pytest
pytest==8.3.3
pytest-cov==5.0.0
pytest-xdist==3.6.1
pytest-sugar==1.0.0
pytest-env==1.1.5
async: Flask[async]>=3.0.0,<4.0
commands =
pytest -vv --tb=short --basetemp={envtmpdir} {posargs}
pytest -n auto -vv --tb=short --basetemp={envtmpdir} {posargs}
12 changes: 12 additions & 0 deletions examples/multiplesite/tests/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
# POSSIBILITY OF SUCH DAMAGE.
import typing as t

import pytest
from multiplesite.app import UnauthorizedError

if t.TYPE_CHECKING:
from flask.testing import FlaskClient

Expand All @@ -46,6 +49,15 @@ def test_index_v2(client: 'FlaskClient') -> None:
assert rv.status_code == 200


def test_index_v2_with_invalid_auth(client: 'FlaskClient') -> None:
with pytest.raises(UnauthorizedError):
client.post(
'/api/v2',
json={'id': 1, 'jsonrpc': '2.0', 'method': 'App.index'},
headers={'X-Username': 'username', 'X-Password': 'invalid'},
)


def test_rpc_describe_v1(client: 'FlaskClient') -> None:
rv = client.post('/api/v1', json={'id': 1, 'jsonrpc': '2.0', 'method': 'rpc.describe'})
data = rv.get_json()
Expand Down
8 changes: 6 additions & 2 deletions examples/multiplesite/tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ envtmpdir = {toxworkdir}/tmp/{envname}
constrain_package_deps = true
use_frozen_constraints = true
deps =
pytest
pytest==8.3.3
pytest-cov==5.0.0
pytest-xdist==3.6.1
pytest-sugar==1.0.0
pytest-env==1.1.5
async: Flask[async]>=3.0.0,<4.0
commands =
pytest -vv --tb=short --basetemp={envtmpdir} {posargs}
pytest -n auto -vv --tb=short --basetemp={envtmpdir} {posargs}
8 changes: 6 additions & 2 deletions examples/openrpc/tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ envtmpdir = {toxworkdir}/tmp/{envname}
constrain_package_deps = true
use_frozen_constraints = true
deps =
pytest
pytest==8.3.3
pytest-cov==5.0.0
pytest-xdist==3.6.1
pytest-sugar==1.0.0
pytest-env==1.1.5
async: Flask[async]>=3.0.0,<4.0
commands =
pytest -vv --tb=short --basetemp={envtmpdir} {posargs}
pytest -n auto -vv --tb=short --basetemp={envtmpdir} {posargs}
Loading

0 comments on commit 381229f

Please sign in to comment.