Skip to content

Commit

Permalink
Merge 2e6e73c into 269a1a0
Browse files Browse the repository at this point in the history
  • Loading branch information
exarkun committed Aug 1, 2023
2 parents 269a1a0 + 2e6e73c commit d56779d
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 26 deletions.
3 changes: 1 addition & 2 deletions .circleci/Dockerfile.debian
Expand Up @@ -18,8 +18,7 @@ RUN apt-get --quiet update && \
libffi-dev \
libssl-dev \
libyaml-dev \
virtualenv \
tor
virtualenv

# Get the project source. This is better than it seems. CircleCI will
# *update* this checkout on each job run, saving us more time per-job.
Expand Down
73 changes: 61 additions & 12 deletions .circleci/config.yml
Expand Up @@ -87,8 +87,8 @@ workflows:
- "oraclelinux-8":
{}

- "nixos":
name: "<<matrix.pythonVersion>>"
- "unittest":
name: "<<matrix.pythonVersion>>-unittest"
nixpkgs: "nixpkgs-unstable"
matrix:
parameters:
Expand All @@ -97,6 +97,14 @@ workflows:
- "python310"
- "python311"

- "integrationtest":
name: "<<matrix.pythonVersion>>-integrationtest"
nixpkgs: "nixpkgs-unstable"
matrix:
parameters:
pythonVersion:
- "python310"

# Eventually, test against PyPy 3.8
#- "pypy27-buster":
# {}
Expand All @@ -112,15 +120,6 @@ workflows:
- "another-locale":
{}

- "integration":
# Run even the slow integration tests here. We need the `--` to
# sneak past tox and get to pytest.
tox-args: "-- --runslow integration"
requires:
# If the unit test suite doesn't pass, don't bother running the
# integration tests.
- "debian-11"

- "typechecks":
{}
- "docs":
Expand Down Expand Up @@ -373,7 +372,55 @@ jobs:
image: "tahoelafsci/fedora:35-py3"
user: "nobody"

nixos:
# A parameterized job which runs the integration test suite in the
# Nix-defined environment.
integrationtest:
parameters:
nixpkgs:
description: >-
Reference the name of a flake-managed nixpkgs input (see `nix flake
metadata` and flake.nix)
type: "string"
pythonVersion:
description: >-
Reference the name of a Python package in nixpkgs to use.
type: "string"

executor: "nix"

steps:
- "nix-build":
nixpkgs: "<<parameters.nixpkgs>>"
pythonVersion: "<<parameters.pythonVersion>>"
buildSteps:
- "run":
name: "Integration Test"
command: |
source .circleci/lib.sh
# Translate the nixpkgs selection into a flake reference we
# can use to override the default nixpkgs input.
NIXPKGS=$(nixpkgs_flake_reference <<parameters.nixpkgs>>)
# Run the integration tests, even the slow ones. Generate
# junit xml results for CircleCI to ingest.
cache_if_able nix run \
--verbose \
--print-build-logs \
--override-input nixpkgs "$NIXPKGS" \
.#<<parameters.pythonVersion>>-integration \
-- \
--verbose \
--runslow \
--capture=no \
--junitxml=integration-results.xml \
integration/
- "store_test_results":
path: "integration-results.xml"

# A parameterized job which runs the unit test suite in the Nix-defined
# environment.
unittest:
parameters:
nixpkgs:
description: >-
Expand Down Expand Up @@ -402,6 +449,8 @@ jobs:
NIXPKGS=$(nixpkgs_flake_reference <<parameters.nixpkgs>>)
cache_if_able nix run \
--verbose \
--print-build-logs \
--override-input nixpkgs "$NIXPKGS" \
.#<<parameters.pythonVersion>>-unittest -- \
--jobs $UNITTEST_CORES \
Expand Down
111 changes: 101 additions & 10 deletions flake.nix
Expand Up @@ -117,6 +117,11 @@
# Construct the unit test application name for the given Python runtime.
unitTestName = pyVersion: "${pyVersion}-unittest";

# string -> string
#
# Construct the integration test application name for the given Python runtime.
integrationTestName = pyVersion: "${pyVersion}-integration";

# (string -> a) -> (string -> b) -> string -> attrset a b
#
# Make a singleton attribute set from the result of two functions.
Expand All @@ -140,24 +145,43 @@
)).overrideAttrs (old: {
# By default, withPackages gives us a derivation with a fairly generic
# name (like "python-env"). Put our name in there for legibility.
# See the similar override in makeTestEnv.
# See the similar override in make*TestEnv.
name = packageName pyVersion;
});

# makeTestEnv :: string -> derivation
# extraRequirements :: derivation -> [string] -> [derivation]
#
# Get a flat list of the additional requirements from the derivation's
# `passthru.extras` attribute for all of the given extra names.
extraRequirements = drv: names:
builtins.concatLists (builtins.map (name: drv.passthru.extras.${name}) names);

