summaryrefslogtreecommitdiffstats
path: root/src/graph_test.cc
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2015-11-04 21:17:33 (GMT)
committerBrad King <brad.king@kitware.com>2019-04-18 12:21:44 (GMT)
commite5c22c0a4b93895334a10d412124ffff69c3fd25 (patch)
treef04be9f0e0d0e2fcfd5101e9dd9a2dfe3cc1141b /src/graph_test.cc
parenta4970769519b09fec5ff6ffe73a5fa2bf9f252e4 (diff)
downloadNinja-e5c22c0a4b93895334a10d412124ffff69c3fd25.zip
Ninja-e5c22c0a4b93895334a10d412124ffff69c3fd25.tar.gz
Ninja-e5c22c0a4b93895334a10d412124ffff69c3fd25.tar.bz2
Teach DependencyScan to load a dyndep file
Add a LoadDyndeps method to load a dyndep file and update the edges that name it in their dyndep binding.
Diffstat (limited to 'src/graph_test.cc')
-rw-r--r--src/graph_test.cc183
1 files changed, 183 insertions, 0 deletions
diff --git a/src/graph_test.cc b/src/graph_test.cc
index 4a66831..f53c0e9 100644
--- a/src/graph_test.cc
+++ b/src/graph_test.cc
@@ -479,3 +479,186 @@ TEST_F(GraphTest, Decanonicalize) {
EXPECT_EQ(root_nodes[3]->PathDecanonicalized(), "out4\\foo");
}
#endif
+
+TEST_F(GraphTest, DyndepLoadTrivial) {
+ AssertParse(&state_,
+"rule r\n"
+" command = unused\n"
+"build out: r in || dd\n"
+" dyndep = dd\n"
+ );
+ fs_.Create("dd",
+"ninja_dyndep_version = 1\n"
+"build out: dyndep\n"
+ );
+
+ string err;
+ ASSERT_TRUE(GetNode("dd")->dyndep_pending());
+ EXPECT_TRUE(scan_.LoadDyndeps(GetNode("dd"), &err));
+ EXPECT_EQ("", err);
+ EXPECT_FALSE(GetNode("dd")->dyndep_pending());
+
+ Edge* edge = GetNode("out")->in_edge();
+ ASSERT_EQ(1u, edge->outputs_.size());
+ EXPECT_EQ("out", edge->outputs_[0]->path());
+ ASSERT_EQ(2u, edge->inputs_.size());
+ EXPECT_EQ("in", edge->inputs_[0]->path());
+ EXPECT_EQ("dd", edge->inputs_[1]->path());
+ EXPECT_EQ(0u, edge->implicit_deps_);
+ EXPECT_EQ(1u, edge->order_only_deps_);
+ EXPECT_FALSE(edge->GetBindingBool("restat"));
+}
+
+TEST_F(GraphTest, DyndepLoadMissingFile) {
+ AssertParse(&state_,
+"rule r\n"
+" command = unused\n"
+"build out: r in || dd\n"
+" dyndep = dd\n"
+ );
+
+ string err;
+ ASSERT_TRUE(GetNode("dd")->dyndep_pending());
+ EXPECT_FALSE(scan_.LoadDyndeps(GetNode("dd"), &err));
+ EXPECT_EQ("loading 'dd': No such file or directory", err);
+}
+
+TEST_F(GraphTest, DyndepLoadMissingEntry) {
+ AssertParse(&state_,
+"rule r\n"
+" command = unused\n"
+"build out: r in || dd\n"
+" dyndep = dd\n"
+ );
+ fs_.Create("dd",
+"ninja_dyndep_version = 1\n"
+ );
+
+ string err;
+ ASSERT_TRUE(GetNode("dd")->dyndep_pending());
+ EXPECT_FALSE(scan_.LoadDyndeps(GetNode("dd"), &err));
+ EXPECT_EQ("'out' not mentioned in its dyndep file 'dd'", err);
+}
+
+TEST_F(GraphTest, DyndepLoadExtraEntry) {
+ AssertParse(&state_,
+"rule r\n"
+" command = unused\n"
+"build out: r in || dd\n"
+" dyndep = dd\n"
+"build out2: r in || dd\n"
+ );
+ fs_.Create("dd",
+"ninja_dyndep_version = 1\n"
+"build out: dyndep\n"
+"build out2: dyndep\n"
+ );
+
+ string err;
+ ASSERT_TRUE(GetNode("dd")->dyndep_pending());
+ EXPECT_FALSE(scan_.LoadDyndeps(GetNode("dd"), &err));
+ EXPECT_EQ("dyndep file 'dd' mentions output 'out2' whose build statement "
+ "does not have a dyndep binding for the file", err);
+}
+
+TEST_F(GraphTest, DyndepLoadOutputWithMultipleRules1) {
+ AssertParse(&state_,
+"rule r\n"
+" command = unused\n"
+"build out1 | out-twice.imp: r in1\n"
+"build out2: r in2 || dd\n"
+" dyndep = dd\n"
+ );
+ fs_.Create("dd",
+"ninja_dyndep_version = 1\n"
+"build out2 | out-twice.imp: dyndep\n"
+ );
+
+ string err;
+ ASSERT_TRUE(GetNode("dd")->dyndep_pending());
+ EXPECT_FALSE(scan_.LoadDyndeps(GetNode("dd"), &err));
+ EXPECT_EQ("multiple rules generate out-twice.imp", err);
+}
+
+TEST_F(GraphTest, DyndepLoadOutputWithMultipleRules2) {
+ AssertParse(&state_,
+"rule r\n"
+" command = unused\n"
+"build out1: r in1 || dd1\n"
+" dyndep = dd1\n"
+"build out2: r in2 || dd2\n"
+" dyndep = dd2\n"
+ );
+ fs_.Create("dd1",
+"ninja_dyndep_version = 1\n"
+"build out1 | out-twice.imp: dyndep\n"
+ );
+ fs_.Create("dd2",
+"ninja_dyndep_version = 1\n"
+"build out2 | out-twice.imp: dyndep\n"
+ );
+
+ string err;
+ ASSERT_TRUE(GetNode("dd1")->dyndep_pending());
+ EXPECT_TRUE(scan_.LoadDyndeps(GetNode("dd1"), &err));
+ EXPECT_EQ("", err);
+ ASSERT_TRUE(GetNode("dd2")->dyndep_pending());
+ EXPECT_FALSE(scan_.LoadDyndeps(GetNode("dd2"), &err));
+ EXPECT_EQ("multiple rules generate out-twice.imp", err);
+}
+
+TEST_F(GraphTest, DyndepLoadMultiple) {
+ AssertParse(&state_,
+"rule r\n"
+" command = unused\n"
+"build out1: r in1 || dd\n"
+" dyndep = dd\n"
+"build out2: r in2 || dd\n"
+" dyndep = dd\n"
+"build outNot: r in3 || dd\n"
+ );
+ fs_.Create("dd",
+"ninja_dyndep_version = 1\n"
+"build out1 | out1imp: dyndep | in1imp\n"
+"build out2: dyndep | in2imp\n"
+" restat = 1\n"
+ );
+
+ string err;
+ ASSERT_TRUE(GetNode("dd")->dyndep_pending());
+ EXPECT_TRUE(scan_.LoadDyndeps(GetNode("dd"), &err));
+ EXPECT_EQ("", err);
+ EXPECT_FALSE(GetNode("dd")->dyndep_pending());
+
+ Edge* edge1 = GetNode("out1")->in_edge();
+ ASSERT_EQ(2u, edge1->outputs_.size());
+ EXPECT_EQ("out1", edge1->outputs_[0]->path());
+ EXPECT_EQ("out1imp", edge1->outputs_[1]->path());
+ EXPECT_EQ(1u, edge1->implicit_outs_);
+ ASSERT_EQ(3u, edge1->inputs_.size());
+ EXPECT_EQ("in1", edge1->inputs_[0]->path());
+ EXPECT_EQ("in1imp", edge1->inputs_[1]->path());
+ EXPECT_EQ("dd", edge1->inputs_[2]->path());
+ EXPECT_EQ(1u, edge1->implicit_deps_);
+ EXPECT_EQ(1u, edge1->order_only_deps_);
+ EXPECT_FALSE(edge1->GetBindingBool("restat"));
+ EXPECT_EQ(edge1, GetNode("out1imp")->in_edge());
+ Node* in1imp = GetNode("in1imp");
+ ASSERT_EQ(1u, in1imp->out_edges().size());
+ EXPECT_EQ(edge1, in1imp->out_edges()[0]);
+
+ Edge* edge2 = GetNode("out2")->in_edge();
+ ASSERT_EQ(1u, edge2->outputs_.size());
+ EXPECT_EQ("out2", edge2->outputs_[0]->path());
+ EXPECT_EQ(0u, edge2->implicit_outs_);
+ ASSERT_EQ(3u, edge2->inputs_.size());
+ EXPECT_EQ("in2", edge2->inputs_[0]->path());
+ EXPECT_EQ("in2imp", edge2->inputs_[1]->path());
+ EXPECT_EQ("dd", edge2->inputs_[2]->path());
+ EXPECT_EQ(1u, edge2->implicit_deps_);
+ EXPECT_EQ(1u, edge2->order_only_deps_);
+ EXPECT_TRUE(edge2->GetBindingBool("restat"));
+ Node* in2imp = GetNode("in2imp");
+ ASSERT_EQ(1u, in2imp->out_edges().size());
+ EXPECT_EQ(edge2, in2imp->out_edges()[0]);
+}