272 lines
7.9 KiB
Nix
272 lines
7.9 KiB
Nix
# Utilities for running the PostgREST test suite
|
|
|
|
{ buildEnv
|
|
, cabal-install
|
|
, checkedShellScript
|
|
, curl
|
|
, devCabalOptions
|
|
, ghc
|
|
, glibcLocales
|
|
, gnugrep
|
|
, haskell
|
|
, hpc-codecov
|
|
, lib
|
|
, postgresql
|
|
, postgresqlVersions
|
|
, postgrest
|
|
, postgrestProfiled
|
|
, python3
|
|
, runtimeShell
|
|
, withTmpDb
|
|
, yq
|
|
}:
|
|
let
|
|
# Create a `withPostgresql` for each PostgreSQL version that we want to test
|
|
# against.
|
|
withPostgresqlVersions =
|
|
builtins.map
|
|
({ name, postgresql }:
|
|
(checkedShellScript
|
|
{
|
|
name = "postgrest-with-${name}";
|
|
docs = "Run the given command in a temporary database with ${name}";
|
|
inRootDir = false;
|
|
}
|
|
''
|
|
${withTmpDb postgresql} "$@"
|
|
''
|
|
).bin
|
|
)
|
|
postgresqlVersions;
|
|
|
|
# Helper script for running a command against all PostgreSQL versions.
|
|
withAllVersions =
|
|
name:
|
|
let
|
|
runners =
|
|
builtins.map
|
|
({ name, postgresql }:
|
|
''
|
|
cat << EOF
|
|
|
|
Running against ${name}...
|
|
|
|
EOF
|
|
|
|
trap 'echo "Failed on ${name}"' exit
|
|
|
|
${withTmpDb postgresql} "$@"
|
|
|
|
trap "" exit
|
|
|
|
cat << EOF
|
|
|
|
Done running against ${name}.
|
|
|
|
EOF
|
|
'')
|
|
postgresqlVersions;
|
|
in
|
|
checkedShellScript
|
|
{
|
|
inherit name;
|
|
docs = "Run command against all supported PostgreSQL versions.";
|
|
inRootDir = true;
|
|
}
|
|
(lib.concatStringsSep "\n\n" runners);
|
|
|
|
# Script to run the Haskell test suite
|
|
testSpec =
|
|
name: postgresql:
|
|
checkedShellScript
|
|
{
|
|
inherit name;
|
|
docs = "Run the Haskell test suite";
|
|
inRootDir = true;
|
|
}
|
|
''
|
|
env="$(cat ${postgrest.env})"
|
|
export PATH="$env/bin:$PATH"
|
|
|
|
${withTmpDb postgresql} ${cabal-install}/bin/cabal v2-test ${devCabalOptions}
|
|
'';
|
|
|
|
testSpecIdempotence =
|
|
name: postgrestql:
|
|
checkedShellScript
|
|
{
|
|
inherit name;
|
|
docs = "Check that the Haskell tests can be run multiple times against the same db.";
|
|
inRootDir = true;
|
|
}
|
|
''
|
|
env="$(cat ${postgrest.env})"
|
|
export PATH="$env/bin:$PATH"
|
|
|
|
${withTmpDb postgresql} ${runtimeShell} -c " \
|
|
${cabal-install}/bin/cabal v2-test ${devCabalOptions} && \
|
|
${cabal-install}/bin/cabal v2-test ${devCabalOptions}"
|
|
'';
|
|
|
|
ioTestPython =
|
|
python3.withPackages (ps: [
|
|
ps.pyjwt
|
|
ps.pytest
|
|
ps.pytest_xdist
|
|
ps.pyyaml
|
|
ps.requests
|
|
ps.requests-unixsocket
|
|
]);
|
|
|
|
testIO =
|
|
name: postgresql:
|
|
checkedShellScript
|
|
{
|
|
inherit name;
|
|
docs = "Run the pytest-based IO tests.";
|
|
inRootDir = true;
|
|
}
|
|
''
|
|
env="$(cat ${postgrest.env})"
|
|
export PATH="$env/bin:$PATH"
|
|
|
|
${cabal-install}/bin/cabal v2-build ${devCabalOptions}
|
|
${cabal-install}/bin/cabal v2-exec ${withTmpDb postgresql} \
|
|
${ioTestPython}/bin/pytest -- -v test/io-tests "$@"
|
|
'';
|
|
|
|
testMemory =
|
|
name: postgresql:
|
|
checkedShellScript
|
|
{
|
|
inherit name;
|
|
docs = "Run the memory tests.";
|
|
inRootDir = true;
|
|
}
|
|
''
|
|
export PATH="${postgrestProfiled}/bin:${curl}/bin:$PATH"
|
|
|
|
${withTmpDb postgresql} test/memory-tests.sh
|
|
'';
|
|
|
|
dumpSchema =
|
|
name: postgresql:
|
|
checkedShellScript
|
|
{
|
|
inherit name;
|
|
docs = "Dump the loaded schema's DbStructure as a yaml file.";
|
|
inRootDir = true;
|
|
}
|
|
''
|
|
env="$(cat ${postgrest.env})"
|
|
export PATH="$env/bin:$PATH"
|
|
|
|
${withTmpDb postgresql} \
|
|
${cabal-install}/bin/cabal v2-run ${devCabalOptions} --verbose=0 -- \
|
|
postgrest --dump-schema \
|
|
| ${yq}/bin/yq -y .
|
|
'';
|
|
|
|
coverage =
|
|
name: postgresql:
|
|
checkedShellScript
|
|
{
|
|
inherit name;
|
|
docs = "Run spec and io tests while collecting hpc coverage data.";
|
|
inRootDir = true;
|
|
redirectTixFiles = false;
|
|
withTmpDir = true;
|
|
}
|
|
''
|
|
env="$(cat ${postgrest.env})"
|
|
export PATH="$env/bin:$PATH"
|
|
export LOCALE_ARCHIVE="${glibcLocales}/lib/locale/locale-archive"
|
|
|
|
# clean up previous coverage reports
|
|
mkdir -p coverage
|
|
rm -rf coverage/*
|
|
|
|
# build once before running all the tests
|
|
${cabal-install}/bin/cabal v2-build ${devCabalOptions} --enable-tests all
|
|
|
|
# collect all tests
|
|
HPCTIXFILE="$tmpdir"/io.tix \
|
|
${withTmpDb postgresql} ${cabal-install}/bin/cabal v2-exec ${devCabalOptions} \
|
|
${ioTestPython}/bin/pytest -- -v test/io-tests
|
|
|
|
HPCTIXFILE="$tmpdir"/spec.tix \
|
|
${withTmpDb postgresql} ${cabal-install}/bin/cabal v2-test ${devCabalOptions}
|
|
|
|
# collect all the tix files
|
|
${ghc}/bin/hpc sum --union --exclude=Paths_postgrest --output="$tmpdir"/tests.tix "$tmpdir"/io*.tix "$tmpdir"/spec.tix
|
|
|
|
# prepare the overlay
|
|
${ghc}/bin/hpc overlay --output="$tmpdir"/overlay.tix test/coverage.overlay
|
|
${ghc}/bin/hpc sum --union --output="$tmpdir"/tests-overlay.tix "$tmpdir"/tests.tix "$tmpdir"/overlay.tix
|
|
|
|
# check nothing in the overlay is actually tested
|
|
${ghc}/bin/hpc map --function=inv --output="$tmpdir"/inverted.tix "$tmpdir"/tests.tix
|
|
${ghc}/bin/hpc combine --function=sub \
|
|
--output="$tmpdir"/check.tix "$tmpdir"/overlay.tix "$tmpdir"/inverted.tix
|
|
# returns zero exit code if any count="<non-zero>" lines are found, i.e.
|
|
# something is covered by both the overlay and the tests
|
|
if ${ghc}/bin/hpc report --xml "$tmpdir"/check.tix | ${gnugrep}/bin/grep -qP 'count="[^0]'
|
|
then
|
|
${ghc}/bin/hpc markup --highlight-covered --destdir=coverage/overlay "$tmpdir"/overlay.tix || true
|
|
${ghc}/bin/hpc markup --highlight-covered --destdir=coverage/check "$tmpdir"/check.tix || true
|
|
echo "ERROR: Something is covered by both the tests and the overlay:"
|
|
echo "file://$(pwd)/coverage/check/hpc_index.html"
|
|
exit 1
|
|
else
|
|
# copy the result .tix file to the coverage/ dir to make it available to postgrest-coverage-draft-overlay, too
|
|
cp "$tmpdir"/tests-overlay.tix coverage/postgrest.tix
|
|
# prepare codecov json report
|
|
${hpc-codecov}/bin/hpc-codecov --mix=.hpc --out=coverage/codecov.json coverage/postgrest.tix
|
|
|
|
# create html and stdout reports
|
|
${ghc}/bin/hpc markup --destdir=coverage coverage/postgrest.tix
|
|
echo "file://$(pwd)/coverage/hpc_index.html"
|
|
${ghc}/bin/hpc report coverage/postgrest.tix "$@"
|
|
fi
|
|
'';
|
|
|
|
coverageDraftOverlay =
|
|
name:
|
|
checkedShellScript
|
|
{
|
|
inherit name;
|
|
docs = "Create a draft overlay from current coverage report.";
|
|
inRootDir = true;
|
|
}
|
|
''
|
|
${ghc}/bin/hpc draft --output=test/coverage.overlay coverage/postgrest.tix
|
|
sed -i 's|^module \(.*\):|module \1/|g' test/coverage.overlay
|
|
'';
|
|
|
|
in
|
|
# Create an environment that contains all the utility scripts for running tests
|
|
# that we defined above.
|
|
buildEnv
|
|
{
|
|
name =
|
|
"postgrest-tests";
|
|
|
|
paths =
|
|
[
|
|
(testSpec "postgrest-test-spec" postgresql).bin
|
|
(testSpecIdempotence "postgrest-test-spec-idempotence" postgresql).bin
|
|
(testIO "postgrest-test-io" postgresql).bin
|
|
(dumpSchema "postgrest-dump-schema" postgresql).bin
|
|
(coverage "postgrest-coverage" postgresql).bin
|
|
(coverageDraftOverlay "postgrest-coverage-draft-overlay").bin
|
|
(withAllVersions "postgrest-with-all").bin
|
|
] ++ withPostgresqlVersions;
|
|
}
|
|
# The memory tests have large dependencies (a profiled build of PostgREST)
|
|
# and are run less often than the spec tests, so we don't include them in
|
|
# the default test environment. We make them available through a separate attribute:
|
|
// {
|
|
memoryTests =
|
|
(testMemory "postgrest-test-memory" postgresql).bin;
|
|
}
|