# makeUnitTestEnv :: string -> derivation
#
# Create a derivation that includes a Python runtime and all of the
# Tahoe-LAFS dependencies, but not Tahoe-LAFS itself, which we'll get
# from the working directory.
makeTestEnv = pyVersion: (pkgs.${pyVersion}.withPackages (ps: with ps;
[ tahoe-lafs ] ++
tahoe-lafs.passthru.extras.i2p ++
tahoe-lafs.passthru.extras.tor ++
tahoe-lafs.passthru.extras.unittest
makeUnitTestEnv = pyVersion: (pkgs.${pyVersion}.withPackages (ps:
ps.tahoe-lafs.passthru.dependencies ++
(extraRequirements ps.tahoe-lafs ["i2p" "tor" "unittest"])
)).overrideAttrs (old: {
# See the similar override in makeRuntimeEnv'.
name = packageName pyVersion;
});

# makeIntegrationTestEnv :: string -> derivation
#
# Create a derivation that includes a Python runtime, Tahoe-LAFS, and
# all of its dependencies. This is suitable for running the integration
# tests, which expect to find `tahoe` on PATH.
makeIntegrationTestEnv = pyVersion: (pkgs.${pyVersion}.withPackages (ps:
[ ps.tahoe-lafs ] ++
(extraRequirements ps.tahoe-lafs ["i2p" "tor" "integrationtest"])
)).overrideAttrs (old: {
# See the similar override in makeRuntimeEnv'.
name = packageName pyVersion;
});

in {
# Include a package set with out overlay on it in our own output. This
# is mainly a development/debugging convenience as it will expose all of
Expand All @@ -175,7 +199,8 @@
mergeAttrs (
[ { default = self.packages.${system}.${packageName defaultPyVersion}; } ]
++ (builtins.map makeRuntimeEnv pythonVersions)
++ (builtins.map (singletonOf unitTestName makeTestEnv) pythonVersions)
++ (builtins.map (singletonOf unitTestName makeUnitTestEnv) pythonVersions)
++ (builtins.map (singletonOf integrationTestName makeIntegrationTestEnv) pythonVersions)
);

# The flake's app outputs. We'll define a version of an app for running
Expand Down Expand Up @@ -218,22 +243,88 @@
type = "app";
program =
let
python = "${makeTestEnv pyVersion}/bin/python";
#
python =
"${self.packages.${system}.${unitTestName pyVersion}}/bin/python";
in
writeScript "unit-tests"
''
# Make sure there is recent generated-version information
# in the tree.
${python} setup.py update_version
# Use the closer-to-deterministic Hypothesis profile for
# better reproducibility.
export TAHOE_LAFS_HYPOTHESIS_PROFILE=ci
# Use the source from the working tree for a
# development-friendly experience.
export PYTHONPATH=$PWD/src
${python} -m twisted.trial "$@"
# Run the unit tests.
if (( $# )) then
${python} -m twisted.trial "$@"
else
${python} -m twisted.trial -j4 allmydata
fi
'';
};
};

# makeIntegrationTestsApp :: string -> attrset
#
# A helper function to define the Tahoe-LAFS integration test
# entrypoint for a certain Python runtime.
makeIntegrationTestsApp = pyVersion: {
"${integrationTestName pyVersion}" = {
type = "app";
program =
let programDrv =
pkgs.writeShellApplication {
name = "integration-tests";
runtimeInputs = [
# Place the integration test package into the
# runtime environment so PATH is updated. The
# integration tests require certain tools to be
# discoverable that way.
self.packages.${system}.${integrationTestName pyVersion}

# Also include non-Python dependencies for the
# integration test suite.
pkgs.tor
];
# Disable checking the shell application. Shell
# checking is nice but our Python package overrides
# mean a huge number of dependencies must be built
# before the check can be run.
checkPhase = "";
text =
''
# Make sure there is recent generated-version
# information in the tree.
python setup.py update_version
# Use the source from the working tree for a
# development-friendly experience.
export PYTHONPATH=$PWD/src
if (( $# )) then
python -m pytest "$@"
else
python -m pytest -v --runslow integration
fi
'';
};
in
"${programDrv}/bin/integration-tests";
};
};
in
# Merge a default app definition with the rest of the apps.
mergeAttrs (
[ { default = self.apps.${system}."tahoe-python3"; } ]
++ (builtins.map makeUnitTestsApp pythonVersions)
++ (builtins.map makeIntegrationTestsApp pythonVersions)
++ (builtins.map makeTahoeApp pythonVersions)
);
}));
Expand Down
6 changes: 4 additions & 2 deletions nix/tahoe-lafs.nix
Expand Up @@ -45,7 +45,9 @@ buildPythonPackage rec {
doCheck = false;

passthru = {
extras = with pythonPackages; {
dependencies = propagatedBuildInputs;

extras = with pythonPackages; rec {
tor = [
txtorcon
];
Expand All @@ -61,7 +63,7 @@ buildPythonPackage rec {
prometheus-client
testtools
];
integrationtest = [
integrationtest = unittest ++ [
pytest
pytest-twisted
paramiko
Expand Down

0 comments on commit d56779d

Please sign in to comment.