From b8301b2c25eeaf9f579a0413f4cb01017e8f636d Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Sun, 3 Aug 2025 00:21:04 +0300 Subject: [PATCH 1/3] libstore-tests: Add nix-store-benchmarks as a meson benchmark --- src/libstore-tests/meson.build | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libstore-tests/meson.build b/src/libstore-tests/meson.build index 89189bab9..87f268828 100644 --- a/src/libstore-tests/meson.build +++ b/src/libstore-tests/meson.build @@ -120,4 +120,6 @@ if get_option('benchmarks') install : false, cpp_args : ['-DNIX_UNIT_TEST_DATA="' + meson.current_source_dir() + '/data"'], ) + + benchmark('nix-store-benchmarks', benchmark_exe) endif From b2b2f2dc53aaaca024b21811fbaef06df4507a85 Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Sun, 3 Aug 2025 00:53:24 +0300 Subject: [PATCH 2/3] libstore-tests: Split bench-main into a separate file This makes it easier to add new benchmarks. --- src/libstore-tests/bench-main.cc | 14 ++++++++++++++ src/libstore-tests/derivation-parser-bench.cc | 13 ------------- src/libstore-tests/meson.build | 7 ++++++- 3 files changed, 20 insertions(+), 14 deletions(-) create mode 100644 src/libstore-tests/bench-main.cc diff --git a/src/libstore-tests/bench-main.cc b/src/libstore-tests/bench-main.cc new file mode 100644 index 000000000..37a72d8ab --- /dev/null +++ b/src/libstore-tests/bench-main.cc @@ -0,0 +1,14 @@ +#include +#include "nix/store/globals.hh" + +// Custom main to initialize Nix before running benchmarks +int main(int argc, char ** argv) +{ + // Initialize libstore + nix::initLibStore(false); + + // Initialize and run benchmarks + ::benchmark::Initialize(&argc, argv); + ::benchmark::RunSpecifiedBenchmarks(); + return 0; +} diff --git a/src/libstore-tests/derivation-parser-bench.cc b/src/libstore-tests/derivation-parser-bench.cc index 7598758f0..d6c1d4551 100644 --- a/src/libstore-tests/derivation-parser-bench.cc +++ b/src/libstore-tests/derivation-parser-bench.cc @@ -3,7 +3,6 @@ #include "nix/store/store-api.hh" #include "nix/util/experimental-features.hh" #include "nix/store/store-open.hh" -#include "nix/store/globals.hh" #include #include @@ -31,15 +30,3 @@ static void BM_ParseRealDerivationFile(benchmark::State & state, const std::stri // Register benchmarks for actual test derivation files if they exist BENCHMARK_CAPTURE(BM_ParseRealDerivationFile, hello, std::string(NIX_UNIT_TEST_DATA) + "/derivation/hello.drv"); BENCHMARK_CAPTURE(BM_ParseRealDerivationFile, firefox, std::string(NIX_UNIT_TEST_DATA) + "/derivation/firefox.drv"); - -// Custom main to initialize Nix before running benchmarks -int main(int argc, char ** argv) -{ - // Initialize libstore - nix::initLibStore(false); - - // Initialize and run benchmarks - ::benchmark::Initialize(&argc, argv); - ::benchmark::RunSpecifiedBenchmarks(); - return 0; -} diff --git a/src/libstore-tests/meson.build b/src/libstore-tests/meson.build index 87f268828..606b8f694 100644 --- a/src/libstore-tests/meson.build +++ b/src/libstore-tests/meson.build @@ -110,9 +110,14 @@ test( if get_option('benchmarks') gbenchmark = dependency('benchmark', required : true) + benchmark_sources = files( + 'bench-main.cc', + 'derivation-parser-bench.cc', + ) + benchmark_exe = executable( 'nix-store-benchmarks', - 'derivation-parser-bench.cc', + benchmark_sources, config_priv_h, dependencies : deps_private_subproject + deps_private + deps_other + [gbenchmark], include_directories : include_dirs, From ea1f67393d26bdb02053fd914815caefa2e9e96a Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Sun, 3 Aug 2025 01:01:26 +0300 Subject: [PATCH 3/3] libstore-tests: Build and run benchmarks in CI This changes our GHA CI and nix-store-tests packaging to build and run the benchmarks. This does not affect the default packaging - the overrides apply only for the GHA CI. --- ci/gha/tests/default.nix | 4 ++- src/libstore-tests/derivation-parser-bench.cc | 11 ++++-- src/libstore-tests/meson.build | 2 +- src/libstore-tests/package.nix | 36 +++++++++++++------ 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/ci/gha/tests/default.nix b/ci/gha/tests/default.nix index 39d1502df..ce44d7cf7 100644 --- a/ci/gha/tests/default.nix +++ b/ci/gha/tests/default.nix @@ -59,7 +59,9 @@ in inherit getStdenv; }).overrideScope ( - _: _: { + final: prev: { + nix-store-tests = prev.nix-store-tests.override { withBenchmarks = true; }; + mesonComponentOverrides = finalAttrs: prevAttrs: { mesonFlags = (prevAttrs.mesonFlags or [ ]) diff --git a/src/libstore-tests/derivation-parser-bench.cc b/src/libstore-tests/derivation-parser-bench.cc index d6c1d4551..ef698b205 100644 --- a/src/libstore-tests/derivation-parser-bench.cc +++ b/src/libstore-tests/derivation-parser-bench.cc @@ -2,6 +2,7 @@ #include "nix/store/derivations.hh" #include "nix/store/store-api.hh" #include "nix/util/experimental-features.hh" +#include "nix/util/environment-variables.hh" #include "nix/store/store-open.hh" #include #include @@ -28,5 +29,11 @@ static void BM_ParseRealDerivationFile(benchmark::State & state, const std::stri } // Register benchmarks for actual test derivation files if they exist -BENCHMARK_CAPTURE(BM_ParseRealDerivationFile, hello, std::string(NIX_UNIT_TEST_DATA) + "/derivation/hello.drv"); -BENCHMARK_CAPTURE(BM_ParseRealDerivationFile, firefox, std::string(NIX_UNIT_TEST_DATA) + "/derivation/firefox.drv"); +BENCHMARK_CAPTURE( + BM_ParseRealDerivationFile, + hello, + getEnvNonEmpty("_NIX_TEST_UNIT_DATA").value_or(NIX_UNIT_TEST_DATA) + "/derivation/hello.drv"); +BENCHMARK_CAPTURE( + BM_ParseRealDerivationFile, + firefox, + getEnvNonEmpty("_NIX_TEST_UNIT_DATA").value_or(NIX_UNIT_TEST_DATA) + "/derivation/firefox.drv"); diff --git a/src/libstore-tests/meson.build b/src/libstore-tests/meson.build index 606b8f694..dfb936fef 100644 --- a/src/libstore-tests/meson.build +++ b/src/libstore-tests/meson.build @@ -122,7 +122,7 @@ if get_option('benchmarks') dependencies : deps_private_subproject + deps_private + deps_other + [gbenchmark], include_directories : include_dirs, link_args: linker_export_flags, - install : false, + install : true, cpp_args : ['-DNIX_UNIT_TEST_DATA="' + meson.current_source_dir() + '/data"'], ) diff --git a/src/libstore-tests/package.nix b/src/libstore-tests/package.nix index 93c71a382..00d40365e 100644 --- a/src/libstore-tests/package.nix +++ b/src/libstore-tests/package.nix @@ -12,12 +12,14 @@ rapidcheck, gtest, + gbenchmark, runCommand, # Configuration Options version, filesetToSource, + withBenchmarks ? false, }: let @@ -41,11 +43,15 @@ mkMesonExecutable (finalAttrs: { ]; # Hack for sake of the dev shell - passthru.externalBuildInputs = [ - sqlite - rapidcheck - gtest - ]; + passthru.externalBuildInputs = + [ + sqlite + rapidcheck + gtest + ] + ++ lib.optionals withBenchmarks [ + gbenchmark + ]; buildInputs = finalAttrs.passthru.externalBuildInputs ++ [ nix-store @@ -54,6 +60,7 @@ mkMesonExecutable (finalAttrs: { ]; mesonFlags = [ + (lib.mesonBool "benchmarks" withBenchmarks) ]; passthru = { @@ -75,12 +82,19 @@ mkMesonExecutable (finalAttrs: { meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages; buildInputs = [ writableTmpDirAsHomeHook ]; } - ('' - export _NIX_TEST_UNIT_DATA=${data + "/src/libstore-tests/data"} - export NIX_REMOTE=$HOME/store - ${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage} - touch $out - ''); + ( + '' + export _NIX_TEST_UNIT_DATA=${data + "/src/libstore-tests/data"} + export NIX_REMOTE=$HOME/store + ${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage} + '' + + lib.optionalString withBenchmarks '' + ${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe' finalAttrs.finalPackage "nix-store-benchmarks"} + '' + + '' + touch $out + '' + ); }; };