Move tests to separate directories, and document

Today, with the tests inside a `tests` intermingled with the
corresponding library's source code, we have a few problems:

- We have to be careful that wildcards don't end up with tests being
  built as part of Nix proper, or test headers being installed as part
  of Nix proper.

- Tests in libraries but not executables is not right:

  - It means each executable runs the previous unit tests again, because
    it needs the libraries.

  - It doesn't work right on Windows, which doesn't want you to load a
    DLL just for the side global variable . It could be made to work
    with the dlopen equivalent, but that's gross!

This reorg solves these problems.

There is a remaining problem which is that sibbling headers (like
`hash.hh` the test header vs `hash.hh` the main `libnixutil` header) end
up shadowing each other. This PR doesn't solve that. That is left as
future work for a future PR.

Co-authored-by: Valentin Gagarin <valentin.gagarin@tweag.io>
This commit is contained in:
John Ericson 2023-08-25 10:20:28 -04:00
parent 77adb55ae4
commit 91b6833686
134 changed files with 464 additions and 352 deletions

6
.gitignore vendored
View File

@ -45,14 +45,14 @@ perl/Makefile.config
/src/libexpr/parser-tab.hh /src/libexpr/parser-tab.hh
/src/libexpr/parser-tab.output /src/libexpr/parser-tab.output
/src/libexpr/nix.tbl /src/libexpr/nix.tbl
/src/libexpr/tests/libnixexpr-tests /tests/unit/libexpr/libnixexpr-tests
# /src/libstore/ # /src/libstore/
*.gen.* *.gen.*
/src/libstore/tests/libnixstore-tests /tests/unit/libstore/libnixstore-tests
# /src/libutil/ # /src/libutil/
/src/libutil/tests/libnixutil-tests /tests/unit/libutil/libnixutil-tests
/src/nix/nix /src/nix/nix

View File

@ -25,11 +25,13 @@ makefiles = \
endif endif
ifeq ($(ENABLE_BUILD)_$(ENABLE_TESTS), yes_yes) ifeq ($(ENABLE_BUILD)_$(ENABLE_TESTS), yes_yes)
UNIT_TEST_ENV = _NIX_TEST_UNIT_DATA=unit-test-data
makefiles += \ makefiles += \
src/libutil/tests/local.mk \ tests/unit/libutil/local.mk \
src/libstore/tests/local.mk \ tests/unit/libutil-support/local.mk \
src/libexpr/tests/local.mk tests/unit/libstore/local.mk \
tests/unit/libstore-support/local.mk \
tests/unit/libexpr/local.mk \
tests/unit/libexpr-support/local.mk
endif endif
ifeq ($(ENABLE_TESTS), yes) ifeq ($(ENABLE_TESTS), yes)

View File

@ -39,17 +39,21 @@ INPUT = \
src/libcmd \ src/libcmd \
src/libexpr \ src/libexpr \
src/libexpr/flake \ src/libexpr/flake \
src/libexpr/tests \ tests/unit/libexpr \
src/libexpr/tests/value \ tests/unit/libexpr/value \
tests/unit/libexpr/test \
tests/unit/libexpr/test/value \
src/libexpr/value \ src/libexpr/value \
src/libfetchers \ src/libfetchers \
src/libmain \ src/libmain \
src/libstore \ src/libstore \
src/libstore/build \ src/libstore/build \
src/libstore/builtins \ src/libstore/builtins \
src/libstore/tests \ tests/unit/libstore \
tests/unit/libstore/test \
src/libutil \ src/libutil \
src/libutil/tests \ tests/unit/libutil \
tests/unit/libutil/test \
src/nix \ src/nix \
src/nix-env \ src/nix-env \
src/nix-store src/nix-store

View File

