Skip to content

Commit

Permalink
Merge pull request #40 from dhellmann/e2e-flit-core-override
Browse files Browse the repository at this point in the history
e2e: extend end-to-end testing
  • Loading branch information
mergify[bot] authored Jun 2, 2024
2 parents 1e06749 + a7e2d23 commit 4b654ab
Show file tree
Hide file tree
Showing 12 changed files with 219 additions and 42 deletions.
1 change: 1 addition & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ jobs:
- bootstrap
- report_missing_dependency
- build_with_build_order
- override

steps:
- name: Get source
Expand Down
3 changes: 3 additions & 0 deletions .mergify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ pull_request_rules:
- or:
- 'title~=^tox:'
- 'title~=^ci:'
- 'title~=^e2e:'
- files~=tox.ini
- files~=.github/
- files~=.markdownlint-config.yaml
- files~=tests/
- files~=e2e/
actions:
label:
add:
Expand Down
22 changes: 22 additions & 0 deletions e2e/flit_core_override/build/lib/package_plugins/flit_core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import logging

from fromager import external_commands

logger = logging.getLogger(__name__)


def build_wheel(ctx, build_env, extra_environ, req, sdist_root_dir):
# flit_core is a basic build system dependency for several
# packages. It is capable of building its own wheels, so we use the
# bootstrapping instructions to do that and put the wheel in the
# local server directory for reuse when building other packages via
# 'pip wheel'.
#
# https://flit.pypa.io/en/stable/bootstrap.html
logger.info('using override to build flit_core wheel in %s', sdist_root_dir)
external_commands.run(
[build_env.python, '-m', 'flit_core.wheel',
'--outdir', ctx.wheels_build],
cwd=sdist_root_dir,
extra_environ=extra_environ,
)
32 changes: 32 additions & 0 deletions e2e/flit_core_override/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[project]
name = "flit-core-overrides"
authors = [
{name = "Doug Hellmann", email="[email protected]"},
]
description = "test package"
dynamic = ["version"]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Environment :: Console",
"Intended Audience :: Developers",
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: Implementation :: CPython",
"Topic :: Utilities",
]

requires-python = ">=3.11"

dependencies = []

[project.entry-points."fromager.project_overrides"]
flit_core = "package_plugins.flit_core"
22 changes: 22 additions & 0 deletions e2e/flit_core_override/src/package_plugins/flit_core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import logging

from fromager import external_commands

logger = logging.getLogger(__name__)


def build_wheel(ctx, build_env, extra_environ, req, sdist_root_dir):
# flit_core is a basic build system dependency for several
# packages. It is capable of building its own wheels, so we use the
# bootstrapping instructions to do that and put the wheel in the
# local server directory for reuse when building other packages via
# 'pip wheel'.
#
# https://flit.pypa.io/en/stable/bootstrap.html
logger.info('using override to build flit_core wheel in %s', sdist_root_dir)
external_commands.run(
[build_env.python, '-m', 'flit_core.wheel',
'--outdir', ctx.wheels_build],
cwd=sdist_root_dir,
extra_environ=extra_environ,
)
18 changes: 11 additions & 7 deletions e2e/test_bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,19 @@ set -x
set -e
set -o pipefail

OUTDIR="e2e-output"
OUTDIR="$(dirname "$SCRIPTDIR")/e2e-output"

rm -rf e2e-outputs
rm -rf "$OUTDIR"
mkdir "$OUTDIR"

tox -e cli -- \
--sdists-repo="$OUTDIR/sdists-repo" \
--wheels-repo="$OUTDIR/wheels-repo" \
--work-dir="$OUTDIR/work-dir" \
bootstrap 'stevedore==5.2.0'
tox -e e2e -n -r
source .tox/e2e/bin/activate

fromager \
--sdists-repo="$OUTDIR/sdists-repo" \
--wheels-repo="$OUTDIR/wheels-repo" \
--work-dir="$OUTDIR/work-dir" \
bootstrap 'stevedore==5.2.0'

find "$OUTDIR/wheels-repo/simple/" -name '*.whl'

Expand Down
37 changes: 32 additions & 5 deletions e2e/test_build_with_build_order.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ rm -rf "$OUTDIR"
mkdir -p "$OUTDIR/build-logs"

# Set up virtualenv with the CLI and dependencies.
tox -e cli -n
source ".tox/cli/bin/activate"
tox -e e2e -n -r
source ".tox/e2e/bin/activate"

# Bootstrap the test project
fromager \
Expand All @@ -42,13 +42,12 @@ cp "$OUTDIR/work-dir/build-order.json" "$OUTDIR/"
rm -r "$OUTDIR/work-dir" "$OUTDIR/sdists-repo" "$OUTDIR/wheels-repo"

# Rebuild the wheel mirror to be empty
rm -rf "$OUTDIR/wheels-repo/simple"
.tox/cli/bin/pypi-mirror create -d "$OUTDIR/wheels-repo/downloads/" -m "$OUTDIR/wheels-repo/simple/"
pypi-mirror create -d "$OUTDIR/wheels-repo/downloads/" -m "$OUTDIR/wheels-repo/simple/"

