1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-07-07 14:21:48 +02:00

Unit tests and external libraries

This commit is contained in:
John Ericson 2024-06-27 11:28:08 -04:00
parent 4fa8068b78
commit 17a8c2bfce
215 changed files with 873 additions and 461 deletions

View file

@ -1 +0,0 @@
../../../.version

View file

@ -1,19 +0,0 @@
libraries += libutil-test-support
libutil-test-support_NAME = libnixutil-test-support
libutil-test-support_DIR := $(d)
ifeq ($(INSTALL_UNIT_TESTS), yes)
libutil-test-support_INSTALL_DIR := $(checklibdir)
else
libutil-test-support_INSTALL_DIR :=
endif
libutil-test-support_SOURCES := $(wildcard $(d)/tests/*.cc)
libutil-test-support_CXXFLAGS += $(libutil-tests_EXTRA_INCLUDES)
libutil-test-support_LIBS = libutil
libutil-test-support_LDFLAGS := $(THREAD_LDFLAGS) -lrapidcheck

View file

@ -1,122 +0,0 @@
project('nix-util-test-support', 'cpp',
version : files('.version'),
default_options : [
'cpp_std=c++2a',
# TODO(Qyriad): increase the warning level
'warning_level=1',
'debug=true',
'optimization=2',
'errorlogs=true', # Please print logs for tests that fail
],
meson_version : '>= 1.1',
license : 'LGPL-2.1-or-later',
)
cxx = meson.get_compiler('cpp')
# See note in ../nix-util/meson.build
deps_private = [ ]
# See note in ../nix-util/meson.build
deps_public = [ ]
# See note in ../nix-util/meson.build
deps_public_subproject = [ ]
# See note in ../nix-util/meson.build
deps_other = [ ]
foreach nix_dep : [
dependency('nix-util'),
]
if nix_dep.type_name() == 'internal'
deps_public_subproject += nix_dep
# subproject sadly no good for pkg-config module
deps_other += nix_dep
else
deps_public += nix_dep
endif
endforeach
rapidcheck = dependency('rapidcheck')
deps_public += rapidcheck
add_project_arguments(
'-Wno-deprecated-declarations',
'-Wimplicit-fallthrough',
'-Werror=switch',
'-Werror=switch-enum',
'-Werror=unused-result',
'-Wdeprecated-copy',
'-Wignored-qualifiers',
# Enable assertions in libstdc++ by default. Harmless on libc++. Benchmarked
# at ~1% overhead in `nix search`.
#
# FIXME: remove when we get meson 1.4.0 which will default this to on for us:
# https://mesonbuild.com/Release-notes-for-1-4-0.html#ndebug-setting-now-controls-c-stdlib-assertions
'-D_GLIBCXX_ASSERTIONS=1',
language : 'cpp',
)
sources = files(
'tests/hash.cc',
'tests/string_callback.cc',
)
include_dirs = [include_directories('.')]
headers = files(
'tests/characterization.hh',
'tests/hash.hh',
'tests/nix_api_util.hh',
'tests/string_callback.hh',
)
if host_machine.system() == 'cygwin' or host_machine.system() == 'windows'
# Windows DLLs are stricter about symbol visibility than Unix shared
# objects --- see https://gcc.gnu.org/wiki/Visibility for details.
# This is a temporary sledgehammer to export everything like on Unix,
# and not detail with this yet.
#
# TODO do not do this, and instead do fine-grained export annotations.
linker_export_flags = ['-Wl,--export-all-symbols']
else
linker_export_flags = []
endif
this_library = library(
'nix-util-test-support',
sources,
dependencies : deps_public + deps_private + deps_other,
include_directories : include_dirs,
# TODO: Remove `-lrapidcheck` when https://github.com/emil-e/rapidcheck/pull/326
# is available. See also ../libutil/build.meson
link_args: linker_export_flags + ['-lrapidcheck'],
install : true,
)
install_headers(headers, subdir : 'nix', preserve_path : true)
requires = []
foreach dep : deps_public_subproject
requires += dep.name()
endforeach
requires += deps_public
import('pkgconfig').generate(
this_library,
filebase : meson.project_name(),
name : 'Nix',
description : 'Nix Package Manager',
subdirs : ['nix'],
extra_cflags : ['-std=c++2a'],
requires : requires,
requires_private : deps_private,
)
meson.override_dependency(meson.project_name(), declare_dependency(
include_directories : include_dirs,
link_with : this_library,
compile_args : ['-std=c++2a'],
dependencies : deps_public_subproject + deps_public,
))

View file

@ -1,99 +0,0 @@
{ lib
, stdenv
, releaseTools
, meson
, ninja
, pkg-config
, nix-util
, rapidcheck
# Configuration Options
, versionSuffix ? ""
# Check test coverage of Nix. Probably want to use with at least
# one of `doCheck` or `doInstallCheck` enabled.
, withCoverageChecks ? false
}:
let
inherit (lib) fileset;
version = lib.fileContents ./.version + versionSuffix;
mkDerivation =
if withCoverageChecks
then
# TODO support `finalAttrs` args function in
# `releaseTools.coverageAnalysis`.
argsFun:
releaseTools.coverageAnalysis (let args = argsFun args; in args)
else stdenv.mkDerivation;
in
mkDerivation (finalAttrs: {
pname = "nix-util-test-support";
inherit version;
src = fileset.toSource {
root = ./.;
fileset = fileset.unions [
./meson.build
# ./meson.options
(fileset.fileFilter (file: file.hasExt "cc") ./.)
(fileset.fileFilter (file: file.hasExt "hh") ./.)
];
};
outputs = [ "out" "dev" ];
nativeBuildInputs = [
meson
ninja
pkg-config
];
buildInputs = [
nix-util
rapidcheck
]
;
propagatedBuildInputs = [
nix-util
];
preConfigure =
# "Inline" .version so it's not a symlink, and includes the suffix
''
echo ${version} > .version
'';
mesonFlags = [
];
env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
LDFLAGS = "-fuse-ld=gold";
};
enableParallelBuilding = true;
separateDebugInfo = !stdenv.hostPlatform.isStatic;
# TODO Always true after https://github.com/NixOS/nixpkgs/issues/318564
strictDeps = !withCoverageChecks;
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
meta = {
platforms = lib.platforms.unix ++ lib.platforms.windows;
};
} // lib.optionalAttrs withCoverageChecks {
lcovFilter = [ "*/boost/*" "*-tab.*" ];
hardeningDisable = [ "fortify" ];
})

View file

@ -1,109 +0,0 @@
#pragma once
///@file
#include <gtest/gtest.h>
#include "types.hh"
#include "environment-variables.hh"
#include "file-system.hh"
namespace nix {
/**
* The path to the unit test data directory. See the contributing guide
* in the manual for further details.
*/
static inline Path getUnitTestData() {
return getEnv("_NIX_TEST_UNIT_DATA").value();
}
/**
* Whether we should update "golden masters" instead of running tests
* against them. See the contributing guide in the manual for further
* details.
*/
static inline bool testAccept() {
return getEnv("_NIX_TEST_ACCEPT") == "1";
}
/**
* Mixin class for writing characterization tests
*/
class CharacterizationTest : public virtual ::testing::Test
{
protected:
/**
* While the "golden master" for this characterization test is
* located. It should not be shared with any other test.
*/
virtual Path goldenMaster(PathView testStem) const = 0;
public:
/**
* Golden test for reading
*
* @param test hook that takes the contents of the file and does the
* actual work
*/
void readTest(PathView testStem, auto && test)
{
auto file = goldenMaster(testStem);
if (testAccept())
{
GTEST_SKIP()
<< "Cannot read golden master "
<< file
<< "because another test is also updating it";
}
else
{
test(readFile(file));
}
}
/**
* Golden test for writing
*
* @param test hook that produces contents of the file and does the
* actual work
*/
void writeTest(
PathView testStem, auto && test, auto && readFile2, auto && writeFile2)
{
auto file = goldenMaster(testStem);
auto got = test();
if (testAccept())
{
createDirs(dirOf(file));
writeFile2(file, got);
GTEST_SKIP()
<< "Updating golden master "
<< file;
}
else
{
decltype(got) expected = readFile2(file);
ASSERT_EQ(got, expected);
}
}
/**
* Specialize to `std::string`
*/
void writeTest(PathView testStem, auto && test)
{
writeTest(
testStem, test,
[](const Path & f) -> std::string {
return readFile(f);
},
[](const Path & f, const std::string & c) {
return writeFile(f, c);
});
}
};
}