@ -20,6 +20,7 @@ The unit tests are defined using the [googletest] and [rapidcheck] frameworks.
[googletest]: https://google.github.io/googletest/ [googletest]: https://google.github.io/googletest/
[rapidcheck]: https://github.com/emil-e/rapidcheck [rapidcheck]: https://github.com/emil-e/rapidcheck
[property testing]: https://en.wikipedia.org/wiki/Property_testing
### Source and header layout ### Source and header layout
@ -28,34 +29,50 @@ The unit tests are defined using the [googletest] and [rapidcheck] frameworks.
> ``` > ```
> src > src
> ├── libexpr > ├── libexpr
> │ ├── local.mk
> │ ├── value/context.hh > │ ├── value/context.hh
> │ ├── value/context.cc > │ ├── value/context.cc
> │ …
> │
> ├── tests
> │ │ > │ │
> │ … > │ …
> └── tests > │ └── unit
> │ ├── value/context.hh > │ ├── libutil
> │ ├── value/context.cc > │ │ ├── local.mk
> │ │ …
> │ │ └── data
> │ │ ├── git/tree.txt
> │ │ …
> │ │ > │ │
> │ … > │ ├── libexpr-support
> │ > │ │ ├── local.mk
> ├── unit-test-data > │ │ └── tests
> │ ├── libstore > │ │ ├── value/context.hh
> │ │ ├── worker-protocol/content-address.bin > │ │ ├── value/context.cc
> │ │ … > │ │ …
> │ … > │ │
> │ ├── libexpr
> │ … ├── local.mk
> │ ├── value/context.cc
> │ …
> … > …
> ``` > ```
The unit tests for each Nix library (`libnixexpr`, `libnixstore`, etc..) live inside a directory `src/${library_shortname}/tests` within the directory for the library (`src/${library_shortname}`). The tests for each Nix library (`libnixexpr`, `libnixstore`, etc..) live inside a directory `tests/unit/${library_name_without-nix}`.
Given a interface (header) and implementation pair in the original library, say, `src/libexpr/value/context.{hh,cc}`, we write tests for it in `tests/unit/libexpr/tests/value/context.cc`, and (possibly) declare/define additional interfaces for testing purposes in `tests/unit/libexpr-support/tests/value/context.{hh,cc}`.
The data is in `unit-test-data`, with one subdir per library, with the same name as where the code goes. Data for unit tests is stored in a `data` subdir of the directory for each unit test executable.
For example, `libnixstore` code is in `src/libstore`, and its test data is in `unit-test-data/libstore`. For example, `libnixstore` code is in `src/libstore`, and its test data is in `tests/unit/libstore/data`.
The path to the `unit-test-data` directory is passed to the unit test executable with the environment variable `_NIX_TEST_UNIT_DATA`. The path to the `tests/unit/data` directory is passed to the unit test executable with the environment variable `_NIX_TEST_UNIT_DATA`.
Note that each executable only gets the data for its tests.
> **Note** The unit test libraries are in `tests/unit/${library_name_without-nix}-lib`.
> Due to the way googletest works, downstream unit test executables will actually include and re-run upstream library tests. All headers are in a `tests` subdirectory so they are included with `#include "tests/"`.
> Therefore it is important that the same value for `_NIX_TEST_UNIT_DATA` be used with the tests for each library.
> That is why we have the test data nested within a single `unit-test-data` directory. The use of all these separate directories for the unit tests might seem inconvenient, as for example the tests are not "right next to" the part of the code they are testing.
But organizing the tests this way has one big benefit:
there is no risk of any build-system wildcards for the library accidentally picking up test code that should not built and installed as part of the library.
### Running tests ### Running tests
@ -69,7 +86,7 @@ See [functional characterisation testing](#characterisation-testing-functional)
Like with the functional characterisation, `_NIX_TEST_ACCEPT=1` is also used. Like with the functional characterisation, `_NIX_TEST_ACCEPT=1` is also used.
For example: For example:
```shell-session ```shell-session
$ _NIX_TEST_ACCEPT=1 make libstore-tests-exe_RUN $ _NIX_TEST_ACCEPT=1 make libstore-tests_RUN
... ...
[ SKIPPED ] WorkerProtoTest.string_read [ SKIPPED ] WorkerProtoTest.string_read
[ SKIPPED ] WorkerProtoTest.string_write [ SKIPPED ] WorkerProtoTest.string_write
@ -80,6 +97,18 @@ $ _NIX_TEST_ACCEPT=1 make libstore-tests-exe_RUN
will regenerate the "golden master" expected result for the `libnixstore` characterisation tests. will regenerate the "golden master" expected result for the `libnixstore` characterisation tests.
The characterisation tests will mark themselves "skipped" since they regenerated the expected result instead of actually testing anything. The characterisation tests will mark themselves "skipped" since they regenerated the expected result instead of actually testing anything.
### Unit test support libraries
There are headers and code which are not just used to test the library in question, but also downstream libraries.
For example, we do [property testing] with the [rapidcheck] library.
This requires writing `Arbitrary` "instances", which are used to describe how to generate values of a given type for the sake of running property tests.
Because types contain other types, `Arbitrary` "instances" for some type are not just useful for testing that type, but also any other type that contains it.
Downstream types frequently contain upstream types, so it is very important that we share arbitrary instances so that downstream libraries' property tests can also use them.
It is important that these testing libraries don't contain any actual tests themselves.
On some platforms they would be run as part of every test executable that uses them, which is redundant.
On other platforms they wouldn't be run at all.
## Functional tests ## Functional tests
The functional tests reside under the `tests/functional` directory and are listed in `tests/functional/local.mk`. The functional tests reside under the `tests/functional` directory and are listed in `tests/functional/local.mk`.

View File

@ -93,7 +93,7 @@
./misc ./misc
./precompiled-headers.h ./precompiled-headers.h
./src ./src
./unit-test-data ./tests/unit
./COPYING ./COPYING
./scripts/local.mk ./scripts/local.mk
functionalTestFiles functionalTestFiles

View File

@ -1,7 +1,7 @@
# Remove overall test dir (at most one of the two should match) and # Remove overall test dir (at most one of the two should match) and
# remove file extension. # remove file extension.
test_name=$(echo -n "$test" | sed \ test_name=$(echo -n "$test" | sed \
-e "s|^unit-test-data/||" \ -e "s|^tests/unit/[^/]*/data/||" \
-e "s|^tests/functional/||" \ -e "s|^tests/functional/||" \
-e "s|\.sh$||" \ -e "s|\.sh$||" \
) )

View File

@ -87,6 +87,6 @@ define build-program
# Phony target to run this program (typically as a dependency of 'check'). # Phony target to run this program (typically as a dependency of 'check').
.PHONY: $(1)_RUN .PHONY: $(1)_RUN
$(1)_RUN: $$($(1)_PATH) $(1)_RUN: $$($(1)_PATH)
$(trace-test) $$(UNIT_TEST_ENV) $$($(1)_PATH) $(trace-test) $$($(1)_ENV) $$($(1)_PATH)
endef endef

View File

@ -1,23 +0,0 @@
check: libexpr-tests_RUN
programs += libexpr-tests
libexpr-tests_NAME := libnixexpr-tests
libexpr-tests_DIR := $(d)
ifeq ($(INSTALL_UNIT_TESTS), yes)
libexpr-tests_INSTALL_DIR := $(checkbindir)
else
libexpr-tests_INSTALL_DIR :=
endif
libexpr-tests_SOURCES := \
$(wildcard $(d)/*.cc) \
$(wildcard $(d)/value/*.cc)
libexpr-tests_CXXFLAGS += -I src/libexpr -I src/libutil -I src/libstore -I src/libexpr/tests -I src/libfetchers
libexpr-tests_LIBS = libstore-tests libutils-tests libexpr libutil libstore libfetchers
libexpr-tests_LDFLAGS := -lrapidcheck $(GTEST_LIBS) -lgmock

View File

@ -1,37 +0,0 @@
check: libstore-tests-exe_RUN
programs += libstore-tests-exe
libstore-tests-exe_NAME = libnixstore-tests
libstore-tests-exe_DIR := $(d)
ifeq ($(INSTALL_UNIT_TESTS), yes)
libstore-tests-exe_INSTALL_DIR := $(checkbindir)
else
libstore-tests-exe_INSTALL_DIR :=
endif
libstore-tests-exe_LIBS = libstore-tests
libstore-tests-exe_LDFLAGS := $(GTEST_LIBS)
libraries += libstore-tests
libstore-tests_NAME = libnixstore-tests
libstore-tests_DIR := $(d)
ifeq ($(INSTALL_UNIT_TESTS), yes)
libstore-tests_INSTALL_DIR := $(checklibdir)
else
libstore-tests_INSTALL_DIR :=
endif
libstore-tests_SOURCES := $(wildcard $(d)/*.cc)
libstore-tests_CXXFLAGS += -I src/libstore -I src/libutil
libstore-tests_LIBS = libutil-tests libstore libutil
libstore-tests_LDFLAGS := -lrapidcheck $(GTEST_LIBS)

View File

@ -1,41 +0,0 @@
check: libutil-tests-exe_RUN
programs += libutil-tests-exe
libutil-tests-exe_NAME = libnixutil-tests
libutil-tests-exe_DIR := $(d)
ifeq ($(INSTALL_UNIT_TESTS), yes)
libutil-tests-exe_INSTALL_DIR := $(checkbindir)
else
libutil-tests-exe_INSTALL_DIR :=
endif
libutil-tests-exe_LIBS = libutil-tests
libutil-tests-exe_LDFLAGS := $(GTEST_LIBS)
libraries += libutil-tests
libutil-tests_NAME = libnixutil-tests
libutil-tests_DIR := $(d)
ifeq ($(INSTALL_UNIT_TESTS), yes)
libutil-tests_INSTALL_DIR := $(checklibdir)
else
libutil-tests_INSTALL_DIR :=
endif
libutil-tests_SOURCES := $(wildcard $(d)/*.cc)
libutil-tests_CXXFLAGS += -I src/libutil
libutil-tests_LIBS = libutil
libutil-tests_LDFLAGS := -lrapidcheck $(GTEST_LIBS)
check: unit-test-data/libutil/git/check-data.sh.test
$(eval $(call run-test,unit-test-data/libutil/git/check-data.sh))

View File

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

View File

@ -0,0 +1,30 @@
#include <rapidcheck.h>
#include "tests/path.hh"
#include "tests/value/context.hh"
namespace rc {
using namespace nix;
Gen<NixStringContextElem::DrvDeep> Arbitrary<NixStringContextElem::DrvDeep>::arbitrary()
{
return gen::just(NixStringContextElem::DrvDeep {
.drvPath = *gen::arbitrary<StorePath>(),
});
}
Gen<NixStringContextElem> Arbitrary<NixStringContextElem>::arbitrary()
{
switch (*gen::inRange<uint8_t>(0, std::variant_size_v<NixStringContextElem::Raw>)) {
case 0:
return gen::just<NixStringContextElem>(*gen::arbitrary<NixStringContextElem::Opaque>());
case 1:
return gen::just<NixStringContextElem>(*gen::arbitrary<NixStringContextElem::DrvDeep>());
case 2:
return gen::just<NixStringContextElem>(*gen::arbitrary<NixStringContextElem::Built>());
default:
assert(false);
}
}
}

View File

@ -3,7 +3,7 @@
#include <rapidcheck/gen/Arbitrary.h> #include <rapidcheck/gen/Arbitrary.h>
#include <value/context.hh> #include "value/context.hh"
namespace rc { namespace rc {
using namespace nix; using namespace nix;

View File

@ -0,0 +1,36 @@
check: libexpr-tests_RUN
programs += libexpr-tests
libexpr-tests_NAME := libnixexpr-tests
libexpr-tests_ENV := _NIX_TEST_UNIT_DATA=$(d)/data
libexpr-tests_DIR := $(d)
ifeq ($(INSTALL_UNIT_TESTS), yes)
libexpr-tests_INSTALL_DIR := $(checkbindir)
else
libexpr-tests_INSTALL_DIR :=
endif
libexpr-tests_SOURCES := \
$(wildcard $(d)/*.cc) \
$(wildcard $(d)/value/*.cc)
libexpr-tests_EXTRA_INCLUDES = \
-I tests/unit/libexpr-support \
-I tests/unit/libstore-support \
-I tests/unit/libutil-support \
-I src/libexpr \
-I src/libfetchers \
-I src/libstore \
-I src/libutil
libexpr-tests_CXXFLAGS += $(libexpr-tests_EXTRA_INCLUDES)
libexpr-tests_LIBS = \
libexpr-test-support libstore-test-support libutils-test-support \
libexpr libfetchers libstore libutil
libexpr-tests_LDFLAGS := -lrapidcheck $(GTEST_LIBS) -lgmock

View File

@ -117,36 +117,6 @@ TEST(NixStringContextElemTest, built_built_xp) {
NixStringContextElem::parse("!foo!bar!g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-x.drv"), MissingExperimentalFeature); NixStringContextElem::parse("!foo!bar!g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-x.drv"), MissingExperimentalFeature);
} }
}
namespace rc {
using namespace nix;
Gen<NixStringContextElem::DrvDeep> Arbitrary<NixStringContextElem::DrvDeep>::arbitrary()
{
return gen::just(NixStringContextElem::DrvDeep {
.drvPath = *gen::arbitrary<StorePath>(),
});
}
Gen<NixStringContextElem> Arbitrary<NixStringContextElem>::arbitrary()
{
switch (*gen::inRange<uint8_t>(0, std::variant_size_v<NixStringContextElem::Raw>)) {
case 0:
return gen::just<NixStringContextElem>(*gen::arbitrary<NixStringContextElem::Opaque>());
case 1:
return gen::just<NixStringContextElem>(*gen::arbitrary<NixStringContextElem::DrvDeep>());
case 2:
return gen::just<NixStringContextElem>(*gen::arbitrary<NixStringContextElem::Built>());
default:
assert(false);
}
}
}
namespace nix {
#ifndef COVERAGE #ifndef COVERAGE
RC_GTEST_PROP( RC_GTEST_PROP(

View File

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

View File

@ -0,0 +1,57 @@
#include <regex>
#include <rapidcheck.h>
#include "tests/derived-path.hh"
namespace rc {
using namespace nix;
Gen<DerivedPath::Opaque> Arbitrary<DerivedPath::Opaque>::arbitrary()
{
return gen::just(DerivedPath::Opaque {
.path = *gen::arbitrary<StorePath>(),
});
}
Gen<SingleDerivedPath::Built> Arbitrary<SingleDerivedPath::Built>::arbitrary()
{
return gen::just(SingleDerivedPath::Built {
.drvPath = make_ref<SingleDerivedPath>(*gen::arbitrary<SingleDerivedPath>()),
.output = (*gen::arbitrary<StorePathName>()).name,
});
}
Gen<DerivedPath::Built> Arbitrary<DerivedPath::Built>::arbitrary()
{
return gen::just(DerivedPath::Built {
.drvPath = make_ref<SingleDerivedPath>(*gen::arbitrary<SingleDerivedPath>()),
.outputs = *gen::arbitrary<OutputsSpec>(),
});
}
Gen<SingleDerivedPath> Arbitrary<SingleDerivedPath>::arbitrary()
{
switch (*gen::inRange<uint8_t>(0, std::variant_size_v<SingleDerivedPath::Raw>)) {
case 0:
return gen::just<SingleDerivedPath>(*gen::arbitrary<SingleDerivedPath::Opaque>());
case 1:
return gen::just<SingleDerivedPath>(*gen::arbitrary<SingleDerivedPath::Built>());
default:
assert(false);
}
}
Gen<DerivedPath> Arbitrary<DerivedPath>::arbitrary()
{
switch (*gen::inRange<uint8_t>(0, std::variant_size_v<DerivedPath::Raw>)) {
case 0:
return gen::just<DerivedPath>(*gen::arbitrary<DerivedPath::Opaque>());
case 1:
return gen::just<DerivedPath>(*gen::arbitrary<DerivedPath::Built>());
default:
assert(false);
}
}
}

View File

@ -0,0 +1,24 @@
#include "tests/outputs-spec.hh"
#include <rapidcheck.h>
namespace rc {
using namespace nix;
Gen<OutputsSpec> Arbitrary<OutputsSpec>::arbitrary()
{
switch (*gen::inRange<uint8_t>(0, std::variant_size_v<OutputsSpec::Raw>)) {
case 0:
return gen::just((OutputsSpec) OutputsSpec::All { });
case 1:
return gen::just((OutputsSpec) OutputsSpec::Names {
*gen::nonEmpty(gen::container<StringSet>(gen::map(
gen::arbitrary<StorePathName>(),
[](StorePathName n) { return n.name; }))),
});
default:
assert(false);
}
}
}

View File

@ -5,7 +5,7 @@
#include <outputs-spec.hh> #include <outputs-spec.hh>
#include <tests/path.hh> #include "tests/path.hh"
namespace rc { namespace rc {
using namespace nix; using namespace nix;

View File

@ -0,0 +1,82 @@
#include <regex>
#include <rapidcheck.h>
#include "path-regex.hh"
#include "store-api.hh"
#include "tests/hash.hh"
#include "tests/path.hh"
namespace nix {
void showValue(const StorePath & p, std::ostream & os)
{
os << p.to_string();
}
}
namespace rc {
using namespace nix;
Gen<StorePathName> Arbitrary<StorePathName>::arbitrary()
{
auto len = *gen::inRange<size_t>(
1,
StorePath::MaxPathLen - StorePath::HashLen);
std::string pre;
pre.reserve(len);
for (size_t c = 0; c < len; ++c) {
switch (auto i = *gen::inRange<uint8_t>(0, 10 + 2 * 26 + 6)) {
case 0 ... 9:
pre += '0' + i;
case 10 ... 35:
pre += 'A' + (i - 10);
break;
case 36 ... 61:
pre += 'a' + (i - 36);
break;
case 62:
pre += '+';
break;
case 63:
pre += '-';
break;
case 64:
// names aren't permitted to start with a period,
// so just fall through to the next case here
if (c != 0) {
pre += '.';
break;
}
case 65:
pre += '_';
break;
case 66:
pre += '?';
break;
case 67:
pre += '=';
break;
default:
assert(false);
}
}
return gen::just(StorePathName {
.name = std::move(pre),
});
}
Gen<StorePath> Arbitrary<StorePath>::arbitrary()
{
return gen::just(StorePath {
*gen::arbitrary<Hash>(),
(*gen::arbitrary<StorePathName>()).name,
});
}
} // namespace rc

View File

@ -11,6 +11,9 @@ struct StorePathName {
std::string name; std::string name;
}; };
// For rapidcheck
void showValue(const StorePath & p, std::ostream & os);
} }
namespace rc { namespace rc {

View File

@ -12,7 +12,7 @@ namespace nix {
template<class Proto, const char * protocolDir> template<class Proto, const char * protocolDir>
class ProtoTest : public CharacterizationTest, public LibStoreTest class ProtoTest : public CharacterizationTest, public LibStoreTest
{ {
Path unitTestData = getUnitTestData() + "/libstore/" + protocolDir; Path unitTestData = getUnitTestData() + "/" + protocolDir;
Path goldenMaster(std::string_view testStem) const override { Path goldenMaster(std::string_view testStem) const override {
return unitTestData + "/" + testStem + ".bin"; return unitTestData + "/" + testStem + ".bin";

View File

@ -13,7 +13,7 @@ using nlohmann::json;
class DerivationTest : public CharacterizationTest, public LibStoreTest class DerivationTest : public CharacterizationTest, public LibStoreTest
{ {
Path unitTestData = getUnitTestData() + "/libstore/derivation"; Path unitTestData = getUnitTestData() + "/derivation";
public: public:
Path goldenMaster(std::string_view testStem) const override { Path goldenMaster(std::string_view testStem) const override {

View File

@ -1,64 +1,11 @@
#include <regex> #include <regex>
#include <nlohmann/json.hpp>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <rapidcheck/gtest.h> #include <rapidcheck/gtest.h>
#include "tests/derived-path.hh" #include "tests/derived-path.hh"
#include "tests/libstore.hh" #include "tests/libstore.hh"
namespace rc {
using namespace nix;
Gen<DerivedPath::Opaque> Arbitrary<DerivedPath::Opaque>::arbitrary()
{
return gen::just(DerivedPath::Opaque {
.path = *gen::arbitrary<StorePath>(),
});
}
Gen<SingleDerivedPath::Built> Arbitrary<SingleDerivedPath::Built>::arbitrary()
{
return gen::just(SingleDerivedPath::Built {
.drvPath = make_ref<SingleDerivedPath>(*gen::arbitrary<SingleDerivedPath>()),
.output = (*gen::arbitrary<StorePathName>()).name,
});
}
Gen<DerivedPath::Built> Arbitrary<DerivedPath::Built>::arbitrary()
{
return gen::just(DerivedPath::Built {
.drvPath = make_ref<SingleDerivedPath>(*gen::arbitrary<SingleDerivedPath>()),
.outputs = *gen::arbitrary<OutputsSpec>(),
});
}
Gen<SingleDerivedPath> Arbitrary<SingleDerivedPath>::arbitrary()
{
switch (*gen::inRange<uint8_t>(0, std::variant_size_v<SingleDerivedPath::Raw>)) {
case 0:
return gen::just<SingleDerivedPath>(*gen::arbitrary<SingleDerivedPath::Opaque>());
case 1:
return gen::just<SingleDerivedPath>(*gen::arbitrary<SingleDerivedPath::Built>());
default:
assert(false);
}
}
Gen<DerivedPath> Arbitrary<DerivedPath>::arbitrary()
{
switch (*gen::inRange<uint8_t>(0, std::variant_size_v<DerivedPath::Raw>)) {
case 0:
return gen::just<DerivedPath>(*gen::arbitrary<DerivedPath::Opaque>());
case 1:
return gen::just<DerivedPath>(*gen::arbitrary<DerivedPath::Built>());
default:
assert(false);
}
}
}
namespace nix { namespace nix {
class DerivedPathTest : public LibStoreTest class DerivedPathTest : public LibStoreTest

View File

@ -0,0 +1,31 @@
check: libstore-tests_RUN
programs += libstore-tests
libstore-tests_NAME = libnixstore-tests
libstore-tests_ENV := _NIX_TEST_UNIT_DATA=$(d)/data
libstore-tests_DIR := $(d)
ifeq ($(INSTALL_UNIT_TESTS), yes)
libstore-tests_INSTALL_DIR := $(checkbindir)
else
libstore-tests_INSTALL_DIR :=
endif
libstore-tests_SOURCES := $(wildcard $(d)/*.cc)
libstore-tests_EXTRA_INCLUDES = \
-I tests/unit/libstore-support \
-I tests/unit/libutil-support \
-I src/libstore \
-I src/libutil
libstore-tests_CXXFLAGS += $(libstore-tests_EXTRA_INCLUDES)
libstore-tests_LIBS = \
libstore-test-support libutil-test-support \
libstore libutil
libstore-tests_LDFLAGS := -lrapidcheck $(GTEST_LIBS)

View File

@ -139,7 +139,7 @@ TEST(machines, getMachinesWithIncorrectFormat) {
} }
TEST(machines, getMachinesWithCorrectFileReference) { TEST(machines, getMachinesWithCorrectFileReference) {
auto path = absPath("src/libstore/tests/test-data/machines.valid"); auto path = absPath("tests/unit/libstore/test-data/machines.valid");
ASSERT_TRUE(pathExists(path)); ASSERT_TRUE(pathExists(path));
settings.builders = std::string("@") + path; settings.builders = std::string("@") + path;
@ -166,6 +166,6 @@ TEST(machines, getMachinesWithIncorrectFileReference) {
} }
TEST(machines, getMachinesWithCorrectFileReferenceToIncorrectFile) { TEST(machines, getMachinesWithCorrectFileReferenceToIncorrectFile) {
settings.builders = std::string("@") + absPath("src/libstore/tests/test-data/machines.bad_format"); settings.builders = std::string("@") + absPath("tests/unit/libstore/test-data/machines.bad_format");
EXPECT_THROW(getMachines(), FormatError); EXPECT_THROW(getMachines(), FormatError);
} }

View File

@ -13,7 +13,7 @@ using nlohmann::json;
class NarInfoTest : public CharacterizationTest, public LibStoreTest class NarInfoTest : public CharacterizationTest, public LibStoreTest
{ {
Path unitTestData = getUnitTestData() + "/libstore/nar-info"; Path unitTestData = getUnitTestData() + "/nar-info";
Path goldenMaster(PathView testStem) const override { Path goldenMaster(PathView testStem) const override {
return unitTestData + "/" + testStem + ".json"; return unitTestData + "/" + testStem + ".json";

View File

@ -1,4 +1,4 @@
#include "outputs-spec.hh" #include "tests/outputs-spec.hh"
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <gtest/gtest.h> #include <gtest/gtest.h>
@ -199,31 +199,6 @@ TEST_JSON(ExtendedOutputsSpec, names, R"(["a","b"])", (ExtendedOutputsSpec::Expl
#undef TEST_JSON #undef TEST_JSON
}
namespace rc {
using namespace nix;
Gen<OutputsSpec> Arbitrary<OutputsSpec>::arbitrary()
{
switch (*gen::inRange<uint8_t>(0, std::variant_size_v<OutputsSpec::Raw>)) {
case 0:
return gen::just((OutputsSpec) OutputsSpec::All { });
case 1:
return gen::just((OutputsSpec) OutputsSpec::Names {
*gen::nonEmpty(gen::container<StringSet>(gen::map(
gen::arbitrary<StorePathName>(),
[](StorePathName n) { return n.name; }))),
});
default:
assert(false);
}
}
}
namespace nix {
#ifndef COVERAGE #ifndef COVERAGE
RC_GTEST_PROP( RC_GTEST_PROP(

View File

@ -12,7 +12,7 @@ using nlohmann::json;
class PathInfoTest : public CharacterizationTest, public LibStoreTest class PathInfoTest : public CharacterizationTest, public LibStoreTest
{ {
Path unitTestData = getUnitTestData() + "/libstore/path-info"; Path unitTestData = getUnitTestData() + "/path-info";
Path goldenMaster(PathView testStem) const override { Path goldenMaster(PathView testStem) const override {
return unitTestData + "/" + testStem + ".json"; return unitTestData + "/" + testStem + ".json";

Some files were not shown because too many files have changed in this diff Show More