# Start a web server for the wheels-repo. We remember the PID so we
# can stop it later, and we determine the primary IP of the host
# because podman won't see the server via localhost.
.tox/cli/bin/python3 -m http.server --directory "$OUTDIR/wheels-repo/" 9090 &
python3 -m http.server --directory "$OUTDIR/wheels-repo/" 9090 &
HTTP_SERVER_PID=$!
IP=$(ip route get 1.1.1.1 | grep 1.1.1.1 | awk '{print $7}')
export WHEEL_SERVER_URL="http://${IP}:9090/simple"
Expand Down Expand Up @@ -92,6 +91,9 @@ build_wheel() {
--wheel-server-url "${WHEEL_SERVER_URL}" \
build "$dist" "$version"

# Move the built wheel into place
mv "$OUTDIR"/wheels-repo/build/*.whl "$OUTDIR/wheels-repo/downloads/"

# update the wheel server
pypi-mirror \
create \
Expand All @@ -108,4 +110,29 @@ build_wheel() {
jq -r '.[] | "build_wheel " + .dist + " " + .version' \
"$OUTDIR/build-order.json" \
> "$OUTDIR/build.sh"
find "$OUTDIR/wheels-repo/"
source "$OUTDIR/build.sh"
find "$OUTDIR/wheels-repo/"

EXPECTED_FILES="
wheels-repo/downloads/flit_core-3.9.0-py3-none-any.whl
wheels-repo/downloads/wheel-0.43.0-py3-none-any.whl
wheels-repo/downloads/setuptools-70.0.0-py3-none-any.whl
wheels-repo/downloads/pbr-6.0.0-py2.py3-none-any.whl
wheels-repo/downloads/stevedore-5.2.0-py3-none-any.whl
sdists-repo/downloads/stevedore-5.2.0.tar.gz
sdists-repo/downloads/setuptools-70.0.0.tar.gz
sdists-repo/downloads/wheel-0.43.0.tar.gz
sdists-repo/downloads/flit_core-3.9.0.tar.gz
sdists-repo/downloads/pbr-6.0.0.tar.gz
"

pass=true
for f in $EXPECTED_FILES; do
if [ ! -f "$OUTDIR/$f" ]; then
echo "FAIL: Did not find $OUTDIR/$f" 1>&2
pass=false
fi
done
$pass
54 changes: 54 additions & 0 deletions e2e/test_override.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/bin/bash
# -*- indent-tabs-mode: nil; tab-width: 2; sh-indentation: 2; -*-

# Tests full bootstrap and installation of a complex package, without
# worrying about isolating the tools from upstream sources or
# restricting network access during the build. This allows us to test
# the overall logic of the build tools separately from the isolated
# build pipelines.

set -x
set -e
set -o pipefail

OUTDIR="$(dirname "$SCRIPTDIR")/e2e-output"

rm -rf "$OUTDIR"
mkdir "$OUTDIR"

tox -e e2e -n -r
source .tox/e2e/bin/activate
pip install e2e/flit_core_override

fromager \
--log-file="$OUTDIR/bootstrap.log" \
--sdists-repo="$OUTDIR/sdists-repo" \
--wheels-repo="$OUTDIR/wheels-repo" \
--work-dir="$OUTDIR/work-dir" \
bootstrap 'flit_core==3.9.0'

find "$OUTDIR/wheels-repo/simple/" -name '*.whl'

# Default to passing
pass=true

# Check for log message
if ! grep -q "using override to build flit_core wheel" "$OUTDIR/bootstrap.log"; then
echo "FAIL: Did not find log message from override in $OUTDIR/bootstrap.log" 1>&2
pass=false
fi

# Check for output files
EXPECTED_FILES="
wheels-repo/downloads/flit_core-3.9.0-py3-none-any.whl
sdists-repo/downloads/flit_core-3.9.0.tar.gz
"

for f in $EXPECTED_FILES; do
if [ ! -f "$OUTDIR/$f" ]; then
echo "FAIL: Did not find $f" 1>&2
pass=false
fi
done
$pass
63 changes: 33 additions & 30 deletions e2e/test_report_missing_dependency.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ on_exit() {
trap on_exit EXIT SIGINT SIGTERM

# Bootstrap to create the build order file.
OUTDIR="e2e-output"
OUTDIR="$(dirname "$SCRIPTDIR")/e2e-output"

# What are we building?
DIST="stevedore"
Expand All @@ -26,11 +26,14 @@ VERSION="5.2.0"
rm -rf "$OUTDIR"
mkdir -p "$OUTDIR/build-logs"

tox -e cli -- \
--sdists-repo="$OUTDIR/sdists-repo" \
--wheels-repo="$OUTDIR/wheels-repo" \
--work-dir="$OUTDIR/work-dir" \
bootstrap "${DIST}==${VERSION}"
tox -e e2e -n -r
source .tox/e2e/bin/activate

fromager \
--sdists-repo="$OUTDIR/sdists-repo" \
--wheels-repo="$OUTDIR/wheels-repo" \
--work-dir="$OUTDIR/work-dir" \
bootstrap "${DIST}==${VERSION}"

# Extract the build dependencies from the bootstrap info.
jq -r '.[] | select( .type | contains("build-") ) | .req' \
Expand All @@ -45,12 +48,12 @@ done

# Rebuild the wheel mirror to only include the things we have not deleted.
rm -rf "$OUTDIR/wheels-repo/simple"
.tox/cli/bin/pypi-mirror create -d "$OUTDIR/wheels-repo/downloads/" -m "$OUTDIR/wheels-repo/simple/"
.tox/e2e/bin/pypi-mirror create -d "$OUTDIR/wheels-repo/downloads/" -m "$OUTDIR/wheels-repo/simple/"

# Start a web server for the wheels-repo. We remember the PID so we
# can stop it later, and we determine the primary IP of the host
# because podman won't see the server via localhost.
.tox/cli/bin/python3 -m http.server --directory "$OUTDIR/wheels-repo/" 9090 &
.tox/e2e/bin/python3 -m http.server --directory "$OUTDIR/wheels-repo/" 9090 &
HTTP_SERVER_PID=$!
IP=$(ip route get 1.1.1.1 | grep 1.1.1.1 | awk '{print $7}')
export WHEEL_SERVER_URL="http://${IP}:9090/simple"
Expand All @@ -59,35 +62,35 @@ export WHEEL_SERVER_URL="http://${IP}:9090/simple"
version=$(jq -r '.[] | select ( .dist == "'$DIST'" ) | .version' "$OUTDIR/work-dir/build-order.json")

# Download the source archive
tox -e cli -- \
--log-file "$OUTDIR/build-logs/download-source-archive.log" \
--work-dir "$OUTDIR/work-dir" \
--sdists-repo "$OUTDIR/sdists-repo" \
--wheels-repo "$OUTDIR/wheels-repo" \
download-source-archive "$DIST" "$VERSION" "https://pypi.org/simple"
fromager \
--log-file "$OUTDIR/build-logs/download-source-archive.log" \
--work-dir "$OUTDIR/work-dir" \
--sdists-repo "$OUTDIR/sdists-repo" \
--wheels-repo "$OUTDIR/wheels-repo" \
download-source-archive "$DIST" "$VERSION" "https://pypi.org/simple"

# Prepare the source dir for building
tox -e cli -- \
--log-file "$OUTDIR/build-logs/prepare-source.log" \
--work-dir "$OUTDIR/work-dir" \
--sdists-repo "$OUTDIR/sdists-repo" \
--wheels-repo "$OUTDIR/wheels-repo" \
prepare-source "$DIST" "$VERSION"
fromager \
--log-file "$OUTDIR/build-logs/prepare-source.log" \
--work-dir "$OUTDIR/work-dir" \
--sdists-repo "$OUTDIR/sdists-repo" \
--wheels-repo "$OUTDIR/wheels-repo" \
prepare-source "$DIST" "$VERSION"

# Prepare the build environment
tox -e cli -- \
--log-file "$OUTDIR/build-logs/prepare-build.log" \
--work-dir "$OUTDIR/work-dir" \
--sdists-repo "$OUTDIR/sdists-repo" \
--wheels-repo "$OUTDIR/wheels-repo" \
--wheel-server-url "${WHEEL_SERVER_URL}" \
prepare-build "$DIST" "$VERSION" \
|| echo "Got expected build error"
fromager \
--log-file "$OUTDIR/build-logs/prepare-build.log" \
--work-dir "$OUTDIR/work-dir" \
--sdists-repo "$OUTDIR/sdists-repo" \
--wheels-repo "$OUTDIR/wheels-repo" \
--wheel-server-url "${WHEEL_SERVER_URL}" \
prepare-build "$DIST" "$VERSION" \
|| echo "Got expected build error"

if grep -q "MissingDependency" "$OUTDIR/build-logs/prepare-build.log"; then
echo "Found expected error"
echo "PASS: Found expected error"
else
echo "Did not find expected error in $OUTDIR/build-logs/prepare-build.log"
echo "FAIL: Did not find expected error in $OUTDIR/build-logs/prepare-build.log"
exit 1
fi

Expand Down
2 changes: 2 additions & 0 deletions src/fromager/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ def main():
# handlers to filter messages at their own level.
logging.getLogger().setLevel(logging.DEBUG)

overrides.log_overrides()

try:
args.func(args)
except Exception as err:
Expand Down
4 changes: 4 additions & 0 deletions src/fromager/overrides.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
logger = logging.getLogger(__name__)


def log_overrides():
logger.debug('loaded overrides for %s', _mgr.entry_points_names())


def patches_for_source_dir(patches_dir, source_dir_name):
"""Iterator producing patches to apply to the source dir.
Expand Down
3 changes: 3 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ deps = .
commands =
fromager {posargs}

[testenv:e2e]
deps = .

[testenv:pkglint]
deps=
.[build]
Expand Down

0 comments on commit 4b654ab

Please sign in to comment.