View file

@ -1,27 +0,0 @@
#include <regex>
#include <rapidcheck.h>
#include "hash.hh"
#include "tests/hash.hh"
namespace rc {
using namespace nix;
Gen<Hash> Arbitrary<Hash>::arbitrary()
{
Hash prototype(HashAlgorithm::SHA1);
return
gen::apply(
[](const std::vector<uint8_t> & v) {
Hash hash(HashAlgorithm::SHA1);
assert(v.size() == hash.hashSize);
std::copy(v.begin(), v.end(), hash.hash);
return hash;
},
gen::container<std::vector<uint8_t>>(prototype.hashSize, gen::arbitrary<uint8_t>())
);
}
}

View file

@ -1,16 +0,0 @@
#pragma once
///@file
#include <rapidcheck/gen/Arbitrary.h>
#include <hash.hh>
namespace rc {
using namespace nix;
template<>
struct Arbitrary<Hash> {
static Gen<Hash> arbitrary();
};
}

View file

@ -1,48 +0,0 @@
#pragma once
///@file
#include "nix_api_util.h"
#include <gtest/gtest.h>
namespace nixC {
class nix_api_util_context : public ::testing::Test
{
protected:
nix_api_util_context()
{
ctx = nix_c_context_create();
nix_libutil_init(ctx);
};
~nix_api_util_context() override
{
nix_c_context_free(ctx);
ctx = nullptr;
}
nix_c_context * ctx;
inline void assert_ctx_ok()
{
if (nix_err_code(ctx) == NIX_OK) {
return;
}
unsigned int n;
const char * p = nix_err_msg(nullptr, ctx, &n);
std::string msg(p, n);
FAIL() << "nix_err_code(ctx) != NIX_OK, message: " << msg;
}
inline void assert_ctx_err()
{
if (nix_err_code(ctx) != NIX_OK) {
return;
}
FAIL() << "Got NIX_OK, but expected an error!";
}
};
}

View file

@ -1,10 +0,0 @@
#include "string_callback.hh"
namespace nix::testing {
void observe_string_cb(const char * start, unsigned int n, std::string * user_data)
{
*user_data = std::string(start);
}
}

View file

@ -1,16 +0,0 @@
#pragma once
#include <string>
namespace nix::testing {
void observe_string_cb(const char * start, unsigned int n, std::string * user_data);
inline void * observe_string_cb_data(std::string & out)
{
return (void *) &out;
};
#define OBSERVE_STRING(str) \
(nix_get_string_callback) nix::testing::observe_string_cb, nix::testing::observe_string_cb_data(str)
}