Move generation of coverage reports from nixos/lib/testing to releaseTools

Also, turn some stdenv adapters into setup hooks.
This commit is contained in:
Eelco Dolstra 2014-03-03 13:39:30 +01:00
parent ad7c518e45
commit 497997cc38
11 changed files with 94 additions and 97 deletions

View File

@ -67,62 +67,16 @@ rec {
};
# Generate a coverage report from the coverage data produced by
# runTests.
makeReport = x: runCommand "report" { buildInputs = [rsync]; }
''
mkdir -p $TMPDIR/gcov/
for d in ${x}/coverage-data/*; do
echo "doing $d"
[ -n "$(ls -A "$d")" ] || continue
for i in $(cd $d/nix/store && ls); do
if ! test -e $TMPDIR/gcov/nix/store/$i; then
echo "copying $i"
mkdir -p $TMPDIR/gcov/$(echo $i | cut -c34-)
rsync -rv /nix/store/$i/.build/* $TMPDIR/gcov/
fi
done
chmod -R u+w $TMPDIR/gcov
find $TMPDIR/gcov -name "*.gcda" -exec rm {} \;
for i in $(cd $d/nix/store && ls); do
rsync -rv $d/nix/store/$i/.build/* $TMPDIR/gcov/
done
find $TMPDIR/gcov -name "*.gcda" -exec chmod 644 {} \;
echo "producing info..."
${pkgs.lcov}/bin/geninfo --ignore-errors source,gcov $TMPDIR/gcov --output-file $TMPDIR/app.info
cat $TMPDIR/app.info >> $TMPDIR/full.info
done
echo "making report..."
mkdir -p $out/coverage
${pkgs.lcov}/bin/genhtml --show-details $TMPDIR/full.info -o $out/coverage
cp $TMPDIR/full.info $out/coverage/
mkdir -p $out/nix-support
cat ${x}/nix-support/hydra-build-products >> $out/nix-support/hydra-build-products
echo "report coverage $out/coverage" >> $out/nix-support/hydra-build-products
[ ! -e ${x}/nix-support/failed ] || touch $out/nix-support/failed
''; # */
makeTest = testFun: complete (call testFun);
makeTests = testsFun: lib.mapAttrs (name: complete) (call testsFun);
apply = makeTest; # compatibility
call = f: f { inherit pkgs system; };
complete = t: t // rec {
complete = { testScript, ... } @ t: t // rec {
nodes = buildVirtualNetwork (
if t ? nodes then t.nodes else
if t ? machine then { machine = t.machine; }
else { } );
t.nodes or (if t ? machine then { machine = t.machine; } else { }));
testScript =
# Call the test script with the computed nodes.
@ -162,7 +116,7 @@ rec {
test = runTests driver;
report = makeReport test;
report = releaseTools.gcovReport { coverageRuns = [ test ]; };
};

View File

@ -213,7 +213,8 @@ in rec {
with lib;
let
testsFor = system:
mapAttrsRecursiveCond (x: !x ? test) (n: v: listToAttrs [(nameValuePair system v.test)])
mapAttrsRecursiveCond (x: !x ? test)
(n: v: listToAttrs [(nameValuePair system (if v.makeCoverageReport or false then v.report else v.test))])
(import ./tests { inherit nixpkgs system; });
in fold recursiveUpdate {} (map testsFor systems);
}

View File

@ -14,11 +14,13 @@ in
rec {
makeCoverageReport = true;
client =
{ config, pkgs, ... }:
{ imports = [ ./common/x11.nix ];
services.xserver.driSupport = true;
hardware.opengl.driSupport = true;
services.xserver.defaultDepth = pkgs.lib.mkOverride 0 16;
environment.systemPackages = [ pkgs.quake3demo ];
nixpkgs.config.packageOverrides = overrides;

View File

@ -20,7 +20,7 @@ let
# To build the kernel with coverage instrumentation, we need a
# special patch to make coverage data available under /proc.
linux = pkgs.linux.override (orig: {
stdenv = cleanupBuildTree (keepBuildTree orig.stdenv);
stdenv = overrideInStdenv pkgs.stdenv [ pkgs.keepBuildTree ];
extraConfig =
''
GCOV_KERNEL y

View File

@ -27,10 +27,14 @@ rec {
} // args);
coverageAnalysis = args: nixBuild (
{ inherit lcov enableCoverageInstrumentation makeCoverageAnalysisReport;
{ inherit lcov enableGCOVInstrumentation makeGCOVReport;
doCoverageAnalysis = true;
} // args);
gcovReport = args: import ./gcov-report.nix (
{ inherit runCommand lcov rsync;
} // args);
rpmBuild = args: import ./rpm-build.nix (
{ inherit vmTools;
} // args);

View File

@ -0,0 +1,49 @@
{ runCommand, lcov, rsync, coverageRuns, lcovFilter ? [ "/nix/store/*" ], baseDirHack ? false }:
runCommand "coverage"
{ buildInputs = [ lcov rsync ];
inherit lcovFilter baseDirHack;
}
''
mkdir -p $TMPDIR/gcov $out/nix-support $out/coverage
info=$out/coverage/full.info
for p in ${toString coverageRuns}; do
if [ -f $p/nix-support/hydra-build-products ]; then
cat $p/nix-support/hydra-build-products >> $out/nix-support/hydra-build-products
fi
[ ! -e $p/nix-support/failed ] || touch $out/nix-support/failed
opts=
for d in $p/coverage-data/*; do
for i in $(cd $d/nix/store && ls); do
if ! [ -e /nix/store/$i/.build ]; then continue; fi
if [ -e $TMPDIR/gcov/nix/store/$i ]; then continue; fi
echo "copying $i..."
rsync -a /nix/store/$i/.build/* $TMPDIR/gcov/
if [ -n "$baseDirHack" ]; then
opts="-b $TMPDIR/gcov/$(cd /nix/store/$i/.build && ls)"
fi
done
for i in $(cd $d/nix/store && ls); do
rsync -a $d/nix/store/$i/.build/* $TMPDIR/gcov/ --include '*/' --include '*.gcda' --exclude '*'
done
done
chmod -R u+w $TMPDIR/gcov
echo "producing info..."
geninfo --ignore-errors source,gcov $TMPDIR/gcov --output-file $TMPDIR/app.info $opts
cat $TMPDIR/app.info >> $info
done
echo "making report..."
set -o noglob
lcov --remove $info ''$lcovFilter > $info.tmp
set +o noglob
mv $info.tmp $info
genhtml --show-details $info -o $out/coverage
echo "report coverage $out/coverage" >> $out/nix-support/hydra-build-products
''

View File

@ -79,7 +79,7 @@ stdenv.mkDerivation (
prePhases = ["initPhase"] ++ prePhases;
buildInputs = buildInputs ++ stdenv.lib.optional doCoverageAnalysis args.makeCoverageAnalysisReport;
buildInputs = buildInputs ++ stdenv.lib.optional doCoverageAnalysis args.makeGCOVReport;
lcovFilter = ["/nix/store/*"] ++ lcovFilter;

View File

@ -1,3 +1,5 @@
postPhases+=" cleanupBuildDir"
# Force GCC to build with coverage instrumentation. Also disable
# optimisation, since it may confuse things.
export NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -O0 --coverage"
@ -12,3 +14,18 @@ postUnpack() {
substituteInPlace $i --replace '*.$objext)' '*.$objext | *.gcno)'
done
}
# Get rid of everything that isn't a gcno file or a C source file.
# Also strip the `.tmp_' prefix from gcno files. (The Linux kernel
# creates these.)
cleanupBuildDir() {
if ! [ -e $out/.build ]; then return; fi
find $out/.build/ -type f -a ! \
\( -name "*.c" -o -name "*.cc" -o -name "*.cpp" -o -name "*.h" -o -name "*.hh" -o -name "*.y" -o -name "*.l" -o -name "*.gcno" \) \
| xargs rm -f --
for i in $(find $out/.build/ -name ".tmp_*.gcno"); do
mv "$i" "$(echo $i | sed s/.tmp_//)"
done
}

View File

@ -0,0 +1,6 @@
prePhases+=" moveBuildDir"
moveBuildDir() {
mkdir -p $out/.build
cd $out/.build
}

View File

@ -187,51 +187,13 @@ rec {
{ mkDerivation = args: stdenv.mkDerivation (args // extraAttrs); };
/* Return a modified stdenv that performs the build under $out/.build
instead of in $TMPDIR. Thus, the sources are kept available.
This is useful for things like debugging or generation of
dynamic analysis reports. */
keepBuildTree = stdenv:
addAttrsToDerivation
{ prePhases = "moveBuildDir";
moveBuildDir =
''
mkdir -p $out/.build
cd $out/.build
'';
} stdenv;
cleanupBuildTree = stdenv:
addAttrsToDerivation
{ postPhases = "cleanupBuildDir";
# Get rid of everything that isn't a gcno file or a C source
# file. This also includes the gcda files; we're not
# interested in coverage resulting from the package's own test
# suite. Also strip the `.tmp_' prefix from gcno files. (The
# Linux kernel creates these.)
cleanupBuildDir =
''
find $out/.build/ -type f -a ! \
\( -name "*.c" -o -name "*.h" -o -name "*.gcno" \) \
| xargs rm -f --
for i in $(find $out/.build/ -name ".tmp_*.gcno"); do
mv "$i" "$(echo $i | sed s/.tmp_//)"
done
'';
} stdenv;
/* Return a modified stdenv that builds packages with GCC's coverage
instrumentation. The coverage note files (*.gcno) are stored in
$out/.build, along with the source code of the package, to enable
programs like lcov to produce pretty-printed reports.
*/
addCoverageInstrumentation = stdenv:
cleanupBuildTree (keepBuildTree (overrideInStdenv stdenv [ pkgs.enableCoverageInstrumentation ]));
overrideInStdenv stdenv [ pkgs.enableGCOVInstrumentation pkgs.keepBuildTree ];
/* Replace the meta.maintainers field of a derivation. This is useful

View File

@ -396,10 +396,12 @@ let
fixDarwinDylibNames = makeSetupHook { } ../build-support/setup-hooks/fix-darwin-dylib-names.sh;
enableCoverageInstrumentation = makeSetupHook { } ../build-support/setup-hooks/enable-coverage-instrumentation.sh;
keepBuildTree = makeSetupHook { } ../build-support/setup-hooks/keep-build-tree.sh;
makeCoverageAnalysisReport = makeSetupHook
{ deps = [ pkgs.lcov pkgs.enableCoverageInstrumentation ]; }
enableGCOVInstrumentation = makeSetupHook { } ../build-support/setup-hooks/enable-coverage-instrumentation.sh;
makeGCOVReport = makeSetupHook
{ deps = [ pkgs.lcov pkgs.enableGCOVInstrumentation ]; }
../build-support/setup-hooks/make-coverage-analysis-report.sh;