mirror of
https://github.com/NixOS/nix.git
synced 2025-11-09 03:56:01 +01:00
Merge c893454926 into 70fbd1cdf4
This commit is contained in:
commit
61393b3fcb
156 changed files with 3897 additions and 1464 deletions
|
|
@ -37,6 +37,7 @@ mkMesonDerivation (finalAttrs: {
|
|||
(fileset.unions [
|
||||
../../.version
|
||||
# For example JSON
|
||||
../../src/libutil-tests/data/memory-source-accessor
|
||||
../../src/libutil-tests/data/hash
|
||||
../../src/libstore-tests/data/content-address
|
||||
../../src/libstore-tests/data/store-path
|
||||
|
|
@ -44,6 +45,7 @@ mkMesonDerivation (finalAttrs: {
|
|||
../../src/libstore-tests/data/derived-path
|
||||
../../src/libstore-tests/data/path-info
|
||||
../../src/libstore-tests/data/nar-info
|
||||
../../src/libstore-tests/data/build-result
|
||||
# Too many different types of files to filter for now
|
||||
../../doc/manual
|
||||
./.
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@
|
|||
- [Architecture and Design](architecture/architecture.md)
|
||||
- [Formats and Protocols](protocols/index.md)
|
||||
- [JSON Formats](protocols/json/index.md)
|
||||
- [File System Object](protocols/json/file-system-object.md)
|
||||
- [Hash](protocols/json/hash.md)
|
||||
- [Content Address](protocols/json/content-address.md)
|
||||
- [Store Path](protocols/json/store-path.md)
|
||||
|
|
@ -127,6 +128,7 @@
|
|||
- [Derivation](protocols/json/derivation.md)
|
||||
- [Deriving Path](protocols/json/deriving-path.md)
|
||||
- [Build Trace Entry](protocols/json/build-trace-entry.md)
|
||||
- [Build Result](protocols/json/build-result.md)
|
||||
- [Serving Tarball Flakes](protocols/tarball-fetcher.md)
|
||||
- [Store Path Specification](protocols/store-path.md)
|
||||
- [Nix Archive (NAR) Format](protocols/nix-archive/index.md)
|
||||
|
|
|
|||
21
doc/manual/source/protocols/json/build-result.md
Normal file
21
doc/manual/source/protocols/json/build-result.md
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{{#include build-result-v1-fixed.md}}
|
||||
|
||||
## Examples
|
||||
|
||||
### Successful build
|
||||
|
||||
```json
|
||||
{{#include schema/build-result-v1/success.json}}
|
||||
```
|
||||
|
||||
### Failed build (output rejected)
|
||||
|
||||
```json
|
||||
{{#include schema/build-result-v1/output-rejected.json}}
|
||||
```
|
||||
|
||||
### Failed build (non-deterministic)
|
||||
|
||||
```json
|
||||
{{#include schema/build-result-v1/not-deterministic.json}}
|
||||
```
|
||||
21
doc/manual/source/protocols/json/file-system-object.md
Normal file
21
doc/manual/source/protocols/json/file-system-object.md
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{{#include file-system-object-v1-fixed.md}}
|
||||
|
||||
## Examples
|
||||
|
||||
### Simple
|
||||
|
||||
```json
|
||||
{{#include schema/file-system-object-v1/simple.json}}
|
||||
```
|
||||
|
||||
### Complex
|
||||
|
||||
```json
|
||||
{{#include schema/file-system-object-v1/complex.json}}
|
||||
```
|
||||
|
||||
<!-- need to convert YAML to JSON first
|
||||
## Raw Schema
|
||||
|
||||
[JSON Schema for File System Object v1](schema/file-system-object-v1.json)
|
||||
-->
|
||||
|
|
@ -11,6 +11,7 @@ s/\\`/`/g
|
|||
#
|
||||
# As we have more such relative links, more replacements of this nature
|
||||
# should appear below.
|
||||
s^#/\$defs/\(regular\|symlink\|directory\)^In this schema^g
|
||||
s^\(./hash-v1.yaml\)\?#/$defs/algorithm^[JSON format for `Hash`](./hash.html#algorithm)^g
|
||||
s^\(./hash-v1.yaml\)^[JSON format for `Hash`](./hash.html)^g
|
||||
s^\(./content-address-v1.yaml\)\?#/$defs/method^[JSON format for `ContentAddress`](./content-address.html#method)^g
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ json_schema_for_humans = find_program('generate-schema-doc', required : false)
|
|||
json_schema_config = files('json-schema-for-humans-config.yaml')
|
||||
|
||||
schemas = [
|
||||
'file-system-object-v1',
|
||||
'hash-v1',
|
||||
'content-address-v1',
|
||||
'store-path-v1',
|
||||
|
|
@ -16,6 +17,7 @@ schemas = [
|
|||
'derivation-v3',
|
||||
'deriving-path-v1',
|
||||
'build-trace-entry-v1',
|
||||
'build-result-v1',
|
||||
]
|
||||
|
||||
schema_files = files()
|
||||
|
|
|
|||
1
doc/manual/source/protocols/json/schema/build-result-v1
Symbolic link
1
doc/manual/source/protocols/json/schema/build-result-v1
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../../../../src/libstore-tests/data/build-result
|
||||
136
doc/manual/source/protocols/json/schema/build-result-v1.yaml
Normal file
136
doc/manual/source/protocols/json/schema/build-result-v1.yaml
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
"$schema": "http://json-schema.org/draft-04/schema"
|
||||
"$id": "https://nix.dev/manual/nix/latest/protocols/json/schema/build-result-v1.json"
|
||||
title: Build Result
|
||||
description: |
|
||||
This schema describes the JSON representation of Nix's `BuildResult` type, which represents the result of building a derivation or substituting store paths.
|
||||
|
||||
Build results can represent either successful builds (with built outputs) or various types of failures.
|
||||
|
||||
oneOf:
|
||||
- "$ref": "#/$defs/success"
|
||||
- "$ref": "#/$defs/failure"
|
||||
type: object
|
||||
required:
|
||||
- success
|
||||
- status
|
||||
properties:
|
||||
timesBuilt:
|
||||
type: integer
|
||||
minimum: 0
|
||||
title: Times built
|
||||
description: |
|
||||
How many times this build was performed.
|
||||
|
||||
startTime:
|
||||
type: integer
|
||||
minimum: 0
|
||||
title: Start time
|
||||
description: |
|
||||
The start time of the build (or one of the rounds, if it was repeated), as a Unix timestamp.
|
||||
|
||||
stopTime:
|
||||
type: integer
|
||||
minimum: 0
|
||||
title: Stop time
|
||||
description: |
|
||||
The stop time of the build (or one of the rounds, if it was repeated), as a Unix timestamp.
|
||||
|
||||
cpuUser:
|
||||
type: integer
|
||||
minimum: 0
|
||||
title: User CPU time
|
||||
description: |
|
||||
User CPU time the build took, in microseconds.
|
||||
|
||||
cpuSystem:
|
||||
type: integer
|
||||
minimum: 0
|
||||
title: System CPU time
|
||||
description: |
|
||||
System CPU time the build took, in microseconds.
|
||||
|
||||
"$defs":
|
||||
success:
|
||||
type: object
|
||||
title: Successful Build Result
|
||||
description: |
|
||||
Represents a successful build with built outputs.
|
||||
required:
|
||||
- success
|
||||
- status
|
||||
- builtOutputs
|
||||
properties:
|
||||
success:
|
||||
const: true
|
||||
title: Success indicator
|
||||
description: |
|
||||
Always true for successful build results.
|
||||
|
||||
status:
|
||||
type: string
|
||||
title: Success status
|
||||
description: |
|
||||
Status string for successful builds.
|
||||
enum:
|
||||
- "Built"
|
||||
- "Substituted"
|
||||
- "AlreadyValid"
|
||||
- "ResolvesToAlreadyValid"
|
||||
|
||||
builtOutputs:
|
||||
type: object
|
||||
title: Built outputs
|
||||
description: |
|
||||
A mapping from output names to their build trace entries.
|
||||
additionalProperties:
|
||||
"$ref": "build-trace-entry-v1.yaml"
|
||||
|
||||
failure:
|
||||
type: object
|
||||
title: Failed Build Result
|
||||
description: |
|
||||
Represents a failed build with error information.
|
||||
required:
|
||||
- success
|
||||
- status
|
||||
- errorMsg
|
||||
properties:
|
||||
success:
|
||||
const: false
|
||||
title: Success indicator
|
||||
description: |
|
||||
Always false for failed build results.
|
||||
|
||||
status:
|
||||
type: string
|
||||
title: Failure status
|
||||
description: |
|
||||
Status string for failed builds.
|
||||
enum:
|
||||
- "PermanentFailure"
|
||||
- "InputRejected"
|
||||
- "OutputRejected"
|
||||
- "TransientFailure"
|
||||
- "CachedFailure"
|
||||
- "TimedOut"
|
||||
- "MiscFailure"
|
||||
- "DependencyFailed"
|
||||
- "LogLimitExceeded"
|
||||
- "NotDeterministic"
|
||||
- "NoSubstituters"
|
||||
- "HashMismatch"
|
||||
|
||||
errorMsg:
|
||||
type: string
|
||||
title: Error message
|
||||
description: |
|
||||
Information about the error if the build failed.
|
||||
|
||||
isNonDeterministic:
|
||||
type: boolean
|
||||
title: Non-deterministic flag
|
||||
description: |
|
||||
If timesBuilt > 1, whether some builds did not produce the same result.
|
||||
|
||||
Note that 'isNonDeterministic = false' does not mean the build is deterministic,
|
||||
just that we don't have evidence of non-determinism.
|
||||
1
doc/manual/source/protocols/json/schema/file-system-object-v1
Symbolic link
1
doc/manual/source/protocols/json/schema/file-system-object-v1
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../../../../src/libutil-tests/data/memory-source-accessor
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
"$schema": http://json-schema.org/draft-04/schema#
|
||||
"$id": https://nix.dev/manual/nix/latest/protocols/json/schema/file-system-object-v1.json
|
||||
title: File System Object
|
||||
description: |
|
||||
This schema describes the JSON representation of Nix's [File System Object](@docroot@/store/file-system-object.md).
|
||||
|
||||
The schema is recursive because file system objects contain other file system objects.
|
||||
type: object
|
||||
required: ["type"]
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
enum: ["regular", "symlink", "directory"]
|
||||
|
||||
# Enforce conditional structure based on `type`
|
||||
anyOf:
|
||||
- $ref: "#/$defs/regular"
|
||||
required: ["type", "contents"]
|
||||
|
||||
- $ref: "#/$defs/symlink"
|
||||
required: ["type", "target"]
|
||||
|
||||
- $ref: "#/$defs/directory"
|
||||
required: ["type", "contents"]
|
||||
|
||||
"$defs":
|
||||
regular:
|
||||
title: Regular File
|
||||
required: ["contents"]
|
||||
properties:
|
||||
type:
|
||||
const: "regular"
|
||||
contents:
|
||||
type: string
|
||||
description: Base64-encoded file contents
|
||||
executable:
|
||||
type: boolean
|
||||
description: Whether the file is executable.
|
||||
default: false
|
||||
additionalProperties: false
|
||||
|
||||
symlink:
|
||||
title: Symbolic Link
|
||||
required: ["target"]
|
||||
properties:
|
||||
type:
|
||||
const: "symlink"
|
||||
target:
|
||||
type: string
|
||||
description: Target path of the symlink.
|
||||
additionalProperties: false
|
||||
|
||||
directory:
|
||||
title: Directory
|
||||
required: ["contents"]
|
||||
properties:
|
||||
type:
|
||||
const: "directory"
|
||||
contents:
|
||||
type: object
|
||||
description: |
|
||||
Map of names to nested file system objects (for type=directory)
|
||||
additionalProperties:
|
||||
$ref: "#"
|
||||
additionalProperties: false
|
||||
1
src/json-schema-checks/build-result
Symbolic link
1
src/json-schema-checks/build-result
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../src/libstore-tests/data/build-result
|
||||
1
src/json-schema-checks/file-system-object
Symbolic link
1
src/json-schema-checks/file-system-object
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../src/libutil-tests/data/memory-source-accessor
|
||||
|
|
@ -20,6 +20,14 @@ schema_dir = meson.current_source_dir() / 'schema'
|
|||
|
||||
# Get all example files
|
||||
schemas = [
|
||||
{
|
||||
'stem' : 'file-system-object',
|
||||
'schema' : schema_dir / 'file-system-object-v1.yaml',
|
||||
'files' : [
|
||||
'simple.json',
|
||||
'complex.json',
|
||||
],
|
||||
},
|
||||
{
|
||||
'stem' : 'hash',
|
||||
'schema' : schema_dir / 'hash-v1.yaml',
|
||||
|
|
@ -150,6 +158,15 @@ schemas += [
|
|||
'impure.json',
|
||||
],
|
||||
},
|
||||
{
|
||||
'stem' : 'build-result',
|
||||
'schema' : schema_dir / 'build-result-v1.yaml',
|
||||
'files' : [
|
||||
'success.json',
|
||||
'output-rejected.json',
|
||||
'not-deterministic.json',
|
||||
],
|
||||
},
|
||||
# Match exact variant
|
||||
{
|
||||
'stem' : 'store-object-info',
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ mkMesonDerivation (finalAttrs: {
|
|||
fileset = lib.fileset.unions [
|
||||
../../.version
|
||||
../../doc/manual/source/protocols/json/schema
|
||||
../../src/libutil-tests/data/memory-source-accessor
|
||||
../../src/libutil-tests/data/hash
|
||||
../../src/libstore-tests/data/content-address
|
||||
../../src/libstore-tests/data/store-path
|
||||
|
|
@ -28,6 +29,7 @@ mkMesonDerivation (finalAttrs: {
|
|||
../../src/libstore-tests/data/derived-path
|
||||
../../src/libstore-tests/data/path-info
|
||||
../../src/libstore-tests/data/nar-info
|
||||
../../src/libstore-tests/data/build-result
|
||||
./.
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -108,20 +108,16 @@ RealisedPath::Set BuiltPath::toRealisedPaths(Store & store) const
|
|||
overloaded{
|
||||
[&](const BuiltPath::Opaque & p) { res.insert(p.path); },
|
||||
[&](const BuiltPath::Built & p) {
|
||||
auto drvHashes = staticOutputHashes(store, store.readDerivation(p.drvPath->outPath()));
|
||||
for (auto & [outputName, outputPath] : p.outputs) {
|
||||
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)) {
|
||||
auto drvOutput = get(drvHashes, outputName);
|
||||
if (!drvOutput)
|
||||
throw Error(
|
||||
"the derivation '%s' has unrealised output '%s' (derived-path.cc/toRealisedPaths)",
|
||||
store.printStorePath(p.drvPath->outPath()),
|
||||
outputName);
|
||||
DrvOutput key{*drvOutput, outputName};
|
||||
DrvOutput key{
|
||||
.drvPath = p.drvPath->outPath(),
|
||||
.outputName = outputName,
|
||||
};
|
||||
auto thisRealisation = store.queryRealisation(key);
|
||||
assert(thisRealisation); // We’ve built it, so we must
|
||||
// have the realisation
|
||||
res.insert(Realisation{*thisRealisation, std::move(key)});
|
||||
// We’ve built it, so we must have the realisation.
|
||||
assert(thisRealisation);
|
||||
res.insert(Realisation{*thisRealisation, key});
|
||||
} else {
|
||||
res.insert(outputPath);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1718,28 +1718,7 @@ static void derivationStrictInternal(EvalState & state, std::string_view drvName
|
|||
drv.outputs.insert_or_assign(i, DerivationOutput::Deferred{});
|
||||
}
|
||||
|
||||
auto hashModulo = hashDerivationModulo(*state.store, Derivation(drv), true);
|
||||
switch (hashModulo.kind) {
|
||||
case DrvHash::Kind::Regular:
|
||||
for (auto & i : outputs) {
|
||||
auto h = get(hashModulo.hashes, i);
|
||||
if (!h)
|
||||
state.error<AssertionError>("derivation produced no hash for output '%s'", i).atPos(v).debugThrow();
|
||||
auto outPath = state.store->makeOutputPath(i, *h, drvName);
|
||||
drv.env[i] = state.store->printStorePath(outPath);
|
||||
drv.outputs.insert_or_assign(
|
||||
i,
|
||||
DerivationOutput::InputAddressed{
|
||||
.path = std::move(outPath),
|
||||
});
|
||||
}
|
||||
break;
|
||||
;
|
||||
case DrvHash::Kind::Deferred:
|
||||
for (auto & i : outputs) {
|
||||
drv.outputs.insert_or_assign(i, DerivationOutput::Deferred{});
|
||||
}
|
||||
}
|
||||
resolveInputAddressed(*state.store, drv);
|
||||
}
|
||||
|
||||
/* Write the resulting term into the Nix store directory. */
|
||||
|
|
|
|||
|
|
@ -109,7 +109,8 @@ std::pair<FlakeRef, std::string> parsePathFlakeRefWithFragment(
|
|||
|
||||
std::smatch match;
|
||||
auto succeeds = std::regex_match(url, match, pathFlakeRegex);
|
||||
assert(succeeds);
|
||||
if (!succeeds)
|
||||
throw Error("invalid flakeref '%s'", url);
|
||||
auto path = match[1].str();
|
||||
auto query = decodeQuery(match[3].str(), /*lenient=*/true);
|
||||
auto fragment = percentDecode(match[5].str());
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "nix/store/tests/libstore.hh"
|
||||
#include "nix/util/tests/characterization.hh"
|
||||
#include "nix/util/tests/json-characterization.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
@ -16,12 +17,30 @@ class ProtoTest : public CharacterizationTest
|
|||
|
||||
std::filesystem::path goldenMaster(std::string_view testStem) const override
|
||||
{
|
||||
return unitTestData / (std::string{testStem + ".bin"});
|
||||
return unitTestData / testStem;
|
||||
}
|
||||
|
||||
public:
|
||||
Path storeDir = "/nix/store";
|
||||
StoreDirConfig store{storeDir};
|
||||
|
||||
/**
|
||||
* Golden test for `T` JSON reading
|
||||
*/
|
||||
template<typename T>
|
||||
void readJsonTest(PathView testStem, const T & expected)
|
||||
{
|
||||
nix::readJsonTest(*this, testStem, expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Golden test for `T` JSON write
|
||||
*/
|
||||
template<typename T>
|
||||
void writeJsonTest(PathView testStem, const T & decoded)
|
||||
{
|
||||
nix::writeJsonTest(*this, testStem, decoded);
|
||||
}
|
||||
};
|
||||
|
||||
template<class Proto, const char * protocolDir>
|
||||
|
|
@ -34,7 +53,7 @@ public:
|
|||
template<typename T>
|
||||
void readProtoTest(PathView testStem, typename Proto::Version version, T expected)
|
||||
{
|
||||
CharacterizationTest::readTest(testStem, [&](const auto & encoded) {
|
||||
CharacterizationTest::readTest(std::string{testStem + ".bin"}, [&](const auto & encoded) {
|
||||
T got = ({
|
||||
StringSource from{encoded};
|
||||
Proto::template Serialise<T>::read(
|
||||
|
|
@ -55,7 +74,7 @@ public:
|
|||
template<typename T>
|
||||
void writeProtoTest(PathView testStem, typename Proto::Version version, const T & decoded)
|
||||
{
|
||||
CharacterizationTest::writeTest(testStem, [&]() {
|
||||
CharacterizationTest::writeTest(std::string{testStem + ".bin"}, [&]() {
|
||||
StringSink to;
|
||||
Proto::template Serialise<T>::write(
|
||||
this->store,
|
||||
|
|
@ -69,14 +88,31 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
#define VERSIONED_CHARACTERIZATION_TEST(FIXTURE, NAME, STEM, VERSION, VALUE) \
|
||||
TEST_F(FIXTURE, NAME##_read) \
|
||||
{ \
|
||||
readProtoTest(STEM, VERSION, VALUE); \
|
||||
} \
|
||||
TEST_F(FIXTURE, NAME##_write) \
|
||||
{ \
|
||||
writeProtoTest(STEM, VERSION, VALUE); \
|
||||
#define VERSIONED_READ_CHARACTERIZATION_TEST_NO_JSON(FIXTURE, NAME, STEM, VERSION, VALUE) \
|
||||
TEST_F(FIXTURE, NAME##_read) \
|
||||
{ \
|
||||
readProtoTest(STEM, VERSION, VALUE); \
|
||||
}
|
||||
|
||||
#define VERSIONED_WRITE_CHARACTERIZATION_TEST_NO_JSON(FIXTURE, NAME, STEM, VERSION, VALUE) \
|
||||
TEST_F(FIXTURE, NAME##_write) \
|
||||
{ \
|
||||
writeProtoTest(STEM, VERSION, VALUE); \
|
||||
}
|
||||
|
||||
#define VERSIONED_CHARACTERIZATION_TEST_NO_JSON(FIXTURE, NAME, STEM, VERSION, VALUE) \
|
||||
VERSIONED_READ_CHARACTERIZATION_TEST_NO_JSON(FIXTURE, NAME, STEM, VERSION, VALUE) \
|
||||
VERSIONED_WRITE_CHARACTERIZATION_TEST_NO_JSON(FIXTURE, NAME, STEM, VERSION, VALUE)
|
||||
|
||||
#define VERSIONED_CHARACTERIZATION_TEST(FIXTURE, NAME, STEM, VERSION, VALUE) \
|
||||
VERSIONED_CHARACTERIZATION_TEST_NO_JSON(FIXTURE, NAME, STEM, VERSION, VALUE) \
|
||||
TEST_F(FIXTURE, NAME##_json_read) \
|
||||
{ \
|
||||
readJsonTest(STEM, VALUE); \
|
||||
} \
|
||||
TEST_F(FIXTURE, NAME##_json_write) \
|
||||
{ \
|
||||
writeJsonTest(STEM, VALUE); \
|
||||
}
|
||||
|
||||
} // namespace nix
|
||||
|
|
|
|||
108
src/libstore-tests/build-result.cc
Normal file
108
src/libstore-tests/build-result.cc
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
#include <gtest/gtest.h>
|
||||
|
||||
#include "nix/store/build-result.hh"
|
||||
#include "nix/util/tests/json-characterization.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
class BuildResultTest : public virtual CharacterizationTest
|
||||
{
|
||||
std::filesystem::path unitTestData = getUnitTestData() / "build-result";
|
||||
|
||||
public:
|
||||
std::filesystem::path goldenMaster(std::string_view testStem) const override
|
||||
{
|
||||
return unitTestData / testStem;
|
||||
}
|
||||
};
|
||||
|
||||
using nlohmann::json;
|
||||
|
||||
struct BuildResultJsonTest : BuildResultTest,
|
||||
JsonCharacterizationTest<BuildResult>,
|
||||
::testing::WithParamInterface<std::pair<std::string_view, BuildResult>>
|
||||
{};
|
||||
|
||||
TEST_P(BuildResultJsonTest, from_json)
|
||||
{
|
||||
auto & [name, expected] = GetParam();
|
||||
readJsonTest(name, expected);
|
||||
}
|
||||
|
||||
TEST_P(BuildResultJsonTest, to_json)
|
||||
{
|
||||
auto & [name, value] = GetParam();
|
||||
writeJsonTest(name, value);
|
||||
}
|
||||
|
||||
using namespace std::literals::chrono_literals;
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
BuildResultJSON,
|
||||
BuildResultJsonTest,
|
||||
::testing::Values(
|
||||
std::pair{
|
||||
"not-deterministic",
|
||||
BuildResult{
|
||||
.inner{BuildResult::Failure{
|
||||
.status = BuildResult::Failure::NotDeterministic,
|
||||
.errorMsg = "no idea why",
|
||||
.isNonDeterministic = false, // Note: This field is separate from the status
|
||||
}},
|
||||
.timesBuilt = 1,
|
||||
},
|
||||
},
|
||||
std::pair{
|
||||
"output-rejected",
|
||||
BuildResult{
|
||||
.inner{BuildResult::Failure{
|
||||
.status = BuildResult::Failure::OutputRejected,
|
||||
.errorMsg = "no idea why",
|
||||
.isNonDeterministic = false,
|
||||
}},
|
||||
.timesBuilt = 3,
|
||||
.startTime = 30,
|
||||
.stopTime = 50,
|
||||
},
|
||||
},
|
||||
std::pair{
|
||||
"success",
|
||||
BuildResult{
|
||||
.inner{BuildResult::Success{
|
||||
.status = BuildResult::Success::Built,
|
||||
.builtOutputs{
|
||||
{
|
||||
"foo",
|
||||
{
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
},
|
||||
DrvOutput{
|
||||
.drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
|
||||
.outputName = "foo",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"bar",
|
||||
{
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar"},
|
||||
},
|
||||
DrvOutput{
|
||||
.drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
|
||||
.outputName = "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
.timesBuilt = 3,
|
||||
.startTime = 30,
|
||||
.stopTime = 50,
|
||||
.cpuUser = std::chrono::microseconds(500s),
|
||||
.cpuSystem = std::chrono::microseconds(604s),
|
||||
},
|
||||
}));
|
||||
|
||||
} // namespace nix
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
#include <nlohmann/json.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "nix/util/json-utils.hh"
|
||||
#include "nix/store/common-protocol.hh"
|
||||
#include "nix/store/common-protocol-impl.hh"
|
||||
#include "nix/store/build-result.hh"
|
||||
|
|
@ -22,7 +23,7 @@ public:
|
|||
template<typename T>
|
||||
void readProtoTest(PathView testStem, const T & expected)
|
||||
{
|
||||
CharacterizationTest::readTest(testStem, [&](const auto & encoded) {
|
||||
CharacterizationTest::readTest(std::string{testStem + ".bin"}, [&](const auto & encoded) {
|
||||
T got = ({
|
||||
StringSource from{encoded};
|
||||
CommonProto::Serialise<T>::read(store, CommonProto::ReadConn{.from = from});
|
||||
|
|
@ -38,7 +39,7 @@ public:
|
|||
template<typename T>
|
||||
void writeProtoTest(PathView testStem, const T & decoded)
|
||||
{
|
||||
CharacterizationTest::writeTest(testStem, [&]() -> std::string {
|
||||
CharacterizationTest::writeTest(std::string{testStem + ".bin"}, [&]() -> std::string {
|
||||
StringSink to;
|
||||
CommonProto::Serialise<T>::write(store, CommonProto::WriteConn{.to = to}, decoded);
|
||||
return to.s;
|
||||
|
|
@ -46,16 +47,30 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
#define CHARACTERIZATION_TEST(NAME, STEM, VALUE) \
|
||||
TEST_F(CommonProtoTest, NAME##_read) \
|
||||
{ \
|
||||
readProtoTest(STEM, VALUE); \
|
||||
} \
|
||||
TEST_F(CommonProtoTest, NAME##_write) \
|
||||
{ \
|
||||
writeProtoTest(STEM, VALUE); \
|
||||
#define READ_CHARACTERIZATION_TEST(NAME, STEM, VALUE) \
|
||||
TEST_F(CommonProtoTest, NAME##_read) \
|
||||
{ \
|
||||
readProtoTest(STEM, VALUE); \
|
||||
} \
|
||||
TEST_F(CommonProtoTest, NAME##_json_read) \
|
||||
{ \
|
||||
readJsonTest(STEM, VALUE); \
|
||||
}
|
||||
|
||||
#define WRITE_CHARACTERIZATION_TEST(NAME, STEM, VALUE) \
|
||||
TEST_F(CommonProtoTest, NAME##_write) \
|
||||
{ \
|
||||
writeProtoTest(STEM, VALUE); \
|
||||
} \
|
||||
TEST_F(CommonProtoTest, NAME##_json_write) \
|
||||
{ \
|
||||
writeJsonTest(STEM, VALUE); \
|
||||
}
|
||||
|
||||
#define CHARACTERIZATION_TEST(NAME, STEM, VALUE) \
|
||||
READ_CHARACTERIZATION_TEST(NAME, STEM, VALUE) \
|
||||
WRITE_CHARACTERIZATION_TEST(NAME, STEM, VALUE)
|
||||
|
||||
CHARACTERIZATION_TEST(
|
||||
string,
|
||||
"string",
|
||||
|
|
@ -93,71 +108,6 @@ CHARACTERIZATION_TEST(
|
|||
},
|
||||
}))
|
||||
|
||||
CHARACTERIZATION_TEST(
|
||||
drvOutput,
|
||||
"drv-output",
|
||||
(std::tuple<DrvOutput, DrvOutput>{
|
||||
{
|
||||
.drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="),
|
||||
.outputName = "baz",
|
||||
},
|
||||
DrvOutput{
|
||||
.drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
|
||||
.outputName = "quux",
|
||||
},
|
||||
}))
|
||||
|
||||
CHARACTERIZATION_TEST(
|
||||
realisation,
|
||||
"realisation",
|
||||
(std::tuple<Realisation, Realisation>{
|
||||
Realisation{
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
},
|
||||
{
|
||||
.drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="),
|
||||
.outputName = "baz",
|
||||
},
|
||||
},
|
||||
Realisation{
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
.signatures = {"asdf", "qwer"},
|
||||
},
|
||||
{
|
||||
.drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="),
|
||||
.outputName = "baz",
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
||||
CHARACTERIZATION_TEST(
|
||||
realisation_with_deps,
|
||||
"realisation-with-deps",
|
||||
(std::tuple<Realisation>{
|
||||
Realisation{
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
.signatures = {"asdf", "qwer"},
|
||||
.dependentRealisations =
|
||||
{
|
||||
{
|
||||
DrvOutput{
|
||||
.drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
|
||||
.outputName = "quux",
|
||||
},
|
||||
StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
.drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="),
|
||||
.outputName = "baz",
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
||||
CHARACTERIZATION_TEST(
|
||||
vector,
|
||||
"vector",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"errorMsg": "no idea why",
|
||||
"isNonDeterministic": false,
|
||||
"startTime": 0,
|
||||
"status": "NotDeterministic",
|
||||
"stopTime": 0,
|
||||
"success": false,
|
||||
"timesBuilt": 1
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"errorMsg": "no idea why",
|
||||
"isNonDeterministic": false,
|
||||
"startTime": 30,
|
||||
"status": "OutputRejected",
|
||||
"stopTime": 50,
|
||||
"success": false,
|
||||
"timesBuilt": 3
|
||||
}
|
||||
23
src/libstore-tests/data/build-result/success.json
Normal file
23
src/libstore-tests/data/build-result/success.json
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"builtOutputs": {
|
||||
"bar": {
|
||||
"dependentRealisations": {},
|
||||
"id": "sha256:6f869f9ea2823bda165e06076fd0de4366dead2c0e8d2dbbad277d4f15c373f5!bar",
|
||||
"outPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
|
||||
"signatures": []
|
||||
},
|
||||
"foo": {
|
||||
"dependentRealisations": {},
|
||||
"id": "sha256:6f869f9ea2823bda165e06076fd0de4366dead2c0e8d2dbbad277d4f15c373f5!foo",
|
||||
"outPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo",
|
||||
"signatures": []
|
||||
}
|
||||
},
|
||||
"cpuSystem": 604000000,
|
||||
"cpuUser": 500000000,
|
||||
"startTime": 30,
|
||||
"status": "Built",
|
||||
"stopTime": 50,
|
||||
"success": true,
|
||||
"timesBuilt": 3
|
||||
}
|
||||
26
src/libstore-tests/data/common-protocol/content-address.json
Normal file
26
src/libstore-tests/data/common-protocol/content-address.json
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
[
|
||||
{
|
||||
"hash": {
|
||||
"algorithm": "sha256",
|
||||
"format": "base64",
|
||||
"hash": "+Xc9Ll6mcPltwaewrk/BAQ56Y3G5T//wzhKUc0zrYu0="
|
||||
},
|
||||
"method": "text"
|
||||
},
|
||||
{
|
||||
"hash": {
|
||||
"algorithm": "sha1",
|
||||
"format": "base64",
|
||||
"hash": "gGemBoenViNZM3hiwqns/Fgzqwo="
|
||||
},
|
||||
"method": "flat"
|
||||
},
|
||||
{
|
||||
"hash": {
|
||||
"algorithm": "sha256",
|
||||
"format": "base64",
|
||||
"hash": "EMIJ+giQ/gLIWoxmPKjno3zHZrxbGymgzGGyZvZBIdM="
|
||||
},
|
||||
"method": "nar"
|
||||
}
|
||||
]
|
||||
4
src/libstore-tests/data/common-protocol/drv-output.json
Normal file
4
src/libstore-tests/data/common-protocol/drv-output.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"sha256:15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527!baz",
|
||||
"sha256:6f869f9ea2823bda165e06076fd0de4366dead2c0e8d2dbbad277d4f15c373f5!quux"
|
||||
]
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
[
|
||||
null,
|
||||
{
|
||||
"hash": {
|
||||
"algorithm": "sha1",
|
||||
"format": "base64",
|
||||
"hash": "gGemBoenViNZM3hiwqns/Fgzqwo="
|
||||
},
|
||||
"method": "flat"
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
null,
|
||||
"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo-bar"
|
||||
]
|
||||
22
src/libstore-tests/data/common-protocol/realisation.json
Normal file
22
src/libstore-tests/data/common-protocol/realisation.json
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
[
|
||||
{
|
||||
"dependentRealisations": {},
|
||||
"id": "sha256:15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527!baz",
|
||||
"outPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo",
|
||||
"signatures": [
|
||||
"asdf",
|
||||
"qwer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dependentRealisations": {
|
||||
"sha256:6f869f9ea2823bda165e06076fd0de4366dead2c0e8d2dbbad277d4f15c373f5!quux": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"
|
||||
},
|
||||
"id": "sha256:15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527!baz",
|
||||
"outPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo",
|
||||
"signatures": [
|
||||
"asdf",
|
||||
"qwer"
|
||||
]
|
||||
}
|
||||
]
|
||||
22
src/libstore-tests/data/common-protocol/set.json
Normal file
22
src/libstore-tests/data/common-protocol/set.json
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
[
|
||||
[],
|
||||
[
|
||||
""
|
||||
],
|
||||
[
|
||||
"",
|
||||
"bar",
|
||||
"foo"
|
||||
],
|
||||
[
|
||||
[],
|
||||
[
|
||||
""
|
||||
],
|
||||
[
|
||||
"",
|
||||
"1",
|
||||
"2"
|
||||
]
|
||||
]
|
||||
]
|
||||
4
src/libstore-tests/data/common-protocol/store-path.json
Normal file
4
src/libstore-tests/data/common-protocol/store-path.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo",
|
||||
"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo-bar"
|
||||
]
|
||||
7
src/libstore-tests/data/common-protocol/string.json
Normal file
7
src/libstore-tests/data/common-protocol/string.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
[
|
||||
"",
|
||||
"hi",
|
||||
"white rabbit",
|
||||
"大白兔",
|
||||
"oh no "
|
||||
]
|
||||
22
src/libstore-tests/data/common-protocol/vector.json
Normal file
22
src/libstore-tests/data/common-protocol/vector.json
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
[
|
||||
[],
|
||||
[
|
||||
""
|
||||
],
|
||||
[
|
||||
"",
|
||||
"foo",
|
||||
"bar"
|
||||
],
|
||||
[
|
||||
[],
|
||||
[
|
||||
""
|
||||
],
|
||||
[
|
||||
"",
|
||||
"1",
|
||||
"2"
|
||||
]
|
||||
]
|
||||
]
|
||||
46
src/libstore-tests/data/derivation/ca/all_set.json
Normal file
46
src/libstore-tests/data/derivation/ca/all_set.json
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"additionalSandboxProfile": "sandcastle",
|
||||
"allowLocalNetworking": true,
|
||||
"allowSubstitutes": false,
|
||||
"exportReferencesGraph": {
|
||||
"refs1": [
|
||||
"/164j69y6zir9z0339n8pjigg3rckinlr77bxsavzizdaaljb7nh9"
|
||||
],
|
||||
"refs2": [
|
||||
"/nix/store/qnml92yh97a6fbrs2m5qg5cqlc8vni58-bar.drv"
|
||||
]
|
||||
},
|
||||
"impureEnvVars": [
|
||||
"UNICORN"
|
||||
],
|
||||
"impureHostDeps": [
|
||||
"/usr/bin/ditto"
|
||||
],
|
||||
"noChroot": true,
|
||||
"outputChecks": {
|
||||
"forAllOutputs": {
|
||||
"allowedReferences": [
|
||||
"/164j69y6zir9z0339n8pjigg3rckinlr77bxsavzizdaaljb7nh9"
|
||||
],
|
||||
"allowedRequisites": [
|
||||
"/0nr45p69vn6izw9446wsh9bng9nndhvn19kpsm4n96a5mycw0s4z"
|
||||
],
|
||||
"disallowedReferences": [
|
||||
"/0nyw57wm2iicnm9rglvjmbci3ikmcp823czdqdzdcgsnnwqps71g"
|
||||
],
|
||||
"disallowedRequisites": [
|
||||
"/07f301yqyz8c6wf6bbbavb2q39j4n8kmcly1s09xadyhgy6x2wr8"
|
||||
],
|
||||
"ignoreSelfRefs": true,
|
||||
"maxClosureSize": null,
|
||||
"maxSize": null
|
||||
}
|
||||
},
|
||||
"passAsFile": [],
|
||||
"preferLocalBuild": true,
|
||||
"requiredSystemFeatures": [
|
||||
"rainbow",
|
||||
"uid-range"
|
||||
],
|
||||
"unsafeDiscardReferences": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
{
|
||||
"additionalSandboxProfile": "sandcastle",
|
||||
"allowLocalNetworking": true,
|
||||
"allowSubstitutes": false,
|
||||
"exportReferencesGraph": {
|
||||
"refs1": [
|
||||
"/164j69y6zir9z0339n8pjigg3rckinlr77bxsavzizdaaljb7nh9"
|
||||
],
|
||||
"refs2": [
|
||||
"/nix/store/qnml92yh97a6fbrs2m5qg5cqlc8vni58-bar.drv"
|
||||
]
|
||||
},
|
||||
"impureEnvVars": [
|
||||
"UNICORN"
|
||||
],
|
||||
"impureHostDeps": [
|
||||
"/usr/bin/ditto"
|
||||
],
|
||||
"noChroot": true,
|
||||
"outputChecks": {
|
||||
"perOutput": {
|
||||
"bin": {
|
||||
"allowedReferences": null,
|
||||
"allowedRequisites": null,
|
||||
"disallowedReferences": [
|
||||
"/0nyw57wm2iicnm9rglvjmbci3ikmcp823czdqdzdcgsnnwqps71g"
|
||||
],
|
||||
"disallowedRequisites": [
|
||||
"/07f301yqyz8c6wf6bbbavb2q39j4n8kmcly1s09xadyhgy6x2wr8"
|
||||
],
|
||||
"ignoreSelfRefs": false,
|
||||
"maxClosureSize": null,
|
||||
"maxSize": null
|
||||
},
|
||||
"dev": {
|
||||
"allowedReferences": null,
|
||||
"allowedRequisites": null,
|
||||
"disallowedReferences": [],
|
||||
"disallowedRequisites": [],
|
||||
"ignoreSelfRefs": false,
|
||||
"maxClosureSize": 5909,
|
||||
"maxSize": 789
|
||||
},
|
||||
"out": {
|
||||
"allowedReferences": [
|
||||
"/164j69y6zir9z0339n8pjigg3rckinlr77bxsavzizdaaljb7nh9"
|
||||
],
|
||||
"allowedRequisites": [
|
||||
"/0nr45p69vn6izw9446wsh9bng9nndhvn19kpsm4n96a5mycw0s4z"
|
||||
],
|
||||
"disallowedReferences": [],
|
||||
"disallowedRequisites": [],
|
||||
"ignoreSelfRefs": false,
|
||||
"maxClosureSize": null,
|
||||
"maxSize": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"passAsFile": [],
|
||||
"preferLocalBuild": true,
|
||||
"requiredSystemFeatures": [
|
||||
"rainbow",
|
||||
"uid-range"
|
||||
],
|
||||
"unsafeDiscardReferences": {}
|
||||
}
|
||||
46
src/libstore-tests/data/derivation/ia/all_set.json
Normal file
46
src/libstore-tests/data/derivation/ia/all_set.json
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"additionalSandboxProfile": "sandcastle",
|
||||
"allowLocalNetworking": true,
|
||||
"allowSubstitutes": false,
|
||||
"exportReferencesGraph": {
|
||||
"refs1": [
|
||||
"/nix/store/p0hax2lzvjpfc2gwkk62xdglz0fcqfzn-foo"
|
||||
],
|
||||
"refs2": [
|
||||
"/nix/store/vj2i49jm2868j2fmqvxm70vlzmzvgv14-bar.drv"
|
||||
]
|
||||
},
|
||||
"impureEnvVars": [
|
||||
"UNICORN"
|
||||
],
|
||||
"impureHostDeps": [
|
||||
"/usr/bin/ditto"
|
||||
],
|
||||
"noChroot": true,
|
||||
"outputChecks": {
|
||||
"forAllOutputs": {
|
||||
"allowedReferences": [
|
||||
"/nix/store/p0hax2lzvjpfc2gwkk62xdglz0fcqfzn-foo"
|
||||
],
|
||||
"allowedRequisites": [
|
||||
"/nix/store/z0rjzy29v9k5qa4nqpykrbzirj7sd43v-foo-dev"
|
||||
],
|
||||
"disallowedReferences": [
|
||||
"/nix/store/r5cff30838majxk5mp3ip2diffi8vpaj-bar"
|
||||
],
|
||||
"disallowedRequisites": [
|
||||
"/nix/store/9b61w26b4avv870dw0ymb6rw4r1hzpws-bar-dev"
|
||||
],
|
||||
"ignoreSelfRefs": true,
|
||||
"maxClosureSize": null,
|
||||
"maxSize": null
|
||||
}
|
||||
},
|
||||
"passAsFile": [],
|
||||
"preferLocalBuild": true,
|
||||
"requiredSystemFeatures": [
|
||||
"rainbow",
|
||||
"uid-range"
|
||||
],
|
||||
"unsafeDiscardReferences": {}
|
||||
}
|
||||
24
src/libstore-tests/data/derivation/ia/defaults.json
Normal file
24
src/libstore-tests/data/derivation/ia/defaults.json
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"additionalSandboxProfile": "",
|
||||
"allowLocalNetworking": false,
|
||||
"allowSubstitutes": true,
|
||||
"exportReferencesGraph": {},
|
||||
"impureEnvVars": [],
|
||||
"impureHostDeps": [],
|
||||
"noChroot": false,
|
||||
"outputChecks": {
|
||||
"forAllOutputs": {
|
||||
"allowedReferences": null,
|
||||
"allowedRequisites": null,
|
||||
"disallowedReferences": [],
|
||||
"disallowedRequisites": [],
|
||||
"ignoreSelfRefs": true,
|
||||
"maxClosureSize": null,
|
||||
"maxSize": null
|
||||
}
|
||||
},
|
||||
"passAsFile": [],
|
||||
"preferLocalBuild": false,
|
||||
"requiredSystemFeatures": [],
|
||||
"unsafeDiscardReferences": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
{
|
||||
"additionalSandboxProfile": "sandcastle",
|
||||
"allowLocalNetworking": true,
|
||||
"allowSubstitutes": false,
|
||||
"exportReferencesGraph": {
|
||||
"refs1": [
|
||||
"/nix/store/p0hax2lzvjpfc2gwkk62xdglz0fcqfzn-foo"
|
||||
],
|
||||
"refs2": [
|
||||
"/nix/store/vj2i49jm2868j2fmqvxm70vlzmzvgv14-bar.drv"
|
||||
]
|
||||
},
|
||||
"impureEnvVars": [
|
||||
"UNICORN"
|
||||
],
|
||||
"impureHostDeps": [
|
||||
"/usr/bin/ditto"
|
||||
],
|
||||
"noChroot": true,
|
||||
"outputChecks": {
|
||||
"perOutput": {
|
||||
"bin": {
|
||||
"allowedReferences": null,
|
||||
"allowedRequisites": null,
|
||||
"disallowedReferences": [
|
||||
"/nix/store/r5cff30838majxk5mp3ip2diffi8vpaj-bar"
|
||||
],
|
||||
"disallowedRequisites": [
|
||||
"/nix/store/9b61w26b4avv870dw0ymb6rw4r1hzpws-bar-dev"
|
||||
],
|
||||
"ignoreSelfRefs": false,
|
||||
"maxClosureSize": null,
|
||||
"maxSize": null
|
||||
},
|
||||
"dev": {
|
||||
"allowedReferences": null,
|
||||
"allowedRequisites": null,
|
||||
"disallowedReferences": [],
|
||||
"disallowedRequisites": [],
|
||||
"ignoreSelfRefs": false,
|
||||
"maxClosureSize": 5909,
|
||||
"maxSize": 789
|
||||
},
|
||||
"out": {
|
||||
"allowedReferences": [
|
||||
"/nix/store/p0hax2lzvjpfc2gwkk62xdglz0fcqfzn-foo"
|
||||
],
|
||||
"allowedRequisites": [
|
||||
"/nix/store/z0rjzy29v9k5qa4nqpykrbzirj7sd43v-foo-dev"
|
||||
],
|
||||
"disallowedReferences": [],
|
||||
"disallowedRequisites": [],
|
||||
"ignoreSelfRefs": false,
|
||||
"maxClosureSize": null,
|
||||
"maxSize": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"passAsFile": [],
|
||||
"preferLocalBuild": true,
|
||||
"requiredSystemFeatures": [
|
||||
"rainbow",
|
||||
"uid-range"
|
||||
],
|
||||
"unsafeDiscardReferences": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"additionalSandboxProfile": "",
|
||||
"allowLocalNetworking": false,
|
||||
"allowSubstitutes": true,
|
||||
"exportReferencesGraph": {},
|
||||
"impureEnvVars": [],
|
||||
"impureHostDeps": [],
|
||||
"noChroot": false,
|
||||
"outputChecks": {
|
||||
"perOutput": {}
|
||||
},
|
||||
"passAsFile": [],
|
||||
"preferLocalBuild": false,
|
||||
"requiredSystemFeatures": [],
|
||||
"unsafeDiscardReferences": {}
|
||||
}
|
||||
6
src/libstore-tests/data/dummy-store/empty.json
Normal file
6
src/libstore-tests/data/dummy-store/empty.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"build-trace": {},
|
||||
"contents": {},
|
||||
"derivations": {},
|
||||
"store-dir": "/nix/store"
|
||||
}
|
||||
18
src/libstore-tests/data/dummy-store/one-derivation.json
Normal file
18
src/libstore-tests/data/dummy-store/one-derivation.json
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"build-trace": {},
|
||||
"contents": {},
|
||||
"derivations": {
|
||||
"rlqjbbb65ggcx9hy577hvnn929wz1aj0-foo.drv": {
|
||||
"args": [],
|
||||
"builder": "",
|
||||
"env": {},
|
||||
"inputDrvs": {},
|
||||
"inputSrcs": [],
|
||||
"name": "foo",
|
||||
"outputs": {},
|
||||
"system": "",
|
||||
"version": 4
|
||||
}
|
||||
},
|
||||
"store-dir": "/nix/store"
|
||||
}
|
||||
35
src/libstore-tests/data/dummy-store/one-flat-file.json
Normal file
35
src/libstore-tests/data/dummy-store/one-flat-file.json
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"build-trace": {},
|
||||
"contents": {
|
||||
"5hizn7xyyrhxr0k2magvxl5ccvk0ci9n-my-file": {
|
||||
"contents": {
|
||||
"contents": "asdf",
|
||||
"executable": false,
|
||||
"type": "regular"
|
||||
},
|
||||
"info": {
|
||||
"ca": {
|
||||
"hash": {
|
||||
"algorithm": "sha256",
|
||||
"format": "base64",
|
||||
"hash": "f1eduuSIYC1BofXA1tycF79Ai2NSMJQtUErx5DxLYSU="
|
||||
},
|
||||
"method": "nar"
|
||||
},
|
||||
"deriver": null,
|
||||
"narHash": {
|
||||
"algorithm": "sha256",
|
||||
"format": "base64",
|
||||
"hash": "f1eduuSIYC1BofXA1tycF79Ai2NSMJQtUErx5DxLYSU="
|
||||
},
|
||||
"narSize": 120,
|
||||
"references": [],
|
||||
"registrationTime": null,
|
||||
"signatures": [],
|
||||
"ultimate": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"derivations": {},
|
||||
"store-dir": "/nix/store"
|
||||
}
|
||||
|
|
@ -1,6 +1,10 @@
|
|||
{
|
||||
"dependentRealisations": {},
|
||||
"id": "sha256:ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad!foo",
|
||||
"outPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv",
|
||||
"signatures": []
|
||||
"key": {
|
||||
"drvPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
|
||||
"outputName": "foo"
|
||||
},
|
||||
"value": {
|
||||
"outPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo",
|
||||
"signatures": []
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
{
|
||||
"dependentRealisations": {},
|
||||
"id": "sha256:ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad!foo",
|
||||
"outPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv",
|
||||
"signatures": [
|
||||
"asdfasdfasdf"
|
||||
]
|
||||
"key": {
|
||||
"drvPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
|
||||
"outputName": "foo"
|
||||
},
|
||||
"value": {
|
||||
"outPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo",
|
||||
"signatures": [
|
||||
"asdfasdfasdf"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
28
src/libstore-tests/data/serve-protocol/build-result-2.2.json
Normal file
28
src/libstore-tests/data/serve-protocol/build-result-2.2.json
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
[
|
||||
{
|
||||
"errorMsg": "no idea why",
|
||||
"isNonDeterministic": false,
|
||||
"startTime": 0,
|
||||
"status": "output rejected",
|
||||
"stopTime": 0,
|
||||
"success": false,
|
||||
"timesBuilt": 0
|
||||
},
|
||||
{
|
||||
"errorMsg": "no idea why",
|
||||
"isNonDeterministic": false,
|
||||
"startTime": 0,
|
||||
"status": "not deterministic",
|
||||
"stopTime": 0,
|
||||
"success": false,
|
||||
"timesBuilt": 0
|
||||
},
|
||||
{
|
||||
"builtOutputs": {},
|
||||
"startTime": 0,
|
||||
"status": "built",
|
||||
"stopTime": 0,
|
||||
"success": true,
|
||||
"timesBuilt": 0
|
||||
}
|
||||
]
|
||||
28
src/libstore-tests/data/serve-protocol/build-result-2.3.json
Normal file
28
src/libstore-tests/data/serve-protocol/build-result-2.3.json
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
[
|
||||
{
|
||||
"errorMsg": "no idea why",
|
||||
"isNonDeterministic": false,
|
||||
"startTime": 0,
|
||||
"status": "output rejected",
|
||||
"stopTime": 0,
|
||||
"success": false,
|
||||
"timesBuilt": 0
|
||||
},
|
||||
{
|
||||
"errorMsg": "no idea why",
|
||||
"isNonDeterministic": true,
|
||||
"startTime": 30,
|
||||
"status": "not deterministic",
|
||||
"stopTime": 50,
|
||||
"success": false,
|
||||
"timesBuilt": 3
|
||||
},
|
||||
{
|
||||
"builtOutputs": {},
|
||||
"startTime": 30,
|
||||
"status": "built",
|
||||
"stopTime": 50,
|
||||
"success": true,
|
||||
"timesBuilt": 0
|
||||
}
|
||||
]
|
||||
41
src/libstore-tests/data/serve-protocol/build-result-2.6.json
Normal file
41
src/libstore-tests/data/serve-protocol/build-result-2.6.json
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
[
|
||||
{
|
||||
"errorMsg": "no idea why",
|
||||
"isNonDeterministic": false,
|
||||
"startTime": 0,
|
||||
"status": "output rejected",
|
||||
"stopTime": 0,
|
||||
"success": false,
|
||||
"timesBuilt": 0
|
||||
},
|
||||
{
|
||||
"errorMsg": "no idea why",
|
||||
"isNonDeterministic": true,
|
||||
"startTime": 30,
|
||||
"status": "not deterministic",
|
||||
"stopTime": 50,
|
||||
"success": false,
|
||||
"timesBuilt": 3
|
||||
},
|
||||
{
|
||||
"builtOutputs": {
|
||||
"bar": {
|
||||
"dependentRealisations": {},
|
||||
"id": "sha256:6f869f9ea2823bda165e06076fd0de4366dead2c0e8d2dbbad277d4f15c373f5!bar",
|
||||
"outPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
|
||||
"signatures": []
|
||||
},
|
||||
"foo": {
|
||||
"dependentRealisations": {},
|
||||
"id": "sha256:6f869f9ea2823bda165e06076fd0de4366dead2c0e8d2dbbad277d4f15c373f5!foo",
|
||||
"outPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo",
|
||||
"signatures": []
|
||||
}
|
||||
},
|
||||
"startTime": 30,
|
||||
"status": "built",
|
||||
"stopTime": 50,
|
||||
"success": true,
|
||||
"timesBuilt": 1
|
||||
}
|
||||
]
|
||||
BIN
src/libstore-tests/data/serve-protocol/build-result-2.8.bin
Normal file
BIN
src/libstore-tests/data/serve-protocol/build-result-2.8.bin
Normal file
Binary file not shown.
26
src/libstore-tests/data/serve-protocol/content-address.json
Normal file
26
src/libstore-tests/data/serve-protocol/content-address.json
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
[
|
||||
{
|
||||
"hash": {
|
||||
"algorithm": "sha256",
|
||||
"format": "base64",
|
||||
"hash": "+Xc9Ll6mcPltwaewrk/BAQ56Y3G5T//wzhKUc0zrYu0="
|
||||
},
|
||||
"method": "text"
|
||||
},
|
||||
{
|
||||
"hash": {
|
||||
"algorithm": "sha1",
|
||||
"format": "base64",
|
||||
"hash": "gGemBoenViNZM3hiwqns/Fgzqwo="
|
||||
},
|
||||
"method": "flat"
|
||||
},
|
||||
{
|
||||
"hash": {
|
||||
"algorithm": "sha256",
|
||||
"format": "base64",
|
||||
"hash": "EMIJ+giQ/gLIWoxmPKjno3zHZrxbGymgzGGyZvZBIdM="
|
||||
},
|
||||
"method": "nar"
|
||||
}
|
||||
]
|
||||
BIN
src/libstore-tests/data/serve-protocol/drv-output-2.8.bin
Normal file
BIN
src/libstore-tests/data/serve-protocol/drv-output-2.8.bin
Normal file
Binary file not shown.
4
src/libstore-tests/data/serve-protocol/drv-output.json
Normal file
4
src/libstore-tests/data/serve-protocol/drv-output.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"sha256:15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527!baz",
|
||||
"sha256:6f869f9ea2823bda165e06076fd0de4366dead2c0e8d2dbbad277d4f15c373f5!quux"
|
||||
]
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
[
|
||||
null,
|
||||
{
|
||||
"hash": {
|
||||
"algorithm": "sha1",
|
||||
"format": "base64",
|
||||
"hash": "gGemBoenViNZM3hiwqns/Fgzqwo="
|
||||
},
|
||||
"method": "flat"
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
null,
|
||||
"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo-bar"
|
||||
]
|
||||
BIN
src/libstore-tests/data/serve-protocol/realisation-2.8.bin
Normal file
BIN
src/libstore-tests/data/serve-protocol/realisation-2.8.bin
Normal file
Binary file not shown.
22
src/libstore-tests/data/serve-protocol/realisation.json
Normal file
22
src/libstore-tests/data/serve-protocol/realisation.json
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
[
|
||||
{
|
||||
"dependentRealisations": {},
|
||||
"id": "sha256:15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527!baz",
|
||||
"outPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo",
|
||||
"signatures": [
|
||||
"asdf",
|
||||
"qwer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dependentRealisations": {
|
||||
"sha256:6f869f9ea2823bda165e06076fd0de4366dead2c0e8d2dbbad277d4f15c373f5!quux": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"
|
||||
},
|
||||
"id": "sha256:15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527!baz",
|
||||
"outPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo",
|
||||
"signatures": [
|
||||
"asdf",
|
||||
"qwer"
|
||||
]
|
||||
}
|
||||
]
|
||||
22
src/libstore-tests/data/serve-protocol/set.json
Normal file
22
src/libstore-tests/data/serve-protocol/set.json
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
[
|
||||
[],
|
||||
[
|
||||
""
|
||||
],
|
||||
[
|
||||
"",
|
||||
"bar",
|
||||
"foo"
|
||||
],
|
||||
[
|
||||
[],
|
||||
[
|
||||
""
|
||||
],
|
||||
[
|
||||
"",
|
||||
"1",
|
||||
"2"
|
||||
]
|
||||
]
|
||||
]
|
||||
4
src/libstore-tests/data/serve-protocol/store-path.json
Normal file
4
src/libstore-tests/data/serve-protocol/store-path.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo",
|
||||
"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo-bar"
|
||||
]
|
||||
7
src/libstore-tests/data/serve-protocol/string.json
Normal file
7
src/libstore-tests/data/serve-protocol/string.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
[
|
||||
"",
|
||||
"hi",
|
||||
"white rabbit",
|
||||
"大白兔",
|
||||
"oh no "
|
||||
]
|
||||
Binary file not shown.
|
|
@ -0,0 +1,32 @@
|
|||
[
|
||||
{
|
||||
"ca": null,
|
||||
"deriver": null,
|
||||
"narHash": {
|
||||
"algorithm": "sha256",
|
||||
"format": "base64",
|
||||
"hash": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
|
||||
},
|
||||
"narSize": 34878,
|
||||
"references": [],
|
||||
"registrationTime": null,
|
||||
"signatures": [],
|
||||
"ultimate": false
|
||||
},
|
||||
{
|
||||
"ca": null,
|
||||
"deriver": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
|
||||
"narHash": {
|
||||
"algorithm": "sha256",
|
||||
"format": "base64",
|
||||
"hash": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
|
||||
},
|
||||
"narSize": 34878,
|
||||
"references": [
|
||||
"g1w7hyyyy1w7hy3qg1w7hy3qgqqqqy3q-foo.drv"
|
||||
],
|
||||
"registrationTime": null,
|
||||
"signatures": [],
|
||||
"ultimate": false
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
[
|
||||
{
|
||||
"ca": null,
|
||||
"deriver": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
|
||||
"narHash": {
|
||||
"algorithm": "sha256",
|
||||
"format": "base64",
|
||||
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="
|
||||
},
|
||||
"narSize": 34878,
|
||||
"references": [
|
||||
"g1w7hyyyy1w7hy3qg1w7hy3qgqqqqy3q-foo.drv"
|
||||
],
|
||||
"registrationTime": null,
|
||||
"signatures": [],
|
||||
"ultimate": false
|
||||
},
|
||||
{
|
||||
"ca": {
|
||||
"hash": {
|
||||
"algorithm": "sha256",
|
||||
"format": "base64",
|
||||
"hash": "EMIJ+giQ/gLIWoxmPKjno3zHZrxbGymgzGGyZvZBIdM="
|
||||
},
|
||||
"method": "nar"
|
||||
},
|
||||
"deriver": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
|
||||
"narHash": {
|
||||
"algorithm": "sha256",
|
||||
"format": "base64",
|
||||
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="
|
||||
},
|
||||
"narSize": 34878,
|
||||
"references": [
|
||||
"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
|
||||
"n5wkd9frr45pa74if5gpz9j7mifg27fh-foo"
|
||||
],
|
||||
"registrationTime": null,
|
||||
"signatures": [
|
||||
"fake-sig-1",
|
||||
"fake-sig-2"
|
||||
],
|
||||
"ultimate": false
|
||||
}
|
||||
]
|
||||
22
src/libstore-tests/data/serve-protocol/vector.json
Normal file
22
src/libstore-tests/data/serve-protocol/vector.json
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
[
|
||||
[],
|
||||
[
|
||||
""
|
||||
],
|
||||
[
|
||||
"",
|
||||
"foo",
|
||||
"bar"
|
||||
],
|
||||
[
|
||||
[],
|
||||
[
|
||||
""
|
||||
],
|
||||
[
|
||||
"",
|
||||
"1",
|
||||
"2"
|
||||
]
|
||||
]
|
||||
]
|
||||
5
src/libstore-tests/data/worker-protocol/build-mode.json
Normal file
5
src/libstore-tests/data/worker-protocol/build-mode.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
[
|
||||
0,
|
||||
1,
|
||||
2
|
||||
]
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
[
|
||||
{
|
||||
"errorMsg": "no idea why",
|
||||
"isNonDeterministic": false,
|
||||
"startTime": 0,
|
||||
"status": "output rejected",
|
||||
"stopTime": 0,
|
||||
"success": false,
|
||||
"timesBuilt": 0
|
||||
},
|
||||
{
|
||||
"errorMsg": "no idea why",
|
||||
"isNonDeterministic": false,
|
||||
"startTime": 0,
|
||||
"status": "not deterministic",
|
||||
"stopTime": 0,
|
||||
"success": false,
|
||||
"timesBuilt": 0
|
||||
},
|
||||
{
|
||||
"builtOutputs": {},
|
||||
"startTime": 0,
|
||||
"status": "built",
|
||||
"stopTime": 0,
|
||||
"success": true,
|
||||
"timesBuilt": 0
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
[
|
||||
{
|
||||
"errorMsg": "no idea why",
|
||||
"isNonDeterministic": false,
|
||||
"startTime": 0,
|
||||
"status": "output rejected",
|
||||
"stopTime": 0,
|
||||
"success": false,
|
||||
"timesBuilt": 0
|
||||
},
|
||||
{
|
||||
"errorMsg": "no idea why",
|
||||
"isNonDeterministic": false,
|
||||
"startTime": 0,
|
||||
"status": "not deterministic",
|
||||
"stopTime": 0,
|
||||
"success": false,
|
||||
"timesBuilt": 0
|
||||
},
|
||||
{
|
||||
"builtOutputs": {
|
||||
"bar": {
|
||||
"dependentRealisations": {},
|
||||
"id": "sha256:6f869f9ea2823bda165e06076fd0de4366dead2c0e8d2dbbad277d4f15c373f5!bar",
|
||||
"outPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
|
||||
"signatures": []
|
||||
},
|
||||
"foo": {
|
||||
"dependentRealisations": {},
|
||||
"id": "sha256:6f869f9ea2823bda165e06076fd0de4366dead2c0e8d2dbbad277d4f15c373f5!foo",
|
||||
"outPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo",
|
||||
"signatures": []
|
||||
}
|
||||
},
|
||||
"startTime": 0,
|
||||
"status": "built",
|
||||
"stopTime": 0,
|
||||
"success": true,
|
||||
"timesBuilt": 0
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
[
|
||||
{
|
||||
"errorMsg": "no idea why",
|
||||
"isNonDeterministic": false,
|
||||
"startTime": 0,
|
||||
"status": "output rejected",
|
||||
"stopTime": 0,
|
||||
"success": false,
|
||||
"timesBuilt": 0
|
||||
},
|
||||
{
|
||||
"errorMsg": "no idea why",
|
||||
"isNonDeterministic": true,
|
||||
"startTime": 30,
|
||||
"status": "not deterministic",
|
||||
"stopTime": 50,
|
||||
"success": false,
|
||||
"timesBuilt": 3
|
||||
},
|
||||
{
|
||||
"builtOutputs": {
|
||||
"bar": {
|
||||
"dependentRealisations": {},
|
||||
"id": "sha256:6f869f9ea2823bda165e06076fd0de4366dead2c0e8d2dbbad277d4f15c373f5!bar",
|
||||
"outPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
|
||||
"signatures": []
|
||||
},
|
||||
"foo": {
|
||||
"dependentRealisations": {},
|
||||
"id": "sha256:6f869f9ea2823bda165e06076fd0de4366dead2c0e8d2dbbad277d4f15c373f5!foo",
|
||||
"outPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo",
|
||||
"signatures": []
|
||||
}
|
||||
},
|
||||
"startTime": 30,
|
||||
"status": "built",
|
||||
"stopTime": 50,
|
||||
"success": true,
|
||||
"timesBuilt": 1
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
[
|
||||
{
|
||||
"errorMsg": "no idea why",
|
||||
"isNonDeterministic": false,
|
||||
"startTime": 0,
|
||||
"status": "output rejected",
|
||||
"stopTime": 0,
|
||||
"success": false,
|
||||
"timesBuilt": 0
|
||||
},
|
||||
{
|
||||
"errorMsg": "no idea why",
|
||||
"isNonDeterministic": true,
|
||||
"startTime": 30,
|
||||
"status": "not deterministic",
|
||||
"stopTime": 50,
|
||||
"success": false,
|
||||
"timesBuilt": 3
|
||||
},
|
||||
{
|
||||
"builtOutputs": {
|
||||
"bar": {
|
||||
"dependentRealisations": {},
|
||||
"id": "sha256:6f869f9ea2823bda165e06076fd0de4366dead2c0e8d2dbbad277d4f15c373f5!bar",
|
||||
"outPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
|
||||
"signatures": []
|
||||
},
|
||||
"foo": {
|
||||
"dependentRealisations": {},
|
||||
"id": "sha256:6f869f9ea2823bda165e06076fd0de4366dead2c0e8d2dbbad277d4f15c373f5!foo",
|
||||
"outPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo",
|
||||
"signatures": []
|
||||
}
|
||||
},
|
||||
"cpuSystem": 604000000,
|
||||
"cpuUser": 500000000,
|
||||
"startTime": 30,
|
||||
"status": "built",
|
||||
"stopTime": 50,
|
||||
"success": true,
|
||||
"timesBuilt": 1
|
||||
}
|
||||
]
|
||||
BIN
src/libstore-tests/data/worker-protocol/build-result-1.39.bin
Normal file
BIN
src/libstore-tests/data/worker-protocol/build-result-1.39.bin
Normal file
Binary file not shown.
26
src/libstore-tests/data/worker-protocol/content-address.json
Normal file
26
src/libstore-tests/data/worker-protocol/content-address.json
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
[
|
||||
{
|
||||
"hash": {
|
||||
"algorithm": "sha256",
|
||||
"format": "base64",
|
||||
"hash": "+Xc9Ll6mcPltwaewrk/BAQ56Y3G5T//wzhKUc0zrYu0="
|
||||
},
|
||||
"method": "text"
|
||||
},
|
||||
{
|
||||
"hash": {
|
||||
"algorithm": "sha1",
|
||||
"format": "base64",
|
||||
"hash": "gGemBoenViNZM3hiwqns/Fgzqwo="
|
||||
},
|
||||
"method": "flat"
|
||||
},
|
||||
{
|
||||
"hash": {
|
||||
"algorithm": "sha256",
|
||||
"format": "base64",
|
||||
"hash": "EMIJ+giQ/gLIWoxmPKjno3zHZrxbGymgzGGyZvZBIdM="
|
||||
},
|
||||
"method": "nar"
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
[
|
||||
"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo",
|
||||
{
|
||||
"drvPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
|
||||
"outputs": [
|
||||
"*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"drvPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
|
||||
"outputs": [
|
||||
"x",
|
||||
"y"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
[
|
||||
"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo",
|
||||
"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv",
|
||||
{
|
||||
"drvPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
|
||||
"outputs": [
|
||||
"*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"drvPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
|
||||
"outputs": [
|
||||
"x",
|
||||
"y"
|
||||
]
|
||||
}
|
||||
]
|
||||
BIN
src/libstore-tests/data/worker-protocol/drv-output-1.39.bin
Normal file
BIN
src/libstore-tests/data/worker-protocol/drv-output-1.39.bin
Normal file
Binary file not shown.
4
src/libstore-tests/data/worker-protocol/drv-output.json
Normal file
4
src/libstore-tests/data/worker-protocol/drv-output.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"sha256:15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527!baz",
|
||||
"sha256:6f869f9ea2823bda165e06076fd0de4366dead2c0e8d2dbbad277d4f15c373f5!quux"
|
||||
]
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
[
|
||||
{
|
||||
"errorMsg": "no idea why",
|
||||
"isNonDeterministic": false,
|
||||
"path": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-xxx",
|
||||
"startTime": 0,
|
||||
"status": "output rejected",
|
||||
"stopTime": 0,
|
||||
"success": false,
|
||||
"timesBuilt": 0
|
||||
},
|
||||
{
|
||||
"errorMsg": "no idea why",
|
||||
"isNonDeterministic": true,
|
||||
"path": {
|
||||
"drvPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
|
||||
"outputs": [
|
||||
"out"
|
||||
]
|
||||
},
|
||||
"startTime": 30,
|
||||
"status": "not deterministic",
|
||||
"stopTime": 50,
|
||||
"success": false,
|
||||
"timesBuilt": 3
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
[
|
||||
null,
|
||||
{
|
||||
"hash": {
|
||||
"algorithm": "sha1",
|
||||
"format": "base64",
|
||||
"hash": "gGemBoenViNZM3hiwqns/Fgzqwo="
|
||||
},
|
||||
"method": "flat"
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
null,
|
||||
"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo-bar"
|
||||
]
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
[
|
||||
null,
|
||||
true,
|
||||
false
|
||||
]
|
||||
BIN
src/libstore-tests/data/worker-protocol/realisation-1.39.bin
Normal file
BIN
src/libstore-tests/data/worker-protocol/realisation-1.39.bin
Normal file
Binary file not shown.
22
src/libstore-tests/data/worker-protocol/realisation.json
Normal file
22
src/libstore-tests/data/worker-protocol/realisation.json
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
[
|
||||
{
|
||||
"dependentRealisations": {},
|
||||
"id": "sha256:15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527!baz",
|
||||
"outPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo",
|
||||
"signatures": [
|
||||
"asdf",
|
||||
"qwer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dependentRealisations": {
|
||||
"sha256:6f869f9ea2823bda165e06076fd0de4366dead2c0e8d2dbbad277d4f15c373f5!quux": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"
|
||||
},
|
||||
"id": "sha256:15e3c560894cbb27085cf65b5a2ecb18488c999497f4531b6907a7581ce6d527!baz",
|
||||
"outPath": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo",
|
||||
"signatures": [
|
||||
"asdf",
|
||||
"qwer"
|
||||
]
|
||||
}
|
||||
]
|
||||
22
src/libstore-tests/data/worker-protocol/set.json
Normal file
22
src/libstore-tests/data/worker-protocol/set.json
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
[
|
||||
[],
|
||||
[
|
||||
""
|
||||
],
|
||||
[
|
||||
"",
|
||||
"bar",
|
||||
"foo"
|
||||
],
|
||||
[
|
||||
[],
|
||||
[
|
||||
""
|
||||
],
|
||||
[
|
||||
"",
|
||||
"1",
|
||||
"2"
|
||||
]
|
||||
]
|
||||
]
|
||||
4
src/libstore-tests/data/worker-protocol/store-path.json
Normal file
4
src/libstore-tests/data/worker-protocol/store-path.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo",
|
||||
"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo-bar"
|
||||
]
|
||||
7
src/libstore-tests/data/worker-protocol/string.json
Normal file
7
src/libstore-tests/data/worker-protocol/string.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
[
|
||||
"",
|
||||
"hi",
|
||||
"white rabbit",
|
||||
"大白兔",
|
||||
"oh no "
|
||||
]
|
||||
Binary file not shown.
|
|
@ -0,0 +1,32 @@
|
|||
[
|
||||
{
|
||||
"ca": null,
|
||||
"deriver": null,
|
||||
"narHash": {
|
||||
"algorithm": "sha256",
|
||||
"format": "base64",
|
||||
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="
|
||||
},
|
||||
"narSize": 34878,
|
||||
"references": [],
|
||||
"registrationTime": 23423,
|
||||
"signatures": [],
|
||||
"ultimate": false
|
||||
},
|
||||
{
|
||||
"ca": null,
|
||||
"deriver": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
|
||||
"narHash": {
|
||||
"algorithm": "sha256",
|
||||
"format": "base64",
|
||||
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="
|
||||
},
|
||||
"narSize": 34878,
|
||||
"references": [
|
||||
"g1w7hyyyy1w7hy3qg1w7hy3qgqqqqy3q-foo.drv"
|
||||
],
|
||||
"registrationTime": 23423,
|
||||
"signatures": [],
|
||||
"ultimate": false
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
[
|
||||
{
|
||||
"ca": null,
|
||||
"deriver": null,
|
||||
"narHash": {
|
||||
"algorithm": "sha256",
|
||||
"format": "base64",
|
||||
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="
|
||||
},
|
||||
"narSize": 34878,
|
||||
"path": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
|
||||
"references": [],
|
||||
"registrationTime": 23423,
|
||||
"signatures": [],
|
||||
"ultimate": false
|
||||
},
|
||||
{
|
||||
"ca": null,
|
||||
"deriver": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
|
||||
"narHash": {
|
||||
"algorithm": "sha256",
|
||||
"format": "base64",
|
||||
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="
|
||||
},
|
||||
"narSize": 34878,
|
||||
"path": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
|
||||
"references": [
|
||||
"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
|
||||
"g1w7hyyyy1w7hy3qg1w7hy3qgqqqqy3q-foo"
|
||||
],
|
||||
"registrationTime": 23423,
|
||||
"signatures": [],
|
||||
"ultimate": false
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
[
|
||||
{
|
||||
"ca": null,
|
||||
"deriver": null,
|
||||
"narHash": {
|
||||
"algorithm": "sha256",
|
||||
"format": "base64",
|
||||
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="
|
||||
},
|
||||
"narSize": 34878,
|
||||
"path": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
|
||||
"references": [],
|
||||
"registrationTime": 23423,
|
||||
"signatures": [],
|
||||
"ultimate": true
|
||||
},
|
||||
{
|
||||
"ca": null,
|
||||
"deriver": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
|
||||
"narHash": {
|
||||
"algorithm": "sha256",
|
||||
"format": "base64",
|
||||
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="
|
||||
},
|
||||
"narSize": 34878,
|
||||
"path": "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
|
||||
"references": [
|
||||
"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
|
||||
"g1w7hyyyy1w7hy3qg1w7hy3qgqqqqy3q-foo"
|
||||
],
|
||||
"registrationTime": 23423,
|
||||
"signatures": [
|
||||
"fake-sig-1",
|
||||
"fake-sig-2"
|
||||
],
|
||||
"ultimate": false
|
||||
},
|
||||
{
|
||||
"ca": {
|
||||
"hash": {
|
||||
"algorithm": "sha256",
|
||||
"format": "base64",
|
||||
"hash": "EMIJ+giQ/gLIWoxmPKjno3zHZrxbGymgzGGyZvZBIdM="
|
||||
},
|
||||
"method": "nar"
|
||||
},
|
||||
"deriver": null,
|
||||
"narHash": {
|
||||
"algorithm": "sha256",
|
||||
"format": "base64",
|
||||
"hash": "FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="
|
||||
},
|
||||
"narSize": 34878,
|
||||
"path": "n5wkd9frr45pa74if5gpz9j7mifg27fh-foo",
|
||||
"references": [
|
||||
"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
|
||||
"n5wkd9frr45pa74if5gpz9j7mifg27fh-foo"
|
||||
],
|
||||
"registrationTime": 23423,
|
||||
"signatures": [],
|
||||
"ultimate": false
|
||||
}
|
||||
]
|
||||
22
src/libstore-tests/data/worker-protocol/vector.json
Normal file
22
src/libstore-tests/data/worker-protocol/vector.json
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
[
|
||||
[],
|
||||
[
|
||||
""
|
||||
],
|
||||
[
|
||||
"",
|
||||
"foo",
|
||||
"bar"
|
||||
],
|
||||
[
|
||||
[],
|
||||
[
|
||||
""
|
||||
],
|
||||
[
|
||||
"",
|
||||
"1",
|
||||
"2"
|
||||
]
|
||||
]
|
||||
]
|
||||
|
|
@ -10,13 +10,15 @@
|
|||
#include "nix/util/json-utils.hh"
|
||||
|
||||
#include "nix/store/tests/libstore.hh"
|
||||
#include "nix/util/tests/characterization.hh"
|
||||
#include "nix/util/tests/json-characterization.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
using namespace nlohmann;
|
||||
|
||||
class DerivationAdvancedAttrsTest : public CharacterizationTest, public LibStoreTest
|
||||
class DerivationAdvancedAttrsTest : public JsonCharacterizationTest<Derivation>,
|
||||
public JsonCharacterizationTest<DerivationOptions>,
|
||||
public LibStoreTest
|
||||
{
|
||||
protected:
|
||||
std::filesystem::path unitTestData = getUnitTestData() / "derivation" / "ia";
|
||||
|
|
@ -32,6 +34,33 @@ public:
|
|||
* to worry about race conditions if the tests run concurrently.
|
||||
*/
|
||||
ExperimentalFeatureSettings mockXpSettings;
|
||||
|
||||
/**
|
||||
* Helper function to test getRequiredSystemFeatures for a given derivation file
|
||||
*/
|
||||
void testRequiredSystemFeatures(const std::string & fileName, const StringSet & expectedFeatures)
|
||||
{
|
||||
this->readTest(fileName, [&](auto encoded) {
|
||||
auto got = parseDerivation(*this->store, std::move(encoded), "foo", this->mockXpSettings);
|
||||
DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs);
|
||||
EXPECT_EQ(options.getRequiredSystemFeatures(got), expectedFeatures);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to test DerivationOptions parsing and comparison
|
||||
*/
|
||||
void testDerivationOptions(
|
||||
const std::string & fileName, const DerivationOptions & expected, const StringSet & expectedSystemFeatures)
|
||||
{
|
||||
this->readTest(fileName, [&](auto encoded) {
|
||||
auto got = parseDerivation(*this->store, std::move(encoded), "foo", this->mockXpSettings);
|
||||
DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs);
|
||||
|
||||
EXPECT_EQ(options, expected);
|
||||
EXPECT_EQ(options.getRequiredSystemFeatures(got), expectedSystemFeatures);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
class CaDerivationAdvancedAttrsTest : public DerivationAdvancedAttrsTest
|
||||
|
|
@ -100,33 +129,35 @@ TEST_ATERM_JSON(advancedAttributes_structuredAttrs_defaults, "advanced-attribute
|
|||
|
||||
using ExportReferencesMap = decltype(DerivationOptions::exportReferencesGraph);
|
||||
|
||||
static const DerivationOptions advancedAttributes_defaults = {
|
||||
.outputChecks =
|
||||
DerivationOptions::OutputChecks{
|
||||
.ignoreSelfRefs = true,
|
||||
},
|
||||
.unsafeDiscardReferences = {},
|
||||
.passAsFile = {},
|
||||
.exportReferencesGraph = {},
|
||||
.additionalSandboxProfile = "",
|
||||
.noChroot = false,
|
||||
.impureHostDeps = {},
|
||||
.impureEnvVars = {},
|
||||
.allowLocalNetworking = false,
|
||||
.requiredSystemFeatures = {},
|
||||
.preferLocalBuild = false,
|
||||
.allowSubstitutes = true,
|
||||
};
|
||||
|
||||
TYPED_TEST(DerivationAdvancedAttrsBothTest, advancedAttributes_defaults)
|
||||
{
|
||||
this->readTest("advanced-attributes-defaults.drv", [&](auto encoded) {
|
||||
auto got = parseDerivation(*this->store, std::move(encoded), "foo", this->mockXpSettings);
|
||||
|
||||
auto drvPath = writeDerivation(*this->store, got, NoRepair, true);
|
||||
|
||||
DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs);
|
||||
|
||||
EXPECT_TRUE(!got.structuredAttrs);
|
||||
|
||||
EXPECT_EQ(options.additionalSandboxProfile, "");
|
||||
EXPECT_EQ(options.noChroot, false);
|
||||
EXPECT_EQ(options.impureHostDeps, StringSet{});
|
||||
EXPECT_EQ(options.impureEnvVars, StringSet{});
|
||||
EXPECT_EQ(options.allowLocalNetworking, false);
|
||||
EXPECT_EQ(options.exportReferencesGraph, ExportReferencesMap{});
|
||||
{
|
||||
auto * checksForAllOutputs_ = std::get_if<0>(&options.outputChecks);
|
||||
ASSERT_TRUE(checksForAllOutputs_ != nullptr);
|
||||
auto & checksForAllOutputs = *checksForAllOutputs_;
|
||||
EXPECT_EQ(options, advancedAttributes_defaults);
|
||||
|
||||
EXPECT_EQ(checksForAllOutputs.allowedReferences, std::nullopt);
|
||||
EXPECT_EQ(checksForAllOutputs.allowedRequisites, std::nullopt);
|
||||
EXPECT_EQ(checksForAllOutputs.disallowedReferences, StringSet{});
|
||||
EXPECT_EQ(checksForAllOutputs.disallowedRequisites, StringSet{});
|
||||
}
|
||||
EXPECT_EQ(options.canBuildLocally(*this->store, got), false);
|
||||
EXPECT_EQ(options.willBuildLocally(*this->store, got), false);
|
||||
EXPECT_EQ(options.substitutesAllowed(), true);
|
||||
|
|
@ -136,152 +167,124 @@ TYPED_TEST(DerivationAdvancedAttrsBothTest, advancedAttributes_defaults)
|
|||
|
||||
TEST_F(DerivationAdvancedAttrsTest, advancedAttributes_defaults)
|
||||
{
|
||||
this->readTest("advanced-attributes-defaults.drv", [&](auto encoded) {
|
||||
auto got = parseDerivation(*this->store, std::move(encoded), "foo", this->mockXpSettings);
|
||||
|
||||
auto drvPath = writeDerivation(*this->store, got, NoRepair, true);
|
||||
|
||||
DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs);
|
||||
|
||||
EXPECT_EQ(options.getRequiredSystemFeatures(got), StringSet{});
|
||||
});
|
||||
testRequiredSystemFeatures("advanced-attributes-defaults.drv", {});
|
||||
};
|
||||
|
||||
TEST_F(CaDerivationAdvancedAttrsTest, advancedAttributes_defaults)
|
||||
{
|
||||
this->readTest("advanced-attributes-defaults.drv", [&](auto encoded) {
|
||||
auto got = parseDerivation(*this->store, std::move(encoded), "foo", this->mockXpSettings);
|
||||
|
||||
auto drvPath = writeDerivation(*this->store, got, NoRepair, true);
|
||||
|
||||
DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs);
|
||||
|
||||
EXPECT_EQ(options.getRequiredSystemFeatures(got), StringSet{"ca-derivations"});
|
||||
});
|
||||
testRequiredSystemFeatures("advanced-attributes-defaults.drv", {"ca-derivations"});
|
||||
};
|
||||
|
||||
TYPED_TEST(DerivationAdvancedAttrsBothTest, advancedAttributes)
|
||||
{
|
||||
DerivationOptions expected = {
|
||||
.outputChecks =
|
||||
DerivationOptions::OutputChecks{
|
||||
.ignoreSelfRefs = true,
|
||||
},
|
||||
.unsafeDiscardReferences = {},
|
||||
.passAsFile = {},
|
||||
.additionalSandboxProfile = "sandcastle",
|
||||
.noChroot = true,
|
||||
.impureHostDeps = {"/usr/bin/ditto"},
|
||||
.impureEnvVars = {"UNICORN"},
|
||||
.allowLocalNetworking = true,
|
||||
.requiredSystemFeatures = {"rainbow", "uid-range"},
|
||||
.preferLocalBuild = true,
|
||||
.allowSubstitutes = false,
|
||||
};
|
||||
|
||||
this->readTest("advanced-attributes.drv", [&](auto encoded) {
|
||||
auto got = parseDerivation(*this->store, std::move(encoded), "foo", this->mockXpSettings);
|
||||
|
||||
auto drvPath = writeDerivation(*this->store, got, NoRepair, true);
|
||||
|
||||
DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs);
|
||||
|
||||
EXPECT_TRUE(!got.structuredAttrs);
|
||||
|
||||
EXPECT_EQ(options.additionalSandboxProfile, "sandcastle");
|
||||
EXPECT_EQ(options.noChroot, true);
|
||||
EXPECT_EQ(options.impureHostDeps, StringSet{"/usr/bin/ditto"});
|
||||
EXPECT_EQ(options.impureEnvVars, StringSet{"UNICORN"});
|
||||
EXPECT_EQ(options.allowLocalNetworking, true);
|
||||
EXPECT_EQ(options.canBuildLocally(*this->store, got), false);
|
||||
EXPECT_EQ(options.willBuildLocally(*this->store, got), false);
|
||||
// Reset fields that vary between test cases to enable whole-object comparison
|
||||
options.outputChecks = DerivationOptions::OutputChecks{.ignoreSelfRefs = true};
|
||||
options.exportReferencesGraph = {};
|
||||
|
||||
EXPECT_EQ(options, expected);
|
||||
|
||||
EXPECT_EQ(options.substitutesAllowed(), false);
|
||||
EXPECT_EQ(options.useUidRange(got), true);
|
||||
});
|
||||
};
|
||||
|
||||
TEST_F(DerivationAdvancedAttrsTest, advancedAttributes)
|
||||
DerivationOptions advancedAttributes_ia = {
|
||||
.outputChecks =
|
||||
DerivationOptions::OutputChecks{
|
||||
.ignoreSelfRefs = true,
|
||||
.allowedReferences = StringSet{"/nix/store/p0hax2lzvjpfc2gwkk62xdglz0fcqfzn-foo"},
|
||||
.disallowedReferences = StringSet{"/nix/store/r5cff30838majxk5mp3ip2diffi8vpaj-bar"},
|
||||
.allowedRequisites = StringSet{"/nix/store/z0rjzy29v9k5qa4nqpykrbzirj7sd43v-foo-dev"},
|
||||
.disallowedRequisites = StringSet{"/nix/store/9b61w26b4avv870dw0ymb6rw4r1hzpws-bar-dev"},
|
||||
},
|
||||
.unsafeDiscardReferences = {},
|
||||
.passAsFile = {},
|
||||
.exportReferencesGraph{
|
||||
{"refs1", {"/nix/store/p0hax2lzvjpfc2gwkk62xdglz0fcqfzn-foo"}},
|
||||
{"refs2", {"/nix/store/vj2i49jm2868j2fmqvxm70vlzmzvgv14-bar.drv"}},
|
||||
},
|
||||
.additionalSandboxProfile = "sandcastle",
|
||||
.noChroot = true,
|
||||
.impureHostDeps = {"/usr/bin/ditto"},
|
||||
.impureEnvVars = {"UNICORN"},
|
||||
.allowLocalNetworking = true,
|
||||
.requiredSystemFeatures = {"rainbow", "uid-range"},
|
||||
.preferLocalBuild = true,
|
||||
.allowSubstitutes = false,
|
||||
};
|
||||
|
||||
TEST_F(DerivationAdvancedAttrsTest, advancedAttributes_ia)
|
||||
{
|
||||
this->readTest("advanced-attributes.drv", [&](auto encoded) {
|
||||
auto got = parseDerivation(*this->store, std::move(encoded), "foo", this->mockXpSettings);
|
||||
testDerivationOptions("advanced-attributes.drv", advancedAttributes_ia, {"rainbow", "uid-range"});
|
||||
};
|
||||
|
||||
auto drvPath = writeDerivation(*this->store, got, NoRepair, true);
|
||||
|
||||
DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs);
|
||||
|
||||
EXPECT_EQ(
|
||||
options.exportReferencesGraph,
|
||||
(ExportReferencesMap{
|
||||
{
|
||||
"refs1",
|
||||
{
|
||||
"/nix/store/p0hax2lzvjpfc2gwkk62xdglz0fcqfzn-foo",
|
||||
},
|
||||
},
|
||||
{
|
||||
"refs2",
|
||||
{
|
||||
"/nix/store/vj2i49jm2868j2fmqvxm70vlzmzvgv14-bar.drv",
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
{
|
||||
auto * checksForAllOutputs_ = std::get_if<0>(&options.outputChecks);
|
||||
ASSERT_TRUE(checksForAllOutputs_ != nullptr);
|
||||
auto & checksForAllOutputs = *checksForAllOutputs_;
|
||||
|
||||
EXPECT_EQ(
|
||||
checksForAllOutputs.allowedReferences, StringSet{"/nix/store/p0hax2lzvjpfc2gwkk62xdglz0fcqfzn-foo"});
|
||||
EXPECT_EQ(
|
||||
checksForAllOutputs.allowedRequisites,
|
||||
StringSet{"/nix/store/z0rjzy29v9k5qa4nqpykrbzirj7sd43v-foo-dev"});
|
||||
EXPECT_EQ(
|
||||
checksForAllOutputs.disallowedReferences, StringSet{"/nix/store/r5cff30838majxk5mp3ip2diffi8vpaj-bar"});
|
||||
EXPECT_EQ(
|
||||
checksForAllOutputs.disallowedRequisites,
|
||||
StringSet{"/nix/store/9b61w26b4avv870dw0ymb6rw4r1hzpws-bar-dev"});
|
||||
}
|
||||
|
||||
StringSet systemFeatures{"rainbow", "uid-range"};
|
||||
|
||||
EXPECT_EQ(options.getRequiredSystemFeatures(got), systemFeatures);
|
||||
});
|
||||
DerivationOptions advancedAttributes_ca = {
|
||||
.outputChecks =
|
||||
DerivationOptions::OutputChecks{
|
||||
.ignoreSelfRefs = true,
|
||||
.allowedReferences = StringSet{"/164j69y6zir9z0339n8pjigg3rckinlr77bxsavzizdaaljb7nh9"},
|
||||
.disallowedReferences = StringSet{"/0nyw57wm2iicnm9rglvjmbci3ikmcp823czdqdzdcgsnnwqps71g"},
|
||||
.allowedRequisites = StringSet{"/0nr45p69vn6izw9446wsh9bng9nndhvn19kpsm4n96a5mycw0s4z"},
|
||||
.disallowedRequisites = StringSet{"/07f301yqyz8c6wf6bbbavb2q39j4n8kmcly1s09xadyhgy6x2wr8"},
|
||||
},
|
||||
.unsafeDiscardReferences = {},
|
||||
.passAsFile = {},
|
||||
.exportReferencesGraph{
|
||||
{"refs1", {"/164j69y6zir9z0339n8pjigg3rckinlr77bxsavzizdaaljb7nh9"}},
|
||||
{"refs2", {"/nix/store/qnml92yh97a6fbrs2m5qg5cqlc8vni58-bar.drv"}},
|
||||
},
|
||||
.additionalSandboxProfile = "sandcastle",
|
||||
.noChroot = true,
|
||||
.impureHostDeps = {"/usr/bin/ditto"},
|
||||
.impureEnvVars = {"UNICORN"},
|
||||
.allowLocalNetworking = true,
|
||||
.requiredSystemFeatures = {"rainbow", "uid-range"},
|
||||
.preferLocalBuild = true,
|
||||
.allowSubstitutes = false,
|
||||
};
|
||||
|
||||
TEST_F(CaDerivationAdvancedAttrsTest, advancedAttributes)
|
||||
{
|
||||
this->readTest("advanced-attributes.drv", [&](auto encoded) {
|
||||
auto got = parseDerivation(*this->store, std::move(encoded), "foo", this->mockXpSettings);
|
||||
testDerivationOptions("advanced-attributes.drv", advancedAttributes_ca, {"rainbow", "uid-range", "ca-derivations"});
|
||||
};
|
||||
|
||||
auto drvPath = writeDerivation(*this->store, got, NoRepair, true);
|
||||
|
||||
DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs);
|
||||
|
||||
EXPECT_EQ(
|
||||
options.exportReferencesGraph,
|
||||
(ExportReferencesMap{
|
||||
{
|
||||
"refs1",
|
||||
{
|
||||
"/164j69y6zir9z0339n8pjigg3rckinlr77bxsavzizdaaljb7nh9",
|
||||
},
|
||||
},
|
||||
{
|
||||
"refs2",
|
||||
{
|
||||
"/nix/store/qnml92yh97a6fbrs2m5qg5cqlc8vni58-bar.drv",
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
{
|
||||
auto * checksForAllOutputs_ = std::get_if<0>(&options.outputChecks);
|
||||
ASSERT_TRUE(checksForAllOutputs_ != nullptr);
|
||||
auto & checksForAllOutputs = *checksForAllOutputs_;
|
||||
|
||||
EXPECT_EQ(
|
||||
checksForAllOutputs.allowedReferences,
|
||||
StringSet{"/164j69y6zir9z0339n8pjigg3rckinlr77bxsavzizdaaljb7nh9"});
|
||||
EXPECT_EQ(
|
||||
checksForAllOutputs.allowedRequisites,
|
||||
StringSet{"/0nr45p69vn6izw9446wsh9bng9nndhvn19kpsm4n96a5mycw0s4z"});
|
||||
EXPECT_EQ(
|
||||
checksForAllOutputs.disallowedReferences,
|
||||
StringSet{"/0nyw57wm2iicnm9rglvjmbci3ikmcp823czdqdzdcgsnnwqps71g"});
|
||||
EXPECT_EQ(
|
||||
checksForAllOutputs.disallowedRequisites,
|
||||
StringSet{"/07f301yqyz8c6wf6bbbavb2q39j4n8kmcly1s09xadyhgy6x2wr8"});
|
||||
}
|
||||
|
||||
StringSet systemFeatures{"rainbow", "uid-range"};
|
||||
systemFeatures.insert("ca-derivations");
|
||||
|
||||
EXPECT_EQ(options.getRequiredSystemFeatures(got), systemFeatures);
|
||||
});
|
||||
DerivationOptions advancedAttributes_structuredAttrs_defaults = {
|
||||
.outputChecks = std::map<std::string, DerivationOptions::OutputChecks>{},
|
||||
.unsafeDiscardReferences = {},
|
||||
.passAsFile = {},
|
||||
.exportReferencesGraph = {},
|
||||
.additionalSandboxProfile = "",
|
||||
.noChroot = false,
|
||||
.impureHostDeps = {},
|
||||
.impureEnvVars = {},
|
||||
.allowLocalNetworking = false,
|
||||
.requiredSystemFeatures = {},
|
||||
.preferLocalBuild = false,
|
||||
.allowSubstitutes = true,
|
||||
};
|
||||
|
||||
TYPED_TEST(DerivationAdvancedAttrsBothTest, advancedAttributes_structuredAttrs_defaults)
|
||||
|
|
@ -289,26 +292,11 @@ TYPED_TEST(DerivationAdvancedAttrsBothTest, advancedAttributes_structuredAttrs_d
|
|||
this->readTest("advanced-attributes-structured-attrs-defaults.drv", [&](auto encoded) {
|
||||
auto got = parseDerivation(*this->store, std::move(encoded), "foo", this->mockXpSettings);
|
||||
|
||||
auto drvPath = writeDerivation(*this->store, got, NoRepair, true);
|
||||
|
||||
DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs);
|
||||
|
||||
EXPECT_TRUE(got.structuredAttrs);
|
||||
|
||||
EXPECT_EQ(options.additionalSandboxProfile, "");
|
||||
EXPECT_EQ(options.noChroot, false);
|
||||
EXPECT_EQ(options.impureHostDeps, StringSet{});
|
||||
EXPECT_EQ(options.impureEnvVars, StringSet{});
|
||||
EXPECT_EQ(options.allowLocalNetworking, false);
|
||||
EXPECT_EQ(options.exportReferencesGraph, ExportReferencesMap{});
|
||||
|
||||
{
|
||||
auto * checksPerOutput_ = std::get_if<1>(&options.outputChecks);
|
||||
ASSERT_TRUE(checksPerOutput_ != nullptr);
|
||||
auto & checksPerOutput = *checksPerOutput_;
|
||||
|
||||
EXPECT_EQ(checksPerOutput.size(), 0u);
|
||||
}
|
||||
EXPECT_EQ(options, advancedAttributes_structuredAttrs_defaults);
|
||||
|
||||
EXPECT_EQ(options.canBuildLocally(*this->store, got), false);
|
||||
EXPECT_EQ(options.willBuildLocally(*this->store, got), false);
|
||||
|
|
@ -319,55 +307,61 @@ TYPED_TEST(DerivationAdvancedAttrsBothTest, advancedAttributes_structuredAttrs_d
|
|||
|
||||
TEST_F(DerivationAdvancedAttrsTest, advancedAttributes_structuredAttrs_defaults)
|
||||
{
|
||||
this->readTest("advanced-attributes-structured-attrs-defaults.drv", [&](auto encoded) {
|
||||
auto got = parseDerivation(*this->store, std::move(encoded), "foo", this->mockXpSettings);
|
||||
|
||||
auto drvPath = writeDerivation(*this->store, got, NoRepair, true);
|
||||
|
||||
DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs);
|
||||
|
||||
EXPECT_EQ(options.getRequiredSystemFeatures(got), StringSet{});
|
||||
});
|
||||
testRequiredSystemFeatures("advanced-attributes-structured-attrs-defaults.drv", {});
|
||||
};
|
||||
|
||||
TEST_F(CaDerivationAdvancedAttrsTest, advancedAttributes_structuredAttrs_defaults)
|
||||
{
|
||||
this->readTest("advanced-attributes-structured-attrs-defaults.drv", [&](auto encoded) {
|
||||
auto got = parseDerivation(*this->store, std::move(encoded), "foo", this->mockXpSettings);
|
||||
|
||||
auto drvPath = writeDerivation(*this->store, got, NoRepair, true);
|
||||
|
||||
DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs);
|
||||
|
||||
EXPECT_EQ(options.getRequiredSystemFeatures(got), StringSet{"ca-derivations"});
|
||||
});
|
||||
testRequiredSystemFeatures("advanced-attributes-structured-attrs-defaults.drv", {"ca-derivations"});
|
||||
};
|
||||
|
||||
TYPED_TEST(DerivationAdvancedAttrsBothTest, advancedAttributes_structuredAttrs)
|
||||
{
|
||||
DerivationOptions expected = {
|
||||
.outputChecks =
|
||||
std::map<std::string, DerivationOptions::OutputChecks>{
|
||||
{"dev",
|
||||
DerivationOptions::OutputChecks{
|
||||
.maxSize = 789,
|
||||
.maxClosureSize = 5909,
|
||||
}},
|
||||
},
|
||||
.unsafeDiscardReferences = {},
|
||||
.passAsFile = {},
|
||||
.exportReferencesGraph = {},
|
||||
.additionalSandboxProfile = "sandcastle",
|
||||
.noChroot = true,
|
||||
.impureHostDeps = {"/usr/bin/ditto"},
|
||||
.impureEnvVars = {"UNICORN"},
|
||||
.allowLocalNetworking = true,
|
||||
.requiredSystemFeatures = {"rainbow", "uid-range"},
|
||||
.preferLocalBuild = true,
|
||||
.allowSubstitutes = false,
|
||||
};
|
||||
|
||||
this->readTest("advanced-attributes-structured-attrs.drv", [&](auto encoded) {
|
||||
auto got = parseDerivation(*this->store, std::move(encoded), "foo", this->mockXpSettings);
|
||||
|
||||
auto drvPath = writeDerivation(*this->store, got, NoRepair, true);
|
||||
|
||||
DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs);
|
||||
|
||||
EXPECT_TRUE(got.structuredAttrs);
|
||||
|
||||
EXPECT_EQ(options.additionalSandboxProfile, "sandcastle");
|
||||
EXPECT_EQ(options.noChroot, true);
|
||||
EXPECT_EQ(options.impureHostDeps, StringSet{"/usr/bin/ditto"});
|
||||
EXPECT_EQ(options.impureEnvVars, StringSet{"UNICORN"});
|
||||
EXPECT_EQ(options.allowLocalNetworking, true);
|
||||
|
||||
// Reset fields that vary between test cases to enable whole-object comparison
|
||||
{
|
||||
auto output_ = get(std::get<1>(options.outputChecks), "dev");
|
||||
ASSERT_TRUE(output_);
|
||||
auto & output = *output_;
|
||||
|
||||
EXPECT_EQ(output.maxSize, 789);
|
||||
EXPECT_EQ(output.maxClosureSize, 5909);
|
||||
// Delete all keys but "dev" in options.outputChecks
|
||||
auto * outputChecksMapP =
|
||||
std::get_if<std::map<std::string, DerivationOptions::OutputChecks>>(&options.outputChecks);
|
||||
ASSERT_TRUE(outputChecksMapP);
|
||||
auto & outputChecksMap = *outputChecksMapP;
|
||||
auto devEntry = outputChecksMap.find("dev");
|
||||
ASSERT_TRUE(devEntry != outputChecksMap.end());
|
||||
auto devChecks = devEntry->second;
|
||||
outputChecksMap.clear();
|
||||
outputChecksMap.emplace("dev", std::move(devChecks));
|
||||
}
|
||||
options.exportReferencesGraph = {};
|
||||
|
||||
EXPECT_EQ(options, expected);
|
||||
|
||||
EXPECT_EQ(options.canBuildLocally(*this->store, got), false);
|
||||
EXPECT_EQ(options.willBuildLocally(*this->store, got), false);
|
||||
|
|
@ -376,112 +370,109 @@ TYPED_TEST(DerivationAdvancedAttrsBothTest, advancedAttributes_structuredAttrs)
|
|||
});
|
||||
};
|
||||
|
||||
DerivationOptions advancedAttributes_structuredAttrs_ia = {
|
||||
.outputChecks =
|
||||
std::map<std::string, DerivationOptions::OutputChecks>{
|
||||
{"out",
|
||||
DerivationOptions::OutputChecks{
|
||||
.allowedReferences = StringSet{"/nix/store/p0hax2lzvjpfc2gwkk62xdglz0fcqfzn-foo"},
|
||||
.allowedRequisites = StringSet{"/nix/store/z0rjzy29v9k5qa4nqpykrbzirj7sd43v-foo-dev"},
|
||||
}},
|
||||
{"bin",
|
||||
DerivationOptions::OutputChecks{
|
||||
.disallowedReferences = StringSet{"/nix/store/r5cff30838majxk5mp3ip2diffi8vpaj-bar"},
|
||||
.disallowedRequisites = StringSet{"/nix/store/9b61w26b4avv870dw0ymb6rw4r1hzpws-bar-dev"},
|
||||
}},
|
||||
{"dev",
|
||||
DerivationOptions::OutputChecks{
|
||||
.maxSize = 789,
|
||||
.maxClosureSize = 5909,
|
||||
}},
|
||||
},
|
||||
.unsafeDiscardReferences = {},
|
||||
.passAsFile = {},
|
||||
.exportReferencesGraph =
|
||||
{
|
||||
{"refs1", {"/nix/store/p0hax2lzvjpfc2gwkk62xdglz0fcqfzn-foo"}},
|
||||
{"refs2", {"/nix/store/vj2i49jm2868j2fmqvxm70vlzmzvgv14-bar.drv"}},
|
||||
},
|
||||
.additionalSandboxProfile = "sandcastle",
|
||||
.noChroot = true,
|
||||
.impureHostDeps = {"/usr/bin/ditto"},
|
||||
.impureEnvVars = {"UNICORN"},
|
||||
.allowLocalNetworking = true,
|
||||
.requiredSystemFeatures = {"rainbow", "uid-range"},
|
||||
.preferLocalBuild = true,
|
||||
.allowSubstitutes = false,
|
||||
};
|
||||
|
||||
TEST_F(DerivationAdvancedAttrsTest, advancedAttributes_structuredAttrs)
|
||||
{
|
||||
this->readTest("advanced-attributes-structured-attrs.drv", [&](auto encoded) {
|
||||
auto got = parseDerivation(*this->store, std::move(encoded), "foo", this->mockXpSettings);
|
||||
|
||||
auto drvPath = writeDerivation(*this->store, got, NoRepair, true);
|
||||
|
||||
DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs);
|
||||
|
||||
EXPECT_EQ(
|
||||
options.exportReferencesGraph,
|
||||
(ExportReferencesMap{
|
||||
{
|
||||
"refs1",
|
||||
{
|
||||
"/nix/store/p0hax2lzvjpfc2gwkk62xdglz0fcqfzn-foo",
|
||||
},
|
||||
},
|
||||
{
|
||||
"refs2",
|
||||
{
|
||||
"/nix/store/vj2i49jm2868j2fmqvxm70vlzmzvgv14-bar.drv",
|
||||
},
|
||||
},
|
||||
}));
|
||||
testDerivationOptions(
|
||||
"advanced-attributes-structured-attrs.drv", advancedAttributes_structuredAttrs_ia, {"rainbow", "uid-range"});
|
||||
};
|
||||
|
||||
DerivationOptions advancedAttributes_structuredAttrs_ca = {
|
||||
.outputChecks =
|
||||
std::map<std::string, DerivationOptions::OutputChecks>{
|
||||
{"out",
|
||||
DerivationOptions::OutputChecks{
|
||||
.allowedReferences = StringSet{"/164j69y6zir9z0339n8pjigg3rckinlr77bxsavzizdaaljb7nh9"},
|
||||
.allowedRequisites = StringSet{"/0nr45p69vn6izw9446wsh9bng9nndhvn19kpsm4n96a5mycw0s4z"},
|
||||
}},
|
||||
{"bin",
|
||||
DerivationOptions::OutputChecks{
|
||||
.disallowedReferences = StringSet{"/0nyw57wm2iicnm9rglvjmbci3ikmcp823czdqdzdcgsnnwqps71g"},
|
||||
.disallowedRequisites = StringSet{"/07f301yqyz8c6wf6bbbavb2q39j4n8kmcly1s09xadyhgy6x2wr8"},
|
||||
}},
|
||||
{"dev",
|
||||
DerivationOptions::OutputChecks{
|
||||
.maxSize = 789,
|
||||
.maxClosureSize = 5909,
|
||||
}},
|
||||
},
|
||||
.unsafeDiscardReferences = {},
|
||||
.passAsFile = {},
|
||||
.exportReferencesGraph =
|
||||
{
|
||||
{
|
||||
auto output_ = get(std::get<1>(options.outputChecks), "out");
|
||||
ASSERT_TRUE(output_);
|
||||
auto & output = *output_;
|
||||
|
||||
EXPECT_EQ(output.allowedReferences, StringSet{"/nix/store/p0hax2lzvjpfc2gwkk62xdglz0fcqfzn-foo"});
|
||||
EXPECT_EQ(output.allowedRequisites, StringSet{"/nix/store/z0rjzy29v9k5qa4nqpykrbzirj7sd43v-foo-dev"});
|
||||
}
|
||||
|
||||
{
|
||||
auto output_ = get(std::get<1>(options.outputChecks), "bin");
|
||||
ASSERT_TRUE(output_);
|
||||
auto & output = *output_;
|
||||
|
||||
EXPECT_EQ(output.disallowedReferences, StringSet{"/nix/store/r5cff30838majxk5mp3ip2diffi8vpaj-bar"});
|
||||
EXPECT_EQ(
|
||||
output.disallowedRequisites, StringSet{"/nix/store/9b61w26b4avv870dw0ymb6rw4r1hzpws-bar-dev"});
|
||||
}
|
||||
}
|
||||
|
||||
StringSet systemFeatures{"rainbow", "uid-range"};
|
||||
|
||||
EXPECT_EQ(options.getRequiredSystemFeatures(got), systemFeatures);
|
||||
});
|
||||
{"refs1", {"/164j69y6zir9z0339n8pjigg3rckinlr77bxsavzizdaaljb7nh9"}},
|
||||
{"refs2", {"/nix/store/qnml92yh97a6fbrs2m5qg5cqlc8vni58-bar.drv"}},
|
||||
},
|
||||
.additionalSandboxProfile = "sandcastle",
|
||||
.noChroot = true,
|
||||
.impureHostDeps = {"/usr/bin/ditto"},
|
||||
.impureEnvVars = {"UNICORN"},
|
||||
.allowLocalNetworking = true,
|
||||
.requiredSystemFeatures = {"rainbow", "uid-range"},
|
||||
.preferLocalBuild = true,
|
||||
.allowSubstitutes = false,
|
||||
};
|
||||
|
||||
TEST_F(CaDerivationAdvancedAttrsTest, advancedAttributes_structuredAttrs)
|
||||
{
|
||||
this->readTest("advanced-attributes-structured-attrs.drv", [&](auto encoded) {
|
||||
auto got = parseDerivation(*this->store, std::move(encoded), "foo", this->mockXpSettings);
|
||||
|
||||
auto drvPath = writeDerivation(*this->store, got, NoRepair, true);
|
||||
|
||||
DerivationOptions options = DerivationOptions::fromStructuredAttrs(got.env, got.structuredAttrs);
|
||||
|
||||
EXPECT_EQ(
|
||||
options.exportReferencesGraph,
|
||||
(ExportReferencesMap{
|
||||
{
|
||||
"refs1",
|
||||
{
|
||||
"/164j69y6zir9z0339n8pjigg3rckinlr77bxsavzizdaaljb7nh9",
|
||||
},
|
||||
},
|
||||
{
|
||||
"refs2",
|
||||
{
|
||||
"/nix/store/qnml92yh97a6fbrs2m5qg5cqlc8vni58-bar.drv",
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
{
|
||||
{
|
||||
auto output_ = get(std::get<1>(options.outputChecks), "out");
|
||||
ASSERT_TRUE(output_);
|
||||
auto & output = *output_;
|
||||
|
||||
EXPECT_EQ(output.allowedReferences, StringSet{"/164j69y6zir9z0339n8pjigg3rckinlr77bxsavzizdaaljb7nh9"});
|
||||
EXPECT_EQ(output.allowedRequisites, StringSet{"/0nr45p69vn6izw9446wsh9bng9nndhvn19kpsm4n96a5mycw0s4z"});
|
||||
}
|
||||
|
||||
{
|
||||
auto output_ = get(std::get<1>(options.outputChecks), "bin");
|
||||
ASSERT_TRUE(output_);
|
||||
auto & output = *output_;
|
||||
|
||||
EXPECT_EQ(
|
||||
output.disallowedReferences, StringSet{"/0nyw57wm2iicnm9rglvjmbci3ikmcp823czdqdzdcgsnnwqps71g"});
|
||||
EXPECT_EQ(
|
||||
output.disallowedRequisites, StringSet{"/07f301yqyz8c6wf6bbbavb2q39j4n8kmcly1s09xadyhgy6x2wr8"});
|
||||
}
|
||||
}
|
||||
|
||||
StringSet systemFeatures{"rainbow", "uid-range"};
|
||||
systemFeatures.insert("ca-derivations");
|
||||
|
||||
EXPECT_EQ(options.getRequiredSystemFeatures(got), systemFeatures);
|
||||
});
|
||||
testDerivationOptions(
|
||||
"advanced-attributes-structured-attrs.drv",
|
||||
advancedAttributes_structuredAttrs_ca,
|
||||
{"rainbow", "uid-range", "ca-derivations"});
|
||||
};
|
||||
|
||||
#define TEST_JSON_OPTIONS(FIXUTURE, VAR, VAR2) \
|
||||
TEST_F(FIXUTURE, DerivationOptions_##VAR##_from_json) \
|
||||
{ \
|
||||
this->JsonCharacterizationTest<DerivationOptions>::readJsonTest(#VAR, advancedAttributes_##VAR2); \
|
||||
} \
|
||||
TEST_F(FIXUTURE, DerivationOptions_##VAR##_to_json) \
|
||||
{ \
|
||||
this->JsonCharacterizationTest<DerivationOptions>::writeJsonTest(#VAR, advancedAttributes_##VAR2); \
|
||||
}
|
||||
|
||||
TEST_JSON_OPTIONS(DerivationAdvancedAttrsTest, defaults, defaults)
|
||||
TEST_JSON_OPTIONS(DerivationAdvancedAttrsTest, all_set, ia)
|
||||
TEST_JSON_OPTIONS(CaDerivationAdvancedAttrsTest, all_set, ca)
|
||||
TEST_JSON_OPTIONS(DerivationAdvancedAttrsTest, structuredAttrs_defaults, structuredAttrs_defaults)
|
||||
TEST_JSON_OPTIONS(DerivationAdvancedAttrsTest, structuredAttrs_all_set, structuredAttrs_ia)
|
||||
TEST_JSON_OPTIONS(CaDerivationAdvancedAttrsTest, structuredAttrs_all_set, structuredAttrs_ca)
|
||||
|
||||
#undef TEST_JSON_OPTIONS
|
||||
|
||||
} // namespace nix
|
||||
|
|
|
|||
|
|
@ -1,11 +1,33 @@
|
|||
#include <gtest/gtest.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "nix/util/bytes.hh"
|
||||
#include "nix/util/memory-source-accessor.hh"
|
||||
#include "nix/store/dummy-store-impl.hh"
|
||||
#include "nix/store/globals.hh"
|
||||
#include "nix/store/realisation.hh"
|
||||
|
||||
#include "nix/util/tests/json-characterization.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
class DummyStoreTest : public virtual CharacterizationTest
|
||||
{
|
||||
std::filesystem::path unitTestData = getUnitTestData() / "dummy-store";
|
||||
|
||||
public:
|
||||
|
||||
std::filesystem::path goldenMaster(std::string_view testStem) const override
|
||||
{
|
||||
return unitTestData / testStem;
|
||||
}
|
||||
|
||||
static void SetUpTestSuite()
|
||||
{
|
||||
initLibStore(false);
|
||||
}
|
||||
};
|
||||
|
||||
TEST(DummyStore, realisation_read)
|
||||
{
|
||||
initLibStore(/*loadConfig=*/false);
|
||||
|
|
@ -16,23 +38,94 @@ TEST(DummyStore, realisation_read)
|
|||
return cfg->openDummyStore();
|
||||
}();
|
||||
|
||||
auto drvHash = Hash::parseExplicitFormatUnprefixed(
|
||||
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", HashAlgorithm::SHA256, HashFormat::Base16);
|
||||
StorePath drvPath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv"};
|
||||
|
||||
auto outputName = "foo";
|
||||
|
||||
EXPECT_EQ(store->queryRealisation({drvHash, outputName}), nullptr);
|
||||
EXPECT_EQ(store->queryRealisation({drvPath, outputName}), nullptr);
|
||||
|
||||
UnkeyedRealisation value{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv"},
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
};
|
||||
|
||||
store->buildTrace.insert({drvHash, {{outputName, make_ref<UnkeyedRealisation>(value)}}});
|
||||
store->buildTrace.insert({drvPath, {{outputName, make_ref<UnkeyedRealisation>(value)}}});
|
||||
|
||||
auto value2 = store->queryRealisation({drvHash, outputName});
|
||||
auto value2 = store->queryRealisation({drvPath, outputName});
|
||||
|
||||
ASSERT_TRUE(value2);
|
||||
EXPECT_EQ(*value2, value);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* JSON
|
||||
* --------------------------------------------------------------------------*/
|
||||
|
||||
using nlohmann::json;
|
||||
|
||||
struct DummyStoreJsonTest : DummyStoreTest,
|
||||
JsonCharacterizationTest<ref<DummyStore>>,
|
||||
::testing::WithParamInterface<std::pair<std::string_view, ref<DummyStore>>>
|
||||
{};
|
||||
|
||||
TEST_P(DummyStoreJsonTest, from_json)
|
||||
{
|
||||
auto & [name, expected] = GetParam();
|
||||
using namespace nlohmann;
|
||||
/* Cannot use `readJsonTest` because need to dereference the stores
|
||||
for equality. */
|
||||
readTest(Path{name} + ".json", [&](const auto & encodedRaw) {
|
||||
auto encoded = json::parse(encodedRaw);
|
||||
ref<DummyStore> decoded = adl_serializer<ref<DummyStore>>::from_json(encoded);
|
||||
ASSERT_EQ(*decoded, *expected);
|
||||
});
|
||||
}
|
||||
|
||||
TEST_P(DummyStoreJsonTest, to_json)
|
||||
{
|
||||
auto & [name, value] = GetParam();
|
||||
writeJsonTest(name, value);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(DummyStoreJSON, DummyStoreJsonTest, [] {
|
||||
initLibStore(false);
|
||||
auto writeCfg = make_ref<DummyStore::Config>(DummyStore::Config::Params{});
|
||||
writeCfg->readOnly = false;
|
||||
return ::testing::Values(
|
||||
std::pair{
|
||||
"empty",
|
||||
make_ref<DummyStore::Config>(DummyStore::Config::Params{})->openDummyStore(),
|
||||
},
|
||||
std::pair{
|
||||
"one-flat-file",
|
||||
[&] {
|
||||
auto store = writeCfg->openDummyStore();
|
||||
store->addToStore(
|
||||
"my-file",
|
||||
SourcePath{
|
||||
[] {
|
||||
auto sc = make_ref<MemorySourceAccessor>();
|
||||
sc->root = MemorySourceAccessor::File{MemorySourceAccessor::File::Regular{
|
||||
.executable = false,
|
||||
.contents = to_owned(as_bytes("asdf")),
|
||||
}};
|
||||
return sc;
|
||||
}(),
|
||||
},
|
||||
ContentAddressMethod::Raw::NixArchive,
|
||||
HashAlgorithm::SHA256);
|
||||
return store;
|
||||
}(),
|
||||
},
|
||||
std::pair{
|
||||
"one-derivation",
|
||||
[&] {
|
||||
auto store = writeCfg->openDummyStore();
|
||||
Derivation drv;
|
||||
drv.name = "foo";
|
||||
store->writeDerivation(drv);
|
||||
return store;
|
||||
}(),
|
||||
});
|
||||
}());
|
||||
|
||||
} // namespace nix
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ deps_private += gtest
|
|||
subdir('nix-meson-build-support/common')
|
||||
|
||||
sources = files(
|
||||
'build-result.cc',
|
||||
'common-protocol.cc',
|
||||
'content-address.cc',
|
||||
'derivation-advanced-attrs.cc',
|
||||
|
|
|
|||
|
|
@ -59,24 +59,24 @@ static NarInfo makeNarInfo(const Store & store, bool includeImpureInfo)
|
|||
return info;
|
||||
}
|
||||
|
||||
#define JSON_TEST(STEM, PURE) \
|
||||
TEST_F(NarInfoTest, NarInfo_##STEM##_from_json) \
|
||||
{ \
|
||||
readTest(#STEM, [&](const auto & encoded_) { \
|
||||
auto encoded = json::parse(encoded_); \
|
||||
auto expected = makeNarInfo(*store, PURE); \
|
||||
NarInfo got = NarInfo::fromJSON(*store, expected.path, encoded); \
|
||||
ASSERT_EQ(got, expected); \
|
||||
}); \
|
||||
} \
|
||||
\
|
||||
TEST_F(NarInfoTest, NarInfo_##STEM##_to_json) \
|
||||
{ \
|
||||
writeTest( \
|
||||
#STEM, \
|
||||
[&]() -> json { return makeNarInfo(*store, PURE).toJSON(*store, PURE, HashFormat::SRI); }, \
|
||||
[](const auto & file) { return json::parse(readFile(file)); }, \
|
||||
[](const auto & file, const auto & got) { return writeFile(file, got.dump(2) + "\n"); }); \
|
||||
#define JSON_TEST(STEM, PURE) \
|
||||
TEST_F(NarInfoTest, NarInfo_##STEM##_from_json) \
|
||||
{ \
|
||||
readTest(#STEM, [&](const auto & encoded_) { \
|
||||
auto encoded = json::parse(encoded_); \
|
||||
auto expected = makeNarInfo(*store, PURE); \
|
||||
auto got = UnkeyedNarInfo::fromJSON(&*store, encoded); \
|
||||
ASSERT_EQ(got, expected); \
|
||||
}); \
|
||||
} \
|
||||
\
|
||||
TEST_F(NarInfoTest, NarInfo_##STEM##_to_json) \
|
||||
{ \
|
||||
writeTest( \
|
||||
#STEM, \
|
||||
[&]() -> json { return makeNarInfo(*store, PURE).toJSON(&*store, PURE); }, \
|
||||
[](const auto & file) { return json::parse(readFile(file)); }, \
|
||||
[](const auto & file, const auto & got) { return writeFile(file, got.dump(2) + "\n"); }); \
|
||||
}
|
||||
|
||||
JSON_TEST(pure, false)
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ static UnkeyedValidPathInfo makeFull(const Store & store, bool includeImpureInfo
|
|||
{ \
|
||||
readTest(#STEM, [&](const auto & encoded_) { \
|
||||
auto encoded = json::parse(encoded_); \
|
||||
UnkeyedValidPathInfo got = UnkeyedValidPathInfo::fromJSON(*store, encoded); \
|
||||
UnkeyedValidPathInfo got = UnkeyedValidPathInfo::fromJSON(&*store, encoded); \
|
||||
auto expected = OBJ; \
|
||||
ASSERT_EQ(got, expected); \
|
||||
}); \
|
||||
|
|
@ -80,7 +80,7 @@ static UnkeyedValidPathInfo makeFull(const Store & store, bool includeImpureInfo
|
|||
{ \
|
||||
writeTest( \
|
||||
#STEM, \
|
||||
[&]() -> json { return OBJ.toJSON(*store, PURE, HashFormat::SRI); }, \
|
||||
[&]() -> json { return OBJ.toJSON(&*store, PURE); }, \
|
||||
[](const auto & file) { return json::parse(readFile(file)); }, \
|
||||
[](const auto & file, const auto & got) { return writeFile(file, got.dump(2) + "\n"); }); \
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,54 +44,30 @@ TEST_P(RealisationJsonTest, to_json)
|
|||
writeJsonTest(name, value);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
RealisationJSON,
|
||||
RealisationJsonTest,
|
||||
([] {
|
||||
Realisation simple{
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv"},
|
||||
},
|
||||
{
|
||||
.drvHash = Hash::parseExplicitFormatUnprefixed(
|
||||
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
|
||||
HashAlgorithm::SHA256,
|
||||
HashFormat::Base16),
|
||||
.outputName = "foo",
|
||||
},
|
||||
};
|
||||
return ::testing::Values(
|
||||
std::pair{
|
||||
"simple",
|
||||
simple,
|
||||
},
|
||||
std::pair{
|
||||
"with-signature",
|
||||
[&] {
|
||||
auto r = simple;
|
||||
// FIXME actually sign properly
|
||||
r.signatures = {"asdfasdfasdf"};
|
||||
return r;
|
||||
}()},
|
||||
std::pair{
|
||||
"with-dependent-realisations",
|
||||
[&] {
|
||||
auto r = simple;
|
||||
r.dependentRealisations = {{
|
||||
{
|
||||
.drvHash = Hash::parseExplicitFormatUnprefixed(
|
||||
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
|
||||
HashAlgorithm::SHA256,
|
||||
HashFormat::Base16),
|
||||
.outputName = "foo",
|
||||
},
|
||||
StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv"},
|
||||
}};
|
||||
return r;
|
||||
}(),
|
||||
});
|
||||
}
|
||||
|
||||
()));
|
||||
INSTANTIATE_TEST_SUITE_P(RealisationJSON, RealisationJsonTest, ([] {
|
||||
Realisation simple{
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
},
|
||||
{
|
||||
.drvPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv"},
|
||||
.outputName = "foo",
|
||||
},
|
||||
};
|
||||
return ::testing::Values(
|
||||
std::pair{
|
||||
"simple",
|
||||
simple,
|
||||
},
|
||||
std::pair{
|
||||
"with-signature",
|
||||
[&] {
|
||||
auto r = simple;
|
||||
// FIXME actually sign properly
|
||||
r.signatures = {"asdfasdfasdf"};
|
||||
return r;
|
||||
}(),
|
||||
});
|
||||
}()));
|
||||
|
||||
} // namespace nix
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "nix/store/references.hh"
|
||||
#include "nix/store/path-references.hh"
|
||||
#include "nix/util/bytes.hh"
|
||||
#include "nix/util/memory-source-accessor.hh"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
|
@ -104,21 +105,21 @@ TEST(references, scanForReferencesDeep)
|
|||
// file1.txt: contains hash1
|
||||
"file1.txt",
|
||||
File::Regular{
|
||||
.contents = "This file references " + hash1 + " in its content",
|
||||
.contents = to_owned(as_bytes("This file references " + hash1 + " in its content")),
|
||||
},
|
||||
},
|
||||
{
|
||||
// file2.txt: contains hash2 and hash3
|
||||
"file2.txt",
|
||||
File::Regular{
|
||||
.contents = "Multiple refs: " + hash2 + " and also " + hash3,
|
||||
.contents = to_owned(as_bytes("Multiple refs: " + hash2 + " and also " + hash3)),
|
||||
},
|
||||
},
|
||||
{
|
||||
// file3.txt: contains no references
|
||||
"file3.txt",
|
||||
File::Regular{
|
||||
.contents = "This file has no store path references at all",
|
||||
.contents = to_owned(as_bytes("This file has no store path references at all")),
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -130,7 +131,7 @@ TEST(references, scanForReferencesDeep)
|
|||
// subdir/file4.txt: contains hash1 again
|
||||
"file4.txt",
|
||||
File::Regular{
|
||||
.contents = "Subdirectory file with " + hash1,
|
||||
.contents = to_owned(as_bytes("Subdirectory file with " + hash1)),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -140,7 +141,7 @@ TEST(references, scanForReferencesDeep)
|
|||
// link1: a symlink that contains a reference in its target
|
||||
"link1",
|
||||
File::Symlink{
|
||||
.target = hash2 + "-target",
|
||||
.target = to_owned(as_bytes(hash2 + "-target")),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <nlohmann/json.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "nix/util/json-utils.hh"
|
||||
#include "nix/store/serve-protocol.hh"
|
||||
#include "nix/store/serve-protocol-impl.hh"
|
||||
#include "nix/store/serve-protocol-connection.hh"
|
||||
|
|
@ -72,16 +73,16 @@ VERSIONED_CHARACTERIZATION_TEST(
|
|||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
ServeProtoTest,
|
||||
drvOutput,
|
||||
"drv-output",
|
||||
defaultVersion,
|
||||
drvOutput_2_8,
|
||||
"drv-output-2.8",
|
||||
2 << 8 | 8,
|
||||
(std::tuple<DrvOutput, DrvOutput>{
|
||||
{
|
||||
.drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="),
|
||||
.drvPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv"},
|
||||
.outputName = "baz",
|
||||
},
|
||||
DrvOutput{
|
||||
.drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
|
||||
.drvPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv"},
|
||||
.outputName = "quux",
|
||||
},
|
||||
}))
|
||||
|
|
@ -90,56 +91,27 @@ VERSIONED_CHARACTERIZATION_TEST(
|
|||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
ServeProtoTest,
|
||||
realisation,
|
||||
"realisation",
|
||||
defaultVersion,
|
||||
(std::tuple<Realisation, Realisation>{
|
||||
Realisation{
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
},
|
||||
{
|
||||
.drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="),
|
||||
.outputName = "baz",
|
||||
},
|
||||
},
|
||||
Realisation{
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
.signatures = {"asdf", "qwer"},
|
||||
},
|
||||
{
|
||||
.drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="),
|
||||
.outputName = "baz",
|
||||
},
|
||||
},
|
||||
unkeyedRealisation_2_8,
|
||||
"unkeyed-realisation-2.8",
|
||||
2 << 8 | 8,
|
||||
(UnkeyedRealisation{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
.signatures = {"asdf", "qwer"},
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
ServeProtoTest,
|
||||
realisation_with_deps,
|
||||
"realisation-with-deps",
|
||||
defaultVersion,
|
||||
(std::tuple<Realisation>{
|
||||
Realisation{
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
.signatures = {"asdf", "qwer"},
|
||||
.dependentRealisations =
|
||||
{
|
||||
{
|
||||
DrvOutput{
|
||||
.drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
|
||||
.outputName = "quux",
|
||||
},
|
||||
StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
.drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="),
|
||||
.outputName = "baz",
|
||||
},
|
||||
realisation_2_8,
|
||||
"realisation-2.8",
|
||||
2 << 8 | 8,
|
||||
(Realisation{
|
||||
UnkeyedRealisation{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
.signatures = {"asdf", "qwer"},
|
||||
},
|
||||
{
|
||||
.drvPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv"},
|
||||
.outputName = "baz",
|
||||
},
|
||||
}))
|
||||
|
||||
|
|
@ -189,7 +161,10 @@ VERSIONED_CHARACTERIZATION_TEST(ServeProtoTest, buildResult_2_3, "build-result-2
|
|||
t;
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
/* We now do a lossy read which does not allow us to faithfully right
|
||||
back, since we changed the data type. We still however want to test
|
||||
that this read works, and so for that we have a one-way test. */
|
||||
VERSIONED_READ_CHARACTERIZATION_TEST(
|
||||
ServeProtoTest, buildResult_2_6, "build-result-2.6", 2 << 8 | 6, ({
|
||||
using namespace std::literals::chrono_literals;
|
||||
std::tuple<BuildResult, BuildResult, BuildResult> t{
|
||||
|
|
@ -215,27 +190,65 @@ VERSIONED_CHARACTERIZATION_TEST(
|
|||
{
|
||||
"foo",
|
||||
{
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
},
|
||||
DrvOutput{
|
||||
.drvHash =
|
||||
Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
|
||||
.outputName = "foo",
|
||||
},
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
},
|
||||
},
|
||||
{
|
||||
"bar",
|
||||
{
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar"},
|
||||
},
|
||||
DrvOutput{
|
||||
.drvHash =
|
||||
Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
|
||||
.outputName = "bar",
|
||||
},
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
.timesBuilt = 1,
|
||||
.startTime = 30,
|
||||
.stopTime = 50,
|
||||
#if 0
|
||||
// These fields are not yet serialized.
|
||||
// FIXME Include in next version of protocol or document
|
||||
// why they are skipped.
|
||||
.cpuUser = std::chrono::milliseconds(500s),
|
||||
.cpuSystem = std::chrono::milliseconds(604s),
|
||||
#endif
|
||||
},
|
||||
};
|
||||
t;
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
ServeProtoTest, buildResult_2_8, "build-result-2.8", 2 << 8 | 8, ({
|
||||
using namespace std::literals::chrono_literals;
|
||||
std::tuple<BuildResult, BuildResult, BuildResult> t{
|
||||
BuildResult{.inner{BuildResult::Failure{
|
||||
.status = BuildResult::Failure::OutputRejected,
|
||||
.errorMsg = "no idea why",
|
||||
}}},
|
||||
BuildResult{
|
||||
.inner{BuildResult::Failure{
|
||||
.status = BuildResult::Failure::NotDeterministic,
|
||||
.errorMsg = "no idea why",
|
||||
.isNonDeterministic = true,
|
||||
}},
|
||||
.timesBuilt = 3,
|
||||
.startTime = 30,
|
||||
.stopTime = 50,
|
||||
},
|
||||
BuildResult{
|
||||
.inner{BuildResult::Success{
|
||||
.status = BuildResult::Success::Built,
|
||||
.builtOutputs =
|
||||
{
|
||||
{
|
||||
"foo",
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
},
|
||||
},
|
||||
{
|
||||
"bar",
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar"},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -334,7 +347,7 @@ VERSIONED_CHARACTERIZATION_TEST(
|
|||
}),
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
VERSIONED_CHARACTERIZATION_TEST_NO_JSON(
|
||||
ServeProtoTest,
|
||||
build_options_2_1,
|
||||
"build-options-2.1",
|
||||
|
|
@ -344,7 +357,7 @@ VERSIONED_CHARACTERIZATION_TEST(
|
|||
.buildTimeout = 6,
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
VERSIONED_CHARACTERIZATION_TEST_NO_JSON(
|
||||
ServeProtoTest,
|
||||
build_options_2_2,
|
||||
"build-options-2.2",
|
||||
|
|
@ -355,7 +368,7 @@ VERSIONED_CHARACTERIZATION_TEST(
|
|||
.maxLogSize = 7,
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
VERSIONED_CHARACTERIZATION_TEST_NO_JSON(
|
||||
ServeProtoTest,
|
||||
build_options_2_3,
|
||||
"build-options-2.3",
|
||||
|
|
@ -368,7 +381,7 @@ VERSIONED_CHARACTERIZATION_TEST(
|
|||
.enforceDeterminism = true,
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
VERSIONED_CHARACTERIZATION_TEST_NO_JSON(
|
||||
ServeProtoTest,
|
||||
build_options_2_7,
|
||||
"build-options-2.7",
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <nlohmann/json.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "nix/util/json-utils.hh"
|
||||
#include "nix/store/worker-protocol.hh"
|
||||
#include "nix/store/worker-protocol-connection.hh"
|
||||
#include "nix/store/worker-protocol-impl.hh"
|
||||
|
|
@ -128,71 +129,42 @@ VERSIONED_CHARACTERIZATION_TEST(
|
|||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
WorkerProtoTest,
|
||||
drvOutput,
|
||||
"drv-output",
|
||||
defaultVersion,
|
||||
"drv-output-1.39",
|
||||
1 << 8 | 39,
|
||||
(std::tuple<DrvOutput, DrvOutput>{
|
||||
{
|
||||
.drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="),
|
||||
.drvPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv"},
|
||||
.outputName = "baz",
|
||||
},
|
||||
DrvOutput{
|
||||
.drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
|
||||
.drvPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv"},
|
||||
.outputName = "quux",
|
||||
},
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
WorkerProtoTest,
|
||||
realisation,
|
||||
"realisation",
|
||||
defaultVersion,
|
||||
(std::tuple<Realisation, Realisation>{
|
||||
Realisation{
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
},
|
||||
{
|
||||
.drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="),
|
||||
.outputName = "baz",
|
||||
},
|
||||
},
|
||||
Realisation{
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
.signatures = {"asdf", "qwer"},
|
||||
},
|
||||
{
|
||||
.drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="),
|
||||
.outputName = "baz",
|
||||
},
|
||||
},
|
||||
unkeyedRealisation_1_39,
|
||||
"unkeyed-realisation-1.39",
|
||||
1 << 8 | 39,
|
||||
(UnkeyedRealisation{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
.signatures = {"asdf", "qwer"},
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
WorkerProtoTest,
|
||||
realisation_with_deps,
|
||||
"realisation-with-deps",
|
||||
defaultVersion,
|
||||
(std::tuple<Realisation>{
|
||||
Realisation{
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
.signatures = {"asdf", "qwer"},
|
||||
.dependentRealisations =
|
||||
{
|
||||
{
|
||||
DrvOutput{
|
||||
.drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
|
||||
.outputName = "quux",
|
||||
},
|
||||
StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
.drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="),
|
||||
.outputName = "baz",
|
||||
},
|
||||
realisation_1_39,
|
||||
"realisation-1.39",
|
||||
1 << 8 | 39,
|
||||
(Realisation{
|
||||
UnkeyedRealisation{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
.signatures = {"asdf", "qwer"},
|
||||
},
|
||||
{
|
||||
.drvPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv"},
|
||||
.outputName = "baz",
|
||||
},
|
||||
}))
|
||||
|
||||
|
|
@ -214,7 +186,10 @@ VERSIONED_CHARACTERIZATION_TEST(WorkerProtoTest, buildResult_1_27, "build-result
|
|||
t;
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
/* We now do a lossy read which does not allow us to faithfully right
|
||||
back, since we changed the data type. We still however want to test
|
||||
that this read works, and so for that we have a one-way test. */
|
||||
VERSIONED_READ_CHARACTERIZATION_TEST(
|
||||
WorkerProtoTest, buildResult_1_28, "build-result-1.28", 1 << 8 | 28, ({
|
||||
using namespace std::literals::chrono_literals;
|
||||
std::tuple<BuildResult, BuildResult, BuildResult> t{
|
||||
|
|
@ -233,25 +208,13 @@ VERSIONED_CHARACTERIZATION_TEST(
|
|||
{
|
||||
"foo",
|
||||
{
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
},
|
||||
DrvOutput{
|
||||
.drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
|
||||
.outputName = "foo",
|
||||
},
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
},
|
||||
},
|
||||
{
|
||||
"bar",
|
||||
{
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar"},
|
||||
},
|
||||
DrvOutput{
|
||||
.drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
|
||||
.outputName = "bar",
|
||||
},
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar"},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -260,7 +223,8 @@ VERSIONED_CHARACTERIZATION_TEST(
|
|||
t;
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
// See above note
|
||||
VERSIONED_READ_CHARACTERIZATION_TEST(
|
||||
WorkerProtoTest, buildResult_1_29, "build-result-1.29", 1 << 8 | 29, ({
|
||||
using namespace std::literals::chrono_literals;
|
||||
std::tuple<BuildResult, BuildResult, BuildResult> t{
|
||||
|
|
@ -286,27 +250,13 @@ VERSIONED_CHARACTERIZATION_TEST(
|
|||
{
|
||||
"foo",
|
||||
{
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
},
|
||||
DrvOutput{
|
||||
.drvHash =
|
||||
Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
|
||||
.outputName = "foo",
|
||||
},
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
},
|
||||
},
|
||||
{
|
||||
"bar",
|
||||
{
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar"},
|
||||
},
|
||||
DrvOutput{
|
||||
.drvHash =
|
||||
Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
|
||||
.outputName = "bar",
|
||||
},
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar"},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -319,7 +269,8 @@ VERSIONED_CHARACTERIZATION_TEST(
|
|||
t;
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
// See above note
|
||||
VERSIONED_READ_CHARACTERIZATION_TEST(
|
||||
WorkerProtoTest, buildResult_1_37, "build-result-1.37", 1 << 8 | 37, ({
|
||||
using namespace std::literals::chrono_literals;
|
||||
std::tuple<BuildResult, BuildResult, BuildResult> t{
|
||||
|
|
@ -345,27 +296,60 @@ VERSIONED_CHARACTERIZATION_TEST(
|
|||
{
|
||||
"foo",
|
||||
{
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
},
|
||||
DrvOutput{
|
||||
.drvHash =
|
||||
Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
|
||||
.outputName = "foo",
|
||||
},
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
},
|
||||
},
|
||||
{
|
||||
"bar",
|
||||
{
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar"},
|
||||
},
|
||||
DrvOutput{
|
||||
.drvHash =
|
||||
Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
|
||||
.outputName = "bar",
|
||||
},
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
.timesBuilt = 1,
|
||||
.startTime = 30,
|
||||
.stopTime = 50,
|
||||
.cpuUser = std::chrono::microseconds(500s),
|
||||
.cpuSystem = std::chrono::microseconds(604s),
|
||||
},
|
||||
};
|
||||
t;
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
WorkerProtoTest, buildResult_1_39, "build-result-1.39", 1 << 8 | 39, ({
|
||||
using namespace std::literals::chrono_literals;
|
||||
std::tuple<BuildResult, BuildResult, BuildResult> t{
|
||||
BuildResult{.inner{BuildResult::Failure{
|
||||
.status = BuildResult::Failure::OutputRejected,
|
||||
.errorMsg = "no idea why",
|
||||
}}},
|
||||
BuildResult{
|
||||
.inner{BuildResult::Failure{
|
||||
.status = BuildResult::Failure::NotDeterministic,
|
||||
.errorMsg = "no idea why",
|
||||
.isNonDeterministic = true,
|
||||
}},
|
||||
.timesBuilt = 3,
|
||||
.startTime = 30,
|
||||
.stopTime = 50,
|
||||
},
|
||||
BuildResult{
|
||||
.inner{BuildResult::Success{
|
||||
.status = BuildResult::Success::Built,
|
||||
.builtOutputs =
|
||||
{
|
||||
{
|
||||
"foo",
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"},
|
||||
},
|
||||
},
|
||||
{
|
||||
"bar",
|
||||
{
|
||||
.outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar"},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -649,7 +633,7 @@ VERSIONED_CHARACTERIZATION_TEST(
|
|||
},
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
VERSIONED_CHARACTERIZATION_TEST_NO_JSON(
|
||||
WorkerProtoTest,
|
||||
clientHandshakeInfo_1_30,
|
||||
"client-handshake-info_1_30",
|
||||
|
|
@ -658,7 +642,7 @@ VERSIONED_CHARACTERIZATION_TEST(
|
|||
{},
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
VERSIONED_CHARACTERIZATION_TEST_NO_JSON(
|
||||
WorkerProtoTest,
|
||||
clientHandshakeInfo_1_33,
|
||||
"client-handshake-info_1_33",
|
||||
|
|
@ -672,7 +656,7 @@ VERSIONED_CHARACTERIZATION_TEST(
|
|||
},
|
||||
}))
|
||||
|
||||
VERSIONED_CHARACTERIZATION_TEST(
|
||||
VERSIONED_CHARACTERIZATION_TEST_NO_JSON(
|
||||
WorkerProtoTest,
|
||||
clientHandshakeInfo_1_35,
|
||||
"client-handshake-info_1_35",
|
||||
|
|
|
|||
|
|
@ -514,7 +514,7 @@ StorePath BinaryCacheStore::addToStore(
|
|||
|
||||
std::string BinaryCacheStore::makeRealisationPath(const DrvOutput & id)
|
||||
{
|
||||
return realisationsPrefix + "/" + id.to_string() + ".doi";
|
||||
return realisationsPrefix + "/" + id.drvPath.to_string() + "/" + id.outputName + ".doi";
|
||||
}
|
||||
|
||||
void BinaryCacheStore::queryRealisationUncached(
|
||||
|
|
@ -535,7 +535,10 @@ void BinaryCacheStore::queryRealisationUncached(
|
|||
realisation = std::make_shared<const UnkeyedRealisation>(nlohmann::json::parse(*data));
|
||||
} catch (Error & e) {
|
||||
e.addTrace(
|
||||
{}, "while parsing file '%s' as a realisation for key '%s'", outputInfoFilePath, id.to_string());
|
||||
{},
|
||||
"while parsing file '%s' as a build trace value for key '%s'",
|
||||
outputInfoFilePath,
|
||||
id.to_string());
|
||||
throw;
|
||||
}
|
||||
return (*callbackPtr)(std::move(realisation));
|
||||
|
|
@ -551,7 +554,10 @@ void BinaryCacheStore::registerDrvOutput(const Realisation & info)
|
|||
{
|
||||
if (diskCache)
|
||||
diskCache->upsertRealisation(config.getReference().render(/*FIXME withParams=*/false), info);
|
||||
upsertFile(makeRealisationPath(info.id), static_cast<nlohmann::json>(info).dump(), "application/json");
|
||||
upsertFile(
|
||||
makeRealisationPath(info.id),
|
||||
static_cast<nlohmann::json>(static_cast<const UnkeyedRealisation &>(info)).dump(),
|
||||
"application/json");
|
||||
}
|
||||
|
||||
ref<RemoteFSAccessor> BinaryCacheStore::getRemoteFSAccessor(bool requireValidPath)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
#include "nix/store/build-result.hh"
|
||||
#include "nix/util/json-utils.hh"
|
||||
#include <array>
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
@ -11,4 +13,160 @@ std::strong_ordering BuildResult::Success::operator<=>(const BuildResult::Succes
|
|||
bool BuildResult::Failure::operator==(const BuildResult::Failure &) const noexcept = default;
|
||||
std::strong_ordering BuildResult::Failure::operator<=>(const BuildResult::Failure &) const noexcept = default;
|
||||
|
||||
static constexpr std::array<std::pair<BuildResult::Success::Status, std::string_view>, 4> successStatusStrings{{
|
||||
#define ENUM_ENTRY(e) {BuildResult::Success::e, #e}
|
||||
ENUM_ENTRY(Built),
|
||||
ENUM_ENTRY(Substituted),
|
||||
ENUM_ENTRY(AlreadyValid),
|
||||
ENUM_ENTRY(ResolvesToAlreadyValid),
|
||||
#undef ENUM_ENTRY
|
||||
}};
|
||||
|
||||
static std::string_view successStatusToString(BuildResult::Success::Status status)
|
||||
{
|
||||
for (const auto & [enumVal, str] : successStatusStrings) {
|
||||
if (enumVal == status)
|
||||
return str;
|
||||
}
|
||||
throw Error("unknown success status: %d", static_cast<int>(status));
|
||||
}
|
||||
|
||||
static BuildResult::Success::Status successStatusFromString(std::string_view str)
|
||||
{
|
||||
for (const auto & [enumVal, enumStr] : successStatusStrings) {
|
||||
if (enumStr == str)
|
||||
return enumVal;
|
||||
}
|
||||
throw Error("unknown built result success status '%s'", str);
|
||||
}
|
||||
|
||||
static constexpr std::array<std::pair<BuildResult::Failure::Status, std::string_view>, 12> failureStatusStrings{{
|
||||
#define ENUM_ENTRY(e) {BuildResult::Failure::e, #e}
|
||||
ENUM_ENTRY(PermanentFailure),
|
||||
ENUM_ENTRY(InputRejected),
|
||||
ENUM_ENTRY(OutputRejected),
|
||||
ENUM_ENTRY(TransientFailure),
|
||||
ENUM_ENTRY(CachedFailure),
|
||||
ENUM_ENTRY(TimedOut),
|
||||
ENUM_ENTRY(MiscFailure),
|
||||
ENUM_ENTRY(DependencyFailed),
|
||||
ENUM_ENTRY(LogLimitExceeded),
|
||||
ENUM_ENTRY(NotDeterministic),
|
||||
ENUM_ENTRY(NoSubstituters),
|
||||
ENUM_ENTRY(HashMismatch),
|
||||
#undef ENUM_ENTRY
|
||||
}};
|
||||
|
||||
static std::string_view failureStatusToString(BuildResult::Failure::Status status)
|
||||
{
|
||||
for (const auto & [enumVal, str] : failureStatusStrings) {
|
||||
if (enumVal == status)
|
||||
return str;
|
||||
}
|
||||
throw Error("unknown failure status: %d", static_cast<int>(status));
|
||||
}
|
||||
|
||||
static BuildResult::Failure::Status failureStatusFromString(std::string_view str)
|
||||
{
|
||||
for (const auto & [enumVal, enumStr] : failureStatusStrings) {
|
||||
if (enumStr == str)
|
||||
return enumVal;
|
||||
}
|
||||
throw Error("unknown built result failure status '%s'", str);
|
||||
}
|
||||
|
||||
} // namespace nix
|
||||
|
||||
namespace nlohmann {
|
||||
|
||||
using namespace nix;
|
||||
|
||||
void adl_serializer<BuildResult>::to_json(json & res, const BuildResult & br)
|
||||
{
|
||||
res = json::object();
|
||||
|
||||
// Common fields
|
||||
res["timesBuilt"] = br.timesBuilt;
|
||||
res["startTime"] = br.startTime;
|
||||
res["stopTime"] = br.stopTime;
|
||||
|
||||
if (br.cpuUser.has_value()) {
|
||||
res["cpuUser"] = br.cpuUser->count();
|
||||
}
|
||||
if (br.cpuSystem.has_value()) {
|
||||
res["cpuSystem"] = br.cpuSystem->count();
|
||||
}
|
||||
|
||||
// Handle success or failure variant
|
||||
std::visit(
|
||||
overloaded{
|
||||
[&](const BuildResult::Success & success) {
|
||||
res["success"] = true;
|
||||
res["status"] = successStatusToString(success.status);
|
||||
res["builtOutputs"] = success.builtOutputs;
|
||||
},
|
||||
[&](const BuildResult::Failure & failure) {
|
||||
res["success"] = false;
|
||||
res["status"] = failureStatusToString(failure.status);
|
||||
res["errorMsg"] = failure.errorMsg;
|
||||
res["isNonDeterministic"] = failure.isNonDeterministic;
|
||||
},
|
||||
},
|
||||
br.inner);
|
||||
}
|
||||
|
||||
BuildResult adl_serializer<BuildResult>::from_json(const json & _json)
|
||||
{
|
||||
auto & json = getObject(_json);
|
||||
|
||||
BuildResult br;
|
||||
|
||||
// Common fields
|
||||
br.timesBuilt = getUnsigned(valueAt(json, "timesBuilt"));
|
||||
br.startTime = getUnsigned(valueAt(json, "startTime"));
|
||||
br.stopTime = getUnsigned(valueAt(json, "stopTime"));
|
||||
|
||||
if (auto cpuUser = optionalValueAt(json, "cpuUser")) {
|
||||
br.cpuUser = std::chrono::microseconds(getUnsigned(*cpuUser));
|
||||
}
|
||||
if (auto cpuSystem = optionalValueAt(json, "cpuSystem")) {
|
||||
br.cpuSystem = std::chrono::microseconds(getUnsigned(*cpuSystem));
|
||||
}
|
||||
|
||||
// Determine success or failure based on success field
|
||||
bool success = getBoolean(valueAt(json, "success"));
|
||||
std::string statusStr = getString(valueAt(json, "status"));
|
||||
|
||||
if (success) {
|
||||
BuildResult::Success s;
|
||||
s.status = successStatusFromString(statusStr);
|
||||
s.builtOutputs = valueAt(json, "builtOutputs");
|
||||
br.inner = std::move(s);
|
||||
} else {
|
||||
BuildResult::Failure f;
|
||||
f.status = failureStatusFromString(statusStr);
|
||||
f.errorMsg = getString(valueAt(json, "errorMsg"));
|
||||
f.isNonDeterministic = getBoolean(valueAt(json, "isNonDeterministic"));
|
||||
br.inner = std::move(f);
|
||||
}
|
||||
|
||||
return br;
|
||||
}
|
||||
|
||||
KeyedBuildResult adl_serializer<KeyedBuildResult>::from_json(const json & json0)
|
||||
{
|
||||
auto json = getObject(json0);
|
||||
|
||||
return KeyedBuildResult{
|
||||
adl_serializer<BuildResult>::from_json(json0),
|
||||
valueAt(json, "path"),
|
||||
};
|
||||
}
|
||||
|
||||
void adl_serializer<KeyedBuildResult>::to_json(json & json, const KeyedBuildResult & kbr)
|
||||
{
|
||||
adl_serializer<BuildResult>::to_json(json, kbr);
|
||||
json["path"] = kbr.path;
|
||||
}
|
||||
|
||||
} // namespace nlohmann
|
||||
|
|
|
|||
|
|
@ -212,9 +212,8 @@ Goal::Co DerivationBuildingGoal::tryToBuild()
|
|||
given this information by the downstream goal, that cannot happen
|
||||
anymore if the downstream goal only cares about one output, but
|
||||
we care about all outputs. */
|
||||
auto outputHashes = staticOutputHashes(worker.evalStore, *drv);
|
||||
for (auto & [outputName, outputHash] : outputHashes) {
|
||||
InitialOutput v{.outputHash = outputHash};
|
||||
for (auto & [outputName, _] : drv->outputs) {
|
||||
InitialOutput v;
|
||||
|
||||
/* TODO we might want to also allow randomizing the paths
|
||||
for regular CA derivations, e.g. for sake of checking
|
||||
|
|
@ -1106,7 +1105,7 @@ DerivationBuildingGoal::checkPathValidity(std::map<std::string, InitialOutput> &
|
|||
: PathStatus::Corrupt,
|
||||
};
|
||||
}
|
||||
auto drvOutput = DrvOutput{info.outputHash, i.first};
|
||||
auto drvOutput = DrvOutput{drvPath, i.first};
|
||||
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)) {
|
||||
if (auto real = worker.store.queryRealisation(drvOutput)) {
|
||||
info.known = {
|
||||
|
|
|
|||
|
|
@ -36,12 +36,6 @@ DerivationGoal::DerivationGoal(
|
|||
, drvPath(drvPath)
|
||||
, wantedOutput(wantedOutput)
|
||||
, drv{std::make_unique<Derivation>(drv)}
|
||||
, outputHash{[&] {
|
||||
auto outputHashes = staticOutputHashes(worker.evalStore, drv);
|
||||
if (auto * mOutputHash = get(outputHashes, wantedOutput))
|
||||
return *mOutputHash;
|
||||
throw Error("derivation '%s' does not have output '%s'", worker.store.printStorePath(drvPath), wantedOutput);
|
||||
}()}
|
||||
, buildMode(buildMode)
|
||||
{
|
||||
|
||||
|
|
@ -100,7 +94,7 @@ Goal::Co DerivationGoal::haveDerivation(bool storeDerivation)
|
|||
them. */
|
||||
if (settings.useSubstitutes && drvOptions.substitutesAllowed()) {
|
||||
if (!checkResult)
|
||||
waitees.insert(upcast_goal(worker.makeDrvOutputSubstitutionGoal(DrvOutput{outputHash, wantedOutput})));
|
||||
waitees.insert(upcast_goal(worker.makeDrvOutputSubstitutionGoal(DrvOutput{drvPath, wantedOutput})));
|
||||
else {
|
||||
auto * cap = getDerivationCA(*drv);
|
||||
waitees.insert(upcast_goal(worker.makePathSubstitutionGoal(
|
||||
|
|
@ -167,12 +161,7 @@ Goal::Co DerivationGoal::haveDerivation(bool storeDerivation)
|
|||
// No `std::visit` for coroutines yet
|
||||
if (auto * successP = resolvedResult.tryGetSuccess()) {
|
||||
auto & success = *successP;
|
||||
auto outputHashes = staticOutputHashes(worker.evalStore, *drv);
|
||||
auto resolvedHashes = staticOutputHashes(worker.store, drvResolved);
|
||||
|
||||
auto outputHash = get(outputHashes, wantedOutput);
|
||||
auto resolvedHash = get(resolvedHashes, wantedOutput);
|
||||
if ((!outputHash) || (!resolvedHash))
|
||||
if (!drv->outputs.contains(wantedOutput))
|
||||
throw Error(
|
||||
"derivation '%s' doesn't have expected output '%s' (derivation-goal.cc/resolve)",
|
||||
worker.store.printStorePath(drvPath),
|
||||
|
|
@ -181,7 +170,7 @@ Goal::Co DerivationGoal::haveDerivation(bool storeDerivation)
|
|||
auto realisation = [&] {
|
||||
auto take1 = get(success.builtOutputs, wantedOutput);
|
||||
if (take1)
|
||||
return static_cast<UnkeyedRealisation>(*take1);
|
||||
return *take1;
|
||||
|
||||
/* The above `get` should work. But stateful tracking of
|
||||
outputs in resolvedResult, this can get out of sync with the
|
||||
|
|
@ -189,7 +178,7 @@ Goal::Co DerivationGoal::haveDerivation(bool storeDerivation)
|
|||
check the store directly if it fails. */
|
||||
auto take2 = worker.evalStore.queryRealisation(
|
||||
DrvOutput{
|
||||
.drvHash = *resolvedHash,
|
||||
.drvPath = pathResolved,
|
||||
.outputName = wantedOutput,
|
||||
});
|
||||
if (take2)
|
||||
|
|
@ -205,15 +194,10 @@ Goal::Co DerivationGoal::haveDerivation(bool storeDerivation)
|
|||
Realisation newRealisation{
|
||||
realisation,
|
||||
{
|
||||
.drvHash = *outputHash,
|
||||
.drvPath = drvPath,
|
||||
.outputName = wantedOutput,
|
||||
}};
|
||||
newRealisation.signatures.clear();
|
||||
if (!drv->type().isFixed()) {
|
||||
auto & drvStore = worker.evalStore.isValidPath(drvPath) ? worker.evalStore : worker.store;
|
||||
newRealisation.dependentRealisations =
|
||||
drvOutputReferences(worker.store, *drv, realisation.outPath, &drvStore);
|
||||
}
|
||||
worker.store.signRealisation(newRealisation);
|
||||
worker.store.registerDrvOutput(newRealisation);
|
||||
}
|
||||
|
|
@ -256,16 +240,7 @@ Goal::Co DerivationGoal::haveDerivation(bool storeDerivation)
|
|||
/* In checking mode, the builder will not register any outputs.
|
||||
So we want to make sure the ones that we wanted to check are
|
||||
properly there. */
|
||||
success.builtOutputs = {{
|
||||
wantedOutput,
|
||||
{
|
||||
assertPathValidity(),
|
||||
{
|
||||
.drvHash = outputHash,
|
||||
.outputName = wantedOutput,
|
||||
},
|
||||
},
|
||||
}};
|
||||
success.builtOutputs = {{wantedOutput, assertPathValidity()}};
|
||||
} else {
|
||||
/* Otherwise the builder will give us info for out output, but
|
||||
also for other outputs. Filter down to just our output so as
|
||||
|
|
@ -390,7 +365,7 @@ std::optional<std::pair<UnkeyedRealisation, PathStatus>> DerivationGoal::checkPa
|
|||
if (drv->type().isImpure())
|
||||
return std::nullopt;
|
||||
|
||||
auto drvOutput = DrvOutput{outputHash, wantedOutput};
|
||||
auto drvOutput = DrvOutput{drvPath, wantedOutput};
|
||||
|
||||
std::optional<UnkeyedRealisation> mRealisation;
|
||||
|
||||
|
|
@ -430,7 +405,7 @@ std::optional<std::pair<UnkeyedRealisation, PathStatus>> DerivationGoal::checkPa
|
|||
Realisation{
|
||||
*mRealisation,
|
||||
{
|
||||
.drvHash = outputHash,
|
||||
.drvPath = drvPath,
|
||||
.outputName = wantedOutput,
|
||||
},
|
||||
});
|
||||
|
|
@ -453,16 +428,7 @@ Goal::Done DerivationGoal::doneSuccess(BuildResult::Success::Status status, Unke
|
|||
{
|
||||
buildResult.inner = BuildResult::Success{
|
||||
.status = status,
|
||||
.builtOutputs = {{
|
||||
wantedOutput,
|
||||
{
|
||||
std::move(builtOutput),
|
||||
DrvOutput{
|
||||
.drvHash = outputHash,
|
||||
.outputName = wantedOutput,
|
||||
},
|
||||
},
|
||||
}},
|
||||
.builtOutputs = {{wantedOutput, std::move(builtOutput)}},
|
||||
};
|
||||
|
||||
mcExpectedBuilds.reset();
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ DrvOutputSubstitutionGoal::DrvOutputSubstitutionGoal(const DrvOutput & id, Worke
|
|||
: Goal(worker, init())
|
||||
, id(id)
|
||||
{
|
||||
name = fmt("substitution of '%s'", id.to_string());
|
||||
name = fmt("substitution of '%s'", id.render(worker.store));
|
||||
trace("created");
|
||||
}
|
||||
|
||||
|
|
@ -86,32 +86,8 @@ Goal::Co DrvOutputSubstitutionGoal::init()
|
|||
if (!outputInfo)
|
||||
continue;
|
||||
|
||||
bool failed = false;
|
||||
|
||||
Goals waitees;
|
||||
|
||||
for (const auto & [depId, depPath] : outputInfo->dependentRealisations) {
|
||||
if (depId != id) {
|
||||
if (auto localOutputInfo = worker.store.queryRealisation(depId);
|
||||
localOutputInfo && localOutputInfo->outPath != depPath) {
|
||||
warn(
|
||||
"substituter '%s' has an incompatible realisation for '%s', ignoring.\n"
|
||||
"Local: %s\n"
|
||||
"Remote: %s",
|
||||
sub->config.getHumanReadableURI(),
|
||||
depId.to_string(),
|
||||
worker.store.printStorePath(localOutputInfo->outPath),
|
||||
worker.store.printStorePath(depPath));
|
||||
failed = true;
|
||||
break;
|
||||
}
|
||||
waitees.insert(worker.makeDrvOutputSubstitutionGoal(depId));
|
||||
}
|
||||
}
|
||||
|
||||
if (failed)
|
||||
continue;
|
||||
|
||||
waitees.insert(worker.makePathSubstitutionGoal(outputInfo->outPath));
|
||||
|
||||
co_await await(std::move(waitees));
|
||||
|
|
@ -131,7 +107,8 @@ Goal::Co DrvOutputSubstitutionGoal::init()
|
|||
|
||||
/* None left. Terminate this goal and let someone else deal
|
||||
with it. */
|
||||
debug("derivation output '%s' is required, but there is no substituter that can provide it", id.to_string());
|
||||
debug(
|
||||
"derivation output '%s' is required, but there is no substituter that can provide it", id.render(worker.store));
|
||||
|
||||
if (substituterFailed) {
|
||||
worker.failedSubstitutions++;
|
||||
|
|
@ -146,7 +123,7 @@ Goal::Co DrvOutputSubstitutionGoal::init()
|
|||
|
||||
std::string DrvOutputSubstitutionGoal::key()
|
||||
{
|
||||
return "a$" + std::string(id.to_string());
|
||||
return "a$" + std::string(id.render(worker.store));
|
||||
}
|
||||
|
||||
void DrvOutputSubstitutionGoal::handleEOF(Descriptor fd)
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue