Skip to content

Commit 84654d8

Browse files
haenoeEricson2314
andcommitted
Unit test for derivation "advanced attrs"
This tests the parser and JSON format using the DRV files from the tests added in the previous commit. Co-Authored-By: John Ericson <John.Ericson@Obsidian.Systems>
1 parent 9340ba8 commit 84654d8

11 files changed

Lines changed: 347 additions & 14 deletions

maintainers/flake-module.nix

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,6 @@
447447
''^tests/unit/libfetchers/public-key\.cc''
448448
''^tests/unit/libstore-support/tests/derived-path\.cc''
449449
''^tests/unit/libstore-support/tests/derived-path\.hh''
450-
''^tests/unit/libstore-support/tests/libstore\.hh''
451450
''^tests/unit/libstore-support/tests/nix_api_store\.hh''
452451
''^tests/unit/libstore-support/tests/outputs-spec\.cc''
453452
''^tests/unit/libstore-support/tests/outputs-spec\.hh''

tests/unit/libstore-support/tests/libstore.hh

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,27 @@
88

99
namespace nix {
1010

11-
class LibStoreTest : public virtual ::testing::Test {
12-
public:
13-
static void SetUpTestSuite() {
14-
initLibStore(false);
15-
}
16-
17-
protected:
18-
LibStoreTest()
19-
: store(openStore("dummy://"))
20-
{ }
21-
22-
ref<Store> store;
11+
class LibStoreTest : public virtual ::testing::Test
12+
{
13+
public:
14+
static void SetUpTestSuite()
15+
{
16+
initLibStore(false);
17+
}
18+
19+
protected:
20+
LibStoreTest()
21+
: store(openStore({
22+
.variant =
23+
StoreReference::Specified{
24+
.scheme = "dummy",
25+
},
26+
.params = {},
27+
}))
28+
{
29+
}
30+
31+
ref<Store> store;
2332
};
2433

25-
2634
} /* namespace nix */
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../../functional/derivation/advanced-attributes-defaults.drv
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"args": [
3+
"-c",
4+
"echo hello > $out"
5+
],
6+
"builder": "/bin/bash",
7+
"env": {
8+
"builder": "/bin/bash",
9+
"name": "advanced-attributes-defaults",
10+
"out": "/nix/store/1qsc7svv43m4dw2prh6mvyf7cai5czji-advanced-attributes-defaults",
11+
"system": "my-system"
12+
},
13+
"inputDrvs": {},
14+
"inputSrcs": [],
15+
"name": "advanced-attributes-defaults",
16+
"outputs": {
17+
"out": {
18+
"path": "/nix/store/1qsc7svv43m4dw2prh6mvyf7cai5czji-advanced-attributes-defaults"
19+
}
20+
},
21+
"system": "my-system"
22+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../../functional/derivation/advanced-attributes-structured-attrs-defaults.drv
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"args": [
3+
"-c",
4+
"echo hello > $out"
5+
],
6+
"builder": "/bin/bash",
7+
"env": {
8+
"__json": "{\"builder\":\"/bin/bash\",\"name\":\"advanced-attributes-structured-attrs-defaults\",\"outputs\":[\"out\",\"dev\"],\"system\":\"my-system\"}",
9+
"dev": "/nix/store/8bazivnbipbyi569623skw5zm91z6kc2-advanced-attributes-structured-attrs-defaults-dev",
10+
"out": "/nix/store/f8f8nvnx32bxvyxyx2ff7akbvwhwd9dw-advanced-attributes-structured-attrs-defaults"
11+
},
12+
"inputDrvs": {},
13+
"inputSrcs": [],
14+
"name": "advanced-attributes-structured-attrs-defaults",
15+
"outputs": {
16+
"dev": {
17+
"path": "/nix/store/8bazivnbipbyi569623skw5zm91z6kc2-advanced-attributes-structured-attrs-defaults-dev"
18+
},
19+
"out": {
20+
"path": "/nix/store/f8f8nvnx32bxvyxyx2ff7akbvwhwd9dw-advanced-attributes-structured-attrs-defaults"
21+
}
22+
},
23+
"system": "my-system"
24+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../../functional/derivation/advanced-attributes-structured-attrs.drv
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"args": [
3+
"-c",
4+
"echo hello > $out"
5+
],
6+
"builder": "/bin/bash",
7+
"env": {
8+
"__json": "{\"__darwinAllowLocalNetworking\":true,\"__impureHostDeps\":[\"/usr/bin/ditto\"],\"__noChroot\":true,\"__sandboxProfile\":\"sandcastle\",\"allowSubstitutes\":false,\"builder\":\"/bin/bash\",\"impureEnvVars\":[\"UNICORN\"],\"name\":\"advanced-attributes-structured-attrs\",\"outputChecks\":{\"bin\":{\"disallowedReferences\":[\"/nix/store/7rhsm8i393hm1wcsmph782awg1hi2f7x-bar\"],\"disallowedRequisites\":[\"/nix/store/7rhsm8i393hm1wcsmph782awg1hi2f7x-bar\"]},\"dev\":{\"maxClosureSize\":5909,\"maxSize\":789},\"out\":{\"allowedReferences\":[\"/nix/store/3c08bzb71z4wiag719ipjxr277653ynp-foo\"],\"allowedRequisites\":[\"/nix/store/3c08bzb71z4wiag719ipjxr277653ynp-foo\"]}},\"outputs\":[\"out\",\"bin\",\"dev\"],\"preferLocalBuild\":true,\"requiredSystemFeatures\":[\"rainbow\",\"uid-range\"],\"system\":\"my-system\"}",
9+
"bin": "/nix/store/pbzb48v0ycf80jgligcp4n8z0rblna4n-advanced-attributes-structured-attrs-bin",
10+
"dev": "/nix/store/7xapi8jv7flcz1qq8jhw55ar8ag8hldh-advanced-attributes-structured-attrs-dev",
11+
"out": "/nix/store/mpq3l1l1qc2yr50q520g08kprprwv79f-advanced-attributes-structured-attrs"
12+
},
13+
"inputDrvs": {
14+
"/nix/store/4xm4wccqsvagz9gjksn24s7rip2fdy7v-foo.drv": {
15+
"dynamicOutputs": {},
16+
"outputs": [
17+
"out"
18+
]
19+
},
20+
"/nix/store/plsq5jbr5nhgqwcgb2qxw7jchc09dnl8-bar.drv": {
21+
"dynamicOutputs": {},
22+
"outputs": [
23+
"out"
24+
]
25+
}
26+
},
27+
"inputSrcs": [],
28+
"name": "advanced-attributes-structured-attrs",
29+
"outputs": {
30+
"bin": {
31+
"path": "/nix/store/pbzb48v0ycf80jgligcp4n8z0rblna4n-advanced-attributes-structured-attrs-bin"
32+
},
33+
"dev": {
34+
"path": "/nix/store/7xapi8jv7flcz1qq8jhw55ar8ag8hldh-advanced-attributes-structured-attrs-dev"
35+
},
36+
"out": {
37+
"path": "/nix/store/mpq3l1l1qc2yr50q520g08kprprwv79f-advanced-attributes-structured-attrs"
38+
}
39+
},
40+
"system": "my-system"
41+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../../functional/derivation/advanced-attributes.drv
Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
#include <nlohmann/json.hpp>
2+
#include <gtest/gtest.h>
3+
#include <optional>
4+
5+
#include "experimental-features.hh"
6+
#include "derivations.hh"
7+
8+
#include "tests/libstore.hh"
9+
#include "tests/characterization.hh"
10+
#include "parsed-derivations.hh"
11+
#include "types.hh"
12+
13+
namespace nix {
14+
15+
using nlohmann::json;
16+
17+
class DerivationAdvancedAttrsTest : public CharacterizationTest, public LibStoreTest
18+
{
19+
Path unitTestData = getUnitTestData() + "/derivation";
20+
21+
public:
22+
Path goldenMaster(std::string_view testStem) const override
23+
{
24+
return unitTestData + "/" + testStem;
25+
}
26+
};
27+
28+
#define TEST_ATERM_JSON(STEM, NAME) \
29+
TEST_F(DerivationAdvancedAttrsTest, Derivation_##STEM##_from_json) \
30+
{ \
31+
readTest(NAME ".json", [&](const auto & encoded_) { \
32+
auto encoded = json::parse(encoded_); \
33+
/* Use DRV file instead of C++ literal as source of truth. */ \
34+
auto aterm = readFile(goldenMaster(NAME ".drv")); \
35+
auto expected = parseDerivation(*store, std::move(aterm), NAME); \
36+
Derivation got = Derivation::fromJSON(*store, encoded); \
37+
EXPECT_EQ(got, expected); \
38+
}); \
39+
} \
40+
\
41+
TEST_F(DerivationAdvancedAttrsTest, Derivation_##STEM##_to_json) \
42+
{ \
43+
writeTest( \
44+
NAME ".json", \
45+
[&]() -> json { \
46+
/* Use DRV file instead of C++ literal as source of truth. */ \
47+
auto aterm = readFile(goldenMaster(NAME ".drv")); \
48+
return parseDerivation(*store, std::move(aterm), NAME).toJSON(*store); \
49+
}, \
50+
[](const auto & file) { return json::parse(readFile(file)); }, \
51+
[](const auto & file, const auto & got) { return writeFile(file, got.dump(2) + "\n"); }); \
52+
} \
53+
\
54+
TEST_F(DerivationAdvancedAttrsTest, Derivation_##STEM##_from_aterm) \
55+
{ \
56+
readTest(NAME ".drv", [&](auto encoded) { \
57+
/* Use JSON file instead of C++ literal as source of truth. */ \
58+
auto json = json::parse(readFile(goldenMaster(NAME ".json"))); \
59+
auto expected = Derivation::fromJSON(*store, json); \
60+
auto got = parseDerivation(*store, std::move(encoded), NAME); \
61+
EXPECT_EQ(got.toJSON(*store), expected.toJSON(*store)); \
62+
EXPECT_EQ(got, expected); \
63+
}); \
64+
} \
65+
\
66+
/* No corresponding write test, because we need to read the drv to write the json file */
67+
68+
TEST_ATERM_JSON(advancedAttributes_defaults, "advanced-attributes-defaults");
69+
TEST_ATERM_JSON(advancedAttributes, "advanced-attributes-defaults");
70+
TEST_ATERM_JSON(advancedAttributes_structuredAttrs_defaults, "advanced-attributes-structured-attrs");
71+
TEST_ATERM_JSON(advancedAttributes_structuredAttrs, "advanced-attributes-structured-attrs-defaults");
72+
73+
#undef TEST_ATERM_JSON
74+
75+
TEST_F(DerivationAdvancedAttrsTest, Derivation_advancedAttributes_defaults)
76+
{
77+
readTest("advanced-attributes-defaults.drv", [&](auto encoded) {
78+
auto got = parseDerivation(*store, std::move(encoded), "foo");
79+
80+
auto drvPath = writeDerivation(*store, got, NoRepair, true);
81+
82+
ParsedDerivation parsedDrv(drvPath, got);
83+
84+
EXPECT_EQ(parsedDrv.getStringAttr("__sandboxProfile").value_or(""), "");
85+
EXPECT_EQ(parsedDrv.getBoolAttr("__noChroot"), false);
86+
EXPECT_EQ(parsedDrv.getStringsAttr("__impureHostDeps").value_or(Strings()), Strings());
87+
EXPECT_EQ(parsedDrv.getStringsAttr("impureEnvVars").value_or(Strings()), Strings());
88+
EXPECT_EQ(parsedDrv.getBoolAttr("__darwinAllowLocalNetworking"), false);
89+
EXPECT_EQ(parsedDrv.getStringsAttr("allowedReferences"), std::nullopt);
90+
EXPECT_EQ(parsedDrv.getStringsAttr("allowedRequisites"), std::nullopt);
91+
EXPECT_EQ(parsedDrv.getStringsAttr("disallowedReferences"), std::nullopt);
92+
EXPECT_EQ(parsedDrv.getStringsAttr("disallowedRequisites"), std::nullopt);
93+
EXPECT_EQ(parsedDrv.getRequiredSystemFeatures(), StringSet());
94+
EXPECT_EQ(parsedDrv.canBuildLocally(*store), false);
95+
EXPECT_EQ(parsedDrv.willBuildLocally(*store), false);
96+
EXPECT_EQ(parsedDrv.substitutesAllowed(), true);
97+
EXPECT_EQ(parsedDrv.useUidRange(), false);
98+
});
99+
};
100+
101+
TEST_F(DerivationAdvancedAttrsTest, Derivation_advancedAttributes)
102+
{
103+
readTest("advanced-attributes.drv", [&](auto encoded) {
104+
auto got = parseDerivation(*store, std::move(encoded), "foo");
105+
106+
auto drvPath = writeDerivation(*store, got, NoRepair, true);
107+
108+
ParsedDerivation parsedDrv(drvPath, got);
109+
110+
StringSet systemFeatures{"rainbow", "uid-range"};
111+
112+
EXPECT_EQ(parsedDrv.getStringAttr("__sandboxProfile").value_or(""), "sandcastle");
113+
EXPECT_EQ(parsedDrv.getBoolAttr("__noChroot"), true);
114+
EXPECT_EQ(parsedDrv.getStringsAttr("__impureHostDeps").value_or(Strings()), Strings{"/usr/bin/ditto"});
115+
EXPECT_EQ(parsedDrv.getStringsAttr("impureEnvVars").value_or(Strings()), Strings{"UNICORN"});
116+
EXPECT_EQ(parsedDrv.getBoolAttr("__darwinAllowLocalNetworking"), true);
117+
EXPECT_EQ(
118+
parsedDrv.getStringsAttr("allowedReferences"), Strings{"/nix/store/3c08bzb71z4wiag719ipjxr277653ynp-foo"});
119+
EXPECT_EQ(
120+
parsedDrv.getStringsAttr("allowedRequisites"), Strings{"/nix/store/3c08bzb71z4wiag719ipjxr277653ynp-foo"});
121+
EXPECT_EQ(
122+
parsedDrv.getStringsAttr("disallowedReferences"),
123+
Strings{"/nix/store/7rhsm8i393hm1wcsmph782awg1hi2f7x-bar"});
124+
EXPECT_EQ(
125+
parsedDrv.getStringsAttr("disallowedRequisites"),
126+
Strings{"/nix/store/7rhsm8i393hm1wcsmph782awg1hi2f7x-bar"});
127+
EXPECT_EQ(parsedDrv.getRequiredSystemFeatures(), systemFeatures);
128+
EXPECT_EQ(parsedDrv.canBuildLocally(*store), false);
129+
EXPECT_EQ(parsedDrv.willBuildLocally(*store), false);
130+
EXPECT_EQ(parsedDrv.substitutesAllowed(), false);
131+
EXPECT_EQ(parsedDrv.useUidRange(), true);
132+
});
133+
};
134+
135+
TEST_F(DerivationAdvancedAttrsTest, Derivation_advancedAttributes_structuredAttrs_defaults)
136+
{
137+
readTest("advanced-attributes-structured-attrs-defaults.drv", [&](auto encoded) {
138+
auto got = parseDerivation(*store, std::move(encoded), "foo");
139+
140+
auto drvPath = writeDerivation(*store, got, NoRepair, true);
141+
142+
ParsedDerivation parsedDrv(drvPath, got);
143+
144+
EXPECT_EQ(parsedDrv.getStringAttr("__sandboxProfile").value_or(""), "");
145+
EXPECT_EQ(parsedDrv.getBoolAttr("__noChroot"), false);
146+
EXPECT_EQ(parsedDrv.getStringsAttr("__impureHostDeps").value_or(Strings()), Strings());
147+
EXPECT_EQ(parsedDrv.getStringsAttr("impureEnvVars").value_or(Strings()), Strings());
148+
EXPECT_EQ(parsedDrv.getBoolAttr("__darwinAllowLocalNetworking"), false);
149+
150+
{
151+
auto structuredAttrs_ = parsedDrv.getStructuredAttrs();
152+
ASSERT_TRUE(structuredAttrs_);
153+
auto & structuredAttrs = *structuredAttrs_;
154+
155+
auto outputChecks_ = get(structuredAttrs, "outputChecks");
156+
ASSERT_FALSE(outputChecks_);
157+
}
158+
159+
EXPECT_EQ(parsedDrv.getRequiredSystemFeatures(), StringSet());
160+
EXPECT_EQ(parsedDrv.canBuildLocally(*store), false);
161+
EXPECT_EQ(parsedDrv.willBuildLocally(*store), false);
162+
EXPECT_EQ(parsedDrv.substitutesAllowed(), true);
163+
EXPECT_EQ(parsedDrv.useUidRange(), false);
164+
});
165+
};
166+
167+
TEST_F(DerivationAdvancedAttrsTest, Derivation_advancedAttributes_structuredAttrs)
168+
{
169+
readTest("advanced-attributes-structured-attrs.drv", [&](auto encoded) {
170+
auto got = parseDerivation(*store, std::move(encoded), "foo");
171+
172+
auto drvPath = writeDerivation(*store, got, NoRepair, true);
173+
174+
ParsedDerivation parsedDrv(drvPath, got);
175+
176+
StringSet systemFeatures{"rainbow", "uid-range"};
177+
178+
EXPECT_EQ(parsedDrv.getStringAttr("__sandboxProfile").value_or(""), "sandcastle");
179+
EXPECT_EQ(parsedDrv.getBoolAttr("__noChroot"), true);
180+
EXPECT_EQ(parsedDrv.getStringsAttr("__impureHostDeps").value_or(Strings()), Strings{"/usr/bin/ditto"});
181+
EXPECT_EQ(parsedDrv.getStringsAttr("impureEnvVars").value_or(Strings()), Strings{"UNICORN"});
182+
EXPECT_EQ(parsedDrv.getBoolAttr("__darwinAllowLocalNetworking"), true);
183+
184+
{
185+
auto structuredAttrs_ = parsedDrv.getStructuredAttrs();
186+
ASSERT_TRUE(structuredAttrs_);
187+
auto & structuredAttrs = *structuredAttrs_;
188+
189+
auto outputChecks_ = get(structuredAttrs, "outputChecks");
190+
ASSERT_TRUE(outputChecks_);
191+
auto & outputChecks = *outputChecks_;
192+
193+
{
194+
auto output_ = get(outputChecks, "out");
195+
ASSERT_TRUE(output_);
196+
auto & output = *output_;
197+
EXPECT_EQ(
198+
get(output, "allowedReferences")->get<Strings>(),
199+
Strings{"/nix/store/3c08bzb71z4wiag719ipjxr277653ynp-foo"});
200+
EXPECT_EQ(
201+
get(output, "allowedRequisites")->get<Strings>(),
202+
Strings{"/nix/store/3c08bzb71z4wiag719ipjxr277653ynp-foo"});
203+
}
204+
205+
{
206+
auto output_ = get(outputChecks, "bin");
207+
ASSERT_TRUE(output_);
208+
auto & output = *output_;
209+
EXPECT_EQ(
210+
get(output, "disallowedReferences")->get<Strings>(),
211+
Strings{"/nix/store/7rhsm8i393hm1wcsmph782awg1hi2f7x-bar"});
212+
EXPECT_EQ(
213+
get(output, "disallowedRequisites")->get<Strings>(),
214+
Strings{"/nix/store/7rhsm8i393hm1wcsmph782awg1hi2f7x-bar"});
215+
}
216+
217+
{
218+
auto output_ = get(outputChecks, "dev");
219+
ASSERT_TRUE(output_);
220+
auto & output = *output_;
221+
EXPECT_EQ(get(output, "maxSize")->get<uint64_t>(), 789);
222+
EXPECT_EQ(get(output, "maxClosureSize")->get<uint64_t>(), 5909);
223+
}
224+
}
225+
226+
EXPECT_EQ(parsedDrv.getRequiredSystemFeatures(), systemFeatures);
227+
EXPECT_EQ(parsedDrv.canBuildLocally(*store), false);
228+
EXPECT_EQ(parsedDrv.willBuildLocally(*store), false);
229+
EXPECT_EQ(parsedDrv.substitutesAllowed(), false);
230+
EXPECT_EQ(parsedDrv.useUidRange(), true);
231+
});
232+
};
233+
234+
}

0 commit comments

Comments
 (0)