mirror of
https://github.com/NixOS/nix
synced 2025-07-08 19:23:54 +02:00
Merge remote-tracking branch 'upstream/master' into support-hardlinks-in-tarballs
This commit is contained in:
commit
86420753ec
583 changed files with 11313 additions and 16547 deletions
1
tests/unit/libexpr-support/.version
Symbolic link
1
tests/unit/libexpr-support/.version
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../.version
|
1
tests/unit/libexpr-support/build-utils-meson
Symbolic link
1
tests/unit/libexpr-support/build-utils-meson
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../build-utils-meson/
|
74
tests/unit/libexpr-support/meson.build
Normal file
74
tests/unit/libexpr-support/meson.build
Normal file
|
@ -0,0 +1,74 @@
|
|||
project('nix-expr-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')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
|
||||
deps_private_maybe_subproject = [
|
||||
]
|
||||
deps_public_maybe_subproject = [
|
||||
dependency('nix-util'),
|
||||
dependency('nix-util-test-support'),
|
||||
dependency('nix-store'),
|
||||
dependency('nix-store-test-support'),
|
||||
dependency('nix-expr'),
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
|
||||
rapidcheck = dependency('rapidcheck')
|
||||
deps_public += rapidcheck
|
||||
|
||||
add_project_arguments(
|
||||
# TODO(Qyriad): Yes this is how the autoconf+Make system did it.
|
||||
# It would be nice for our headers to be idempotent instead.
|
||||
'-include', 'config-util.hh',
|
||||
'-include', 'config-store.hh',
|
||||
'-include', 'config-expr.hh',
|
||||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/diagnostics')
|
||||
|
||||
sources = files(
|
||||
'tests/value/context.cc',
|
||||
)
|
||||
|
||||
include_dirs = [include_directories('.')]
|
||||
|
||||
headers = files(
|
||||
'tests/libexpr.hh',
|
||||
'tests/nix_api_expr.hh',
|
||||
'tests/value/context.hh',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
|
||||
this_library = library(
|
||||
'nix-expr-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'],
|
||||
prelink : true, # For C++ static initializers
|
||||
install : true,
|
||||
)
|
||||
|
||||
install_headers(headers, subdir : 'nix', preserve_path : true)
|
||||
|
||||
libraries_private = []
|
||||
|
||||
subdir('build-utils-meson/export')
|
81
tests/unit/libexpr-support/package.nix
Normal file
81
tests/unit/libexpr-support/package.nix
Normal file
|
@ -0,0 +1,81 @@
|
|||
{ lib
|
||||
, stdenv
|
||||
, mkMesonDerivation
|
||||
, releaseTools
|
||||
|
||||
, meson
|
||||
, ninja
|
||||
, pkg-config
|
||||
|
||||
, nix-store-test-support
|
||||
, nix-expr
|
||||
|
||||
, rapidcheck
|
||||
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) fileset;
|
||||
in
|
||||
|
||||
mkMesonDerivation (finalAttrs: {
|
||||
pname = "nix-util-test-support";
|
||||
inherit version;
|
||||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../../.version
|
||||
./.version
|
||||
./meson.build
|
||||
# ./meson.options
|
||||
(fileset.fileFilter (file: file.hasExt "cc") ./.)
|
||||
(fileset.fileFilter (file: file.hasExt "hh") ./.)
|
||||
];
|
||||
|
||||
outputs = [ "out" "dev" ];
|
||||
|
||||
nativeBuildInputs = [
|
||||
meson
|
||||
ninja
|
||||
pkg-config
|
||||
];
|
||||
|
||||
propagatedBuildInputs = [
|
||||
nix-store-test-support
|
||||
nix-expr
|
||||
rapidcheck
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
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;
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
};
|
||||
|
||||
})
|
|
@ -19,14 +19,14 @@ namespace nix {
|
|||
static void SetUpTestSuite() {
|
||||
LibStoreTest::SetUpTestSuite();
|
||||
initGC();
|
||||
evalSettings.nixPath = {};
|
||||
}
|
||||
|
||||
protected:
|
||||
LibExprTest()
|
||||
: LibStoreTest()
|
||||
, state({}, store)
|
||||
, state({}, store, evalSettings, nullptr)
|
||||
{
|
||||
evalSettings.nixPath = {};
|
||||
}
|
||||
Value eval(std::string input, bool forceValue = true) {
|
||||
Value v;
|
||||
|
@ -42,6 +42,8 @@ namespace nix {
|
|||
return state.symbols.create(value);
|
||||
}
|
||||
|
||||
bool readOnlyMode = true;
|
||||
EvalSettings evalSettings{readOnlyMode};
|
||||
EvalState state;
|
||||
};
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ protected:
|
|||
}
|
||||
|
||||
EvalState * state;
|
||||
Value * value;
|
||||
nix_value * value;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
1
tests/unit/libexpr/.version
Symbolic link
1
tests/unit/libexpr/.version
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../.version
|
1
tests/unit/libexpr/build-utils-meson
Symbolic link
1
tests/unit/libexpr/build-utils-meson
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../build-utils-meson/
|
0
tests/unit/libexpr/data/.gitkeep
Normal file
0
tests/unit/libexpr/data/.gitkeep
Normal file
|
@ -4,7 +4,7 @@ programs += libexpr-tests
|
|||
|
||||
libexpr-tests_NAME := libnixexpr-tests
|
||||
|
||||
libexpr-tests_ENV := _NIX_TEST_UNIT_DATA=$(d)/data
|
||||
libexpr-tests_ENV := _NIX_TEST_UNIT_DATA=$(d)/data GTEST_OUTPUT=xml:$$testresults/libexpr-tests.xml
|
||||
|
||||
libexpr-tests_DIR := $(d)
|
||||
|
||||
|
|
90
tests/unit/libexpr/meson.build
Normal file
90
tests/unit/libexpr/meson.build
Normal file
|
@ -0,0 +1,90 @@
|
|||
project('nix-expr-tests', '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')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
|
||||
deps_private_maybe_subproject = [
|
||||
dependency('nix-expr'),
|
||||
dependency('nix-expr-c'),
|
||||
dependency('nix-expr-test-support'),
|
||||
]
|
||||
deps_public_maybe_subproject = [
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
|
||||
rapidcheck = dependency('rapidcheck')
|
||||
deps_private += rapidcheck
|
||||
|
||||
gtest = dependency('gtest')
|
||||
deps_private += gtest
|
||||
|
||||
gtest = dependency('gmock')
|
||||
deps_private += gtest
|
||||
|
||||
add_project_arguments(
|
||||
# TODO(Qyriad): Yes this is how the autoconf+Make system did it.
|
||||
# It would be nice for our headers to be idempotent instead.
|
||||
'-include', 'config-util.hh',
|
||||
'-include', 'config-store.hh',
|
||||
'-include', 'config-expr.hh',
|
||||
'-include', 'config-util.h',
|
||||
'-include', 'config-store.h',
|
||||
'-include', 'config-expr.h',
|
||||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/diagnostics')
|
||||
|
||||
sources = files(
|
||||
'derived-path.cc',
|
||||
'error_traces.cc',
|
||||
'eval.cc',
|
||||
'json.cc',
|
||||
'main.cc',
|
||||
'nix_api_expr.cc',
|
||||
'nix_api_external.cc',
|
||||
'nix_api_value.cc',
|
||||
'primops.cc',
|
||||
'search-path.cc',
|
||||
'trivial.cc',
|
||||
'value/context.cc',
|
||||
'value/print.cc',
|
||||
'value/value.cc',
|
||||
)
|
||||
|
||||
include_dirs = [include_directories('.')]
|
||||
|
||||
|
||||
this_exe = executable(
|
||||
meson.project_name(),
|
||||
sources,
|
||||
dependencies : deps_private_subproject + deps_private + deps_other,
|
||||
include_directories : include_dirs,
|
||||
# TODO: -lrapidcheck, see ../libutil-support/build.meson
|
||||
link_args: linker_export_flags + ['-lrapidcheck'],
|
||||
install : true,
|
||||
)
|
||||
|
||||
test(
|
||||
meson.project_name(),
|
||||
this_exe,
|
||||
env : {
|
||||
'_NIX_TEST_UNIT_DATA': meson.current_source_dir() / 'data',
|
||||
},
|
||||
protocol : 'gtest',
|
||||
)
|
|
@ -39,12 +39,12 @@ TEST_F(nix_api_expr_test, nix_expr_eval_drv)
|
|||
ASSERT_EQ(NIX_TYPE_ATTRS, nix_get_type(nullptr, value));
|
||||
|
||||
EvalState * stateFn = nix_state_create(nullptr, nullptr, store);
|
||||
Value * valueFn = nix_alloc_value(nullptr, state);
|
||||
nix_value * valueFn = nix_alloc_value(nullptr, state);
|
||||
nix_expr_eval_from_string(nullptr, stateFn, "builtins.toString", ".", valueFn);
|
||||
ASSERT_EQ(NIX_TYPE_FUNCTION, nix_get_type(nullptr, valueFn));
|
||||
|
||||
EvalState * stateResult = nix_state_create(nullptr, nullptr, store);
|
||||
Value * valueResult = nix_alloc_value(nullptr, stateResult);
|
||||
nix_value * valueResult = nix_alloc_value(nullptr, stateResult);
|
||||
nix_value_call(ctx, stateResult, valueFn, value, valueResult);
|
||||
ASSERT_EQ(NIX_TYPE_STRING, nix_get_type(nullptr, valueResult));
|
||||
|
||||
|
@ -70,7 +70,7 @@ TEST_F(nix_api_expr_test, nix_build_drv)
|
|||
})";
|
||||
nix_expr_eval_from_string(nullptr, state, expr, ".", value);
|
||||
|
||||
Value * drvPathValue = nix_get_attr_byname(nullptr, value, state, "drvPath");
|
||||
nix_value * drvPathValue = nix_get_attr_byname(nullptr, value, state, "drvPath");
|
||||
std::string drvPath;
|
||||
nix_get_string(nullptr, drvPathValue, OBSERVE_STRING(drvPath));
|
||||
|
||||
|
@ -84,7 +84,7 @@ TEST_F(nix_api_expr_test, nix_build_drv)
|
|||
StorePath * drvStorePath = nix_store_parse_path(ctx, store, drvPath.c_str());
|
||||
ASSERT_EQ(true, nix_store_is_valid_path(ctx, store, drvStorePath));
|
||||
|
||||
Value * outPathValue = nix_get_attr_byname(ctx, value, state, "outPath");
|
||||
nix_value * outPathValue = nix_get_attr_byname(ctx, value, state, "outPath");
|
||||
std::string outPath;
|
||||
nix_get_string(ctx, outPathValue, OBSERVE_STRING(outPath));
|
||||
|
||||
|
@ -193,7 +193,8 @@ TEST_F(nix_api_expr_test, nix_expr_realise_context)
|
|||
|
||||
const char * SAMPLE_USER_DATA = "whatever";
|
||||
|
||||
static void primop_square(void * user_data, nix_c_context * context, EvalState * state, Value ** args, Value * ret)
|
||||
static void
|
||||
primop_square(void * user_data, nix_c_context * context, EvalState * state, nix_value ** args, nix_value * ret)
|
||||
{
|
||||
assert(context);
|
||||
assert(state);
|
||||
|
@ -207,17 +208,17 @@ TEST_F(nix_api_expr_test, nix_expr_primop)
|
|||
PrimOp * primop =
|
||||
nix_alloc_primop(ctx, primop_square, 1, "square", nullptr, "square an integer", (void *) SAMPLE_USER_DATA);
|
||||
assert_ctx_ok();
|
||||
Value * primopValue = nix_alloc_value(ctx, state);
|
||||
nix_value * primopValue = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_init_primop(ctx, primopValue, primop);
|
||||
assert_ctx_ok();
|
||||
|
||||
Value * three = nix_alloc_value(ctx, state);
|
||||
nix_value * three = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_init_int(ctx, three, 3);
|
||||
assert_ctx_ok();
|
||||
|
||||
Value * result = nix_alloc_value(ctx, state);
|
||||
nix_value * result = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_value_call(ctx, state, primopValue, three, result);
|
||||
assert_ctx_ok();
|
||||
|
@ -226,7 +227,8 @@ TEST_F(nix_api_expr_test, nix_expr_primop)
|
|||
ASSERT_EQ(9, r);
|
||||
}
|
||||
|
||||
static void primop_repeat(void * user_data, nix_c_context * context, EvalState * state, Value ** args, Value * ret)
|
||||
static void
|
||||
primop_repeat(void * user_data, nix_c_context * context, EvalState * state, nix_value ** args, nix_value * ret)
|
||||
{
|
||||
assert(context);
|
||||
assert(state);
|
||||
|
@ -255,27 +257,27 @@ TEST_F(nix_api_expr_test, nix_expr_primop_arity_2_multiple_calls)
|
|||
PrimOp * primop =
|
||||
nix_alloc_primop(ctx, primop_repeat, 2, "repeat", nullptr, "repeat a string", (void *) SAMPLE_USER_DATA);
|
||||
assert_ctx_ok();
|
||||
Value * primopValue = nix_alloc_value(ctx, state);
|
||||
nix_value * primopValue = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_init_primop(ctx, primopValue, primop);
|
||||
assert_ctx_ok();
|
||||
|
||||
Value * hello = nix_alloc_value(ctx, state);
|
||||
nix_value * hello = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_init_string(ctx, hello, "hello");
|
||||
assert_ctx_ok();
|
||||
|
||||
Value * three = nix_alloc_value(ctx, state);
|
||||
nix_value * three = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_init_int(ctx, three, 3);
|
||||
assert_ctx_ok();
|
||||
|
||||
Value * partial = nix_alloc_value(ctx, state);
|
||||
nix_value * partial = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_value_call(ctx, state, primopValue, hello, partial);
|
||||
assert_ctx_ok();
|
||||
|
||||
Value * result = nix_alloc_value(ctx, state);
|
||||
nix_value * result = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_value_call(ctx, state, partial, three, result);
|
||||
assert_ctx_ok();
|
||||
|
@ -290,22 +292,22 @@ TEST_F(nix_api_expr_test, nix_expr_primop_arity_2_single_call)
|
|||
PrimOp * primop =
|
||||
nix_alloc_primop(ctx, primop_repeat, 2, "repeat", nullptr, "repeat a string", (void *) SAMPLE_USER_DATA);
|
||||
assert_ctx_ok();
|
||||
Value * primopValue = nix_alloc_value(ctx, state);
|
||||
nix_value * primopValue = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_init_primop(ctx, primopValue, primop);
|
||||
assert_ctx_ok();
|
||||
|
||||
Value * hello = nix_alloc_value(ctx, state);
|
||||
nix_value * hello = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_init_string(ctx, hello, "hello");
|
||||
assert_ctx_ok();
|
||||
|
||||
Value * three = nix_alloc_value(ctx, state);
|
||||
nix_value * three = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_init_int(ctx, three, 3);
|
||||
assert_ctx_ok();
|
||||
|
||||
Value * result = nix_alloc_value(ctx, state);
|
||||
nix_value * result = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
NIX_VALUE_CALL(ctx, state, result, primopValue, hello, three);
|
||||
assert_ctx_ok();
|
||||
|
@ -318,7 +320,7 @@ TEST_F(nix_api_expr_test, nix_expr_primop_arity_2_single_call)
|
|||
}
|
||||
|
||||
static void
|
||||
primop_bad_no_return(void * user_data, nix_c_context * context, EvalState * state, Value ** args, Value * ret)
|
||||
primop_bad_no_return(void * user_data, nix_c_context * context, EvalState * state, nix_value ** args, nix_value * ret)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -327,17 +329,17 @@ TEST_F(nix_api_expr_test, nix_expr_primop_bad_no_return)
|
|||
PrimOp * primop =
|
||||
nix_alloc_primop(ctx, primop_bad_no_return, 1, "badNoReturn", nullptr, "a broken primop", nullptr);
|
||||
assert_ctx_ok();
|
||||
Value * primopValue = nix_alloc_value(ctx, state);
|
||||
nix_value * primopValue = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_init_primop(ctx, primopValue, primop);
|
||||
assert_ctx_ok();
|
||||
|
||||
Value * three = nix_alloc_value(ctx, state);
|
||||
nix_value * three = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_init_int(ctx, three, 3);
|
||||
assert_ctx_ok();
|
||||
|
||||
Value * result = nix_alloc_value(ctx, state);
|
||||
nix_value * result = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_value_call(ctx, state, primopValue, three, result);
|
||||
ASSERT_EQ(ctx->last_err_code, NIX_ERR_NIX_ERROR);
|
||||
|
@ -348,8 +350,8 @@ TEST_F(nix_api_expr_test, nix_expr_primop_bad_no_return)
|
|||
ASSERT_THAT(ctx->last_err, testing::Optional(testing::HasSubstr("badNoReturn")));
|
||||
}
|
||||
|
||||
static void
|
||||
primop_bad_return_thunk(void * user_data, nix_c_context * context, EvalState * state, Value ** args, Value * ret)
|
||||
static void primop_bad_return_thunk(
|
||||
void * user_data, nix_c_context * context, EvalState * state, nix_value ** args, nix_value * ret)
|
||||
{
|
||||
nix_init_apply(context, ret, args[0], args[1]);
|
||||
}
|
||||
|
@ -358,22 +360,22 @@ TEST_F(nix_api_expr_test, nix_expr_primop_bad_return_thunk)
|
|||
PrimOp * primop =
|
||||
nix_alloc_primop(ctx, primop_bad_return_thunk, 2, "badReturnThunk", nullptr, "a broken primop", nullptr);
|
||||
assert_ctx_ok();
|
||||
Value * primopValue = nix_alloc_value(ctx, state);
|
||||
nix_value * primopValue = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_init_primop(ctx, primopValue, primop);
|
||||
assert_ctx_ok();
|
||||
|
||||
Value * toString = nix_alloc_value(ctx, state);
|
||||
nix_value * toString = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_expr_eval_from_string(ctx, state, "builtins.toString", ".", toString);
|
||||
assert_ctx_ok();
|
||||
|
||||
Value * four = nix_alloc_value(ctx, state);
|
||||
nix_value * four = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_init_int(ctx, four, 4);
|
||||
assert_ctx_ok();
|
||||
|
||||
Value * result = nix_alloc_value(ctx, state);
|
||||
nix_value * result = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
NIX_VALUE_CALL(ctx, state, result, primopValue, toString, four);
|
||||
|
||||
|
@ -387,11 +389,11 @@ TEST_F(nix_api_expr_test, nix_expr_primop_bad_return_thunk)
|
|||
|
||||
TEST_F(nix_api_expr_test, nix_value_call_multi_no_args)
|
||||
{
|
||||
Value * n = nix_alloc_value(ctx, state);
|
||||
nix_value * n = nix_alloc_value(ctx, state);
|
||||
nix_init_int(ctx, n, 3);
|
||||
assert_ctx_ok();
|
||||
|
||||
Value * r = nix_alloc_value(ctx, state);
|
||||
nix_value * r = nix_alloc_value(ctx, state);
|
||||
nix_value_call_multi(ctx, state, n, 0, nullptr, r);
|
||||
assert_ctx_ok();
|
||||
|
||||
|
|
|
@ -49,10 +49,10 @@ TEST_F(nix_api_expr_test, nix_expr_eval_external)
|
|||
nix_init_external(ctx, value, val);
|
||||
|
||||
EvalState * stateResult = nix_state_create(nullptr, nullptr, store);
|
||||
Value * valueResult = nix_alloc_value(nullptr, stateResult);
|
||||
nix_value * valueResult = nix_alloc_value(nullptr, stateResult);
|
||||
|
||||
EvalState * stateFn = nix_state_create(nullptr, nullptr, store);
|
||||
Value * valueFn = nix_alloc_value(nullptr, stateFn);
|
||||
nix_value * valueFn = nix_alloc_value(nullptr, stateFn);
|
||||
|
||||
nix_expr_eval_from_string(nullptr, state, "builtins.typeOf", ".", valueFn);
|
||||
|
||||
|
|
|
@ -4,16 +4,26 @@
|
|||
#include "nix_api_util_internal.h"
|
||||
#include "nix_api_expr.h"
|
||||
#include "nix_api_value.h"
|
||||
#include "nix_api_expr_internal.h"
|
||||
|
||||
#include "tests/nix_api_expr.hh"
|
||||
#include "tests/string_callback.hh"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace nixC {
|
||||
|
||||
TEST_F(nix_api_expr_test, as_nix_value_ptr)
|
||||
{
|
||||
// nix_alloc_value casts nix::Value to nix_value
|
||||
// It should be obvious from the decl that that works, but if it doesn't,
|
||||
// the whole implementation would be utterly broken.
|
||||
ASSERT_EQ(sizeof(nix::Value), sizeof(nix_value));
|
||||
}
|
||||
|
||||
TEST_F(nix_api_expr_test, nix_value_get_int_invalid)
|
||||
{
|
||||
ASSERT_EQ(0, nix_get_int(ctx, nullptr));
|
||||
|
@ -138,8 +148,8 @@ TEST_F(nix_api_expr_test, nix_build_and_init_list)
|
|||
int size = 10;
|
||||
ListBuilder * builder = nix_make_list_builder(ctx, state, size);
|
||||
|
||||
Value * intValue = nix_alloc_value(ctx, state);
|
||||
Value * intValue2 = nix_alloc_value(ctx, state);
|
||||
nix_value * intValue = nix_alloc_value(ctx, state);
|
||||
nix_value * intValue2 = nix_alloc_value(ctx, state);
|
||||
|
||||
// `init` and `insert` can be called in any order
|
||||
nix_init_int(ctx, intValue, 42);
|
||||
|
@ -194,10 +204,10 @@ TEST_F(nix_api_expr_test, nix_build_and_init_attr)
|
|||
|
||||
BindingsBuilder * builder = nix_make_bindings_builder(ctx, state, size);
|
||||
|
||||
Value * intValue = nix_alloc_value(ctx, state);
|
||||
nix_value * intValue = nix_alloc_value(ctx, state);
|
||||
nix_init_int(ctx, intValue, 42);
|
||||
|
||||
Value * stringValue = nix_alloc_value(ctx, state);
|
||||
nix_value * stringValue = nix_alloc_value(ctx, state);
|
||||
nix_init_string(ctx, stringValue, "foo");
|
||||
|
||||
nix_bindings_builder_insert(ctx, builder, "a", intValue);
|
||||
|
@ -207,7 +217,7 @@ TEST_F(nix_api_expr_test, nix_build_and_init_attr)
|
|||
|
||||
ASSERT_EQ(2, nix_get_attrs_size(ctx, value));
|
||||
|
||||
Value * out_value = nix_get_attr_byname(ctx, value, state, "a");
|
||||
nix_value * out_value = nix_get_attr_byname(ctx, value, state, "a");
|
||||
ASSERT_EQ(42, nix_get_int(ctx, out_value));
|
||||
nix_gc_decref(ctx, out_value);
|
||||
|
||||
|
@ -251,10 +261,10 @@ TEST_F(nix_api_expr_test, nix_value_init)
|
|||
// two = 2;
|
||||
// f = a: a * a;
|
||||
|
||||
Value * two = nix_alloc_value(ctx, state);
|
||||
nix_value * two = nix_alloc_value(ctx, state);
|
||||
nix_init_int(ctx, two, 2);
|
||||
|
||||
Value * f = nix_alloc_value(ctx, state);
|
||||
nix_value * f = nix_alloc_value(ctx, state);
|
||||
nix_expr_eval_from_string(
|
||||
ctx,
|
||||
state,
|
||||
|
@ -268,7 +278,7 @@ TEST_F(nix_api_expr_test, nix_value_init)
|
|||
|
||||
// r = f two;
|
||||
|
||||
Value * r = nix_alloc_value(ctx, state);
|
||||
nix_value * r = nix_alloc_value(ctx, state);
|
||||
nix_init_apply(ctx, r, f, two);
|
||||
assert_ctx_ok();
|
||||
|
||||
|
@ -297,11 +307,11 @@ TEST_F(nix_api_expr_test, nix_value_init)
|
|||
|
||||
TEST_F(nix_api_expr_test, nix_value_init_apply_error)
|
||||
{
|
||||
Value * some_string = nix_alloc_value(ctx, state);
|
||||
nix_value * some_string = nix_alloc_value(ctx, state);
|
||||
nix_init_string(ctx, some_string, "some string");
|
||||
assert_ctx_ok();
|
||||
|
||||
Value * v = nix_alloc_value(ctx, state);
|
||||
nix_value * v = nix_alloc_value(ctx, state);
|
||||
nix_init_apply(ctx, v, some_string, some_string);
|
||||
assert_ctx_ok();
|
||||
|
||||
|
@ -326,7 +336,7 @@ TEST_F(nix_api_expr_test, nix_value_init_apply_lazy_arg)
|
|||
// r = f e
|
||||
// r should not throw an exception, because e is not evaluated
|
||||
|
||||
Value * f = nix_alloc_value(ctx, state);
|
||||
nix_value * f = nix_alloc_value(ctx, state);
|
||||
nix_expr_eval_from_string(
|
||||
ctx,
|
||||
state,
|
||||
|
@ -337,9 +347,9 @@ TEST_F(nix_api_expr_test, nix_value_init_apply_lazy_arg)
|
|||
f);
|
||||
assert_ctx_ok();
|
||||
|
||||
Value * e = nix_alloc_value(ctx, state);
|
||||
nix_value * e = nix_alloc_value(ctx, state);
|
||||
{
|
||||
Value * g = nix_alloc_value(ctx, state);
|
||||
nix_value * g = nix_alloc_value(ctx, state);
|
||||
nix_expr_eval_from_string(
|
||||
ctx,
|
||||
state,
|
||||
|
@ -355,7 +365,7 @@ TEST_F(nix_api_expr_test, nix_value_init_apply_lazy_arg)
|
|||
nix_gc_decref(ctx, g);
|
||||
}
|
||||
|
||||
Value * r = nix_alloc_value(ctx, state);
|
||||
nix_value * r = nix_alloc_value(ctx, state);
|
||||
nix_init_apply(ctx, r, f, e);
|
||||
assert_ctx_ok();
|
||||
|
||||
|
@ -367,7 +377,7 @@ TEST_F(nix_api_expr_test, nix_value_init_apply_lazy_arg)
|
|||
ASSERT_EQ(1, n);
|
||||
|
||||
// nix_get_attr_byname isn't lazy (it could have been) so it will throw the exception
|
||||
Value * foo = nix_get_attr_byname(ctx, r, state, "foo");
|
||||
nix_value * foo = nix_get_attr_byname(ctx, r, state, "foo");
|
||||
ASSERT_EQ(nullptr, foo);
|
||||
ASSERT_THAT(ctx->last_err.value(), testing::HasSubstr("error message for test case nix_value_init_apply_lazy_arg"));
|
||||
|
||||
|
@ -378,7 +388,7 @@ TEST_F(nix_api_expr_test, nix_value_init_apply_lazy_arg)
|
|||
|
||||
TEST_F(nix_api_expr_test, nix_copy_value)
|
||||
{
|
||||
Value * source = nix_alloc_value(ctx, state);
|
||||
nix_value * source = nix_alloc_value(ctx, state);
|
||||
|
||||
nix_init_int(ctx, source, 42);
|
||||
nix_copy_value(ctx, value, source);
|
||||
|
|
99
tests/unit/libexpr/package.nix
Normal file
99
tests/unit/libexpr/package.nix
Normal file
|
@ -0,0 +1,99 @@
|
|||
{ lib
|
||||
, stdenv
|
||||
, mkMesonDerivation
|
||||
, releaseTools
|
||||
|
||||
, meson
|
||||
, ninja
|
||||
, pkg-config
|
||||
|
||||
, nix-expr
|
||||
, nix-expr-c
|
||||
, nix-expr-test-support
|
||||
|
||||
, rapidcheck
|
||||
, gtest
|
||||
, runCommand
|
||||
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
, resolvePath
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) fileset;
|
||||
in
|
||||
|
||||
mkMesonDerivation (finalAttrs: {
|
||||
pname = "nix-expr-tests";
|
||||
inherit version;
|
||||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../../.version
|
||||
./.version
|
||||
./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-expr
|
||||
nix-expr-c
|
||||
nix-expr-test-support
|
||||
rapidcheck
|
||||
gtest
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
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;
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||
|
||||
passthru = {
|
||||
tests = {
|
||||
run = runCommand "${finalAttrs.pname}-run" {
|
||||
} ''
|
||||
PATH="${lib.makeBinPath [ finalAttrs.finalPackage ]}:$PATH"
|
||||
export _NIX_TEST_UNIT_DATA=${resolvePath ./data}
|
||||
nix-expr-tests
|
||||
touch $out
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
};
|
||||
|
||||
})
|
1
tests/unit/libfetchers/.version
Symbolic link
1
tests/unit/libfetchers/.version
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../.version
|
1
tests/unit/libfetchers/build-utils-meson
Symbolic link
1
tests/unit/libfetchers/build-utils-meson
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../build-utils-meson/
|
|
@ -4,7 +4,7 @@ programs += libfetchers-tests
|
|||
|
||||
libfetchers-tests_NAME = libnixfetchers-tests
|
||||
|
||||
libfetchers-tests_ENV := _NIX_TEST_UNIT_DATA=$(d)/data
|
||||
libfetchers-tests_ENV := _NIX_TEST_UNIT_DATA=$(d)/data GTEST_OUTPUT=xml:$$testresults/libfetchers-tests.xml
|
||||
|
||||
libfetchers-tests_DIR := $(d)
|
||||
|
||||
|
|
71
tests/unit/libfetchers/meson.build
Normal file
71
tests/unit/libfetchers/meson.build
Normal file
|
@ -0,0 +1,71 @@
|
|||
project('nix-fetchers-tests', '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')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
|
||||
deps_private_maybe_subproject = [
|
||||
dependency('nix-store-test-support'),
|
||||
dependency('nix-fetchers'),
|
||||
]
|
||||
deps_public_maybe_subproject = [
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
|
||||
rapidcheck = dependency('rapidcheck')
|
||||
deps_private += rapidcheck
|
||||
|
||||
gtest = dependency('gtest', main : true)
|
||||
deps_private += gtest
|
||||
|
||||
add_project_arguments(
|
||||
# TODO(Qyriad): Yes this is how the autoconf+Make system did it.
|
||||
# It would be nice for our headers to be idempotent instead.
|
||||
'-include', 'config-util.hh',
|
||||
'-include', 'config-store.hh',
|
||||
# '-include', 'config-fetchers.h',
|
||||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/diagnostics')
|
||||
|
||||
sources = files(
|
||||
'public-key.cc',
|
||||
)
|
||||
|
||||
include_dirs = [include_directories('.')]
|
||||
|
||||
|
||||
this_exe = executable(
|
||||
meson.project_name(),
|
||||
sources,
|
||||
dependencies : deps_private_subproject + deps_private + deps_other,
|
||||
include_directories : include_dirs,
|
||||
# TODO: -lrapidcheck, see ../libutil-support/build.meson
|
||||
link_args: linker_export_flags + ['-lrapidcheck'],
|
||||
# get main from gtest
|
||||
install : true,
|
||||
)
|
||||
|
||||
test(
|
||||
meson.project_name(),
|
||||
this_exe,
|
||||
env : {
|
||||
'_NIX_TEST_UNIT_DATA': meson.current_source_dir() / 'data',
|
||||
},
|
||||
protocol : 'gtest',
|
||||
)
|
97
tests/unit/libfetchers/package.nix
Normal file
97
tests/unit/libfetchers/package.nix
Normal file
|
@ -0,0 +1,97 @@
|
|||
{ lib
|
||||
, stdenv
|
||||
, mkMesonDerivation
|
||||
, releaseTools
|
||||
|
||||
, meson
|
||||
, ninja
|
||||
, pkg-config
|
||||
|
||||
, nix-fetchers
|
||||
, nix-store-test-support
|
||||
|
||||
, rapidcheck
|
||||
, gtest
|
||||
, runCommand
|
||||
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
, resolvePath
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) fileset;
|
||||
in
|
||||
|
||||
mkMesonDerivation (finalAttrs: {
|
||||
pname = "nix-fetchers-tests";
|
||||
inherit version;
|
||||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../../.version
|
||||
./.version
|
||||
./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-fetchers
|
||||
nix-store-test-support
|
||||
rapidcheck
|
||||
gtest
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
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;
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||
|
||||
passthru = {
|
||||
tests = {
|
||||
run = runCommand "${finalAttrs.pname}-run" {
|
||||
} ''
|
||||
PATH="${lib.makeBinPath [ finalAttrs.finalPackage ]}:$PATH"
|
||||
export _NIX_TEST_UNIT_DATA=${resolvePath ./data}
|
||||
nix-fetchers-tests
|
||||
touch $out
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
};
|
||||
|
||||
})
|
1
tests/unit/libflake/.version
Symbolic link
1
tests/unit/libflake/.version
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../.version
|
1
tests/unit/libflake/build-utils-meson
Symbolic link
1
tests/unit/libflake/build-utils-meson
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../build-utils-meson/
|
0
tests/unit/libflake/data/.gitkeep
Normal file
0
tests/unit/libflake/data/.gitkeep
Normal file
43
tests/unit/libflake/local.mk
Normal file
43
tests/unit/libflake/local.mk
Normal file
|
@ -0,0 +1,43 @@
|
|||
check: libflake-tests_RUN
|
||||
|
||||
programs += libflake-tests
|
||||
|
||||
libflake-tests_NAME := libnixflake-tests
|
||||
|
||||
libflake-tests_ENV := _NIX_TEST_UNIT_DATA=$(d)/data GTEST_OUTPUT=xml:$$testresults/libflake-tests.xml
|
||||
|
||||
libflake-tests_DIR := $(d)
|
||||
|
||||
ifeq ($(INSTALL_UNIT_TESTS), yes)
|
||||
libflake-tests_INSTALL_DIR := $(checkbindir)
|
||||
else
|
||||
libflake-tests_INSTALL_DIR :=
|
||||
endif
|
||||
|
||||
libflake-tests_SOURCES := \
|
||||
$(wildcard $(d)/*.cc) \
|
||||
$(wildcard $(d)/value/*.cc) \
|
||||
$(wildcard $(d)/flake/*.cc)
|
||||
|
||||
libflake-tests_EXTRA_INCLUDES = \
|
||||
-I tests/unit/libflake-support \
|
||||
-I tests/unit/libstore-support \
|
||||
-I tests/unit/libutil-support \
|
||||
$(INCLUDE_libflake) \
|
||||
$(INCLUDE_libexpr) \
|
||||
$(INCLUDE_libfetchers) \
|
||||
$(INCLUDE_libstore) \
|
||||
$(INCLUDE_libutil) \
|
||||
|
||||
libflake-tests_CXXFLAGS += $(libflake-tests_EXTRA_INCLUDES)
|
||||
|
||||
libflake-tests_LIBS = \
|
||||
libexpr-test-support libstore-test-support libutil-test-support \
|
||||
libflake libexpr libfetchers libstore libutil
|
||||
|
||||
libflake-tests_LDFLAGS := -lrapidcheck $(GTEST_LIBS) -lgmock
|
||||
|
||||
ifdef HOST_WINDOWS
|
||||
# Increase the default reserved stack size to 65 MB so Nix doesn't run out of space
|
||||
libflake-tests_LDFLAGS += -Wl,--stack,$(shell echo $$((65 * 1024 * 1024)))
|
||||
endif
|
72
tests/unit/libflake/meson.build
Normal file
72
tests/unit/libflake/meson.build
Normal file
|
@ -0,0 +1,72 @@
|
|||
project('nix-flake-tests', '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')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
|
||||
deps_private_maybe_subproject = [
|
||||
dependency('nix-expr-test-support'),
|
||||
dependency('nix-flake'),
|
||||
]
|
||||
deps_public_maybe_subproject = [
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
|
||||
rapidcheck = dependency('rapidcheck')
|
||||
deps_private += rapidcheck
|
||||
|
||||
gtest = dependency('gtest', main : true)
|
||||
deps_private += gtest
|
||||
|
||||
add_project_arguments(
|
||||
# TODO(Qyriad): Yes this is how the autoconf+Make system did it.
|
||||
# It would be nice for our headers to be idempotent instead.
|
||||
'-include', 'config-util.hh',
|
||||
'-include', 'config-store.hh',
|
||||
'-include', 'config-expr.hh',
|
||||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/diagnostics')
|
||||
|
||||
sources = files(
|
||||
'flakeref.cc',
|
||||
'url-name.cc',
|
||||
)
|
||||
|
||||
include_dirs = [include_directories('.')]
|
||||
|
||||
|
||||
this_exe = executable(
|
||||
meson.project_name(),
|
||||
sources,
|
||||
dependencies : deps_private_subproject + deps_private + deps_other,
|
||||
include_directories : include_dirs,
|
||||
# TODO: -lrapidcheck, see ../libutil-support/build.meson
|
||||
link_args: linker_export_flags + ['-lrapidcheck'],
|
||||
# get main from gtest
|
||||
install : true,
|
||||
)
|
||||
|
||||
test(
|
||||
meson.project_name(),
|
||||
this_exe,
|
||||
env : {
|
||||
'_NIX_TEST_UNIT_DATA': meson.current_source_dir() / 'data',
|
||||
},
|
||||
protocol : 'gtest',
|
||||
)
|
97
tests/unit/libflake/package.nix
Normal file
97
tests/unit/libflake/package.nix
Normal file
|
@ -0,0 +1,97 @@
|
|||
{ lib
|
||||
, stdenv
|
||||
, mkMesonDerivation
|
||||
, releaseTools
|
||||
|
||||
, meson
|
||||
, ninja
|
||||
, pkg-config
|
||||
|
||||
, nix-flake
|
||||
, nix-expr-test-support
|
||||
|
||||
, rapidcheck
|
||||
, gtest
|
||||
, runCommand
|
||||
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
, resolvePath
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) fileset;
|
||||
in
|
||||
|
||||
mkMesonDerivation (finalAttrs: {
|
||||
pname = "nix-flake-tests";
|
||||
inherit version;
|
||||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../../.version
|
||||
./.version
|
||||
./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-flake
|
||||
nix-expr-test-support
|
||||
rapidcheck
|
||||
gtest
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
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;
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||
|
||||
passthru = {
|
||||
tests = {
|
||||
run = runCommand "${finalAttrs.pname}-run" {
|
||||
} ''
|
||||
PATH="${lib.makeBinPath [ finalAttrs.finalPackage ]}:$PATH"
|
||||
export _NIX_TEST_UNIT_DATA=${resolvePath ./data}
|
||||
nix-flake-tests
|
||||
touch $out
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
};
|
||||
|
||||
})
|
1
tests/unit/libstore-support/.version
Symbolic link
1
tests/unit/libstore-support/.version
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../.version
|
1
tests/unit/libstore-support/build-utils-meson
Symbolic link
1
tests/unit/libstore-support/build-utils-meson
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../build-utils-meson/
|
76
tests/unit/libstore-support/meson.build
Normal file
76
tests/unit/libstore-support/meson.build
Normal file
|
@ -0,0 +1,76 @@
|
|||
project('nix-store-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')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
|
||||
deps_private_maybe_subproject = [
|
||||
]
|
||||
deps_public_maybe_subproject = [
|
||||
dependency('nix-util'),
|
||||
dependency('nix-util-test-support'),
|
||||
dependency('nix-store'),
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
|
||||
rapidcheck = dependency('rapidcheck')
|
||||
deps_public += rapidcheck
|
||||
|
||||
add_project_arguments(
|
||||
# TODO(Qyriad): Yes this is how the autoconf+Make system did it.
|
||||
# It would be nice for our headers to be idempotent instead.
|
||||
'-include', 'config-util.hh',
|
||||
'-include', 'config-store.hh',
|
||||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/diagnostics')
|
||||
|
||||
sources = files(
|
||||
'tests/derived-path.cc',
|
||||
'tests/outputs-spec.cc',
|
||||
'tests/path.cc',
|
||||
)
|
||||
|
||||
include_dirs = [include_directories('.')]
|
||||
|
||||
headers = files(
|
||||
'tests/derived-path.hh',
|
||||
'tests/libstore.hh',
|
||||
'tests/nix_api_store.hh',
|
||||
'tests/outputs-spec.hh',
|
||||
'tests/path.hh',
|
||||
'tests/protocol.hh',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
|
||||
this_library = library(
|
||||
'nix-store-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'],
|
||||
prelink : true, # For C++ static initializers
|
||||
install : true,
|
||||
)
|
||||
|
||||
install_headers(headers, subdir : 'nix', preserve_path : true)
|
||||
|
||||
libraries_private = []
|
||||
|
||||
subdir('build-utils-meson/export')
|
81
tests/unit/libstore-support/package.nix
Normal file
81
tests/unit/libstore-support/package.nix
Normal file
|
@ -0,0 +1,81 @@
|
|||
{ lib
|
||||
, stdenv
|
||||
, mkMesonDerivation
|
||||
, releaseTools
|
||||
|
||||
, meson
|
||||
, ninja
|
||||
, pkg-config
|
||||
|
||||
, nix-util-test-support
|
||||
, nix-store
|
||||
|
||||
, rapidcheck
|
||||
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) fileset;
|
||||
in
|
||||
|
||||
mkMesonDerivation (finalAttrs: {
|
||||
pname = "nix-store-test-support";
|
||||
inherit version;
|
||||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../../.version
|
||||
./.version
|
||||
./meson.build
|
||||
# ./meson.options
|
||||
(fileset.fileFilter (file: file.hasExt "cc") ./.)
|
||||
(fileset.fileFilter (file: file.hasExt "hh") ./.)
|
||||
];
|
||||
|
||||
outputs = [ "out" "dev" ];
|
||||
|
||||
nativeBuildInputs = [
|
||||
meson
|
||||
ninja
|
||||
pkg-config
|
||||
];
|
||||
|
||||
propagatedBuildInputs = [
|
||||
nix-util-test-support
|
||||
nix-store
|
||||
rapidcheck
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
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;
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
};
|
||||
|
||||
})
|
|
@ -8,19 +8,27 @@
|
|||
|
||||
namespace nix {
|
||||
|
||||
class LibStoreTest : public virtual ::testing::Test {
|
||||
public:
|
||||
static void SetUpTestSuite() {
|
||||
initLibStore(false);
|
||||
}
|
||||
class LibStoreTest : public virtual ::testing::Test
|
||||
{
|
||||
public:
|
||||
static void SetUpTestSuite()
|
||||
{
|
||||
initLibStore(false);
|
||||
}
|
||||
|
||||
protected:
|
||||
LibStoreTest()
|
||||
: store(openStore("dummy://"))
|
||||
{ }
|
||||
protected:
|
||||
LibStoreTest()
|
||||
: store(openStore({
|
||||
.variant =
|
||||
StoreReference::Specified{
|
||||
.scheme = "dummy",
|
||||
},
|
||||
.params = {},
|
||||
}))
|
||||
{
|
||||
}
|
||||
|
||||
ref<Store> store;
|
||||
ref<Store> store;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace nix */
|
||||
|
|
1
tests/unit/libstore/.version
Symbolic link
1
tests/unit/libstore/.version
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../.version
|
1
tests/unit/libstore/build-utils-meson
Symbolic link
1
tests/unit/libstore/build-utils-meson
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../build-utils-meson/
|
|
@ -83,15 +83,15 @@ CHARACTERIZATION_TEST(
|
|||
"content-address",
|
||||
(std::tuple<ContentAddress, ContentAddress, ContentAddress> {
|
||||
ContentAddress {
|
||||
.method = TextIngestionMethod {},
|
||||
.method = ContentAddressMethod::Raw::Text,
|
||||
.hash = hashString(HashAlgorithm::SHA256, "Derive(...)"),
|
||||
},
|
||||
ContentAddress {
|
||||
.method = FileIngestionMethod::Flat,
|
||||
.method = ContentAddressMethod::Raw::Flat,
|
||||
.hash = hashString(HashAlgorithm::SHA1, "blob blob..."),
|
||||
},
|
||||
ContentAddress {
|
||||
.method = FileIngestionMethod::Recursive,
|
||||
.method = ContentAddressMethod::Raw::NixArchive,
|
||||
.hash = hashString(HashAlgorithm::SHA256, "(...)"),
|
||||
},
|
||||
}))
|
||||
|
@ -178,7 +178,7 @@ CHARACTERIZATION_TEST(
|
|||
std::nullopt,
|
||||
std::optional {
|
||||
ContentAddress {
|
||||
.method = FileIngestionMethod::Flat,
|
||||
.method = ContentAddressMethod::Raw::Flat,
|
||||
.hash = hashString(HashAlgorithm::SHA1, "blob blob..."),
|
||||
},
|
||||
},
|
||||
|
|
|
@ -9,11 +9,11 @@ namespace nix {
|
|||
* --------------------------------------------------------------------------*/
|
||||
|
||||
TEST(ContentAddressMethod, testRoundTripPrintParse_1) {
|
||||
for (const ContentAddressMethod & cam : {
|
||||
ContentAddressMethod { TextIngestionMethod {} },
|
||||
ContentAddressMethod { FileIngestionMethod::Flat },
|
||||
ContentAddressMethod { FileIngestionMethod::Recursive },
|
||||
ContentAddressMethod { FileIngestionMethod::Git },
|
||||
for (ContentAddressMethod cam : {
|
||||
ContentAddressMethod::Raw::Text,
|
||||
ContentAddressMethod::Raw::Flat,
|
||||
ContentAddressMethod::Raw::NixArchive,
|
||||
ContentAddressMethod::Raw::Git,
|
||||
}) {
|
||||
EXPECT_EQ(ContentAddressMethod::parse(cam.render()), cam);
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
../../../../functional/derivation/advanced-attributes-defaults.drv
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"args": [
|
||||
"-c",
|
||||
"echo hello > $out"
|
||||
],
|
||||
"builder": "/bin/bash",
|
||||
"env": {
|
||||
"builder": "/bin/bash",
|
||||
"name": "advanced-attributes-defaults",
|
||||
"out": "/nix/store/1qsc7svv43m4dw2prh6mvyf7cai5czji-advanced-attributes-defaults",
|
||||
"system": "my-system"
|
||||
},
|
||||
"inputDrvs": {},
|
||||
"inputSrcs": [],
|
||||
"name": "advanced-attributes-defaults",
|
||||
"outputs": {
|
||||
"out": {
|
||||
"path": "/nix/store/1qsc7svv43m4dw2prh6mvyf7cai5czji-advanced-attributes-defaults"
|
||||
}
|
||||
},
|
||||
"system": "my-system"
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
../../../../functional/derivation/advanced-attributes-structured-attrs-defaults.drv
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"args": [
|
||||
"-c",
|
||||
"echo hello > $out"
|
||||
],
|
||||
"builder": "/bin/bash",
|
||||
"env": {
|
||||
"__json": "{\"builder\":\"/bin/bash\",\"name\":\"advanced-attributes-structured-attrs-defaults\",\"outputs\":[\"out\",\"dev\"],\"system\":\"my-system\"}",
|
||||
"dev": "/nix/store/8bazivnbipbyi569623skw5zm91z6kc2-advanced-attributes-structured-attrs-defaults-dev",
|
||||
"out": "/nix/store/f8f8nvnx32bxvyxyx2ff7akbvwhwd9dw-advanced-attributes-structured-attrs-defaults"
|
||||
},
|
||||
"inputDrvs": {},
|
||||
"inputSrcs": [],
|
||||
"name": "advanced-attributes-structured-attrs-defaults",
|
||||
"outputs": {
|
||||
"dev": {
|
||||
"path": "/nix/store/8bazivnbipbyi569623skw5zm91z6kc2-advanced-attributes-structured-attrs-defaults-dev"
|
||||
},
|
||||
"out": {
|
||||
"path": "/nix/store/f8f8nvnx32bxvyxyx2ff7akbvwhwd9dw-advanced-attributes-structured-attrs-defaults"
|
||||
}
|
||||
},
|
||||
"system": "my-system"
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
../../../../functional/derivation/advanced-attributes-structured-attrs.drv
|
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"args": [
|
||||
"-c",
|
||||
"echo hello > $out"
|
||||
],
|
||||
"builder": "/bin/bash",
|
||||
"env": {
|
||||
"__json": "{\"__darwinAllowLocalNetworking\":true,\"__impureHostDeps\":[\"/usr/bin/ditto\"],\"__noChroot\":true,\"__sandboxProfile\":\"sandcastle\",\"allowSubstitutes\":false,\"builder\":\"/bin/bash\",\"impureEnvVars\":[\"UNICORN\"],\"name\":\"advanced-attributes-structured-attrs\",\"outputChecks\":{\"bin\":{\"disallowedReferences\":[\"/nix/store/7rhsm8i393hm1wcsmph782awg1hi2f7x-bar\"],\"disallowedRequisites\":[\"/nix/store/7rhsm8i393hm1wcsmph782awg1hi2f7x-bar\"]},\"dev\":{\"maxClosureSize\":5909,\"maxSize\":789},\"out\":{\"allowedReferences\":[\"/nix/store/3c08bzb71z4wiag719ipjxr277653ynp-foo\"],\"allowedRequisites\":[\"/nix/store/3c08bzb71z4wiag719ipjxr277653ynp-foo\"]}},\"outputs\":[\"out\",\"bin\",\"dev\"],\"preferLocalBuild\":true,\"requiredSystemFeatures\":[\"rainbow\",\"uid-range\"],\"system\":\"my-system\"}",
|
||||
"bin": "/nix/store/pbzb48v0ycf80jgligcp4n8z0rblna4n-advanced-attributes-structured-attrs-bin",
|
||||
"dev": "/nix/store/7xapi8jv7flcz1qq8jhw55ar8ag8hldh-advanced-attributes-structured-attrs-dev",
|
||||
"out": "/nix/store/mpq3l1l1qc2yr50q520g08kprprwv79f-advanced-attributes-structured-attrs"
|
||||
},
|
||||
"inputDrvs": {
|
||||
"/nix/store/4xm4wccqsvagz9gjksn24s7rip2fdy7v-foo.drv": {
|
||||
"dynamicOutputs": {},
|
||||
"outputs": [
|
||||
"out"
|
||||
]
|
||||
},
|
||||
"/nix/store/plsq5jbr5nhgqwcgb2qxw7jchc09dnl8-bar.drv": {
|
||||
"dynamicOutputs": {},
|
||||
"outputs": [
|
||||
"out"
|
||||
]
|
||||
}
|
||||
},
|
||||
"inputSrcs": [],
|
||||
"name": "advanced-attributes-structured-attrs",
|
||||
"outputs": {
|
||||
"bin": {
|
||||
"path": "/nix/store/pbzb48v0ycf80jgligcp4n8z0rblna4n-advanced-attributes-structured-attrs-bin"
|
||||
},
|
||||
"dev": {
|
||||
"path": "/nix/store/7xapi8jv7flcz1qq8jhw55ar8ag8hldh-advanced-attributes-structured-attrs-dev"
|
||||
},
|
||||
"out": {
|
||||
"path": "/nix/store/mpq3l1l1qc2yr50q520g08kprprwv79f-advanced-attributes-structured-attrs"
|
||||
}
|
||||
},
|
||||
"system": "my-system"
|
||||
}
|
1
tests/unit/libstore/data/derivation/advanced-attributes.drv
Symbolic link
1
tests/unit/libstore/data/derivation/advanced-attributes.drv
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../../functional/derivation/advanced-attributes.drv
|
234
tests/unit/libstore/derivation-advanced-attrs.cc
Normal file
234
tests/unit/libstore/derivation-advanced-attrs.cc
Normal file
|
@ -0,0 +1,234 @@
|
|||
#include <nlohmann/json.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
#include <optional>
|
||||
|
||||
#include "experimental-features.hh"
|
||||
#include "derivations.hh"
|
||||
|
||||
#include "tests/libstore.hh"
|
||||
#include "tests/characterization.hh"
|
||||
#include "parsed-derivations.hh"
|
||||
#include "types.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
using nlohmann::json;
|
||||
|
||||
class DerivationAdvancedAttrsTest : public CharacterizationTest, public LibStoreTest
|
||||
{
|
||||
Path unitTestData = getUnitTestData() + "/derivation";
|
||||
|
||||
public:
|
||||
Path goldenMaster(std::string_view testStem) const override
|
||||
{
|
||||
return unitTestData + "/" + testStem;
|
||||
}
|
||||
};
|
||||
|
||||
#define TEST_ATERM_JSON(STEM, NAME) \
|
||||
TEST_F(DerivationAdvancedAttrsTest, Derivation_##STEM##_from_json) \
|
||||
{ \
|
||||
readTest(NAME ".json", [&](const auto & encoded_) { \
|
||||
auto encoded = json::parse(encoded_); \
|
||||
/* Use DRV file instead of C++ literal as source of truth. */ \
|
||||
auto aterm = readFile(goldenMaster(NAME ".drv")); \
|
||||
auto expected = parseDerivation(*store, std::move(aterm), NAME); \
|
||||
Derivation got = Derivation::fromJSON(*store, encoded); \
|
||||
EXPECT_EQ(got, expected); \
|
||||
}); \
|
||||
} \
|
||||
\
|
||||
TEST_F(DerivationAdvancedAttrsTest, Derivation_##STEM##_to_json) \
|
||||
{ \
|
||||
writeTest( \
|
||||
NAME ".json", \
|
||||
[&]() -> json { \
|
||||
/* Use DRV file instead of C++ literal as source of truth. */ \
|
||||
auto aterm = readFile(goldenMaster(NAME ".drv")); \
|
||||
return parseDerivation(*store, std::move(aterm), NAME).toJSON(*store); \
|
||||
}, \
|
||||
[](const auto & file) { return json::parse(readFile(file)); }, \
|
||||
[](const auto & file, const auto & got) { return writeFile(file, got.dump(2) + "\n"); }); \
|
||||
} \
|
||||
\
|
||||
TEST_F(DerivationAdvancedAttrsTest, Derivation_##STEM##_from_aterm) \
|
||||
{ \
|
||||
readTest(NAME ".drv", [&](auto encoded) { \
|
||||
/* Use JSON file instead of C++ literal as source of truth. */ \
|
||||
auto json = json::parse(readFile(goldenMaster(NAME ".json"))); \
|
||||
auto expected = Derivation::fromJSON(*store, json); \
|
||||
auto got = parseDerivation(*store, std::move(encoded), NAME); \
|
||||
EXPECT_EQ(got.toJSON(*store), expected.toJSON(*store)); \
|
||||
EXPECT_EQ(got, expected); \
|
||||
}); \
|
||||
} \
|
||||
\
|
||||
/* No corresponding write test, because we need to read the drv to write the json file */
|
||||
|
||||
TEST_ATERM_JSON(advancedAttributes_defaults, "advanced-attributes-defaults");
|
||||
TEST_ATERM_JSON(advancedAttributes, "advanced-attributes-defaults");
|
||||
TEST_ATERM_JSON(advancedAttributes_structuredAttrs_defaults, "advanced-attributes-structured-attrs");
|
||||
TEST_ATERM_JSON(advancedAttributes_structuredAttrs, "advanced-attributes-structured-attrs-defaults");
|
||||
|
||||
#undef TEST_ATERM_JSON
|
||||
|
||||
TEST_F(DerivationAdvancedAttrsTest, Derivation_advancedAttributes_defaults)
|
||||
{
|
||||
readTest("advanced-attributes-defaults.drv", [&](auto encoded) {
|
||||
auto got = parseDerivation(*store, std::move(encoded), "foo");
|
||||
|
||||
auto drvPath = writeDerivation(*store, got, NoRepair, true);
|
||||
|
||||
ParsedDerivation parsedDrv(drvPath, got);
|
||||
|
||||
EXPECT_EQ(parsedDrv.getStringAttr("__sandboxProfile").value_or(""), "");
|
||||
EXPECT_EQ(parsedDrv.getBoolAttr("__noChroot"), false);
|
||||
EXPECT_EQ(parsedDrv.getStringsAttr("__impureHostDeps").value_or(Strings()), Strings());
|
||||
EXPECT_EQ(parsedDrv.getStringsAttr("impureEnvVars").value_or(Strings()), Strings());
|
||||
EXPECT_EQ(parsedDrv.getBoolAttr("__darwinAllowLocalNetworking"), false);
|
||||
EXPECT_EQ(parsedDrv.getStringsAttr("allowedReferences"), std::nullopt);
|
||||
EXPECT_EQ(parsedDrv.getStringsAttr("allowedRequisites"), std::nullopt);
|
||||
EXPECT_EQ(parsedDrv.getStringsAttr("disallowedReferences"), std::nullopt);
|
||||
EXPECT_EQ(parsedDrv.getStringsAttr("disallowedRequisites"), std::nullopt);
|
||||
EXPECT_EQ(parsedDrv.getRequiredSystemFeatures(), StringSet());
|
||||
EXPECT_EQ(parsedDrv.canBuildLocally(*store), false);
|
||||
EXPECT_EQ(parsedDrv.willBuildLocally(*store), false);
|
||||
EXPECT_EQ(parsedDrv.substitutesAllowed(), true);
|
||||
EXPECT_EQ(parsedDrv.useUidRange(), false);
|
||||
});
|
||||
};
|
||||
|
||||
TEST_F(DerivationAdvancedAttrsTest, Derivation_advancedAttributes)
|
||||
{
|
||||
readTest("advanced-attributes.drv", [&](auto encoded) {
|
||||
auto got = parseDerivation(*store, std::move(encoded), "foo");
|
||||
|
||||
auto drvPath = writeDerivation(*store, got, NoRepair, true);
|
||||
|
||||
ParsedDerivation parsedDrv(drvPath, got);
|
||||
|
||||
StringSet systemFeatures{"rainbow", "uid-range"};
|
||||
|
||||
EXPECT_EQ(parsedDrv.getStringAttr("__sandboxProfile").value_or(""), "sandcastle");
|
||||
EXPECT_EQ(parsedDrv.getBoolAttr("__noChroot"), true);
|
||||
EXPECT_EQ(parsedDrv.getStringsAttr("__impureHostDeps").value_or(Strings()), Strings{"/usr/bin/ditto"});
|
||||
EXPECT_EQ(parsedDrv.getStringsAttr("impureEnvVars").value_or(Strings()), Strings{"UNICORN"});
|
||||
EXPECT_EQ(parsedDrv.getBoolAttr("__darwinAllowLocalNetworking"), true);
|
||||
EXPECT_EQ(
|
||||
parsedDrv.getStringsAttr("allowedReferences"), Strings{"/nix/store/3c08bzb71z4wiag719ipjxr277653ynp-foo"});
|
||||
EXPECT_EQ(
|
||||
parsedDrv.getStringsAttr("allowedRequisites"), Strings{"/nix/store/3c08bzb71z4wiag719ipjxr277653ynp-foo"});
|
||||
EXPECT_EQ(
|
||||
parsedDrv.getStringsAttr("disallowedReferences"),
|
||||
Strings{"/nix/store/7rhsm8i393hm1wcsmph782awg1hi2f7x-bar"});
|
||||
EXPECT_EQ(
|
||||
parsedDrv.getStringsAttr("disallowedRequisites"),
|
||||
Strings{"/nix/store/7rhsm8i393hm1wcsmph782awg1hi2f7x-bar"});
|
||||
EXPECT_EQ(parsedDrv.getRequiredSystemFeatures(), systemFeatures);
|
||||
EXPECT_EQ(parsedDrv.canBuildLocally(*store), false);
|
||||
EXPECT_EQ(parsedDrv.willBuildLocally(*store), false);
|
||||
EXPECT_EQ(parsedDrv.substitutesAllowed(), false);
|
||||
EXPECT_EQ(parsedDrv.useUidRange(), true);
|
||||
});
|
||||
};
|
||||
|
||||
TEST_F(DerivationAdvancedAttrsTest, Derivation_advancedAttributes_structuredAttrs_defaults)
|
||||
{
|
||||
readTest("advanced-attributes-structured-attrs-defaults.drv", [&](auto encoded) {
|
||||
auto got = parseDerivation(*store, std::move(encoded), "foo");
|
||||
|
||||
auto drvPath = writeDerivation(*store, got, NoRepair, true);
|
||||
|
||||
ParsedDerivation parsedDrv(drvPath, got);
|
||||
|
||||
EXPECT_EQ(parsedDrv.getStringAttr("__sandboxProfile").value_or(""), "");
|
||||
EXPECT_EQ(parsedDrv.getBoolAttr("__noChroot"), false);
|
||||
EXPECT_EQ(parsedDrv.getStringsAttr("__impureHostDeps").value_or(Strings()), Strings());
|
||||
EXPECT_EQ(parsedDrv.getStringsAttr("impureEnvVars").value_or(Strings()), Strings());
|
||||
EXPECT_EQ(parsedDrv.getBoolAttr("__darwinAllowLocalNetworking"), false);
|
||||
|
||||
{
|
||||
auto structuredAttrs_ = parsedDrv.getStructuredAttrs();
|
||||
ASSERT_TRUE(structuredAttrs_);
|
||||
auto & structuredAttrs = *structuredAttrs_;
|
||||
|
||||
auto outputChecks_ = get(structuredAttrs, "outputChecks");
|
||||
ASSERT_FALSE(outputChecks_);
|
||||
}
|
||||
|
||||
EXPECT_EQ(parsedDrv.getRequiredSystemFeatures(), StringSet());
|
||||
EXPECT_EQ(parsedDrv.canBuildLocally(*store), false);
|
||||
EXPECT_EQ(parsedDrv.willBuildLocally(*store), false);
|
||||
EXPECT_EQ(parsedDrv.substitutesAllowed(), true);
|
||||
EXPECT_EQ(parsedDrv.useUidRange(), false);
|
||||
});
|
||||
};
|
||||
|
||||
TEST_F(DerivationAdvancedAttrsTest, Derivation_advancedAttributes_structuredAttrs)
|
||||
{
|
||||
readTest("advanced-attributes-structured-attrs.drv", [&](auto encoded) {
|
||||
auto got = parseDerivation(*store, std::move(encoded), "foo");
|
||||
|
||||
auto drvPath = writeDerivation(*store, got, NoRepair, true);
|
||||
|
||||
ParsedDerivation parsedDrv(drvPath, got);
|
||||
|
||||
StringSet systemFeatures{"rainbow", "uid-range"};
|
||||
|
||||
EXPECT_EQ(parsedDrv.getStringAttr("__sandboxProfile").value_or(""), "sandcastle");
|
||||
EXPECT_EQ(parsedDrv.getBoolAttr("__noChroot"), true);
|
||||
EXPECT_EQ(parsedDrv.getStringsAttr("__impureHostDeps").value_or(Strings()), Strings{"/usr/bin/ditto"});
|
||||
EXPECT_EQ(parsedDrv.getStringsAttr("impureEnvVars").value_or(Strings()), Strings{"UNICORN"});
|
||||
EXPECT_EQ(parsedDrv.getBoolAttr("__darwinAllowLocalNetworking"), true);
|
||||
|
||||
{
|
||||
auto structuredAttrs_ = parsedDrv.getStructuredAttrs();
|
||||
ASSERT_TRUE(structuredAttrs_);
|
||||
auto & structuredAttrs = *structuredAttrs_;
|
||||
|
||||
auto outputChecks_ = get(structuredAttrs, "outputChecks");
|
||||
ASSERT_TRUE(outputChecks_);
|
||||
auto & outputChecks = *outputChecks_;
|
||||
|
||||
{
|
||||
auto output_ = get(outputChecks, "out");
|
||||
ASSERT_TRUE(output_);
|
||||
auto & output = *output_;
|
||||
EXPECT_EQ(
|
||||
get(output, "allowedReferences")->get<Strings>(),
|
||||
Strings{"/nix/store/3c08bzb71z4wiag719ipjxr277653ynp-foo"});
|
||||
EXPECT_EQ(
|
||||
get(output, "allowedRequisites")->get<Strings>(),
|
||||
Strings{"/nix/store/3c08bzb71z4wiag719ipjxr277653ynp-foo"});
|
||||
}
|
||||
|
||||
{
|
||||
auto output_ = get(outputChecks, "bin");
|
||||
ASSERT_TRUE(output_);
|
||||
auto & output = *output_;
|
||||
EXPECT_EQ(
|
||||
get(output, "disallowedReferences")->get<Strings>(),
|
||||
Strings{"/nix/store/7rhsm8i393hm1wcsmph782awg1hi2f7x-bar"});
|
||||
EXPECT_EQ(
|
||||
get(output, "disallowedRequisites")->get<Strings>(),
|
||||
Strings{"/nix/store/7rhsm8i393hm1wcsmph782awg1hi2f7x-bar"});
|
||||
}
|
||||
|
||||
{
|
||||
auto output_ = get(outputChecks, "dev");
|
||||
ASSERT_TRUE(output_);
|
||||
auto & output = *output_;
|
||||
EXPECT_EQ(get(output, "maxSize")->get<uint64_t>(), 789);
|
||||
EXPECT_EQ(get(output, "maxClosureSize")->get<uint64_t>(), 5909);
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_EQ(parsedDrv.getRequiredSystemFeatures(), systemFeatures);
|
||||
EXPECT_EQ(parsedDrv.canBuildLocally(*store), false);
|
||||
EXPECT_EQ(parsedDrv.willBuildLocally(*store), false);
|
||||
EXPECT_EQ(parsedDrv.substitutesAllowed(), false);
|
||||
EXPECT_EQ(parsedDrv.useUidRange(), true);
|
||||
});
|
||||
};
|
||||
|
||||
}
|
|
@ -108,7 +108,7 @@ TEST_JSON(DerivationTest, inputAddressed,
|
|||
TEST_JSON(DerivationTest, caFixedFlat,
|
||||
(DerivationOutput::CAFixed {
|
||||
.ca = {
|
||||
.method = FileIngestionMethod::Flat,
|
||||
.method = ContentAddressMethod::Raw::Flat,
|
||||
.hash = Hash::parseAnyPrefixed("sha256-iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="),
|
||||
},
|
||||
}),
|
||||
|
@ -117,7 +117,7 @@ TEST_JSON(DerivationTest, caFixedFlat,
|
|||
TEST_JSON(DerivationTest, caFixedNAR,
|
||||
(DerivationOutput::CAFixed {
|
||||
.ca = {
|
||||
.method = FileIngestionMethod::Recursive,
|
||||
.method = ContentAddressMethod::Raw::NixArchive,
|
||||
.hash = Hash::parseAnyPrefixed("sha256-iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="),
|
||||
},
|
||||
}),
|
||||
|
@ -126,6 +126,7 @@ TEST_JSON(DerivationTest, caFixedNAR,
|
|||
TEST_JSON(DynDerivationTest, caFixedText,
|
||||
(DerivationOutput::CAFixed {
|
||||
.ca = {
|
||||
.method = ContentAddressMethod::Raw::Text,
|
||||
.hash = Hash::parseAnyPrefixed("sha256-iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="),
|
||||
},
|
||||
}),
|
||||
|
@ -133,7 +134,7 @@ TEST_JSON(DynDerivationTest, caFixedText,
|
|||
|
||||
TEST_JSON(CaDerivationTest, caFloating,
|
||||
(DerivationOutput::CAFloating {
|
||||
.method = FileIngestionMethod::Recursive,
|
||||
.method = ContentAddressMethod::Raw::NixArchive,
|
||||
.hashAlgo = HashAlgorithm::SHA256,
|
||||
}),
|
||||
"drv-name", "output-name")
|
||||
|
@ -144,7 +145,7 @@ TEST_JSON(DerivationTest, deferred,
|
|||
|
||||
TEST_JSON(ImpureDerivationTest, impure,
|
||||
(DerivationOutput::Impure {
|
||||
.method = FileIngestionMethod::Recursive,
|
||||
.method = ContentAddressMethod::Raw::NixArchive,
|
||||
.hashAlgo = HashAlgorithm::SHA256,
|
||||
}),
|
||||
"drv-name", "output-name")
|
||||
|
|
|
@ -4,7 +4,7 @@ programs += libstore-tests
|
|||
|
||||
libstore-tests_NAME = libnixstore-tests
|
||||
|
||||
libstore-tests_ENV := _NIX_TEST_UNIT_DATA=$(d)/data
|
||||
libstore-tests_ENV := _NIX_TEST_UNIT_DATA=$(d)/data GTEST_OUTPUT=xml:$$testresults/libstore-tests.xml
|
||||
|
||||
libstore-tests_DIR := $(d)
|
||||
|
||||
|
|
95
tests/unit/libstore/meson.build
Normal file
95
tests/unit/libstore/meson.build
Normal file
|
@ -0,0 +1,95 @@
|
|||
project('nix-store-tests', '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')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
|
||||
deps_private_maybe_subproject = [
|
||||
dependency('nix-store'),
|
||||
dependency('nix-store-c'),
|
||||
dependency('nix-store-test-support'),
|
||||
]
|
||||
deps_public_maybe_subproject = [
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
|
||||
sqlite = dependency('sqlite3', 'sqlite', version : '>=3.6.19')
|
||||
deps_private += sqlite
|
||||
|
||||
rapidcheck = dependency('rapidcheck')
|
||||
deps_private += rapidcheck
|
||||
|
||||
gtest = dependency('gtest', main : true)
|
||||
deps_private += gtest
|
||||
|
||||
gtest = dependency('gmock')
|
||||
deps_private += gtest
|
||||
|
||||
add_project_arguments(
|
||||
# TODO(Qyriad): Yes this is how the autoconf+Make system did it.
|
||||
# It would be nice for our headers to be idempotent instead.
|
||||
'-include', 'config-util.hh',
|
||||
'-include', 'config-store.hh',
|
||||
'-include', 'config-util.h',
|
||||
'-include', 'config-store.h',
|
||||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/diagnostics')
|
||||
|
||||
sources = files(
|
||||
'common-protocol.cc',
|
||||
'content-address.cc',
|
||||
'derivation-advanced-attrs.cc',
|
||||
'derivation.cc',
|
||||
'derived-path.cc',
|
||||
'downstream-placeholder.cc',
|
||||
'machines.cc',
|
||||
'nar-info-disk-cache.cc',
|
||||
'nar-info.cc',
|
||||
'nix_api_store.cc',
|
||||
'outputs-spec.cc',
|
||||
'path-info.cc',
|
||||
'path.cc',
|
||||
'references.cc',
|
||||
'serve-protocol.cc',
|
||||
'store-reference.cc',
|
||||
'worker-protocol.cc',
|
||||
)
|
||||
|
||||
include_dirs = [include_directories('.')]
|
||||
|
||||
|
||||
this_exe = executable(
|
||||
meson.project_name(),
|
||||
sources,
|
||||
dependencies : deps_private_subproject + deps_private + deps_other,
|
||||
include_directories : include_dirs,
|
||||
# TODO: -lrapidcheck, see ../libutil-support/build.meson
|
||||
link_args: linker_export_flags + ['-lrapidcheck'],
|
||||
# get main from gtest
|
||||
install : true,
|
||||
)
|
||||
|
||||
test(
|
||||
meson.project_name(),
|
||||
this_exe,
|
||||
env : {
|
||||
'_NIX_TEST_UNIT_DATA': meson.current_source_dir() / 'data',
|
||||
},
|
||||
protocol : 'gtest',
|
||||
)
|
|
@ -25,7 +25,7 @@ static NarInfo makeNarInfo(const Store & store, bool includeImpureInfo) {
|
|||
store,
|
||||
"foo",
|
||||
FixedOutputInfo {
|
||||
.method = FileIngestionMethod::Recursive,
|
||||
.method = FileIngestionMethod::NixArchive,
|
||||
.hash = hashString(HashAlgorithm::SHA256, "(...)"),
|
||||
|
||||
.references = {
|
||||
|
|
110
tests/unit/libstore/package.nix
Normal file
110
tests/unit/libstore/package.nix
Normal file
|
@ -0,0 +1,110 @@
|
|||
{ lib
|
||||
, stdenv
|
||||
, mkMesonDerivation
|
||||
, releaseTools
|
||||
|
||||
, meson
|
||||
, ninja
|
||||
, pkg-config
|
||||
|
||||
, nix-store
|
||||
, nix-store-c
|
||||
, nix-store-test-support
|
||||
, sqlite
|
||||
|
||||
, rapidcheck
|
||||
, gtest
|
||||
, runCommand
|
||||
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
, filesetToSource
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) fileset;
|
||||
in
|
||||
|
||||
mkMesonDerivation (finalAttrs: {
|
||||
pname = "nix-store-tests";
|
||||
inherit version;
|
||||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../../.version
|
||||
./.version
|
||||
./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-store
|
||||
nix-store-c
|
||||
nix-store-test-support
|
||||
sqlite
|
||||
rapidcheck
|
||||
gtest
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
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;
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||
|
||||
passthru = {
|
||||
tests = {
|
||||
run = let
|
||||
# Some data is shared with the functional tests: they create it,
|
||||
# we consume it.
|
||||
data = filesetToSource {
|
||||
root = ../..;
|
||||
fileset = lib.fileset.unions [
|
||||
./data
|
||||
../../functional/derivation
|
||||
];
|
||||
};
|
||||
in runCommand "${finalAttrs.pname}-run" {} ''
|
||||
PATH="${lib.makeBinPath [ finalAttrs.finalPackage ]}:$PATH"
|
||||
export _NIX_TEST_UNIT_DATA=${data + "/unit/libstore/data"}
|
||||
nix-store-tests
|
||||
touch $out
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
};
|
||||
|
||||
})
|
|
@ -32,7 +32,7 @@ static UnkeyedValidPathInfo makeFull(const Store & store, bool includeImpureInfo
|
|||
store,
|
||||
"foo",
|
||||
FixedOutputInfo {
|
||||
.method = FileIngestionMethod::Recursive,
|
||||
.method = FileIngestionMethod::NixArchive,
|
||||
.hash = hashString(HashAlgorithm::SHA256, "(...)"),
|
||||
|
||||
.references = {
|
||||
|
|
|
@ -26,10 +26,19 @@ static std::regex nameRegex { std::string { nameRegexStr } };
|
|||
TEST_F(StorePathTest, bad_ ## NAME) { \
|
||||
std::string_view str = \
|
||||
STORE_DIR HASH_PART "-" STR; \
|
||||
ASSERT_THROW( \
|
||||
store->parseStorePath(str), \
|
||||
BadStorePath); \
|
||||
/* ASSERT_THROW generates a duplicate goto label */ \
|
||||
/* A lambda isolates those labels. */ \
|
||||
[&](){ \
|
||||
ASSERT_THROW( \
|
||||
store->parseStorePath(str), \
|
||||
BadStorePath); \
|
||||
}(); \
|
||||
std::string name { STR }; \
|
||||
[&](){ \
|
||||
ASSERT_THROW( \
|
||||
nix::checkName(name), \
|
||||
BadStorePathName); \
|
||||
}(); \
|
||||
EXPECT_FALSE(std::regex_match(name, nameRegex)); \
|
||||
}
|
||||
|
||||
|
@ -54,6 +63,7 @@ TEST_DONT_PARSE(dot_dash_a, ".-a")
|
|||
STORE_DIR HASH_PART "-" STR; \
|
||||
auto p = store->parseStorePath(str); \
|
||||
std::string name { p.name() }; \
|
||||
EXPECT_EQ(p.name(), STR); \
|
||||
EXPECT_TRUE(std::regex_match(name, nameRegex)); \
|
||||
}
|
||||
|
||||
|
|
|
@ -55,15 +55,15 @@ VERSIONED_CHARACTERIZATION_TEST(
|
|||
defaultVersion,
|
||||
(std::tuple<ContentAddress, ContentAddress, ContentAddress> {
|
||||
ContentAddress {
|
||||
.method = TextIngestionMethod {},
|
||||
.method = ContentAddressMethod::Raw::Text,
|
||||
.hash = hashString(HashAlgorithm::SHA256, "Derive(...)"),
|
||||
},
|
||||
ContentAddress {
|
||||
.method = FileIngestionMethod::Flat,
|
||||
.method = ContentAddressMethod::Raw::Flat,
|
||||
.hash = hashString(HashAlgorithm::SHA1, "blob blob..."),
|
||||
},
|
||||
ContentAddress {
|
||||
.method = FileIngestionMethod::Recursive,
|
||||
.method = ContentAddressMethod::Raw::NixArchive,
|
||||
.hash = hashString(HashAlgorithm::SHA256, "(...)"),
|
||||
},
|
||||
}))
|
||||
|
@ -280,7 +280,7 @@ VERSIONED_CHARACTERIZATION_TEST(
|
|||
*LibStoreTest::store,
|
||||
"foo",
|
||||
FixedOutputInfo {
|
||||
.method = FileIngestionMethod::Recursive,
|
||||
.method = FileIngestionMethod::NixArchive,
|
||||
.hash = hashString(HashAlgorithm::SHA256, "(...)"),
|
||||
.references = {
|
||||
.others = {
|
||||
|
@ -398,7 +398,7 @@ VERSIONED_CHARACTERIZATION_TEST(
|
|||
std::nullopt,
|
||||
std::optional {
|
||||
ContentAddress {
|
||||
.method = FileIngestionMethod::Flat,
|
||||
.method = ContentAddressMethod::Raw::Flat,
|
||||
.hash = hashString(HashAlgorithm::SHA1, "blob blob..."),
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <regex>
|
||||
#include <thread>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
|
@ -55,15 +56,15 @@ VERSIONED_CHARACTERIZATION_TEST(
|
|||
defaultVersion,
|
||||
(std::tuple<ContentAddress, ContentAddress, ContentAddress> {
|
||||
ContentAddress {
|
||||
.method = TextIngestionMethod {},
|
||||
.method = ContentAddressMethod::Raw::Text,
|
||||
.hash = hashString(HashAlgorithm::SHA256, "Derive(...)"),
|
||||
},
|
||||
ContentAddress {
|
||||
.method = FileIngestionMethod::Flat,
|
||||
.method = ContentAddressMethod::Raw::Flat,
|
||||
.hash = hashString(HashAlgorithm::SHA1, "blob blob..."),
|
||||
},
|
||||
ContentAddress {
|
||||
.method = FileIngestionMethod::Recursive,
|
||||
.method = ContentAddressMethod::Raw::NixArchive,
|
||||
.hash = hashString(HashAlgorithm::SHA256, "(...)"),
|
||||
},
|
||||
}))
|
||||
|
@ -511,7 +512,7 @@ VERSIONED_CHARACTERIZATION_TEST(
|
|||
*LibStoreTest::store,
|
||||
"foo",
|
||||
FixedOutputInfo {
|
||||
.method = FileIngestionMethod::Recursive,
|
||||
.method = FileIngestionMethod::NixArchive,
|
||||
.hash = hashString(HashAlgorithm::SHA256, "(...)"),
|
||||
.references = {
|
||||
.others = {
|
||||
|
@ -597,7 +598,7 @@ VERSIONED_CHARACTERIZATION_TEST(
|
|||
std::nullopt,
|
||||
std::optional {
|
||||
ContentAddress {
|
||||
.method = FileIngestionMethod::Flat,
|
||||
.method = ContentAddressMethod::Raw::Flat,
|
||||
.hash = hashString(HashAlgorithm::SHA1, "blob blob..."),
|
||||
},
|
||||
},
|
||||
|
|
1
tests/unit/libutil-support/.version
Symbolic link
1
tests/unit/libutil-support/.version
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../.version
|
1
tests/unit/libutil-support/build-utils-meson
Symbolic link
1
tests/unit/libutil-support/build-utils-meson
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../build-utils-meson/
|
70
tests/unit/libutil-support/meson.build
Normal file
70
tests/unit/libutil-support/meson.build
Normal file
|
@ -0,0 +1,70 @@
|
|||
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')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
|
||||
deps_private_maybe_subproject = [
|
||||
]
|
||||
deps_public_maybe_subproject = [
|
||||
dependency('nix-util'),
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
|
||||
rapidcheck = dependency('rapidcheck')
|
||||
deps_public += rapidcheck
|
||||
|
||||
add_project_arguments(
|
||||
# TODO(Qyriad): Yes this is how the autoconf+Make system did it.
|
||||
# It would be nice for our headers to be idempotent instead.
|
||||
'-include', 'config-util.hh',
|
||||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/diagnostics')
|
||||
|
||||
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',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
|
||||
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'],
|
||||
prelink : true, # For C++ static initializers
|
||||
install : true,
|
||||
)
|
||||
|
||||
install_headers(headers, subdir : 'nix', preserve_path : true)
|
||||
|
||||
libraries_private = []
|
||||
|
||||
subdir('build-utils-meson/export')
|
79
tests/unit/libutil-support/package.nix
Normal file
79
tests/unit/libutil-support/package.nix
Normal file
|
@ -0,0 +1,79 @@
|
|||
{ lib
|
||||
, stdenv
|
||||
, mkMesonDerivation
|
||||
, releaseTools
|
||||
|
||||
, meson
|
||||
, ninja
|
||||
, pkg-config
|
||||
|
||||
, nix-util
|
||||
|
||||
, rapidcheck
|
||||
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) fileset;
|
||||
in
|
||||
|
||||
mkMesonDerivation (finalAttrs: {
|
||||
pname = "nix-util-test-support";
|
||||
inherit version;
|
||||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../../.version
|
||||
./.version
|
||||
./meson.build
|
||||
# ./meson.options
|
||||
(fileset.fileFilter (file: file.hasExt "cc") ./.)
|
||||
(fileset.fileFilter (file: file.hasExt "hh") ./.)
|
||||
];
|
||||
|
||||
outputs = [ "out" "dev" ];
|
||||
|
||||
nativeBuildInputs = [
|
||||
meson
|
||||
ninja
|
||||
pkg-config
|
||||
];
|
||||
|
||||
propagatedBuildInputs = [
|
||||
nix-util
|
||||
rapidcheck
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
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;
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
};
|
||||
|
||||
})
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "types.hh"
|
||||
#include "environment-variables.hh"
|
||||
#include "file-system.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
1
tests/unit/libutil/.version
Symbolic link
1
tests/unit/libutil/.version
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../.version
|
1
tests/unit/libutil/build-utils-meson
Symbolic link
1
tests/unit/libutil/build-utils-meson
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../../build-utils-meson/
|
|
@ -11,7 +11,7 @@ namespace nix {
|
|||
TEST(FileSerialisationMethod, testRoundTripPrintParse_1) {
|
||||
for (const FileSerialisationMethod fim : {
|
||||
FileSerialisationMethod::Flat,
|
||||
FileSerialisationMethod::Recursive,
|
||||
FileSerialisationMethod::NixArchive,
|
||||
}) {
|
||||
EXPECT_EQ(parseFileSerialisationMethod(renderFileSerialisationMethod(fim)), fim);
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ TEST(FileSerialisationMethod, testParseFileSerialisationMethodOptException) {
|
|||
TEST(FileIngestionMethod, testRoundTripPrintParse_1) {
|
||||
for (const FileIngestionMethod fim : {
|
||||
FileIngestionMethod::Flat,
|
||||
FileIngestionMethod::Recursive,
|
||||
FileIngestionMethod::NixArchive,
|
||||
FileIngestionMethod::Git,
|
||||
}) {
|
||||
EXPECT_EQ(parseFileIngestionMethod(renderFileIngestionMethod(fim)), fim);
|
||||
|
|
|
@ -67,7 +67,7 @@ TEST_F(GitTest, blob_read) {
|
|||
StringSink out;
|
||||
RegularFileSink out2 { out };
|
||||
ASSERT_EQ(parseObjectType(in, mockXpSettings), ObjectType::Blob);
|
||||
parseBlob(out2, "", in, BlobMode::Regular, mockXpSettings);
|
||||
parseBlob(out2, CanonPath::root, in, BlobMode::Regular, mockXpSettings);
|
||||
|
||||
auto expected = readFile(goldenMaster("hello-world.bin"));
|
||||
|
||||
|
@ -132,8 +132,8 @@ TEST_F(GitTest, tree_read) {
|
|||
NullFileSystemObjectSink out;
|
||||
Tree got;
|
||||
ASSERT_EQ(parseObjectType(in, mockXpSettings), ObjectType::Tree);
|
||||
parseTree(out, "", in, [&](auto & name, auto entry) {
|
||||
auto name2 = name;
|
||||
parseTree(out, CanonPath::root, in, [&](auto & name, auto entry) {
|
||||
auto name2 = std::string{name.rel()};
|
||||
if (entry.mode == Mode::Directory)
|
||||
name2 += '/';
|
||||
got.insert_or_assign(name2, std::move(entry));
|
||||
|
@ -210,14 +210,14 @@ TEST_F(GitTest, both_roundrip) {
|
|||
|
||||
MemorySink sinkFiles2 { *files2 };
|
||||
|
||||
std::function<void(const Path, const Hash &, BlobMode)> mkSinkHook;
|
||||
std::function<void(const CanonPath, const Hash &, BlobMode)> mkSinkHook;
|
||||
mkSinkHook = [&](auto prefix, auto & hash, auto blobMode) {
|
||||
StringSource in { cas[hash] };
|
||||
parse(
|
||||
sinkFiles2, prefix, in, blobMode,
|
||||
[&](const Path & name, const auto & entry) {
|
||||
[&](const CanonPath & name, const auto & entry) {
|
||||
mkSinkHook(
|
||||
prefix + "/" + name,
|
||||
prefix / name,
|
||||
entry.hash,
|
||||
// N.B. this cast would not be acceptable in real
|
||||
// code, because it would make an assert reachable,
|
||||
|
@ -227,7 +227,7 @@ TEST_F(GitTest, both_roundrip) {
|
|||
mockXpSettings);
|
||||
};
|
||||
|
||||
mkSinkHook("", root.hash, BlobMode::Regular);
|
||||
mkSinkHook(CanonPath::root, root.hash, BlobMode::Regular);
|
||||
|
||||
ASSERT_EQ(*files, *files2);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ programs += libutil-tests
|
|||
|
||||
libutil-tests_NAME = libnixutil-tests
|
||||
|
||||
libutil-tests_ENV := _NIX_TEST_UNIT_DATA=$(d)/data
|
||||
libutil-tests_ENV := _NIX_TEST_UNIT_DATA=$(d)/data GTEST_OUTPUT=xml:$$testresults/libutil-tests.xml
|
||||
|
||||
libutil-tests_DIR := $(d)
|
||||
|
||||
|
|
91
tests/unit/libutil/meson.build
Normal file
91
tests/unit/libutil/meson.build
Normal file
|
@ -0,0 +1,91 @@
|
|||
project('nix-util-tests', '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')
|
||||
|
||||
subdir('build-utils-meson/deps-lists')
|
||||
|
||||
deps_private_maybe_subproject = [
|
||||
dependency('nix-util'),
|
||||
dependency('nix-util-c'),
|
||||
dependency('nix-util-test-support'),
|
||||
]
|
||||
deps_public_maybe_subproject = [
|
||||
]
|
||||
subdir('build-utils-meson/subprojects')
|
||||
|
||||
subdir('build-utils-meson/export-all-symbols')
|
||||
|
||||
rapidcheck = dependency('rapidcheck')
|
||||
deps_private += rapidcheck
|
||||
|
||||
gtest = dependency('gtest', main : true)
|
||||
deps_private += gtest
|
||||
|
||||
add_project_arguments(
|
||||
# TODO(Qyriad): Yes this is how the autoconf+Make system did it.
|
||||
# It would be nice for our headers to be idempotent instead.
|
||||
'-include', 'config-util.hh',
|
||||
'-include', 'config-util.h',
|
||||
language : 'cpp',
|
||||
)
|
||||
|
||||
subdir('build-utils-meson/diagnostics')
|
||||
|
||||
sources = files(
|
||||
'args.cc',
|
||||
'canon-path.cc',
|
||||
'chunked-vector.cc',
|
||||
'closure.cc',
|
||||
'compression.cc',
|
||||
'config.cc',
|
||||
'file-content-address.cc',
|
||||
'git.cc',
|
||||
'hash.cc',
|
||||
'hilite.cc',
|
||||
'json-utils.cc',
|
||||
'logging.cc',
|
||||
'lru-cache.cc',
|
||||
'nix_api_util.cc',
|
||||
'pool.cc',
|
||||
'references.cc',
|
||||
'spawn.cc',
|
||||
'suggestions.cc',
|
||||
'tests.cc',
|
||||
'url.cc',
|
||||
'xml-writer.cc',
|
||||
)
|
||||
|
||||
include_dirs = [include_directories('.')]
|
||||
|
||||
|
||||
this_exe = executable(
|
||||
meson.project_name(),
|
||||
sources,
|
||||
dependencies : deps_private_subproject + deps_private + deps_other,
|
||||
include_directories : include_dirs,
|
||||
# TODO: -lrapidcheck, see ../libutil-support/build.meson
|
||||
link_args: linker_export_flags + ['-lrapidcheck'],
|
||||
# get main from gtest
|
||||
install : true,
|
||||
)
|
||||
|
||||
test(
|
||||
meson.project_name(),
|
||||
this_exe,
|
||||
env : {
|
||||
'_NIX_TEST_UNIT_DATA': meson.current_source_dir() / 'data',
|
||||
},
|
||||
protocol : 'gtest',
|
||||
)
|
|
@ -1,4 +1,4 @@
|
|||
#include "config.hh"
|
||||
#include "config-global.hh"
|
||||
#include "args.hh"
|
||||
#include "nix_api_util.h"
|
||||
#include "nix_api_util_internal.h"
|
||||
|
|
98
tests/unit/libutil/package.nix
Normal file
98
tests/unit/libutil/package.nix
Normal file
|
@ -0,0 +1,98 @@
|
|||
{ lib
|
||||
, stdenv
|
||||
, mkMesonDerivation
|
||||
, releaseTools
|
||||
|
||||
, meson
|
||||
, ninja
|
||||
, pkg-config
|
||||
|
||||
, nix-util
|
||||
, nix-util-c
|
||||
, nix-util-test-support
|
||||
|
||||
, rapidcheck
|
||||
, gtest
|
||||
, runCommand
|
||||
|
||||
# Configuration Options
|
||||
|
||||
, version
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) fileset;
|
||||
in
|
||||
|
||||
mkMesonDerivation (finalAttrs: {
|
||||
pname = "nix-util-tests";
|
||||
inherit version;
|
||||
|
||||
workDir = ./.;
|
||||
fileset = fileset.unions [
|
||||
../../../build-utils-meson
|
||||
./build-utils-meson
|
||||
../../../.version
|
||||
./.version
|
||||
./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
|
||||
nix-util-c
|
||||
nix-util-test-support
|
||||
rapidcheck
|
||||
gtest
|
||||
];
|
||||
|
||||
preConfigure =
|
||||
# "Inline" .version so it's not a symlink, and includes the suffix.
|
||||
# Do the meson utils, without modification.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
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;
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||
|
||||
passthru = {
|
||||
tests = {
|
||||
run = runCommand "${finalAttrs.pname}-run" {
|
||||
} ''
|
||||
PATH="${lib.makeBinPath [ finalAttrs.finalPackage ]}:$PATH"
|
||||
export _NIX_TEST_UNIT_DATA=${./data}
|
||||
nix-util-tests
|
||||
touch $out
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
meta = {
|
||||
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||
};
|
||||
|
||||
})
|
36
tests/unit/libutil/spawn.cc
Normal file
36
tests/unit/libutil/spawn.cc
Normal file
|
@ -0,0 +1,36 @@
|
|||
#include <gtest/gtest.h>
|
||||
|
||||
#include "processes.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
#ifdef _WIN32
|
||||
TEST(SpawnTest, spawnEcho)
|
||||
{
|
||||
auto output = runProgram(RunOptions{.program = "cmd.exe", .args = {"/C", "echo", "hello world"}});
|
||||
ASSERT_EQ(output.first, 0);
|
||||
ASSERT_EQ(output.second, "\"hello world\"\r\n");
|
||||
}
|
||||
|
||||
std::string windowsEscape(const std::string & str, bool cmd);
|
||||
|
||||
TEST(SpawnTest, windowsEscape)
|
||||
{
|
||||
auto empty = windowsEscape("", false);
|
||||
ASSERT_EQ(empty, R"("")");
|
||||
// There's no quotes in this argument so the input should equal the output
|
||||
auto backslashStr = R"(\\\\)";
|
||||
auto backslashes = windowsEscape(backslashStr, false);
|
||||
ASSERT_EQ(backslashes, backslashStr);
|
||||
|
||||
auto nestedQuotes = windowsEscape(R"(he said: "hello there")", false);
|
||||
ASSERT_EQ(nestedQuotes, R"("he said: \"hello there\"")");
|
||||
|
||||
auto middleQuote = windowsEscape(R"( \\\" )", false);
|
||||
ASSERT_EQ(middleQuote, R"(" \\\\\\\" ")");
|
||||
|
||||
auto space = windowsEscape("hello world", false);
|
||||
ASSERT_EQ(space, R"("hello world")");
|
||||
}
|
||||
#endif
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue