1 // Copyright 2011 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "build.h"
16 
17 #include <assert.h>
18 
19 #include "build_log.h"
20 #include "deps_log.h"
21 #include "graph.h"
22 #include "test.h"
23 
24 using namespace std;
25 
26 struct CompareEdgesByOutput {
cmpCompareEdgesByOutput27   static bool cmp(const Edge* a, const Edge* b) {
28     return a->outputs_[0]->path() < b->outputs_[0]->path();
29   }
30 };
31 
32 /// Fixture for tests involving Plan.
33 // Though Plan doesn't use State, it's useful to have one around
34 // to create Nodes and Edges.
35 struct PlanTest : public StateTestWithBuiltinRules {
36   Plan plan_;
37 
38   /// Because FindWork does not return Edges in any sort of predictable order,
39   // provide a means to get available Edges in order and in a format which is
40   // easy to write tests around.
FindWorkSortedPlanTest41   void FindWorkSorted(deque<Edge*>* ret, int count) {
42     for (int i = 0; i < count; ++i) {
43       ASSERT_TRUE(plan_.more_to_do());
44       Edge* edge = plan_.FindWork();
45       ASSERT_TRUE(edge);
46       ret->push_back(edge);
47     }
48     ASSERT_FALSE(plan_.FindWork());
49     sort(ret->begin(), ret->end(), CompareEdgesByOutput::cmp);
50   }
51 
52   void TestPoolWithDepthOne(const char *test_case);
53 };
54 
TEST_F(PlanTest,Basic)55 TEST_F(PlanTest, Basic) {
56   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
57 "build out: cat mid\n"
58 "build mid: cat in\n"));
59   GetNode("mid")->MarkDirty();
60   GetNode("out")->MarkDirty();
61   string err;
62   EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
63   ASSERT_EQ("", err);
64   ASSERT_TRUE(plan_.more_to_do());
65 
66   Edge* edge = plan_.FindWork();
67   ASSERT_TRUE(edge);
68   ASSERT_EQ("in",  edge->inputs_[0]->path());
69   ASSERT_EQ("mid", edge->outputs_[0]->path());
70 
71   ASSERT_FALSE(plan_.FindWork());
72 
73   plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
74   ASSERT_EQ("", err);
75 
76   edge = plan_.FindWork();
77   ASSERT_TRUE(edge);
78   ASSERT_EQ("mid", edge->inputs_[0]->path());
79   ASSERT_EQ("out", edge->outputs_[0]->path());
80 
81   plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
82   ASSERT_EQ("", err);
83 
84   ASSERT_FALSE(plan_.more_to_do());
85   edge = plan_.FindWork();
86   ASSERT_EQ(0, edge);
87 }
88 
89 // Test that two outputs from one rule can be handled as inputs to the next.
TEST_F(PlanTest,DoubleOutputDirect)90 TEST_F(PlanTest, DoubleOutputDirect) {
91   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
92 "build out: cat mid1 mid2\n"
93 "build mid1 mid2: cat in\n"));
94   GetNode("mid1")->MarkDirty();
95   GetNode("mid2")->MarkDirty();
96   GetNode("out")->MarkDirty();
97 
98   string err;
99   EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
100   ASSERT_EQ("", err);
101   ASSERT_TRUE(plan_.more_to_do());
102 
103   Edge* edge;
104   edge = plan_.FindWork();
105   ASSERT_TRUE(edge);  // cat in
106   plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
107   ASSERT_EQ("", err);
108 
109   edge = plan_.FindWork();
110   ASSERT_TRUE(edge);  // cat mid1 mid2
111   plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
112   ASSERT_EQ("", err);
113 
114   edge = plan_.FindWork();
115   ASSERT_FALSE(edge);  // done
116 }
117 
118 // Test that two outputs from one rule can eventually be routed to another.
TEST_F(PlanTest,DoubleOutputIndirect)119 TEST_F(PlanTest, DoubleOutputIndirect) {
120   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
121 "build out: cat b1 b2\n"
122 "build b1: cat a1\n"
123 "build b2: cat a2\n"
124 "build a1 a2: cat in\n"));
125   GetNode("a1")->MarkDirty();
126   GetNode("a2")->MarkDirty();
127   GetNode("b1")->MarkDirty();
128   GetNode("b2")->MarkDirty();
129   GetNode("out")->MarkDirty();
130   string err;
131   EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
132   ASSERT_EQ("", err);
133   ASSERT_TRUE(plan_.more_to_do());
134 
135   Edge* edge;
136   edge = plan_.FindWork();
137   ASSERT_TRUE(edge);  // cat in
138   plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
139   ASSERT_EQ("", err);
140 
141   edge = plan_.FindWork();
142   ASSERT_TRUE(edge);  // cat a1
143   plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
144   ASSERT_EQ("", err);
145 
146   edge = plan_.FindWork();
147   ASSERT_TRUE(edge);  // cat a2
148   plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
149   ASSERT_EQ("", err);
150 
151   edge = plan_.FindWork();
152   ASSERT_TRUE(edge);  // cat b1 b2
153   plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
154   ASSERT_EQ("", err);
155 
156   edge = plan_.FindWork();
157   ASSERT_FALSE(edge);  // done
158 }
159 
160 // Test that two edges from one output can both execute.
TEST_F(PlanTest,DoubleDependent)161 TEST_F(PlanTest, DoubleDependent) {
162   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
163 "build out: cat a1 a2\n"
164 "build a1: cat mid\n"
165 "build a2: cat mid\n"
166 "build mid: cat in\n"));
167   GetNode("mid")->MarkDirty();
168   GetNode("a1")->MarkDirty();
169   GetNode("a2")->MarkDirty();
170   GetNode("out")->MarkDirty();
171 
172   string err;
173   EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
174   ASSERT_EQ("", err);
175   ASSERT_TRUE(plan_.more_to_do());
176 
177   Edge* edge;
178   edge = plan_.FindWork();
179   ASSERT_TRUE(edge);  // cat in
180   plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
181   ASSERT_EQ("", err);
182 
183   edge = plan_.FindWork();
184   ASSERT_TRUE(edge);  // cat mid
185   plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
186   ASSERT_EQ("", err);
187 
188   edge = plan_.FindWork();
189   ASSERT_TRUE(edge);  // cat mid
190   plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
191   ASSERT_EQ("", err);
192 
193   edge = plan_.FindWork();
194   ASSERT_TRUE(edge);  // cat a1 a2
195   plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
196   ASSERT_EQ("", err);
197 
198   edge = plan_.FindWork();
199   ASSERT_FALSE(edge);  // done
200 }
201 
TestPoolWithDepthOne(const char * test_case)202 void PlanTest::TestPoolWithDepthOne(const char* test_case) {
203   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_, test_case));
204   GetNode("out1")->MarkDirty();
205   GetNode("out2")->MarkDirty();
206   string err;
207   EXPECT_TRUE(plan_.AddTarget(GetNode("out1"), &err));
208   ASSERT_EQ("", err);
209   EXPECT_TRUE(plan_.AddTarget(GetNode("out2"), &err));
210   ASSERT_EQ("", err);
211   ASSERT_TRUE(plan_.more_to_do());
212 
213   Edge* edge = plan_.FindWork();
214   ASSERT_TRUE(edge);
215   ASSERT_EQ("in",  edge->inputs_[0]->path());
216   ASSERT_EQ("out1", edge->outputs_[0]->path());
217 
218   // This will be false since poolcat is serialized
219   ASSERT_FALSE(plan_.FindWork());
220 
221   plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
222   ASSERT_EQ("", err);
223 
224   edge = plan_.FindWork();
225   ASSERT_TRUE(edge);
226   ASSERT_EQ("in", edge->inputs_[0]->path());
227   ASSERT_EQ("out2", edge->outputs_[0]->path());
228 
229   ASSERT_FALSE(plan_.FindWork());
230 
231   plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
232   ASSERT_EQ("", err);
233 
234   ASSERT_FALSE(plan_.more_to_do());
235   edge = plan_.FindWork();
236   ASSERT_EQ(0, edge);
237 }
238 
TEST_F(PlanTest,PoolWithDepthOne)239 TEST_F(PlanTest, PoolWithDepthOne) {
240   TestPoolWithDepthOne(
241 "pool foobar\n"
242 "  depth = 1\n"
243 "rule poolcat\n"
244 "  command = cat $in > $out\n"
245 "  pool = foobar\n"
246 "build out1: poolcat in\n"
247 "build out2: poolcat in\n");
248 }
249 
TEST_F(PlanTest,ConsolePool)250 TEST_F(PlanTest, ConsolePool) {
251   TestPoolWithDepthOne(
252 "rule poolcat\n"
253 "  command = cat $in > $out\n"
254 "  pool = console\n"
255 "build out1: poolcat in\n"
256 "build out2: poolcat in\n");
257 }
258 
TEST_F(PlanTest,PoolsWithDepthTwo)259 TEST_F(PlanTest, PoolsWithDepthTwo) {
260   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
261 "pool foobar\n"
262 "  depth = 2\n"
263 "pool bazbin\n"
264 "  depth = 2\n"
265 "rule foocat\n"
266 "  command = cat $in > $out\n"
267 "  pool = foobar\n"
268 "rule bazcat\n"
269 "  command = cat $in > $out\n"
270 "  pool = bazbin\n"
271 "build out1: foocat in\n"
272 "build out2: foocat in\n"
273 "build out3: foocat in\n"
274 "build outb1: bazcat in\n"
275 "build outb2: bazcat in\n"
276 "build outb3: bazcat in\n"
277 "  pool =\n"
278 "build allTheThings: cat out1 out2 out3 outb1 outb2 outb3\n"
279 ));
280   // Mark all the out* nodes dirty
281   for (int i = 0; i < 3; ++i) {
282     GetNode("out" + string(1, '1' + static_cast<char>(i)))->MarkDirty();
283     GetNode("outb" + string(1, '1' + static_cast<char>(i)))->MarkDirty();
284   }
285   GetNode("allTheThings")->MarkDirty();
286 
287   string err;
288   EXPECT_TRUE(plan_.AddTarget(GetNode("allTheThings"), &err));
289   ASSERT_EQ("", err);
290 
291   deque<Edge*> edges;
292   FindWorkSorted(&edges, 5);
293 
294   for (int i = 0; i < 4; ++i) {
295     Edge *edge = edges[i];
296     ASSERT_EQ("in",  edge->inputs_[0]->path());
297     string base_name(i < 2 ? "out" : "outb");
298     ASSERT_EQ(base_name + string(1, '1' + (i % 2)), edge->outputs_[0]->path());
299   }
300 
301   // outb3 is exempt because it has an empty pool
302   Edge* edge = edges[4];
303   ASSERT_TRUE(edge);
304   ASSERT_EQ("in",  edge->inputs_[0]->path());
305   ASSERT_EQ("outb3", edge->outputs_[0]->path());
306 
307   // finish out1
308   plan_.EdgeFinished(edges.front(), Plan::kEdgeSucceeded, &err);
309   ASSERT_EQ("", err);
310   edges.pop_front();
311 
312   // out3 should be available
313   Edge* out3 = plan_.FindWork();
314   ASSERT_TRUE(out3);
315   ASSERT_EQ("in",  out3->inputs_[0]->path());
316   ASSERT_EQ("out3", out3->outputs_[0]->path());
317 
318   ASSERT_FALSE(plan_.FindWork());
319 
320   plan_.EdgeFinished(out3, Plan::kEdgeSucceeded, &err);
321   ASSERT_EQ("", err);
322 
323   ASSERT_FALSE(plan_.FindWork());
324 
325   for (deque<Edge*>::iterator it = edges.begin(); it != edges.end(); ++it) {
326     plan_.EdgeFinished(*it, Plan::kEdgeSucceeded, &err);
327     ASSERT_EQ("", err);
328   }
329 
330   Edge* last = plan_.FindWork();
331   ASSERT_TRUE(last);
332   ASSERT_EQ("allTheThings", last->outputs_[0]->path());
333 
334   plan_.EdgeFinished(last, Plan::kEdgeSucceeded, &err);
335   ASSERT_EQ("", err);
336 
337   ASSERT_FALSE(plan_.more_to_do());
338   ASSERT_FALSE(plan_.FindWork());
339 }
340 
TEST_F(PlanTest,PoolWithRedundantEdges)341 TEST_F(PlanTest, PoolWithRedundantEdges) {
342   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
343     "pool compile\n"
344     "  depth = 1\n"
345     "rule gen_foo\n"
346     "  command = touch foo.cpp\n"
347     "rule gen_bar\n"
348     "  command = touch bar.cpp\n"
349     "rule echo\n"
350     "  command = echo $out > $out\n"
351     "build foo.cpp.obj: echo foo.cpp || foo.cpp\n"
352     "  pool = compile\n"
353     "build bar.cpp.obj: echo bar.cpp || bar.cpp\n"
354     "  pool = compile\n"
355     "build libfoo.a: echo foo.cpp.obj bar.cpp.obj\n"
356     "build foo.cpp: gen_foo\n"
357     "build bar.cpp: gen_bar\n"
358     "build all: phony libfoo.a\n"));
359   GetNode("foo.cpp")->MarkDirty();
360   GetNode("foo.cpp.obj")->MarkDirty();
361   GetNode("bar.cpp")->MarkDirty();
362   GetNode("bar.cpp.obj")->MarkDirty();
363   GetNode("libfoo.a")->MarkDirty();
364   GetNode("all")->MarkDirty();
365   string err;
366   EXPECT_TRUE(plan_.AddTarget(GetNode("all"), &err));
367   ASSERT_EQ("", err);
368   ASSERT_TRUE(plan_.more_to_do());
369 
370   Edge* edge = NULL;
371 
372   deque<Edge*> initial_edges;
373   FindWorkSorted(&initial_edges, 2);
374 
375   edge = initial_edges[1];  // Foo first
376   ASSERT_EQ("foo.cpp", edge->outputs_[0]->path());
377   plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
378   ASSERT_EQ("", err);
379 
380   edge = plan_.FindWork();
381   ASSERT_TRUE(edge);
382   ASSERT_FALSE(plan_.FindWork());
383   ASSERT_EQ("foo.cpp", edge->inputs_[0]->path());
384   ASSERT_EQ("foo.cpp", edge->inputs_[1]->path());
385   ASSERT_EQ("foo.cpp.obj", edge->outputs_[0]->path());
386   plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
387   ASSERT_EQ("", err);
388 
389   edge = initial_edges[0];  // Now for bar
390   ASSERT_EQ("bar.cpp", edge->outputs_[0]->path());
391   plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
392   ASSERT_EQ("", err);
393 
394   edge = plan_.FindWork();
395   ASSERT_TRUE(edge);
396   ASSERT_FALSE(plan_.FindWork());
397   ASSERT_EQ("bar.cpp", edge->inputs_[0]->path());
398   ASSERT_EQ("bar.cpp", edge->inputs_[1]->path());
399   ASSERT_EQ("bar.cpp.obj", edge->outputs_[0]->path());
400   plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
401   ASSERT_EQ("", err);
402 
403   edge = plan_.FindWork();
404   ASSERT_TRUE(edge);
405   ASSERT_FALSE(plan_.FindWork());
406   ASSERT_EQ("foo.cpp.obj", edge->inputs_[0]->path());
407   ASSERT_EQ("bar.cpp.obj", edge->inputs_[1]->path());
408   ASSERT_EQ("libfoo.a", edge->outputs_[0]->path());
409   plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
410   ASSERT_EQ("", err);
411 
412   edge = plan_.FindWork();
413   ASSERT_TRUE(edge);
414   ASSERT_FALSE(plan_.FindWork());
415   ASSERT_EQ("libfoo.a", edge->inputs_[0]->path());
416   ASSERT_EQ("all", edge->outputs_[0]->path());
417   plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
418   ASSERT_EQ("", err);
419 
420   edge = plan_.FindWork();
421   ASSERT_FALSE(edge);
422   ASSERT_FALSE(plan_.more_to_do());
423 }
424 
TEST_F(PlanTest,PoolWithFailingEdge)425 TEST_F(PlanTest, PoolWithFailingEdge) {
426   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
427     "pool foobar\n"
428     "  depth = 1\n"
429     "rule poolcat\n"
430     "  command = cat $in > $out\n"
431     "  pool = foobar\n"
432     "build out1: poolcat in\n"
433     "build out2: poolcat in\n"));
434   GetNode("out1")->MarkDirty();
435   GetNode("out2")->MarkDirty();
436   string err;
437   EXPECT_TRUE(plan_.AddTarget(GetNode("out1"), &err));
438   ASSERT_EQ("", err);
439   EXPECT_TRUE(plan_.AddTarget(GetNode("out2"), &err));
440   ASSERT_EQ("", err);
441   ASSERT_TRUE(plan_.more_to_do());
442 
443   Edge* edge = plan_.FindWork();
444   ASSERT_TRUE(edge);
445   ASSERT_EQ("in",  edge->inputs_[0]->path());
446   ASSERT_EQ("out1", edge->outputs_[0]->path());
447 
448   // This will be false since poolcat is serialized
449   ASSERT_FALSE(plan_.FindWork());
450 
451   plan_.EdgeFinished(edge, Plan::kEdgeFailed, &err);
452   ASSERT_EQ("", err);
453 
454   edge = plan_.FindWork();
455   ASSERT_TRUE(edge);
456   ASSERT_EQ("in", edge->inputs_[0]->path());
457   ASSERT_EQ("out2", edge->outputs_[0]->path());
458 
459   ASSERT_FALSE(plan_.FindWork());
460 
461   plan_.EdgeFinished(edge, Plan::kEdgeFailed, &err);
462   ASSERT_EQ("", err);
463 
464   ASSERT_TRUE(plan_.more_to_do()); // Jobs have failed
465   edge = plan_.FindWork();
466   ASSERT_EQ(0, edge);
467 }
468 
469 /// Fake implementation of CommandRunner, useful for tests.
470 struct FakeCommandRunner : public CommandRunner {
FakeCommandRunnerFakeCommandRunner471   explicit FakeCommandRunner(VirtualFileSystem* fs) :
472       max_active_edges_(1), fs_(fs) {}
473 
474   // CommandRunner impl
475   virtual bool CanRunMore() const;
476   virtual bool StartCommand(Edge* edge);
477   virtual bool WaitForCommand(Result* result);
478   virtual vector<Edge*> GetActiveEdges();
479   virtual void Abort();
480 
481   vector<string> commands_ran_;
482   vector<Edge*> active_edges_;
483   size_t max_active_edges_;
484   VirtualFileSystem* fs_;
485 };
486 
487 struct BuildTest : public StateTestWithBuiltinRules, public BuildLogUser {
BuildTestBuildTest488   BuildTest() : config_(MakeConfig()), command_runner_(&fs_),
489                 builder_(&state_, config_, NULL, NULL, &fs_),
490                 status_(config_) {
491   }
492 
BuildTestBuildTest493   BuildTest(DepsLog* log) : config_(MakeConfig()), command_runner_(&fs_),
494                             builder_(&state_, config_, NULL, log, &fs_),
495                             status_(config_) {
496   }
497 
SetUpBuildTest498   virtual void SetUp() {
499     StateTestWithBuiltinRules::SetUp();
500 
501     builder_.command_runner_.reset(&command_runner_);
502     AssertParse(&state_,
503 "build cat1: cat in1\n"
504 "build cat2: cat in1 in2\n"
505 "build cat12: cat cat1 cat2\n");
506 
507     fs_.Create("in1", "");
508     fs_.Create("in2", "");
509   }
510 
~BuildTestBuildTest511   ~BuildTest() {
512     builder_.command_runner_.release();
513   }
514 
IsPathDeadBuildTest515   virtual bool IsPathDead(StringPiece s) const { return false; }
516 
517   /// Rebuild target in the 'working tree' (fs_).
518   /// State of command_runner_ and logs contents (if specified) ARE MODIFIED.
519   /// Handy to check for NOOP builds, and higher-level rebuild tests.
520   void RebuildTarget(const string& target, const char* manifest,
521                      const char* log_path = NULL, const char* deps_path = NULL,
522                      State* state = NULL);
523 
524   // Mark a path dirty.
525   void Dirty(const string& path);
526 
MakeConfigBuildTest527   BuildConfig MakeConfig() {
528     BuildConfig config;
529     config.verbosity = BuildConfig::QUIET;
530     return config;
531   }
532 
533   BuildConfig config_;
534   FakeCommandRunner command_runner_;
535   VirtualFileSystem fs_;
536   Builder builder_;
537 
538   BuildStatus status_;
539 };
540 
RebuildTarget(const string & target,const char * manifest,const char * log_path,const char * deps_path,State * state)541 void BuildTest::RebuildTarget(const string& target, const char* manifest,
542                               const char* log_path, const char* deps_path,
543                               State* state) {
544   State local_state, *pstate = &local_state;
545   if (state)
546     pstate = state;
547   ASSERT_NO_FATAL_FAILURE(AddCatRule(pstate));
548   AssertParse(pstate, manifest);
549 
550   string err;
551   BuildLog build_log, *pbuild_log = NULL;
552   if (log_path) {
553     ASSERT_TRUE(build_log.Load(log_path, &err));
554     ASSERT_TRUE(build_log.OpenForWrite(log_path, *this, &err));
555     ASSERT_EQ("", err);
556     pbuild_log = &build_log;
557   }
558 
559   DepsLog deps_log, *pdeps_log = NULL;
560   if (deps_path) {
561     ASSERT_TRUE(deps_log.Load(deps_path, pstate, &err));
562     ASSERT_TRUE(deps_log.OpenForWrite(deps_path, &err));
563     ASSERT_EQ("", err);
564     pdeps_log = &deps_log;
565   }
566 
567   Builder builder(pstate, config_, pbuild_log, pdeps_log, &fs_);
568   EXPECT_TRUE(builder.AddTarget(target, &err));
569 
570   command_runner_.commands_ran_.clear();
571   builder.command_runner_.reset(&command_runner_);
572   if (!builder.AlreadyUpToDate()) {
573     bool build_res = builder.Build(&err);
574     EXPECT_TRUE(build_res);
575   }
576   builder.command_runner_.release();
577 }
578 
CanRunMore() const579 bool FakeCommandRunner::CanRunMore() const {
580   return active_edges_.size() < max_active_edges_;
581 }
582 
StartCommand(Edge * edge)583 bool FakeCommandRunner::StartCommand(Edge* edge) {
584   assert(active_edges_.size() < max_active_edges_);
585   assert(find(active_edges_.begin(), active_edges_.end(), edge)
586          == active_edges_.end());
587   commands_ran_.push_back(edge->EvaluateCommand());
588   if (edge->rule().name() == "cat"  ||
589       edge->rule().name() == "cat_rsp" ||
590       edge->rule().name() == "cat_rsp_out" ||
591       edge->rule().name() == "cc" ||
592       edge->rule().name() == "cp_multi_msvc" ||
593       edge->rule().name() == "cp_multi_gcc" ||
594       edge->rule().name() == "touch" ||
595       edge->rule().name() == "touch-interrupt" ||
596       edge->rule().name() == "touch-fail-tick2") {
597     for (vector<Node*>::iterator out = edge->outputs_.begin();
598          out != edge->outputs_.end(); ++out) {
599       fs_->Create((*out)->path(), "");
600     }
601   } else if (edge->rule().name() == "true" ||
602              edge->rule().name() == "fail" ||
603              edge->rule().name() == "interrupt" ||
604              edge->rule().name() == "console") {
605     // Don't do anything.
606   } else if (edge->rule().name() == "cp") {
607     assert(!edge->inputs_.empty());
608     assert(edge->outputs_.size() == 1);
609     string content;
610     string err;
611     if (fs_->ReadFile(edge->inputs_[0]->path(), &content, &err) ==
612         DiskInterface::Okay)
613       fs_->WriteFile(edge->outputs_[0]->path(), content);
614   } else {
615     printf("unknown command\n");
616     return false;
617   }
618 
619   active_edges_.push_back(edge);
620 
621   // Allow tests to control the order by the name of the first output.
622   sort(active_edges_.begin(), active_edges_.end(),
623        CompareEdgesByOutput::cmp);
624 
625   return true;
626 }
627 
WaitForCommand(Result * result)628 bool FakeCommandRunner::WaitForCommand(Result* result) {
629   if (active_edges_.empty())
630     return false;
631 
632   // All active edges were already completed immediately when started,
633   // so we can pick any edge here.  Pick the last edge.  Tests can
634   // control the order of edges by the name of the first output.
635   vector<Edge*>::iterator edge_iter = active_edges_.end() - 1;
636 
637   Edge* edge = *edge_iter;
638   result->edge = edge;
639 
640   if (edge->rule().name() == "interrupt" ||
641       edge->rule().name() == "touch-interrupt") {
642     result->status = ExitInterrupted;
643     return true;
644   }
645 
646   if (edge->rule().name() == "console") {
647     if (edge->use_console())
648       result->status = ExitSuccess;
649     else
650       result->status = ExitFailure;
651     active_edges_.erase(edge_iter);
652     return true;
653   }
654 
655   if (edge->rule().name() == "cp_multi_msvc") {
656     const std::string prefix = edge->GetBinding("msvc_deps_prefix");
657     for (std::vector<Node*>::iterator in = edge->inputs_.begin();
658          in != edge->inputs_.end(); ++in) {
659       result->output += prefix + (*in)->path() + '\n';
660     }
661   }
662 
663   if (edge->rule().name() == "fail" ||
664       (edge->rule().name() == "touch-fail-tick2" && fs_->now_ == 2))
665     result->status = ExitFailure;
666   else
667     result->status = ExitSuccess;
668 
669   // Provide a way for test cases to verify when an edge finishes that
670   // some other edge is still active.  This is useful for test cases
671   // covering behavior involving multiple active edges.
672   const string& verify_active_edge = edge->GetBinding("verify_active_edge");
673   if (!verify_active_edge.empty()) {
674     bool verify_active_edge_found = false;
675     for (vector<Edge*>::iterator i = active_edges_.begin();
676          i != active_edges_.end(); ++i) {
677       if (!(*i)->outputs_.empty() &&
678           (*i)->outputs_[0]->path() == verify_active_edge) {
679         verify_active_edge_found = true;
680       }
681     }
682     EXPECT_TRUE(verify_active_edge_found);
683   }
684 
685   active_edges_.erase(edge_iter);
686   return true;
687 }
688 
GetActiveEdges()689 vector<Edge*> FakeCommandRunner::GetActiveEdges() {
690   return active_edges_;
691 }
692 
Abort()693 void FakeCommandRunner::Abort() {
694   active_edges_.clear();
695 }
696 
Dirty(const string & path)697 void BuildTest::Dirty(const string& path) {
698   Node* node = GetNode(path);
699   node->MarkDirty();
700 
701   // If it's an input file, mark that we've already stat()ed it and
702   // it's missing.
703   if (!node->in_edge())
704     node->MarkMissing();
705 }
706 
TEST_F(BuildTest,NoWork)707 TEST_F(BuildTest, NoWork) {
708   string err;
709   EXPECT_TRUE(builder_.AlreadyUpToDate());
710 }
711 
TEST_F(BuildTest,OneStep)712 TEST_F(BuildTest, OneStep) {
713   // Given a dirty target with one ready input,
714   // we should rebuild the target.
715   Dirty("cat1");
716   string err;
717   EXPECT_TRUE(builder_.AddTarget("cat1", &err));
718   ASSERT_EQ("", err);
719   EXPECT_TRUE(builder_.Build(&err));
720   ASSERT_EQ("", err);
721 
722   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
723   EXPECT_EQ("cat in1 > cat1", command_runner_.commands_ran_[0]);
724 }
725 
TEST_F(BuildTest,OneStep2)726 TEST_F(BuildTest, OneStep2) {
727   // Given a target with one dirty input,
728   // we should rebuild the target.
729   Dirty("cat1");
730   string err;
731   EXPECT_TRUE(builder_.AddTarget("cat1", &err));
732   ASSERT_EQ("", err);
733   EXPECT_TRUE(builder_.Build(&err));
734   EXPECT_EQ("", err);
735 
736   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
737   EXPECT_EQ("cat in1 > cat1", command_runner_.commands_ran_[0]);
738 }
739 
TEST_F(BuildTest,TwoStep)740 TEST_F(BuildTest, TwoStep) {
741   string err;
742   EXPECT_TRUE(builder_.AddTarget("cat12", &err));
743   ASSERT_EQ("", err);
744   EXPECT_TRUE(builder_.Build(&err));
745   EXPECT_EQ("", err);
746   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
747   // Depending on how the pointers work out, we could've ran
748   // the first two commands in either order.
749   EXPECT_TRUE((command_runner_.commands_ran_[0] == "cat in1 > cat1" &&
750                command_runner_.commands_ran_[1] == "cat in1 in2 > cat2") ||
751               (command_runner_.commands_ran_[1] == "cat in1 > cat1" &&
752                command_runner_.commands_ran_[0] == "cat in1 in2 > cat2"));
753 
754   EXPECT_EQ("cat cat1 cat2 > cat12", command_runner_.commands_ran_[2]);
755 
756   fs_.Tick();
757 
758   // Modifying in2 requires rebuilding one intermediate file
759   // and the final file.
760   fs_.Create("in2", "");
761   state_.Reset();
762   EXPECT_TRUE(builder_.AddTarget("cat12", &err));
763   ASSERT_EQ("", err);
764   EXPECT_TRUE(builder_.Build(&err));
765   ASSERT_EQ("", err);
766   ASSERT_EQ(5u, command_runner_.commands_ran_.size());
767   EXPECT_EQ("cat in1 in2 > cat2", command_runner_.commands_ran_[3]);
768   EXPECT_EQ("cat cat1 cat2 > cat12", command_runner_.commands_ran_[4]);
769 }
770 
TEST_F(BuildTest,TwoOutputs)771 TEST_F(BuildTest, TwoOutputs) {
772   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
773 "rule touch\n"
774 "  command = touch $out\n"
775 "build out1 out2: touch in.txt\n"));
776 
777   fs_.Create("in.txt", "");
778 
779   string err;
780   EXPECT_TRUE(builder_.AddTarget("out1", &err));
781   ASSERT_EQ("", err);
782   EXPECT_TRUE(builder_.Build(&err));
783   EXPECT_EQ("", err);
784   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
785   EXPECT_EQ("touch out1 out2", command_runner_.commands_ran_[0]);
786 }
787 
TEST_F(BuildTest,ImplicitOutput)788 TEST_F(BuildTest, ImplicitOutput) {
789   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
790 "rule touch\n"
791 "  command = touch $out $out.imp\n"
792 "build out | out.imp: touch in.txt\n"));
793   fs_.Create("in.txt", "");
794 
795   string err;
796   EXPECT_TRUE(builder_.AddTarget("out.imp", &err));
797   ASSERT_EQ("", err);
798   EXPECT_TRUE(builder_.Build(&err));
799   EXPECT_EQ("", err);
800   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
801   EXPECT_EQ("touch out out.imp", command_runner_.commands_ran_[0]);
802 }
803 
804 // Test case from
805 //   https://github.com/ninja-build/ninja/issues/148
TEST_F(BuildTest,MultiOutIn)806 TEST_F(BuildTest, MultiOutIn) {
807   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
808 "rule touch\n"
809 "  command = touch $out\n"
810 "build in1 otherfile: touch in\n"
811 "build out: touch in | in1\n"));
812 
813   fs_.Create("in", "");
814   fs_.Tick();
815   fs_.Create("in1", "");
816 
817   string err;
818   EXPECT_TRUE(builder_.AddTarget("out", &err));
819   ASSERT_EQ("", err);
820   EXPECT_TRUE(builder_.Build(&err));
821   EXPECT_EQ("", err);
822 }
823 
TEST_F(BuildTest,Chain)824 TEST_F(BuildTest, Chain) {
825   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
826 "build c2: cat c1\n"
827 "build c3: cat c2\n"
828 "build c4: cat c3\n"
829 "build c5: cat c4\n"));
830 
831   fs_.Create("c1", "");
832 
833   string err;
834   EXPECT_TRUE(builder_.AddTarget("c5", &err));
835   ASSERT_EQ("", err);
836   EXPECT_TRUE(builder_.Build(&err));
837   EXPECT_EQ("", err);
838   ASSERT_EQ(4u, command_runner_.commands_ran_.size());
839 
840   err.clear();
841   command_runner_.commands_ran_.clear();
842   state_.Reset();
843   EXPECT_TRUE(builder_.AddTarget("c5", &err));
844   ASSERT_EQ("", err);
845   EXPECT_TRUE(builder_.AlreadyUpToDate());
846 
847   fs_.Tick();
848 
849   fs_.Create("c3", "");
850   err.clear();
851   command_runner_.commands_ran_.clear();
852   state_.Reset();
853   EXPECT_TRUE(builder_.AddTarget("c5", &err));
854   ASSERT_EQ("", err);
855   EXPECT_FALSE(builder_.AlreadyUpToDate());
856   EXPECT_TRUE(builder_.Build(&err));
857   ASSERT_EQ(2u, command_runner_.commands_ran_.size());  // 3->4, 4->5
858 }
859 
TEST_F(BuildTest,MissingInput)860 TEST_F(BuildTest, MissingInput) {
861   // Input is referenced by build file, but no rule for it.
862   string err;
863   Dirty("in1");
864   EXPECT_FALSE(builder_.AddTarget("cat1", &err));
865   EXPECT_EQ("'in1', needed by 'cat1', missing and no known rule to make it",
866             err);
867 }
868 
TEST_F(BuildTest,MissingTarget)869 TEST_F(BuildTest, MissingTarget) {
870   // Target is not referenced by build file.
871   string err;
872   EXPECT_FALSE(builder_.AddTarget("meow", &err));
873   EXPECT_EQ("unknown target: 'meow'", err);
874 }
875 
TEST_F(BuildTest,MakeDirs)876 TEST_F(BuildTest, MakeDirs) {
877   string err;
878 
879 #ifdef _WIN32
880   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
881                                       "build subdir\\dir2\\file: cat in1\n"));
882 #else
883   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
884                                       "build subdir/dir2/file: cat in1\n"));
885 #endif
886   EXPECT_TRUE(builder_.AddTarget("subdir/dir2/file", &err));
887 
888   EXPECT_EQ("", err);
889   EXPECT_TRUE(builder_.Build(&err));
890   ASSERT_EQ("", err);
891   ASSERT_EQ(2u, fs_.directories_made_.size());
892   EXPECT_EQ("subdir", fs_.directories_made_[0]);
893   EXPECT_EQ("subdir/dir2", fs_.directories_made_[1]);
894 }
895 
TEST_F(BuildTest,DepFileMissing)896 TEST_F(BuildTest, DepFileMissing) {
897   string err;
898   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
899 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
900 "build fo$ o.o: cc foo.c\n"));
901   fs_.Create("foo.c", "");
902 
903   EXPECT_TRUE(builder_.AddTarget("fo o.o", &err));
904   ASSERT_EQ("", err);
905   ASSERT_EQ(1u, fs_.files_read_.size());
906   EXPECT_EQ("fo o.o.d", fs_.files_read_[0]);
907 }
908 
TEST_F(BuildTest,DepFileOK)909 TEST_F(BuildTest, DepFileOK) {
910   string err;
911   int orig_edges = state_.edges_.size();
912   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
913 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
914 "build foo.o: cc foo.c\n"));
915   Edge* edge = state_.edges_.back();
916 
917   fs_.Create("foo.c", "");
918   GetNode("bar.h")->MarkDirty();  // Mark bar.h as missing.
919   fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
920   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
921   ASSERT_EQ("", err);
922   ASSERT_EQ(1u, fs_.files_read_.size());
923   EXPECT_EQ("foo.o.d", fs_.files_read_[0]);
924 
925   // Expect three new edges: one generating foo.o, and two more from
926   // loading the depfile.
927   ASSERT_EQ(orig_edges + 3, (int)state_.edges_.size());
928   // Expect our edge to now have three inputs: foo.c and two headers.
929   ASSERT_EQ(3u, edge->inputs_.size());
930 
931   // Expect the command line we generate to only use the original input.
932   ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
933 }
934 
TEST_F(BuildTest,DepFileParseError)935 TEST_F(BuildTest, DepFileParseError) {
936   string err;
937   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
938 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
939 "build foo.o: cc foo.c\n"));
940   fs_.Create("foo.c", "");
941   fs_.Create("foo.o.d", "randomtext\n");
942   EXPECT_FALSE(builder_.AddTarget("foo.o", &err));
943   EXPECT_EQ("foo.o.d: expected ':' in depfile", err);
944 }
945 
TEST_F(BuildTest,EncounterReadyTwice)946 TEST_F(BuildTest, EncounterReadyTwice) {
947   string err;
948   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
949 "rule touch\n"
950 "  command = touch $out\n"
951 "build c: touch\n"
952 "build b: touch || c\n"
953 "build a: touch | b || c\n"));
954 
955   vector<Edge*> c_out = GetNode("c")->out_edges();
956   ASSERT_EQ(2u, c_out.size());
957   EXPECT_EQ("b", c_out[0]->outputs_[0]->path());
958   EXPECT_EQ("a", c_out[1]->outputs_[0]->path());
959 
960   fs_.Create("b", "");
961   EXPECT_TRUE(builder_.AddTarget("a", &err));
962   ASSERT_EQ("", err);
963 
964   EXPECT_TRUE(builder_.Build(&err));
965   ASSERT_EQ("", err);
966   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
967 }
968 
TEST_F(BuildTest,OrderOnlyDeps)969 TEST_F(BuildTest, OrderOnlyDeps) {
970   string err;
971   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
972 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
973 "build foo.o: cc foo.c || otherfile\n"));
974   Edge* edge = state_.edges_.back();
975 
976   fs_.Create("foo.c", "");
977   fs_.Create("otherfile", "");
978   fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
979   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
980   ASSERT_EQ("", err);
981 
982   // One explicit, two implicit, one order only.
983   ASSERT_EQ(4u, edge->inputs_.size());
984   EXPECT_EQ(2, edge->implicit_deps_);
985   EXPECT_EQ(1, edge->order_only_deps_);
986   // Verify the inputs are in the order we expect
987   // (explicit then implicit then orderonly).
988   EXPECT_EQ("foo.c", edge->inputs_[0]->path());
989   EXPECT_EQ("blah.h", edge->inputs_[1]->path());
990   EXPECT_EQ("bar.h", edge->inputs_[2]->path());
991   EXPECT_EQ("otherfile", edge->inputs_[3]->path());
992 
993   // Expect the command line we generate to only use the original input.
994   ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
995 
996   // explicit dep dirty, expect a rebuild.
997   EXPECT_TRUE(builder_.Build(&err));
998   ASSERT_EQ("", err);
999   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1000 
1001   fs_.Tick();
1002 
1003   // Recreate the depfile, as it should have been deleted by the build.
1004   fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
1005 
1006   // implicit dep dirty, expect a rebuild.
1007   fs_.Create("blah.h", "");
1008   fs_.Create("bar.h", "");
1009   command_runner_.commands_ran_.clear();
1010   state_.Reset();
1011   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
1012   EXPECT_TRUE(builder_.Build(&err));
1013   ASSERT_EQ("", err);
1014   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1015 
1016   fs_.Tick();
1017 
1018   // Recreate the depfile, as it should have been deleted by the build.
1019   fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
1020 
1021   // order only dep dirty, no rebuild.
1022   fs_.Create("otherfile", "");
1023   command_runner_.commands_ran_.clear();
1024   state_.Reset();
1025   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
1026   EXPECT_EQ("", err);
1027   EXPECT_TRUE(builder_.AlreadyUpToDate());
1028 
1029   // implicit dep missing, expect rebuild.
1030   fs_.RemoveFile("bar.h");
1031   command_runner_.commands_ran_.clear();
1032   state_.Reset();
1033   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
1034   EXPECT_TRUE(builder_.Build(&err));
1035   ASSERT_EQ("", err);
1036   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1037 }
1038 
TEST_F(BuildTest,RebuildOrderOnlyDeps)1039 TEST_F(BuildTest, RebuildOrderOnlyDeps) {
1040   string err;
1041   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1042 "rule cc\n  command = cc $in\n"
1043 "rule true\n  command = true\n"
1044 "build oo.h: cc oo.h.in\n"
1045 "build foo.o: cc foo.c || oo.h\n"));
1046 
1047   fs_.Create("foo.c", "");
1048   fs_.Create("oo.h.in", "");
1049 
1050   // foo.o and order-only dep dirty, build both.
1051   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
1052   EXPECT_TRUE(builder_.Build(&err));
1053   ASSERT_EQ("", err);
1054   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1055 
1056   // all clean, no rebuild.
1057   command_runner_.commands_ran_.clear();
1058   state_.Reset();
1059   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
1060   EXPECT_EQ("", err);
1061   EXPECT_TRUE(builder_.AlreadyUpToDate());
1062 
1063   // order-only dep missing, build it only.
1064   fs_.RemoveFile("oo.h");
1065   command_runner_.commands_ran_.clear();
1066   state_.Reset();
1067   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
1068   EXPECT_TRUE(builder_.Build(&err));
1069   ASSERT_EQ("", err);
1070   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1071   ASSERT_EQ("cc oo.h.in", command_runner_.commands_ran_[0]);
1072 
1073   fs_.Tick();
1074 
1075   // order-only dep dirty, build it only.
1076   fs_.Create("oo.h.in", "");
1077   command_runner_.commands_ran_.clear();
1078   state_.Reset();
1079   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
1080   EXPECT_TRUE(builder_.Build(&err));
1081   ASSERT_EQ("", err);
1082   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1083   ASSERT_EQ("cc oo.h.in", command_runner_.commands_ran_[0]);
1084 }
1085 
1086 #ifdef _WIN32
TEST_F(BuildTest,DepFileCanonicalize)1087 TEST_F(BuildTest, DepFileCanonicalize) {
1088   string err;
1089   int orig_edges = state_.edges_.size();
1090   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1091 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
1092 "build gen/stuff\\things/foo.o: cc x\\y/z\\foo.c\n"));
1093   Edge* edge = state_.edges_.back();
1094 
1095   fs_.Create("x/y/z/foo.c", "");
1096   GetNode("bar.h")->MarkDirty();  // Mark bar.h as missing.
1097   // Note, different slashes from manifest.
1098   fs_.Create("gen/stuff\\things/foo.o.d",
1099              "gen\\stuff\\things\\foo.o: blah.h bar.h\n");
1100   EXPECT_TRUE(builder_.AddTarget("gen/stuff/things/foo.o", &err));
1101   ASSERT_EQ("", err);
1102   ASSERT_EQ(1u, fs_.files_read_.size());
1103   // The depfile path does not get Canonicalize as it seems unnecessary.
1104   EXPECT_EQ("gen/stuff\\things/foo.o.d", fs_.files_read_[0]);
1105 
1106   // Expect three new edges: one generating foo.o, and two more from
1107   // loading the depfile.
1108   ASSERT_EQ(orig_edges + 3, (int)state_.edges_.size());
1109   // Expect our edge to now have three inputs: foo.c and two headers.
1110   ASSERT_EQ(3u, edge->inputs_.size());
1111 
1112   // Expect the command line we generate to only use the original input, and
1113   // using the slashes from the manifest.
1114   ASSERT_EQ("cc x\\y/z\\foo.c", edge->EvaluateCommand());
1115 }
1116 #endif
1117 
TEST_F(BuildTest,Phony)1118 TEST_F(BuildTest, Phony) {
1119   string err;
1120   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1121 "build out: cat bar.cc\n"
1122 "build all: phony out\n"));
1123   fs_.Create("bar.cc", "");
1124 
1125   EXPECT_TRUE(builder_.AddTarget("all", &err));
1126   ASSERT_EQ("", err);
1127 
1128   // Only one command to run, because phony runs no command.
1129   EXPECT_FALSE(builder_.AlreadyUpToDate());
1130   EXPECT_TRUE(builder_.Build(&err));
1131   ASSERT_EQ("", err);
1132   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1133 }
1134 
TEST_F(BuildTest,PhonyNoWork)1135 TEST_F(BuildTest, PhonyNoWork) {
1136   string err;
1137   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1138 "build out: cat bar.cc\n"
1139 "build all: phony out\n"));
1140   fs_.Create("bar.cc", "");
1141   fs_.Create("out", "");
1142 
1143   EXPECT_TRUE(builder_.AddTarget("all", &err));
1144   ASSERT_EQ("", err);
1145   EXPECT_TRUE(builder_.AlreadyUpToDate());
1146 }
1147 
1148 // Test a self-referencing phony.  Ideally this should not work, but
1149 // ninja 1.7 and below tolerated and CMake 2.8.12.x and 3.0.x both
1150 // incorrectly produce it.  We tolerate it for compatibility.
TEST_F(BuildTest,PhonySelfReference)1151 TEST_F(BuildTest, PhonySelfReference) {
1152   string err;
1153   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1154 "build a: phony a\n"));
1155 
1156   EXPECT_TRUE(builder_.AddTarget("a", &err));
1157   ASSERT_EQ("", err);
1158   EXPECT_TRUE(builder_.AlreadyUpToDate());
1159 }
1160 
TEST_F(BuildTest,Fail)1161 TEST_F(BuildTest, Fail) {
1162   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1163 "rule fail\n"
1164 "  command = fail\n"
1165 "build out1: fail\n"));
1166 
1167   string err;
1168   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1169   ASSERT_EQ("", err);
1170 
1171   EXPECT_FALSE(builder_.Build(&err));
1172   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1173   ASSERT_EQ("subcommand failed", err);
1174 }
1175 
TEST_F(BuildTest,SwallowFailures)1176 TEST_F(BuildTest, SwallowFailures) {
1177   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1178 "rule fail\n"
1179 "  command = fail\n"
1180 "build out1: fail\n"
1181 "build out2: fail\n"
1182 "build out3: fail\n"
1183 "build all: phony out1 out2 out3\n"));
1184 
1185   // Swallow two failures, die on the third.
1186   config_.failures_allowed = 3;
1187 
1188   string err;
1189   EXPECT_TRUE(builder_.AddTarget("all", &err));
1190   ASSERT_EQ("", err);
1191 
1192   EXPECT_FALSE(builder_.Build(&err));
1193   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1194   ASSERT_EQ("subcommands failed", err);
1195 }
1196 
TEST_F(BuildTest,SwallowFailuresLimit)1197 TEST_F(BuildTest, SwallowFailuresLimit) {
1198   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1199 "rule fail\n"
1200 "  command = fail\n"
1201 "build out1: fail\n"
1202 "build out2: fail\n"
1203 "build out3: fail\n"
1204 "build final: cat out1 out2 out3\n"));
1205 
1206   // Swallow ten failures; we should stop before building final.
1207   config_.failures_allowed = 11;
1208 
1209   string err;
1210   EXPECT_TRUE(builder_.AddTarget("final", &err));
1211   ASSERT_EQ("", err);
1212 
1213   EXPECT_FALSE(builder_.Build(&err));
1214   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1215   ASSERT_EQ("cannot make progress due to previous errors", err);
1216 }
1217 
TEST_F(BuildTest,SwallowFailuresPool)1218 TEST_F(BuildTest, SwallowFailuresPool) {
1219   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1220 "pool failpool\n"
1221 "  depth = 1\n"
1222 "rule fail\n"
1223 "  command = fail\n"
1224 "  pool = failpool\n"
1225 "build out1: fail\n"
1226 "build out2: fail\n"
1227 "build out3: fail\n"
1228 "build final: cat out1 out2 out3\n"));
1229 
1230   // Swallow ten failures; we should stop before building final.
1231   config_.failures_allowed = 11;
1232 
1233   string err;
1234   EXPECT_TRUE(builder_.AddTarget("final", &err));
1235   ASSERT_EQ("", err);
1236 
1237   EXPECT_FALSE(builder_.Build(&err));
1238   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1239   ASSERT_EQ("cannot make progress due to previous errors", err);
1240 }
1241 
TEST_F(BuildTest,PoolEdgesReadyButNotWanted)1242 TEST_F(BuildTest, PoolEdgesReadyButNotWanted) {
1243   fs_.Create("x", "");
1244 
1245   const char* manifest =
1246     "pool some_pool\n"
1247     "  depth = 4\n"
1248     "rule touch\n"
1249     "  command = touch $out\n"
1250     "  pool = some_pool\n"
1251     "rule cc\n"
1252     "  command = touch grit\n"
1253     "\n"
1254     "build B.d.stamp: cc | x\n"
1255     "build C.stamp: touch B.d.stamp\n"
1256     "build final.stamp: touch || C.stamp\n";
1257 
1258   RebuildTarget("final.stamp", manifest);
1259 
1260   fs_.RemoveFile("B.d.stamp");
1261 
1262   State save_state;
1263   RebuildTarget("final.stamp", manifest, NULL, NULL, &save_state);
1264   EXPECT_GE(save_state.LookupPool("some_pool")->current_use(), 0);
1265 }
1266 
1267 struct BuildWithLogTest : public BuildTest {
BuildWithLogTestBuildWithLogTest1268   BuildWithLogTest() {
1269     builder_.SetBuildLog(&build_log_);
1270   }
1271 
1272   BuildLog build_log_;
1273 };
1274 
TEST_F(BuildWithLogTest,NotInLogButOnDisk)1275 TEST_F(BuildWithLogTest, NotInLogButOnDisk) {
1276   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1277 "rule cc\n"
1278 "  command = cc\n"
1279 "build out1: cc in\n"));
1280 
1281   // Create input/output that would be considered up to date when
1282   // not considering the command line hash.
1283   fs_.Create("in", "");
1284   fs_.Create("out1", "");
1285   string err;
1286 
1287   // Because it's not in the log, it should not be up-to-date until
1288   // we build again.
1289   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1290   EXPECT_FALSE(builder_.AlreadyUpToDate());
1291 
1292   command_runner_.commands_ran_.clear();
1293   state_.Reset();
1294 
1295   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1296   EXPECT_TRUE(builder_.Build(&err));
1297   EXPECT_TRUE(builder_.AlreadyUpToDate());
1298 }
1299 
TEST_F(BuildWithLogTest,RebuildAfterFailure)1300 TEST_F(BuildWithLogTest, RebuildAfterFailure) {
1301   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1302 "rule touch-fail-tick2\n"
1303 "  command = touch-fail-tick2\n"
1304 "build out1: touch-fail-tick2 in\n"));
1305 
1306   string err;
1307 
1308   fs_.Create("in", "");
1309 
1310   // Run once successfully to get out1 in the log
1311   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1312   EXPECT_TRUE(builder_.Build(&err));
1313   EXPECT_EQ("", err);
1314   EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1315 
1316   command_runner_.commands_ran_.clear();
1317   state_.Reset();
1318   builder_.Cleanup();
1319   builder_.plan_.Reset();
1320 
1321   fs_.Tick();
1322   fs_.Create("in", "");
1323 
1324   // Run again with a failure that updates the output file timestamp
1325   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1326   EXPECT_FALSE(builder_.Build(&err));
1327   EXPECT_EQ("subcommand failed", err);
1328   EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1329 
1330   command_runner_.commands_ran_.clear();
1331   state_.Reset();
1332   builder_.Cleanup();
1333   builder_.plan_.Reset();
1334 
1335   fs_.Tick();
1336 
1337   // Run again, should rerun even though the output file is up to date on disk
1338   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1339   EXPECT_FALSE(builder_.AlreadyUpToDate());
1340   EXPECT_TRUE(builder_.Build(&err));
1341   EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1342   EXPECT_EQ("", err);
1343 }
1344 
TEST_F(BuildWithLogTest,RebuildWithNoInputs)1345 TEST_F(BuildWithLogTest, RebuildWithNoInputs) {
1346   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1347 "rule touch\n"
1348 "  command = touch\n"
1349 "build out1: touch\n"
1350 "build out2: touch in\n"));
1351 
1352   string err;
1353 
1354   fs_.Create("in", "");
1355 
1356   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1357   EXPECT_TRUE(builder_.AddTarget("out2", &err));
1358   EXPECT_TRUE(builder_.Build(&err));
1359   EXPECT_EQ("", err);
1360   EXPECT_EQ(2u, command_runner_.commands_ran_.size());
1361 
1362   command_runner_.commands_ran_.clear();
1363   state_.Reset();
1364 
1365   fs_.Tick();
1366 
1367   fs_.Create("in", "");
1368 
1369   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1370   EXPECT_TRUE(builder_.AddTarget("out2", &err));
1371   EXPECT_TRUE(builder_.Build(&err));
1372   EXPECT_EQ("", err);
1373   EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1374 }
1375 
TEST_F(BuildWithLogTest,RestatTest)1376 TEST_F(BuildWithLogTest, RestatTest) {
1377   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1378 "rule true\n"
1379 "  command = true\n"
1380 "  restat = 1\n"
1381 "rule cc\n"
1382 "  command = cc\n"
1383 "  restat = 1\n"
1384 "build out1: cc in\n"
1385 "build out2: true out1\n"
1386 "build out3: cat out2\n"));
1387 
1388   fs_.Create("out1", "");
1389   fs_.Create("out2", "");
1390   fs_.Create("out3", "");
1391 
1392   fs_.Tick();
1393 
1394   fs_.Create("in", "");
1395 
1396   // Do a pre-build so that there's commands in the log for the outputs,
1397   // otherwise, the lack of an entry in the build log will cause out3 to rebuild
1398   // regardless of restat.
1399   string err;
1400   EXPECT_TRUE(builder_.AddTarget("out3", &err));
1401   ASSERT_EQ("", err);
1402   EXPECT_TRUE(builder_.Build(&err));
1403   ASSERT_EQ("", err);
1404   EXPECT_EQ("[3/3]", builder_.status_->FormatProgressStatus("[%s/%t]",
1405       BuildStatus::kEdgeStarted));
1406   command_runner_.commands_ran_.clear();
1407   state_.Reset();
1408 
1409   fs_.Tick();
1410 
1411   fs_.Create("in", "");
1412   // "cc" touches out1, so we should build out2.  But because "true" does not
1413   // touch out2, we should cancel the build of out3.
1414   EXPECT_TRUE(builder_.AddTarget("out3", &err));
1415   ASSERT_EQ("", err);
1416   EXPECT_TRUE(builder_.Build(&err));
1417   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1418 
1419   // If we run again, it should be a no-op, because the build log has recorded
1420   // that we've already built out2 with an input timestamp of 2 (from out1).
1421   command_runner_.commands_ran_.clear();
1422   state_.Reset();
1423   EXPECT_TRUE(builder_.AddTarget("out3", &err));
1424   ASSERT_EQ("", err);
1425   EXPECT_TRUE(builder_.AlreadyUpToDate());
1426 
1427   fs_.Tick();
1428 
1429   fs_.Create("in", "");
1430 
1431   // The build log entry should not, however, prevent us from rebuilding out2
1432   // if out1 changes.
1433   command_runner_.commands_ran_.clear();
1434   state_.Reset();
1435   EXPECT_TRUE(builder_.AddTarget("out3", &err));
1436   ASSERT_EQ("", err);
1437   EXPECT_TRUE(builder_.Build(&err));
1438   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1439 }
1440 
TEST_F(BuildWithLogTest,RestatMissingFile)1441 TEST_F(BuildWithLogTest, RestatMissingFile) {
1442   // If a restat rule doesn't create its output, and the output didn't
1443   // exist before the rule was run, consider that behavior equivalent
1444   // to a rule that doesn't modify its existent output file.
1445 
1446   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1447 "rule true\n"
1448 "  command = true\n"
1449 "  restat = 1\n"
1450 "rule cc\n"
1451 "  command = cc\n"
1452 "build out1: true in\n"
1453 "build out2: cc out1\n"));
1454 
1455   fs_.Create("in", "");
1456   fs_.Create("out2", "");
1457 
1458   // Do a pre-build so that there's commands in the log for the outputs,
1459   // otherwise, the lack of an entry in the build log will cause out2 to rebuild
1460   // regardless of restat.
1461   string err;
1462   EXPECT_TRUE(builder_.AddTarget("out2", &err));
1463   ASSERT_EQ("", err);
1464   EXPECT_TRUE(builder_.Build(&err));
1465   ASSERT_EQ("", err);
1466   command_runner_.commands_ran_.clear();
1467   state_.Reset();
1468 
1469   fs_.Tick();
1470   fs_.Create("in", "");
1471   fs_.Create("out2", "");
1472 
1473   // Run a build, expect only the first command to run.
1474   // It doesn't touch its output (due to being the "true" command), so
1475   // we shouldn't run the dependent build.
1476   EXPECT_TRUE(builder_.AddTarget("out2", &err));
1477   ASSERT_EQ("", err);
1478   EXPECT_TRUE(builder_.Build(&err));
1479   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1480 }
1481 
TEST_F(BuildWithLogTest,RestatSingleDependentOutputDirty)1482 TEST_F(BuildWithLogTest, RestatSingleDependentOutputDirty) {
1483   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1484     "rule true\n"
1485     "  command = true\n"
1486     "  restat = 1\n"
1487     "rule touch\n"
1488     "  command = touch\n"
1489     "build out1: true in\n"
1490     "build out2 out3: touch out1\n"
1491     "build out4: touch out2\n"
1492     ));
1493 
1494   // Create the necessary files
1495   fs_.Create("in", "");
1496 
1497   string err;
1498   EXPECT_TRUE(builder_.AddTarget("out4", &err));
1499   ASSERT_EQ("", err);
1500   EXPECT_TRUE(builder_.Build(&err));
1501   ASSERT_EQ("", err);
1502   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1503 
1504   fs_.Tick();
1505   fs_.Create("in", "");
1506   fs_.RemoveFile("out3");
1507 
1508   // Since "in" is missing, out1 will be built. Since "out3" is missing,
1509   // out2 and out3 will be built even though "in" is not touched when built.
1510   // Then, since out2 is rebuilt, out4 should be rebuilt -- the restat on the
1511   // "true" rule should not lead to the "touch" edge writing out2 and out3 being
1512   // cleard.
1513   command_runner_.commands_ran_.clear();
1514   state_.Reset();
1515   EXPECT_TRUE(builder_.AddTarget("out4", &err));
1516   ASSERT_EQ("", err);
1517   EXPECT_TRUE(builder_.Build(&err));
1518   ASSERT_EQ("", err);
1519   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1520 }
1521 
1522 // Test scenario, in which an input file is removed, but output isn't changed
1523 // https://github.com/ninja-build/ninja/issues/295
TEST_F(BuildWithLogTest,RestatMissingInput)1524 TEST_F(BuildWithLogTest, RestatMissingInput) {
1525   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1526     "rule true\n"
1527     "  command = true\n"
1528     "  depfile = $out.d\n"
1529     "  restat = 1\n"
1530     "rule cc\n"
1531     "  command = cc\n"
1532     "build out1: true in\n"
1533     "build out2: cc out1\n"));
1534 
1535   // Create all necessary files
1536   fs_.Create("in", "");
1537 
1538   // The implicit dependencies and the depfile itself
1539   // are newer than the output
1540   TimeStamp restat_mtime = fs_.Tick();
1541   fs_.Create("out1.d", "out1: will.be.deleted restat.file\n");
1542   fs_.Create("will.be.deleted", "");
1543   fs_.Create("restat.file", "");
1544 
1545   // Run the build, out1 and out2 get built
1546   string err;
1547   EXPECT_TRUE(builder_.AddTarget("out2", &err));
1548   ASSERT_EQ("", err);
1549   EXPECT_TRUE(builder_.Build(&err));
1550   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1551 
1552   // See that an entry in the logfile is created, capturing
1553   // the right mtime
1554   BuildLog::LogEntry* log_entry = build_log_.LookupByOutput("out1");
1555   ASSERT_TRUE(NULL != log_entry);
1556   ASSERT_EQ(restat_mtime, log_entry->mtime);
1557 
1558   // Now remove a file, referenced from depfile, so that target becomes
1559   // dirty, but the output does not change
1560   fs_.RemoveFile("will.be.deleted");
1561 
1562   // Trigger the build again - only out1 gets built
1563   command_runner_.commands_ran_.clear();
1564   state_.Reset();
1565   EXPECT_TRUE(builder_.AddTarget("out2", &err));
1566   ASSERT_EQ("", err);
1567   EXPECT_TRUE(builder_.Build(&err));
1568   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1569 
1570   // Check that the logfile entry remains correctly set
1571   log_entry = build_log_.LookupByOutput("out1");
1572   ASSERT_TRUE(NULL != log_entry);
1573   ASSERT_EQ(restat_mtime, log_entry->mtime);
1574 }
1575 
1576 struct BuildDryRun : public BuildWithLogTest {
BuildDryRunBuildDryRun1577   BuildDryRun() {
1578     config_.dry_run = true;
1579   }
1580 };
1581 
TEST_F(BuildDryRun,AllCommandsShown)1582 TEST_F(BuildDryRun, AllCommandsShown) {
1583   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1584 "rule true\n"
1585 "  command = true\n"
1586 "  restat = 1\n"
1587 "rule cc\n"
1588 "  command = cc\n"
1589 "  restat = 1\n"
1590 "build out1: cc in\n"
1591 "build out2: true out1\n"
1592 "build out3: cat out2\n"));
1593 
1594   fs_.Create("out1", "");
1595   fs_.Create("out2", "");
1596   fs_.Create("out3", "");
1597 
1598   fs_.Tick();
1599 
1600   fs_.Create("in", "");
1601 
1602   // "cc" touches out1, so we should build out2.  But because "true" does not
1603   // touch out2, we should cancel the build of out3.
1604   string err;
1605   EXPECT_TRUE(builder_.AddTarget("out3", &err));
1606   ASSERT_EQ("", err);
1607   EXPECT_TRUE(builder_.Build(&err));
1608   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1609 }
1610 
1611 // Test that RSP files are created when & where appropriate and deleted after
1612 // successful execution.
TEST_F(BuildTest,RspFileSuccess)1613 TEST_F(BuildTest, RspFileSuccess)
1614 {
1615   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1616     "rule cat_rsp\n"
1617     "  command = cat $rspfile > $out\n"
1618     "  rspfile = $rspfile\n"
1619     "  rspfile_content = $long_command\n"
1620     "rule cat_rsp_out\n"
1621     "  command = cat $rspfile > $out\n"
1622     "  rspfile = $out.rsp\n"
1623     "  rspfile_content = $long_command\n"
1624     "build out1: cat in\n"
1625     "build out2: cat_rsp in\n"
1626     "  rspfile = out 2.rsp\n"
1627     "  long_command = Some very long command\n"
1628     "build out$ 3: cat_rsp_out in\n"
1629     "  long_command = Some very long command\n"));
1630 
1631   fs_.Create("out1", "");
1632   fs_.Create("out2", "");
1633   fs_.Create("out 3", "");
1634 
1635   fs_.Tick();
1636 
1637   fs_.Create("in", "");
1638 
1639   string err;
1640   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1641   ASSERT_EQ("", err);
1642   EXPECT_TRUE(builder_.AddTarget("out2", &err));
1643   ASSERT_EQ("", err);
1644   EXPECT_TRUE(builder_.AddTarget("out 3", &err));
1645   ASSERT_EQ("", err);
1646 
1647   size_t files_created = fs_.files_created_.size();
1648   size_t files_removed = fs_.files_removed_.size();
1649 
1650   EXPECT_TRUE(builder_.Build(&err));
1651   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1652 
1653   // The RSP files were created
1654   ASSERT_EQ(files_created + 2, fs_.files_created_.size());
1655   ASSERT_EQ(1u, fs_.files_created_.count("out 2.rsp"));
1656   ASSERT_EQ(1u, fs_.files_created_.count("out 3.rsp"));
1657 
1658   // The RSP files were removed
1659   ASSERT_EQ(files_removed + 2, fs_.files_removed_.size());
1660   ASSERT_EQ(1u, fs_.files_removed_.count("out 2.rsp"));
1661   ASSERT_EQ(1u, fs_.files_removed_.count("out 3.rsp"));
1662 }
1663 
1664 // Test that RSP file is created but not removed for commands, which fail
TEST_F(BuildTest,RspFileFailure)1665 TEST_F(BuildTest, RspFileFailure) {
1666   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1667     "rule fail\n"
1668     "  command = fail\n"
1669     "  rspfile = $rspfile\n"
1670     "  rspfile_content = $long_command\n"
1671     "build out: fail in\n"
1672     "  rspfile = out.rsp\n"
1673     "  long_command = Another very long command\n"));
1674 
1675   fs_.Create("out", "");
1676   fs_.Tick();
1677   fs_.Create("in", "");
1678 
1679   string err;
1680   EXPECT_TRUE(builder_.AddTarget("out", &err));
1681   ASSERT_EQ("", err);
1682 
1683   size_t files_created = fs_.files_created_.size();
1684   size_t files_removed = fs_.files_removed_.size();
1685 
1686   EXPECT_FALSE(builder_.Build(&err));
1687   ASSERT_EQ("subcommand failed", err);
1688   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1689 
1690   // The RSP file was created
1691   ASSERT_EQ(files_created + 1, fs_.files_created_.size());
1692   ASSERT_EQ(1u, fs_.files_created_.count("out.rsp"));
1693 
1694   // The RSP file was NOT removed
1695   ASSERT_EQ(files_removed, fs_.files_removed_.size());
1696   ASSERT_EQ(0u, fs_.files_removed_.count("out.rsp"));
1697 
1698   // The RSP file contains what it should
1699   ASSERT_EQ("Another very long command", fs_.files_["out.rsp"].contents);
1700 }
1701 
1702 // Test that contents of the RSP file behaves like a regular part of
1703 // command line, i.e. triggers a rebuild if changed
TEST_F(BuildWithLogTest,RspFileCmdLineChange)1704 TEST_F(BuildWithLogTest, RspFileCmdLineChange) {
1705   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1706     "rule cat_rsp\n"
1707     "  command = cat $rspfile > $out\n"
1708     "  rspfile = $rspfile\n"
1709     "  rspfile_content = $long_command\n"
1710     "build out: cat_rsp in\n"
1711     "  rspfile = out.rsp\n"
1712     "  long_command = Original very long command\n"));
1713 
1714   fs_.Create("out", "");
1715   fs_.Tick();
1716   fs_.Create("in", "");
1717 
1718   string err;
1719   EXPECT_TRUE(builder_.AddTarget("out", &err));
1720   ASSERT_EQ("", err);
1721 
1722   // 1. Build for the 1st time (-> populate log)
1723   EXPECT_TRUE(builder_.Build(&err));
1724   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1725 
1726   // 2. Build again (no change)
1727   command_runner_.commands_ran_.clear();
1728   state_.Reset();
1729   EXPECT_TRUE(builder_.AddTarget("out", &err));
1730   EXPECT_EQ("", err);
1731   ASSERT_TRUE(builder_.AlreadyUpToDate());
1732 
1733   // 3. Alter the entry in the logfile
1734   // (to simulate a change in the command line between 2 builds)
1735   BuildLog::LogEntry* log_entry = build_log_.LookupByOutput("out");
1736   ASSERT_TRUE(NULL != log_entry);
1737   ASSERT_NO_FATAL_FAILURE(AssertHash(
1738         "cat out.rsp > out;rspfile=Original very long command",
1739         log_entry->command_hash));
1740   log_entry->command_hash++;  // Change the command hash to something else.
1741   // Now expect the target to be rebuilt
1742   command_runner_.commands_ran_.clear();
1743   state_.Reset();
1744   EXPECT_TRUE(builder_.AddTarget("out", &err));
1745   EXPECT_EQ("", err);
1746   EXPECT_TRUE(builder_.Build(&err));
1747   EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1748 }
1749 
TEST_F(BuildTest,InterruptCleanup)1750 TEST_F(BuildTest, InterruptCleanup) {
1751   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1752 "rule interrupt\n"
1753 "  command = interrupt\n"
1754 "rule touch-interrupt\n"
1755 "  command = touch-interrupt\n"
1756 "build out1: interrupt in1\n"
1757 "build out2: touch-interrupt in2\n"));
1758 
1759   fs_.Create("out1", "");
1760   fs_.Create("out2", "");
1761   fs_.Tick();
1762   fs_.Create("in1", "");
1763   fs_.Create("in2", "");
1764 
1765   // An untouched output of an interrupted command should be retained.
1766   string err;
1767   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1768   EXPECT_EQ("", err);
1769   EXPECT_FALSE(builder_.Build(&err));
1770   EXPECT_EQ("interrupted by user", err);
1771   builder_.Cleanup();
1772   EXPECT_GT(fs_.Stat("out1", &err), 0);
1773   err = "";
1774 
1775   // A touched output of an interrupted command should be deleted.
1776   EXPECT_TRUE(builder_.AddTarget("out2", &err));
1777   EXPECT_EQ("", err);
1778   EXPECT_FALSE(builder_.Build(&err));
1779   EXPECT_EQ("interrupted by user", err);
1780   builder_.Cleanup();
1781   EXPECT_EQ(0, fs_.Stat("out2", &err));
1782 }
1783 
TEST_F(BuildTest,StatFailureAbortsBuild)1784 TEST_F(BuildTest, StatFailureAbortsBuild) {
1785   const string kTooLongToStat(400, 'i');
1786   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1787 ("build " + kTooLongToStat + ": cat in\n").c_str()));
1788   fs_.Create("in", "");
1789 
1790   // This simulates a stat failure:
1791   fs_.files_[kTooLongToStat].mtime = -1;
1792   fs_.files_[kTooLongToStat].stat_error = "stat failed";
1793 
1794   string err;
1795   EXPECT_FALSE(builder_.AddTarget(kTooLongToStat, &err));
1796   EXPECT_EQ("stat failed", err);
1797 }
1798 
TEST_F(BuildTest,PhonyWithNoInputs)1799 TEST_F(BuildTest, PhonyWithNoInputs) {
1800   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1801 "build nonexistent: phony\n"
1802 "build out1: cat || nonexistent\n"
1803 "build out2: cat nonexistent\n"));
1804   fs_.Create("out1", "");
1805   fs_.Create("out2", "");
1806 
1807   // out1 should be up to date even though its input is dirty, because its
1808   // order-only dependency has nothing to do.
1809   string err;
1810   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1811   ASSERT_EQ("", err);
1812   EXPECT_TRUE(builder_.AlreadyUpToDate());
1813 
1814   // out2 should still be out of date though, because its input is dirty.
1815   err.clear();
1816   command_runner_.commands_ran_.clear();
1817   state_.Reset();
1818   EXPECT_TRUE(builder_.AddTarget("out2", &err));
1819   ASSERT_EQ("", err);
1820   EXPECT_TRUE(builder_.Build(&err));
1821   EXPECT_EQ("", err);
1822   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1823 }
1824 
TEST_F(BuildTest,DepsGccWithEmptyDepfileErrorsOut)1825 TEST_F(BuildTest, DepsGccWithEmptyDepfileErrorsOut) {
1826   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1827 "rule cc\n"
1828 "  command = cc\n"
1829 "  deps = gcc\n"
1830 "build out: cc\n"));
1831   Dirty("out");
1832 
1833   string err;
1834   EXPECT_TRUE(builder_.AddTarget("out", &err));
1835   ASSERT_EQ("", err);
1836   EXPECT_FALSE(builder_.AlreadyUpToDate());
1837 
1838   EXPECT_FALSE(builder_.Build(&err));
1839   ASSERT_EQ("subcommand failed", err);
1840   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1841 }
1842 
TEST_F(BuildTest,StatusFormatElapsed)1843 TEST_F(BuildTest, StatusFormatElapsed) {
1844   status_.BuildStarted();
1845   // Before any task is done, the elapsed time must be zero.
1846   EXPECT_EQ("[%/e0.000]",
1847             status_.FormatProgressStatus("[%%/e%e]",
1848                 BuildStatus::kEdgeStarted));
1849 }
1850 
TEST_F(BuildTest,StatusFormatReplacePlaceholder)1851 TEST_F(BuildTest, StatusFormatReplacePlaceholder) {
1852   EXPECT_EQ("[%/s0/t0/r0/u0/f0]",
1853             status_.FormatProgressStatus("[%%/s%s/t%t/r%r/u%u/f%f]",
1854                 BuildStatus::kEdgeStarted));
1855 }
1856 
TEST_F(BuildTest,FailedDepsParse)1857 TEST_F(BuildTest, FailedDepsParse) {
1858   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1859 "build bad_deps.o: cat in1\n"
1860 "  deps = gcc\n"
1861 "  depfile = in1.d\n"));
1862 
1863   string err;
1864   EXPECT_TRUE(builder_.AddTarget("bad_deps.o", &err));
1865   ASSERT_EQ("", err);
1866 
1867   // These deps will fail to parse, as they should only have one
1868   // path to the left of the colon.
1869   fs_.Create("in1.d", "AAA BBB");
1870 
1871   EXPECT_FALSE(builder_.Build(&err));
1872   EXPECT_EQ("subcommand failed", err);
1873 }
1874 
1875 struct BuildWithQueryDepsLogTest : public BuildTest {
BuildWithQueryDepsLogTestBuildWithQueryDepsLogTest1876   BuildWithQueryDepsLogTest() : BuildTest(&log_) {
1877   }
1878 
~BuildWithQueryDepsLogTestBuildWithQueryDepsLogTest1879   ~BuildWithQueryDepsLogTest() {
1880     log_.Close();
1881   }
1882 
SetUpBuildWithQueryDepsLogTest1883   virtual void SetUp() {
1884     BuildTest::SetUp();
1885 
1886     temp_dir_.CreateAndEnter("BuildWithQueryDepsLogTest");
1887 
1888     std::string err;
1889     ASSERT_TRUE(log_.OpenForWrite("ninja_deps", &err));
1890     ASSERT_EQ("", err);
1891   }
1892 
1893   ScopedTempDir temp_dir_;
1894 
1895   DepsLog log_;
1896 };
1897 
1898 /// Test a MSVC-style deps log with multiple outputs.
TEST_F(BuildWithQueryDepsLogTest,TwoOutputsDepFileMSVC)1899 TEST_F(BuildWithQueryDepsLogTest, TwoOutputsDepFileMSVC) {
1900   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1901 "rule cp_multi_msvc\n"
1902 "    command = echo 'using $in' && for file in $out; do cp $in $$file; done\n"
1903 "    deps = msvc\n"
1904 "    msvc_deps_prefix = using \n"
1905 "build out1 out2: cp_multi_msvc in1\n"));
1906 
1907   std::string err;
1908   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1909   ASSERT_EQ("", err);
1910   EXPECT_TRUE(builder_.Build(&err));
1911   EXPECT_EQ("", err);
1912   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1913   EXPECT_EQ("echo 'using in1' && for file in out1 out2; do cp in1 $file; done", command_runner_.commands_ran_[0]);
1914 
1915   Node* out1_node = state_.LookupNode("out1");
1916   DepsLog::Deps* out1_deps = log_.GetDeps(out1_node);
1917   EXPECT_EQ(1, out1_deps->node_count);
1918   EXPECT_EQ("in1", out1_deps->nodes[0]->path());
1919 
1920   Node* out2_node = state_.LookupNode("out2");
1921   DepsLog::Deps* out2_deps = log_.GetDeps(out2_node);
1922   EXPECT_EQ(1, out2_deps->node_count);
1923   EXPECT_EQ("in1", out2_deps->nodes[0]->path());
1924 }
1925 
1926 /// Test a GCC-style deps log with multiple outputs.
TEST_F(BuildWithQueryDepsLogTest,TwoOutputsDepFileGCCOneLine)1927 TEST_F(BuildWithQueryDepsLogTest, TwoOutputsDepFileGCCOneLine) {
1928   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1929 "rule cp_multi_gcc\n"
1930 "    command = echo '$out: $in' > in.d && for file in $out; do cp in1 $$file; done\n"
1931 "    deps = gcc\n"
1932 "    depfile = in.d\n"
1933 "build out1 out2: cp_multi_gcc in1 in2\n"));
1934 
1935   std::string err;
1936   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1937   ASSERT_EQ("", err);
1938   fs_.Create("in.d", "out1 out2: in1 in2");
1939   EXPECT_TRUE(builder_.Build(&err));
1940   EXPECT_EQ("", err);
1941   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1942   EXPECT_EQ("echo 'out1 out2: in1 in2' > in.d && for file in out1 out2; do cp in1 $file; done", command_runner_.commands_ran_[0]);
1943 
1944   Node* out1_node = state_.LookupNode("out1");
1945   DepsLog::Deps* out1_deps = log_.GetDeps(out1_node);
1946   EXPECT_EQ(2, out1_deps->node_count);
1947   EXPECT_EQ("in1", out1_deps->nodes[0]->path());
1948   EXPECT_EQ("in2", out1_deps->nodes[1]->path());
1949 
1950   Node* out2_node = state_.LookupNode("out2");
1951   DepsLog::Deps* out2_deps = log_.GetDeps(out2_node);
1952   EXPECT_EQ(2, out2_deps->node_count);
1953   EXPECT_EQ("in1", out2_deps->nodes[0]->path());
1954   EXPECT_EQ("in2", out2_deps->nodes[1]->path());
1955 }
1956 
1957 /// Test a GCC-style deps log with multiple outputs using a line per input.
TEST_F(BuildWithQueryDepsLogTest,TwoOutputsDepFileGCCMultiLineInput)1958 TEST_F(BuildWithQueryDepsLogTest, TwoOutputsDepFileGCCMultiLineInput) {
1959   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1960 "rule cp_multi_gcc\n"
1961 "    command = echo '$out: in1\\n$out: in2' > in.d && for file in $out; do cp in1 $$file; done\n"
1962 "    deps = gcc\n"
1963 "    depfile = in.d\n"
1964 "build out1 out2: cp_multi_gcc in1 in2\n"));
1965 
1966   std::string err;
1967   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1968   ASSERT_EQ("", err);
1969   fs_.Create("in.d", "out1 out2: in1\nout1 out2: in2");
1970   EXPECT_TRUE(builder_.Build(&err));
1971   EXPECT_EQ("", err);
1972   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1973   EXPECT_EQ("echo 'out1 out2: in1\\nout1 out2: in2' > in.d && for file in out1 out2; do cp in1 $file; done", command_runner_.commands_ran_[0]);
1974 
1975   Node* out1_node = state_.LookupNode("out1");
1976   DepsLog::Deps* out1_deps = log_.GetDeps(out1_node);
1977   EXPECT_EQ(2, out1_deps->node_count);
1978   EXPECT_EQ("in1", out1_deps->nodes[0]->path());
1979   EXPECT_EQ("in2", out1_deps->nodes[1]->path());
1980 
1981   Node* out2_node = state_.LookupNode("out2");
1982   DepsLog::Deps* out2_deps = log_.GetDeps(out2_node);
1983   EXPECT_EQ(2, out2_deps->node_count);
1984   EXPECT_EQ("in1", out2_deps->nodes[0]->path());
1985   EXPECT_EQ("in2", out2_deps->nodes[1]->path());
1986 }
1987 
1988 /// Test a GCC-style deps log with multiple outputs using a line per output.
TEST_F(BuildWithQueryDepsLogTest,TwoOutputsDepFileGCCMultiLineOutput)1989 TEST_F(BuildWithQueryDepsLogTest, TwoOutputsDepFileGCCMultiLineOutput) {
1990   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1991 "rule cp_multi_gcc\n"
1992 "    command = echo 'out1: $in\\nout2: $in' > in.d && for file in $out; do cp in1 $$file; done\n"
1993 "    deps = gcc\n"
1994 "    depfile = in.d\n"
1995 "build out1 out2: cp_multi_gcc in1 in2\n"));
1996 
1997   std::string err;
1998   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1999   ASSERT_EQ("", err);
2000   fs_.Create("in.d", "out1: in1 in2\nout2: in1 in2");
2001   EXPECT_TRUE(builder_.Build(&err));
2002   EXPECT_EQ("", err);
2003   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2004   EXPECT_EQ("echo 'out1: in1 in2\\nout2: in1 in2' > in.d && for file in out1 out2; do cp in1 $file; done", command_runner_.commands_ran_[0]);
2005 
2006   Node* out1_node = state_.LookupNode("out1");
2007   DepsLog::Deps* out1_deps = log_.GetDeps(out1_node);
2008   EXPECT_EQ(2, out1_deps->node_count);
2009   EXPECT_EQ("in1", out1_deps->nodes[0]->path());
2010   EXPECT_EQ("in2", out1_deps->nodes[1]->path());
2011 
2012   Node* out2_node = state_.LookupNode("out2");
2013   DepsLog::Deps* out2_deps = log_.GetDeps(out2_node);
2014   EXPECT_EQ(2, out2_deps->node_count);
2015   EXPECT_EQ("in1", out2_deps->nodes[0]->path());
2016   EXPECT_EQ("in2", out2_deps->nodes[1]->path());
2017 }
2018 
2019 /// Test a GCC-style deps log with multiple outputs mentioning only the main output.
TEST_F(BuildWithQueryDepsLogTest,TwoOutputsDepFileGCCOnlyMainOutput)2020 TEST_F(BuildWithQueryDepsLogTest, TwoOutputsDepFileGCCOnlyMainOutput) {
2021   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
2022 "rule cp_multi_gcc\n"
2023 "    command = echo 'out1: $in' > in.d && for file in $out; do cp in1 $$file; done\n"
2024 "    deps = gcc\n"
2025 "    depfile = in.d\n"
2026 "build out1 out2: cp_multi_gcc in1 in2\n"));
2027 
2028   std::string err;
2029   EXPECT_TRUE(builder_.AddTarget("out1", &err));
2030   ASSERT_EQ("", err);
2031   fs_.Create("in.d", "out1: in1 in2");
2032   EXPECT_TRUE(builder_.Build(&err));
2033   EXPECT_EQ("", err);
2034   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2035   EXPECT_EQ("echo 'out1: in1 in2' > in.d && for file in out1 out2; do cp in1 $file; done", command_runner_.commands_ran_[0]);
2036 
2037   Node* out1_node = state_.LookupNode("out1");
2038   DepsLog::Deps* out1_deps = log_.GetDeps(out1_node);
2039   EXPECT_EQ(2, out1_deps->node_count);
2040   EXPECT_EQ("in1", out1_deps->nodes[0]->path());
2041   EXPECT_EQ("in2", out1_deps->nodes[1]->path());
2042 
2043   Node* out2_node = state_.LookupNode("out2");
2044   DepsLog::Deps* out2_deps = log_.GetDeps(out2_node);
2045   EXPECT_EQ(2, out2_deps->node_count);
2046   EXPECT_EQ("in1", out2_deps->nodes[0]->path());
2047   EXPECT_EQ("in2", out2_deps->nodes[1]->path());
2048 }
2049 
2050 /// Test a GCC-style deps log with multiple outputs mentioning only the secondary output.
TEST_F(BuildWithQueryDepsLogTest,TwoOutputsDepFileGCCOnlySecondaryOutput)2051 TEST_F(BuildWithQueryDepsLogTest, TwoOutputsDepFileGCCOnlySecondaryOutput) {
2052   // Note: This ends up short-circuiting the node creation due to the primary
2053   // output not being present, but it should still work.
2054   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
2055 "rule cp_multi_gcc\n"
2056 "    command = echo 'out2: $in' > in.d && for file in $out; do cp in1 $$file; done\n"
2057 "    deps = gcc\n"
2058 "    depfile = in.d\n"
2059 "build out1 out2: cp_multi_gcc in1 in2\n"));
2060 
2061   std::string err;
2062   EXPECT_TRUE(builder_.AddTarget("out1", &err));
2063   ASSERT_EQ("", err);
2064   fs_.Create("in.d", "out2: in1 in2");
2065   EXPECT_TRUE(builder_.Build(&err));
2066   EXPECT_EQ("", err);
2067   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2068   EXPECT_EQ("echo 'out2: in1 in2' > in.d && for file in out1 out2; do cp in1 $file; done", command_runner_.commands_ran_[0]);
2069 
2070   Node* out1_node = state_.LookupNode("out1");
2071   DepsLog::Deps* out1_deps = log_.GetDeps(out1_node);
2072   EXPECT_EQ(2, out1_deps->node_count);
2073   EXPECT_EQ("in1", out1_deps->nodes[0]->path());
2074   EXPECT_EQ("in2", out1_deps->nodes[1]->path());
2075 
2076   Node* out2_node = state_.LookupNode("out2");
2077   DepsLog::Deps* out2_deps = log_.GetDeps(out2_node);
2078   EXPECT_EQ(2, out2_deps->node_count);
2079   EXPECT_EQ("in1", out2_deps->nodes[0]->path());
2080   EXPECT_EQ("in2", out2_deps->nodes[1]->path());
2081 }
2082 
2083 /// Tests of builds involving deps logs necessarily must span
2084 /// multiple builds.  We reuse methods on BuildTest but not the
2085 /// builder_ it sets up, because we want pristine objects for
2086 /// each build.
2087 struct BuildWithDepsLogTest : public BuildTest {
BuildWithDepsLogTestBuildWithDepsLogTest2088   BuildWithDepsLogTest() {}
2089 
SetUpBuildWithDepsLogTest2090   virtual void SetUp() {
2091     BuildTest::SetUp();
2092 
2093     temp_dir_.CreateAndEnter("BuildWithDepsLogTest");
2094   }
2095 
TearDownBuildWithDepsLogTest2096   virtual void TearDown() {
2097     temp_dir_.Cleanup();
2098   }
2099 
2100   ScopedTempDir temp_dir_;
2101 
2102   /// Shadow parent class builder_ so we don't accidentally use it.
2103   void* builder_;
2104 };
2105 
2106 /// Run a straightforwad build where the deps log is used.
TEST_F(BuildWithDepsLogTest,Straightforward)2107 TEST_F(BuildWithDepsLogTest, Straightforward) {
2108   string err;
2109   // Note: in1 was created by the superclass SetUp().
2110   const char* manifest =
2111       "build out: cat in1\n"
2112       "  deps = gcc\n"
2113       "  depfile = in1.d\n";
2114   {
2115     State state;
2116     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2117     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2118 
2119     // Run the build once, everything should be ok.
2120     DepsLog deps_log;
2121     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2122     ASSERT_EQ("", err);
2123 
2124     Builder builder(&state, config_, NULL, &deps_log, &fs_);
2125     builder.command_runner_.reset(&command_runner_);
2126     EXPECT_TRUE(builder.AddTarget("out", &err));
2127     ASSERT_EQ("", err);
2128     fs_.Create("in1.d", "out: in2");
2129     EXPECT_TRUE(builder.Build(&err));
2130     EXPECT_EQ("", err);
2131 
2132     // The deps file should have been removed.
2133     EXPECT_EQ(0, fs_.Stat("in1.d", &err));
2134     // Recreate it for the next step.
2135     fs_.Create("in1.d", "out: in2");
2136     deps_log.Close();
2137     builder.command_runner_.release();
2138   }
2139 
2140   {
2141     State state;
2142     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2143     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2144 
2145     // Touch the file only mentioned in the deps.
2146     fs_.Tick();
2147     fs_.Create("in2", "");
2148 
2149     // Run the build again.
2150     DepsLog deps_log;
2151     ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
2152     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2153 
2154     Builder builder(&state, config_, NULL, &deps_log, &fs_);
2155     builder.command_runner_.reset(&command_runner_);
2156     command_runner_.commands_ran_.clear();
2157     EXPECT_TRUE(builder.AddTarget("out", &err));
2158     ASSERT_EQ("", err);
2159     EXPECT_TRUE(builder.Build(&err));
2160     EXPECT_EQ("", err);
2161 
2162     // We should have rebuilt the output due to in2 being
2163     // out of date.
2164     EXPECT_EQ(1u, command_runner_.commands_ran_.size());
2165 
2166     builder.command_runner_.release();
2167   }
2168 }
2169 
2170 /// Verify that obsolete dependency info causes a rebuild.
2171 /// 1) Run a successful build where everything has time t, record deps.
2172 /// 2) Move input/output to time t+1 -- despite files in alignment,
2173 ///    should still need to rebuild due to deps at older time.
TEST_F(BuildWithDepsLogTest,ObsoleteDeps)2174 TEST_F(BuildWithDepsLogTest, ObsoleteDeps) {
2175   string err;
2176   // Note: in1 was created by the superclass SetUp().
2177   const char* manifest =
2178       "build out: cat in1\n"
2179       "  deps = gcc\n"
2180       "  depfile = in1.d\n";
2181   {
2182     // Run an ordinary build that gathers dependencies.
2183     fs_.Create("in1", "");
2184     fs_.Create("in1.d", "out: ");
2185 
2186     State state;
2187     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2188     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2189 
2190     // Run the build once, everything should be ok.
2191     DepsLog deps_log;
2192     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2193     ASSERT_EQ("", err);
2194 
2195     Builder builder(&state, config_, NULL, &deps_log, &fs_);
2196     builder.command_runner_.reset(&command_runner_);
2197     EXPECT_TRUE(builder.AddTarget("out", &err));
2198     ASSERT_EQ("", err);
2199     EXPECT_TRUE(builder.Build(&err));
2200     EXPECT_EQ("", err);
2201 
2202     deps_log.Close();
2203     builder.command_runner_.release();
2204   }
2205 
2206   // Push all files one tick forward so that only the deps are out
2207   // of date.
2208   fs_.Tick();
2209   fs_.Create("in1", "");
2210   fs_.Create("out", "");
2211 
2212   // The deps file should have been removed, so no need to timestamp it.
2213   EXPECT_EQ(0, fs_.Stat("in1.d", &err));
2214 
2215   {
2216     State state;
2217     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2218     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2219 
2220     DepsLog deps_log;
2221     ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
2222     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2223 
2224     Builder builder(&state, config_, NULL, &deps_log, &fs_);
2225     builder.command_runner_.reset(&command_runner_);
2226     command_runner_.commands_ran_.clear();
2227     EXPECT_TRUE(builder.AddTarget("out", &err));
2228     ASSERT_EQ("", err);
2229 
2230     // Recreate the deps file here because the build expects them to exist.
2231     fs_.Create("in1.d", "out: ");
2232 
2233     EXPECT_TRUE(builder.Build(&err));
2234     EXPECT_EQ("", err);
2235 
2236     // We should have rebuilt the output due to the deps being
2237     // out of date.
2238     EXPECT_EQ(1u, command_runner_.commands_ran_.size());
2239 
2240     builder.command_runner_.release();
2241   }
2242 }
2243 
TEST_F(BuildWithDepsLogTest,DepsIgnoredInDryRun)2244 TEST_F(BuildWithDepsLogTest, DepsIgnoredInDryRun) {
2245   const char* manifest =
2246       "build out: cat in1\n"
2247       "  deps = gcc\n"
2248       "  depfile = in1.d\n";
2249 
2250   fs_.Create("out", "");
2251   fs_.Tick();
2252   fs_.Create("in1", "");
2253 
2254   State state;
2255   ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2256   ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2257 
2258   // The deps log is NULL in dry runs.
2259   config_.dry_run = true;
2260   Builder builder(&state, config_, NULL, NULL, &fs_);
2261   builder.command_runner_.reset(&command_runner_);
2262   command_runner_.commands_ran_.clear();
2263 
2264   string err;
2265   EXPECT_TRUE(builder.AddTarget("out", &err));
2266   ASSERT_EQ("", err);
2267   EXPECT_TRUE(builder.Build(&err));
2268   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2269 
2270   builder.command_runner_.release();
2271 }
2272 
2273 /// Check that a restat rule generating a header cancels compilations correctly.
TEST_F(BuildTest,RestatDepfileDependency)2274 TEST_F(BuildTest, RestatDepfileDependency) {
2275   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
2276 "rule true\n"
2277 "  command = true\n"  // Would be "write if out-of-date" in reality.
2278 "  restat = 1\n"
2279 "build header.h: true header.in\n"
2280 "build out: cat in1\n"
2281 "  depfile = in1.d\n"));
2282 
2283   fs_.Create("header.h", "");
2284   fs_.Create("in1.d", "out: header.h");
2285   fs_.Tick();
2286   fs_.Create("header.in", "");
2287 
2288   string err;
2289   EXPECT_TRUE(builder_.AddTarget("out", &err));
2290   ASSERT_EQ("", err);
2291   EXPECT_TRUE(builder_.Build(&err));
2292   EXPECT_EQ("", err);
2293 }
2294 
2295 /// Check that a restat rule generating a header cancels compilations correctly,
2296 /// depslog case.
TEST_F(BuildWithDepsLogTest,RestatDepfileDependencyDepsLog)2297 TEST_F(BuildWithDepsLogTest, RestatDepfileDependencyDepsLog) {
2298   string err;
2299   // Note: in1 was created by the superclass SetUp().
2300   const char* manifest =
2301       "rule true\n"
2302       "  command = true\n"  // Would be "write if out-of-date" in reality.
2303       "  restat = 1\n"
2304       "build header.h: true header.in\n"
2305       "build out: cat in1\n"
2306       "  deps = gcc\n"
2307       "  depfile = in1.d\n";
2308   {
2309     State state;
2310     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2311     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2312 
2313     // Run the build once, everything should be ok.
2314     DepsLog deps_log;
2315     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2316     ASSERT_EQ("", err);
2317 
2318     Builder builder(&state, config_, NULL, &deps_log, &fs_);
2319     builder.command_runner_.reset(&command_runner_);
2320     EXPECT_TRUE(builder.AddTarget("out", &err));
2321     ASSERT_EQ("", err);
2322     fs_.Create("in1.d", "out: header.h");
2323     EXPECT_TRUE(builder.Build(&err));
2324     EXPECT_EQ("", err);
2325 
2326     deps_log.Close();
2327     builder.command_runner_.release();
2328   }
2329 
2330   {
2331     State state;
2332     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2333     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2334 
2335     // Touch the input of the restat rule.
2336     fs_.Tick();
2337     fs_.Create("header.in", "");
2338 
2339     // Run the build again.
2340     DepsLog deps_log;
2341     ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
2342     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2343 
2344     Builder builder(&state, config_, NULL, &deps_log, &fs_);
2345     builder.command_runner_.reset(&command_runner_);
2346     command_runner_.commands_ran_.clear();
2347     EXPECT_TRUE(builder.AddTarget("out", &err));
2348     ASSERT_EQ("", err);
2349     EXPECT_TRUE(builder.Build(&err));
2350     EXPECT_EQ("", err);
2351 
2352     // Rule "true" should have run again, but the build of "out" should have
2353     // been cancelled due to restat propagating through the depfile header.
2354     EXPECT_EQ(1u, command_runner_.commands_ran_.size());
2355 
2356     builder.command_runner_.release();
2357   }
2358 }
2359 
TEST_F(BuildWithDepsLogTest,DepFileOKDepsLog)2360 TEST_F(BuildWithDepsLogTest, DepFileOKDepsLog) {
2361   string err;
2362   const char* manifest =
2363       "rule cc\n  command = cc $in\n  depfile = $out.d\n  deps = gcc\n"
2364       "build fo$ o.o: cc foo.c\n";
2365 
2366   fs_.Create("foo.c", "");
2367 
2368   {
2369     State state;
2370     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2371 
2372     // Run the build once, everything should be ok.
2373     DepsLog deps_log;
2374     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2375     ASSERT_EQ("", err);
2376 
2377     Builder builder(&state, config_, NULL, &deps_log, &fs_);
2378     builder.command_runner_.reset(&command_runner_);
2379     EXPECT_TRUE(builder.AddTarget("fo o.o", &err));
2380     ASSERT_EQ("", err);
2381     fs_.Create("fo o.o.d", "fo\\ o.o: blah.h bar.h\n");
2382     EXPECT_TRUE(builder.Build(&err));
2383     EXPECT_EQ("", err);
2384 
2385     deps_log.Close();
2386     builder.command_runner_.release();
2387   }
2388 
2389   {
2390     State state;
2391     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2392 
2393     DepsLog deps_log;
2394     ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
2395     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2396     ASSERT_EQ("", err);
2397 
2398     Builder builder(&state, config_, NULL, &deps_log, &fs_);
2399     builder.command_runner_.reset(&command_runner_);
2400 
2401     Edge* edge = state.edges_.back();
2402 
2403     state.GetNode("bar.h", 0)->MarkDirty();  // Mark bar.h as missing.
2404     EXPECT_TRUE(builder.AddTarget("fo o.o", &err));
2405     ASSERT_EQ("", err);
2406 
2407     // Expect three new edges: one generating fo o.o, and two more from
2408     // loading the depfile.
2409     ASSERT_EQ(3u, state.edges_.size());
2410     // Expect our edge to now have three inputs: foo.c and two headers.
2411     ASSERT_EQ(3u, edge->inputs_.size());
2412 
2413     // Expect the command line we generate to only use the original input.
2414     ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
2415 
2416     deps_log.Close();
2417     builder.command_runner_.release();
2418   }
2419 }
2420 
2421 #ifdef _WIN32
TEST_F(BuildWithDepsLogTest,DepFileDepsLogCanonicalize)2422 TEST_F(BuildWithDepsLogTest, DepFileDepsLogCanonicalize) {
2423   string err;
2424   const char* manifest =
2425       "rule cc\n  command = cc $in\n  depfile = $out.d\n  deps = gcc\n"
2426       "build a/b\\c\\d/e/fo$ o.o: cc x\\y/z\\foo.c\n";
2427 
2428   fs_.Create("x/y/z/foo.c", "");
2429 
2430   {
2431     State state;
2432     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2433 
2434     // Run the build once, everything should be ok.
2435     DepsLog deps_log;
2436     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2437     ASSERT_EQ("", err);
2438 
2439     Builder builder(&state, config_, NULL, &deps_log, &fs_);
2440     builder.command_runner_.reset(&command_runner_);
2441     EXPECT_TRUE(builder.AddTarget("a/b/c/d/e/fo o.o", &err));
2442     ASSERT_EQ("", err);
2443     // Note, different slashes from manifest.
2444     fs_.Create("a/b\\c\\d/e/fo o.o.d",
2445                "a\\b\\c\\d\\e\\fo\\ o.o: blah.h bar.h\n");
2446     EXPECT_TRUE(builder.Build(&err));
2447     EXPECT_EQ("", err);
2448 
2449     deps_log.Close();
2450     builder.command_runner_.release();
2451   }
2452 
2453   {
2454     State state;
2455     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2456 
2457     DepsLog deps_log;
2458     ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
2459     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2460     ASSERT_EQ("", err);
2461 
2462     Builder builder(&state, config_, NULL, &deps_log, &fs_);
2463     builder.command_runner_.reset(&command_runner_);
2464 
2465     Edge* edge = state.edges_.back();
2466 
2467     state.GetNode("bar.h", 0)->MarkDirty();  // Mark bar.h as missing.
2468     EXPECT_TRUE(builder.AddTarget("a/b/c/d/e/fo o.o", &err));
2469     ASSERT_EQ("", err);
2470 
2471     // Expect three new edges: one generating fo o.o, and two more from
2472     // loading the depfile.
2473     ASSERT_EQ(3u, state.edges_.size());
2474     // Expect our edge to now have three inputs: foo.c and two headers.
2475     ASSERT_EQ(3u, edge->inputs_.size());
2476 
2477     // Expect the command line we generate to only use the original input.
2478     // Note, slashes from manifest, not .d.
2479     ASSERT_EQ("cc x\\y/z\\foo.c", edge->EvaluateCommand());
2480 
2481     deps_log.Close();
2482     builder.command_runner_.release();
2483   }
2484 }
2485 #endif
2486 
2487 /// Check that a restat rule doesn't clear an edge if the depfile is missing.
2488 /// Follows from: https://github.com/ninja-build/ninja/issues/603
TEST_F(BuildTest,RestatMissingDepfile)2489 TEST_F(BuildTest, RestatMissingDepfile) {
2490 const char* manifest =
2491 "rule true\n"
2492 "  command = true\n"  // Would be "write if out-of-date" in reality.
2493 "  restat = 1\n"
2494 "build header.h: true header.in\n"
2495 "build out: cat header.h\n"
2496 "  depfile = out.d\n";
2497 
2498   fs_.Create("header.h", "");
2499   fs_.Tick();
2500   fs_.Create("out", "");
2501   fs_.Create("header.in", "");
2502 
2503   // Normally, only 'header.h' would be rebuilt, as
2504   // its rule doesn't touch the output and has 'restat=1' set.
2505   // But we are also missing the depfile for 'out',
2506   // which should force its command to run anyway!
2507   RebuildTarget("out", manifest);
2508   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
2509 }
2510 
2511 /// Check that a restat rule doesn't clear an edge if the deps are missing.
2512 /// https://github.com/ninja-build/ninja/issues/603
TEST_F(BuildWithDepsLogTest,RestatMissingDepfileDepslog)2513 TEST_F(BuildWithDepsLogTest, RestatMissingDepfileDepslog) {
2514   string err;
2515   const char* manifest =
2516 "rule true\n"
2517 "  command = true\n"  // Would be "write if out-of-date" in reality.
2518 "  restat = 1\n"
2519 "build header.h: true header.in\n"
2520 "build out: cat header.h\n"
2521 "  deps = gcc\n"
2522 "  depfile = out.d\n";
2523 
2524   // Build once to populate ninja deps logs from out.d
2525   fs_.Create("header.in", "");
2526   fs_.Create("out.d", "out: header.h");
2527   fs_.Create("header.h", "");
2528 
2529   RebuildTarget("out", manifest, "build_log", "ninja_deps");
2530   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
2531 
2532   // Sanity: this rebuild should be NOOP
2533   RebuildTarget("out", manifest, "build_log", "ninja_deps");
2534   ASSERT_EQ(0u, command_runner_.commands_ran_.size());
2535 
2536   // Touch 'header.in', blank dependencies log (create a different one).
2537   // Building header.h triggers 'restat' outputs cleanup.
2538   // Validate that out is rebuilt netherless, as deps are missing.
2539   fs_.Tick();
2540   fs_.Create("header.in", "");
2541 
2542   // (switch to a new blank deps_log "ninja_deps2")
2543   RebuildTarget("out", manifest, "build_log", "ninja_deps2");
2544   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
2545 
2546   // Sanity: this build should be NOOP
2547   RebuildTarget("out", manifest, "build_log", "ninja_deps2");
2548   ASSERT_EQ(0u, command_runner_.commands_ran_.size());
2549 
2550   // Check that invalidating deps by target timestamp also works here
2551   // Repeat the test but touch target instead of blanking the log.
2552   fs_.Tick();
2553   fs_.Create("header.in", "");
2554   fs_.Create("out", "");
2555   RebuildTarget("out", manifest, "build_log", "ninja_deps2");
2556   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
2557 
2558   // And this build should be NOOP again
2559   RebuildTarget("out", manifest, "build_log", "ninja_deps2");
2560   ASSERT_EQ(0u, command_runner_.commands_ran_.size());
2561 }
2562 
TEST_F(BuildTest,WrongOutputInDepfileCausesRebuild)2563 TEST_F(BuildTest, WrongOutputInDepfileCausesRebuild) {
2564   string err;
2565   const char* manifest =
2566 "rule cc\n"
2567 "  command = cc $in\n"
2568 "  depfile = $out.d\n"
2569 "build foo.o: cc foo.c\n";
2570 
2571   fs_.Create("foo.c", "");
2572   fs_.Create("foo.o", "");
2573   fs_.Create("header.h", "");
2574   fs_.Create("foo.o.d", "bar.o.d: header.h\n");
2575 
2576   RebuildTarget("foo.o", manifest, "build_log", "ninja_deps");
2577   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2578 }
2579 
TEST_F(BuildTest,Console)2580 TEST_F(BuildTest, Console) {
2581   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
2582 "rule console\n"
2583 "  command = console\n"
2584 "  pool = console\n"
2585 "build cons: console in.txt\n"));
2586 
2587   fs_.Create("in.txt", "");
2588 
2589   string err;
2590   EXPECT_TRUE(builder_.AddTarget("cons", &err));
2591   ASSERT_EQ("", err);
2592   EXPECT_TRUE(builder_.Build(&err));
2593   EXPECT_EQ("", err);
2594   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2595 }
2596 
TEST_F(BuildTest,DyndepMissingAndNoRule)2597 TEST_F(BuildTest, DyndepMissingAndNoRule) {
2598   // Verify that we can diagnose when a dyndep file is missing and
2599   // has no rule to build it.
2600   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
2601 "rule touch\n"
2602 "  command = touch $out\n"
2603 "build out: touch || dd\n"
2604 "  dyndep = dd\n"
2605 ));
2606 
2607   string err;
2608   EXPECT_FALSE(builder_.AddTarget("out", &err));
2609   EXPECT_EQ("loading 'dd': No such file or directory", err);
2610 }
2611 
TEST_F(BuildTest,DyndepReadyImplicitConnection)2612 TEST_F(BuildTest, DyndepReadyImplicitConnection) {
2613   // Verify that a dyndep file can be loaded immediately to discover
2614   // that one edge has an implicit output that is also an implicit
2615   // input of another edge.
2616   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
2617 "rule touch\n"
2618 "  command = touch $out $out.imp\n"
2619 "build tmp: touch || dd\n"
2620 "  dyndep = dd\n"
2621 "build out: touch || dd\n"
2622 "  dyndep = dd\n"
2623 ));
2624   fs_.Create("dd",
2625 "ninja_dyndep_version = 1\n"
2626 "build out | out.imp: dyndep | tmp.imp\n"
2627 "build tmp | tmp.imp: dyndep\n"
2628 );
2629 
2630   string err;
2631   EXPECT_TRUE(builder_.AddTarget("out", &err));
2632   ASSERT_EQ("", err);
2633   EXPECT_TRUE(builder_.Build(&err));
2634   EXPECT_EQ("", err);
2635   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
2636   EXPECT_EQ("touch tmp tmp.imp", command_runner_.commands_ran_[0]);
2637   EXPECT_EQ("touch out out.imp", command_runner_.commands_ran_[1]);
2638 }
2639 
TEST_F(BuildTest,DyndepReadySyntaxError)2640 TEST_F(BuildTest, DyndepReadySyntaxError) {
2641   // Verify that a dyndep file can be loaded immediately to discover
2642   // and reject a syntax error in it.
2643   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
2644 "rule touch\n"
2645 "  command = touch $out\n"
2646 "build out: touch || dd\n"
2647 "  dyndep = dd\n"
2648 ));
2649   fs_.Create("dd",
2650 "build out: dyndep\n"
2651 );
2652 
2653   string err;
2654   EXPECT_FALSE(builder_.AddTarget("out", &err));
2655   EXPECT_EQ("dd:1: expected 'ninja_dyndep_version = ...'\n", err);
2656 }
2657 
TEST_F(BuildTest,DyndepReadyCircular)2658 TEST_F(BuildTest, DyndepReadyCircular) {
2659   // Verify that a dyndep file can be loaded immediately to discover
2660   // and reject a circular dependency.
2661   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
2662 "rule r\n"
2663 "  command = unused\n"
2664 "build out: r in || dd\n"
2665 "  dyndep = dd\n"
2666 "build in: r circ\n"
2667   ));
2668   fs_.Create("dd",
2669 "ninja_dyndep_version = 1\n"
2670 "build out | circ: dyndep\n"
2671   );
2672   fs_.Create("out", "");
2673 
2674   string err;
2675   EXPECT_FALSE(builder_.AddTarget("out", &err));
2676   EXPECT_EQ("dependency cycle: circ -> in -> circ", err);
2677 }
2678 
TEST_F(BuildTest,DyndepBuild)2679 TEST_F(BuildTest, DyndepBuild) {
2680   // Verify that a dyndep file can be built and loaded to discover nothing.
2681   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
2682 "rule touch\n"
2683 "  command = touch $out\n"
2684 "rule cp\n"
2685 "  command = cp $in $out\n"
2686 "build dd: cp dd-in\n"
2687 "build out: touch || dd\n"
2688 "  dyndep = dd\n"
2689 ));
2690   fs_.Create("dd-in",
2691 "ninja_dyndep_version = 1\n"
2692 "build out: dyndep\n"
2693 );
2694 
2695   string err;
2696   EXPECT_TRUE(builder_.AddTarget("out", &err));
2697   EXPECT_EQ("", err);
2698 
2699   size_t files_created = fs_.files_created_.size();
2700   EXPECT_TRUE(builder_.Build(&err));
2701   EXPECT_EQ("", err);
2702 
2703   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
2704   EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
2705   EXPECT_EQ("touch out", command_runner_.commands_ran_[1]);
2706   ASSERT_EQ(2u, fs_.files_read_.size());
2707   EXPECT_EQ("dd-in", fs_.files_read_[0]);
2708   EXPECT_EQ("dd", fs_.files_read_[1]);
2709   ASSERT_EQ(2u + files_created, fs_.files_created_.size());
2710   EXPECT_EQ(1u, fs_.files_created_.count("dd"));
2711   EXPECT_EQ(1u, fs_.files_created_.count("out"));
2712 }
2713 
TEST_F(BuildTest,DyndepBuildSyntaxError)2714 TEST_F(BuildTest, DyndepBuildSyntaxError) {
2715   // Verify that a dyndep file can be built and loaded to discover
2716   // and reject a syntax error in it.
2717   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
2718 "rule touch\n"
2719 "  command = touch $out\n"
2720 "rule cp\n"
2721 "  command = cp $in $out\n"
2722 "build dd: cp dd-in\n"
2723 "build out: touch || dd\n"
2724 "  dyndep = dd\n"
2725 ));
2726   fs_.Create("dd-in",
2727 "build out: dyndep\n"
2728 );
2729 
2730   string err;
2731   EXPECT_TRUE(builder_.AddTarget("out", &err));
2732   EXPECT_EQ("", err);
2733 
2734   EXPECT_FALSE(builder_.Build(&err));
2735   EXPECT_EQ("dd:1: expected 'ninja_dyndep_version = ...'\n", err);
2736 }
2737 
TEST_F(BuildTest,DyndepBuildUnrelatedOutput)2738 TEST_F(BuildTest, DyndepBuildUnrelatedOutput) {
2739   // Verify that a dyndep file can have dependents that do not specify
2740   // it as their dyndep binding.
2741   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
2742 "rule touch\n"
2743 "  command = touch $out\n"
2744 "rule cp\n"
2745 "  command = cp $in $out\n"
2746 "build dd: cp dd-in\n"
2747 "build unrelated: touch || dd\n"
2748 "build out: touch unrelated || dd\n"
2749 "  dyndep = dd\n"
2750   ));
2751   fs_.Create("dd-in",
2752 "ninja_dyndep_version = 1\n"
2753 "build out: dyndep\n"
2754 );
2755   fs_.Tick();
2756   fs_.Create("out", "");
2757 
2758   string err;
2759   EXPECT_TRUE(builder_.AddTarget("out", &err));
2760   EXPECT_EQ("", err);
2761 
2762   EXPECT_TRUE(builder_.Build(&err));
2763   EXPECT_EQ("", err);
2764   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
2765   EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
2766   EXPECT_EQ("touch unrelated", command_runner_.commands_ran_[1]);
2767   EXPECT_EQ("touch out", command_runner_.commands_ran_[2]);
2768 }
2769 
TEST_F(BuildTest,DyndepBuildDiscoverNewOutput)2770 TEST_F(BuildTest, DyndepBuildDiscoverNewOutput) {
2771   // Verify that a dyndep file can be built and loaded to discover
2772   // a new output of an edge.
2773   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
2774 "rule touch\n"
2775 "  command = touch $out $out.imp\n"
2776 "rule cp\n"
2777 "  command = cp $in $out\n"
2778 "build dd: cp dd-in\n"
2779 "build out: touch in || dd\n"
2780 "  dyndep = dd\n"
2781   ));
2782   fs_.Create("in", "");
2783   fs_.Create("dd-in",
2784 "ninja_dyndep_version = 1\n"
2785 "build out | out.imp: dyndep\n"
2786 );
2787   fs_.Tick();
2788   fs_.Create("out", "");
2789 
2790   string err;
2791   EXPECT_TRUE(builder_.AddTarget("out", &err));
2792   EXPECT_EQ("", err);
2793 
2794   EXPECT_TRUE(builder_.Build(&err));
2795   EXPECT_EQ("", err);
2796   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
2797   EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
2798   EXPECT_EQ("touch out out.imp", command_runner_.commands_ran_[1]);
2799 }
2800 
TEST_F(BuildTest,DyndepBuildDiscoverNewOutputWithMultipleRules1)2801 TEST_F(BuildTest, DyndepBuildDiscoverNewOutputWithMultipleRules1) {
2802   // Verify that a dyndep file can be built and loaded to discover
2803   // a new output of an edge that is already the output of another edge.
2804   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
2805 "rule touch\n"
2806 "  command = touch $out $out.imp\n"
2807 "rule cp\n"
2808 "  command = cp $in $out\n"
2809 "build dd: cp dd-in\n"
2810 "build out1 | out-twice.imp: touch in\n"
2811 "build out2: touch in || dd\n"
2812 "  dyndep = dd\n"
2813   ));
2814   fs_.Create("in", "");
2815   fs_.Create("dd-in",
2816 "ninja_dyndep_version = 1\n"
2817 "build out2 | out-twice.imp: dyndep\n"
2818 );
2819   fs_.Tick();
2820   fs_.Create("out1", "");
2821   fs_.Create("out2", "");
2822 
2823   string err;
2824   EXPECT_TRUE(builder_.AddTarget("out1", &err));
2825   EXPECT_TRUE(builder_.AddTarget("out2", &err));
2826   EXPECT_EQ("", err);
2827 
2828   EXPECT_FALSE(builder_.Build(&err));
2829   EXPECT_EQ("multiple rules generate out-twice.imp", err);
2830 }
2831 
TEST_F(BuildTest,DyndepBuildDiscoverNewOutputWithMultipleRules2)2832 TEST_F(BuildTest, DyndepBuildDiscoverNewOutputWithMultipleRules2) {
2833   // Verify that a dyndep file can be built and loaded to discover
2834   // a new output of an edge that is already the output of another
2835   // edge also discovered by dyndep.
2836   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
2837 "rule touch\n"
2838 "  command = touch $out $out.imp\n"
2839 "rule cp\n"
2840 "  command = cp $in $out\n"
2841 "build dd1: cp dd1-in\n"
2842 "build out1: touch || dd1\n"
2843 "  dyndep = dd1\n"
2844 "build dd2: cp dd2-in || dd1\n" // make order predictable for test
2845 "build out2: touch || dd2\n"
2846 "  dyndep = dd2\n"
2847 ));
2848   fs_.Create("out1", "");
2849   fs_.Create("out2", "");
2850   fs_.Create("dd1-in",
2851 "ninja_dyndep_version = 1\n"
2852 "build out1 | out-twice.imp: dyndep\n"
2853 );
2854   fs_.Create("dd2-in", "");
2855   fs_.Create("dd2",
2856 "ninja_dyndep_version = 1\n"
2857 "build out2 | out-twice.imp: dyndep\n"
2858 );
2859   fs_.Tick();
2860   fs_.Create("out1", "");
2861   fs_.Create("out2", "");
2862 
2863   string err;
2864   EXPECT_TRUE(builder_.AddTarget("out1", &err));
2865   EXPECT_TRUE(builder_.AddTarget("out2", &err));
2866   EXPECT_EQ("", err);
2867 
2868   EXPECT_FALSE(builder_.Build(&err));
2869   EXPECT_EQ("multiple rules generate out-twice.imp", err);
2870 }
2871 
TEST_F(BuildTest,DyndepBuildDiscoverNewInput)2872 TEST_F(BuildTest, DyndepBuildDiscoverNewInput) {
2873   // Verify that a dyndep file can be built and loaded to discover
2874   // a new input to an edge.
2875   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
2876 "rule touch\n"
2877 "  command = touch $out\n"
2878 "rule cp\n"
2879 "  command = cp $in $out\n"
2880 "build dd: cp dd-in\n"
2881 "build in: touch\n"
2882 "build out: touch || dd\n"
2883 "  dyndep = dd\n"
2884   ));
2885   fs_.Create("dd-in",
2886 "ninja_dyndep_version = 1\n"
2887 "build out: dyndep | in\n"
2888 );
2889   fs_.Tick();
2890   fs_.Create("out", "");
2891 
2892   string err;
2893   EXPECT_TRUE(builder_.AddTarget("out", &err));
2894   EXPECT_EQ("", err);
2895 
2896   EXPECT_TRUE(builder_.Build(&err));
2897   EXPECT_EQ("", err);
2898   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
2899   EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
2900   EXPECT_EQ("touch in", command_runner_.commands_ran_[1]);
2901   EXPECT_EQ("touch out", command_runner_.commands_ran_[2]);
2902 }
2903 
TEST_F(BuildTest,DyndepBuildDiscoverImplicitConnection)2904 TEST_F(BuildTest, DyndepBuildDiscoverImplicitConnection) {
2905   // Verify that a dyndep file can be built and loaded to discover
2906   // that one edge has an implicit output that is also an implicit
2907   // input of another edge.
2908   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
2909 "rule touch\n"
2910 "  command = touch $out $out.imp\n"
2911 "rule cp\n"
2912 "  command = cp $in $out\n"
2913 "build dd: cp dd-in\n"
2914 "build tmp: touch || dd\n"
2915 "  dyndep = dd\n"
2916 "build out: touch || dd\n"
2917 "  dyndep = dd\n"
2918 ));
2919   fs_.Create("dd-in",
2920 "ninja_dyndep_version = 1\n"
2921 "build out | out.imp: dyndep | tmp.imp\n"
2922 "build tmp | tmp.imp: dyndep\n"
2923 );
2924 
2925   string err;
2926   EXPECT_TRUE(builder_.AddTarget("out", &err));
2927   ASSERT_EQ("", err);
2928   EXPECT_TRUE(builder_.Build(&err));
2929   EXPECT_EQ("", err);
2930   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
2931   EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
2932   EXPECT_EQ("touch tmp tmp.imp", command_runner_.commands_ran_[1]);
2933   EXPECT_EQ("touch out out.imp", command_runner_.commands_ran_[2]);
2934 }
2935 
TEST_F(BuildTest,DyndepBuildDiscoverNowWantEdge)2936 TEST_F(BuildTest, DyndepBuildDiscoverNowWantEdge) {
2937   // Verify that a dyndep file can be built and loaded to discover
2938   // that an edge is actually wanted due to a missing implicit output.
2939   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
2940 "rule touch\n"
2941 "  command = touch $out $out.imp\n"
2942 "rule cp\n"
2943 "  command = cp $in $out\n"
2944 "build dd: cp dd-in\n"
2945 "build tmp: touch || dd\n"
2946 "  dyndep = dd\n"
2947 "build out: touch tmp || dd\n"
2948 "  dyndep = dd\n"
2949 ));
2950   fs_.Create("tmp", "");
2951   fs_.Create("out", "");
2952   fs_.Create("dd-in",
2953 "ninja_dyndep_version = 1\n"
2954 "build out: dyndep\n"
2955 "build tmp | tmp.imp: dyndep\n"
2956 );
2957 
2958   string err;
2959   EXPECT_TRUE(builder_.AddTarget("out", &err));
2960   ASSERT_EQ("", err);
2961   EXPECT_TRUE(builder_.Build(&err));
2962   EXPECT_EQ("", err);
2963   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
2964   EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
2965   EXPECT_EQ("touch tmp tmp.imp", command_runner_.commands_ran_[1]);
2966   EXPECT_EQ("touch out out.imp", command_runner_.commands_ran_[2]);
2967 }
2968 
TEST_F(BuildTest,DyndepBuildDiscoverNowWantEdgeAndDependent)2969 TEST_F(BuildTest, DyndepBuildDiscoverNowWantEdgeAndDependent) {
2970   // Verify that a dyndep file can be built and loaded to discover
2971   // that an edge and a dependent are actually wanted.
2972   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
2973 "rule touch\n"
2974 "  command = touch $out $out.imp\n"
2975 "rule cp\n"
2976 "  command = cp $in $out\n"
2977 "build dd: cp dd-in\n"
2978 "build tmp: touch || dd\n"
2979 "  dyndep = dd\n"
2980 "build out: touch tmp\n"
2981 ));
2982   fs_.Create("tmp", "");
2983   fs_.Create("out", "");
2984   fs_.Create("dd-in",
2985 "ninja_dyndep_version = 1\n"
2986 "build tmp | tmp.imp: dyndep\n"
2987 );
2988 
2989   string err;
2990   EXPECT_TRUE(builder_.AddTarget("out", &err));
2991   ASSERT_EQ("", err);
2992   EXPECT_TRUE(builder_.Build(&err));
2993   EXPECT_EQ("", err);
2994   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
2995   EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
2996   EXPECT_EQ("touch tmp tmp.imp", command_runner_.commands_ran_[1]);
2997   EXPECT_EQ("touch out out.imp", command_runner_.commands_ran_[2]);
2998 }
2999 
TEST_F(BuildTest,DyndepBuildDiscoverCircular)3000 TEST_F(BuildTest, DyndepBuildDiscoverCircular) {
3001   // Verify that a dyndep file can be built and loaded to discover
3002   // and reject a circular dependency.
3003   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
3004 "rule r\n"
3005 "  command = unused\n"
3006 "rule cp\n"
3007 "  command = cp $in $out\n"
3008 "build dd: cp dd-in\n"
3009 "build out: r in || dd\n"
3010 "  depfile = out.d\n"
3011 "  dyndep = dd\n"
3012 "build in: r || dd\n"
3013 "  dyndep = dd\n"
3014   ));
3015   fs_.Create("out.d", "out: inimp\n");
3016   fs_.Create("dd-in",
3017 "ninja_dyndep_version = 1\n"
3018 "build out | circ: dyndep\n"
3019 "build in: dyndep | circ\n"
3020   );
3021   fs_.Create("out", "");
3022 
3023   string err;
3024   EXPECT_TRUE(builder_.AddTarget("out", &err));
3025   EXPECT_EQ("", err);
3026 
3027   EXPECT_FALSE(builder_.Build(&err));
3028   // Depending on how the pointers in Plan::ready_ work out, we could have
3029   // discovered the cycle from either starting point.
3030   EXPECT_TRUE(err == "dependency cycle: circ -> in -> circ" ||
3031               err == "dependency cycle: in -> circ -> in");
3032 }
3033 
TEST_F(BuildWithLogTest,DyndepBuildDiscoverRestat)3034 TEST_F(BuildWithLogTest, DyndepBuildDiscoverRestat) {
3035   // Verify that a dyndep file can be built and loaded to discover
3036   // that an edge has a restat binding.
3037   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
3038 "rule true\n"
3039 "  command = true\n"
3040 "rule cp\n"
3041 "  command = cp $in $out\n"
3042 "build dd: cp dd-in\n"
3043 "build out1: true in || dd\n"
3044 "  dyndep = dd\n"
3045 "build out2: cat out1\n"));
3046 
3047   fs_.Create("out1", "");
3048   fs_.Create("out2", "");
3049   fs_.Create("dd-in",
3050 "ninja_dyndep_version = 1\n"
3051 "build out1: dyndep\n"
3052 "  restat = 1\n"
3053 );
3054   fs_.Tick();
3055   fs_.Create("in", "");
3056 
3057   // Do a pre-build so that there's commands in the log for the outputs,
3058   // otherwise, the lack of an entry in the build log will cause "out2" to
3059   // rebuild regardless of restat.
3060   string err;
3061   EXPECT_TRUE(builder_.AddTarget("out2", &err));
3062   ASSERT_EQ("", err);
3063   EXPECT_TRUE(builder_.Build(&err));
3064   ASSERT_EQ("", err);
3065   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3066   EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
3067   EXPECT_EQ("true", command_runner_.commands_ran_[1]);
3068   EXPECT_EQ("cat out1 > out2", command_runner_.commands_ran_[2]);
3069 
3070   command_runner_.commands_ran_.clear();
3071   state_.Reset();
3072   fs_.Tick();
3073   fs_.Create("in", "");
3074 
3075   // We touched "in", so we should build "out1".  But because "true" does not
3076   // touch "out1", we should cancel the build of "out2".
3077   EXPECT_TRUE(builder_.AddTarget("out2", &err));
3078   ASSERT_EQ("", err);
3079   EXPECT_TRUE(builder_.Build(&err));
3080   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
3081   EXPECT_EQ("true", command_runner_.commands_ran_[0]);
3082 }
3083 
TEST_F(BuildTest,DyndepBuildDiscoverScheduledEdge)3084 TEST_F(BuildTest, DyndepBuildDiscoverScheduledEdge) {
3085   // Verify that a dyndep file can be built and loaded to discover a
3086   // new input that itself is an output from an edge that has already
3087   // been scheduled but not finished.  We should not re-schedule it.
3088   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
3089 "rule touch\n"
3090 "  command = touch $out $out.imp\n"
3091 "rule cp\n"
3092 "  command = cp $in $out\n"
3093 "build out1 | out1.imp: touch\n"
3094 "build zdd: cp zdd-in\n"
3095 "  verify_active_edge = out1\n" // verify out1 is active when zdd is finished
3096 "build out2: cp out1 || zdd\n"
3097 "  dyndep = zdd\n"
3098 ));
3099   fs_.Create("zdd-in",
3100 "ninja_dyndep_version = 1\n"
3101 "build out2: dyndep | out1.imp\n"
3102 );
3103 
3104   // Enable concurrent builds so that we can load the dyndep file
3105   // while another edge is still active.
3106   command_runner_.max_active_edges_ = 2;
3107 
3108   // During the build "out1" and "zdd" should be built concurrently.
3109   // The fake command runner will finish these in reverse order
3110   // of the names of the first outputs, so "zdd" will finish first
3111   // and we will load the dyndep file while the edge for "out1" is
3112   // still active.  This will add a new dependency on "out1.imp",
3113   // also produced by the active edge.  The builder should not
3114   // re-schedule the already-active edge.
3115 
3116   string err;
3117   EXPECT_TRUE(builder_.AddTarget("out1", &err));
3118   EXPECT_TRUE(builder_.AddTarget("out2", &err));
3119   ASSERT_EQ("", err);
3120   EXPECT_TRUE(builder_.Build(&err));
3121   EXPECT_EQ("", err);
3122   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3123   // Depending on how the pointers in Plan::ready_ work out, the first
3124   // two commands may have run in either order.
3125   EXPECT_TRUE((command_runner_.commands_ran_[0] == "touch out1 out1.imp" &&
3126                command_runner_.commands_ran_[1] == "cp zdd-in zdd") ||
3127               (command_runner_.commands_ran_[1] == "touch out1 out1.imp" &&
3128                command_runner_.commands_ran_[0] == "cp zdd-in zdd"));
3129   EXPECT_EQ("cp out1 out2", command_runner_.commands_ran_[2]);
3130 }
3131 
TEST_F(BuildTest,DyndepTwoLevelDirect)3132 TEST_F(BuildTest, DyndepTwoLevelDirect) {
3133   // Verify that a clean dyndep file can depend on a dirty dyndep file
3134   // and be loaded properly after the dirty one is built and loaded.
3135   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
3136 "rule touch\n"
3137 "  command = touch $out $out.imp\n"
3138 "rule cp\n"
3139 "  command = cp $in $out\n"
3140 "build dd1: cp dd1-in\n"
3141 "build out1 | out1.imp: touch || dd1\n"
3142 "  dyndep = dd1\n"
3143 "build dd2: cp dd2-in || dd1\n" // direct order-only dep on dd1
3144 "build out2: touch || dd2\n"
3145 "  dyndep = dd2\n"
3146 ));
3147   fs_.Create("out1.imp", "");
3148   fs_.Create("out2", "");
3149   fs_.Create("out2.imp", "");
3150   fs_.Create("dd1-in",
3151 "ninja_dyndep_version = 1\n"
3152 "build out1: dyndep\n"
3153 );
3154   fs_.Create("dd2-in", "");
3155   fs_.Create("dd2",
3156 "ninja_dyndep_version = 1\n"
3157 "build out2 | out2.imp: dyndep | out1.imp\n"
3158 );
3159 
3160   // During the build dd1 should be built and loaded.  The RecomputeDirty
3161   // called as a result of loading dd1 should not cause dd2 to be loaded
3162   // because the builder will never get a chance to update the build plan
3163   // to account for dd2.  Instead dd2 should only be later loaded once the
3164   // builder recognizes that it is now ready (as its order-only dependency
3165   // on dd1 has been satisfied).  This test case verifies that each dyndep
3166   // file is loaded to update the build graph independently.
3167 
3168   string err;
3169   EXPECT_TRUE(builder_.AddTarget("out2", &err));
3170   ASSERT_EQ("", err);
3171   EXPECT_TRUE(builder_.Build(&err));
3172   EXPECT_EQ("", err);
3173   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3174   EXPECT_EQ("cp dd1-in dd1", command_runner_.commands_ran_[0]);
3175   EXPECT_EQ("touch out1 out1.imp", command_runner_.commands_ran_[1]);
3176   EXPECT_EQ("touch out2 out2.imp", command_runner_.commands_ran_[2]);
3177 }
3178 
TEST_F(BuildTest,DyndepTwoLevelIndirect)3179 TEST_F(BuildTest, DyndepTwoLevelIndirect) {
3180   // Verify that dyndep files can add to an edge new implicit inputs that
3181   // correspond to implicit outputs added to other edges by other dyndep
3182   // files on which they (order-only) depend.
3183   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
3184 "rule touch\n"
3185 "  command = touch $out $out.imp\n"
3186 "rule cp\n"
3187 "  command = cp $in $out\n"
3188 "build dd1: cp dd1-in\n"
3189 "build out1: touch || dd1\n"
3190 "  dyndep = dd1\n"
3191 "build dd2: cp dd2-in || out1\n" // indirect order-only dep on dd1
3192 "build out2: touch || dd2\n"
3193 "  dyndep = dd2\n"
3194 ));
3195   fs_.Create("out1.imp", "");
3196   fs_.Create("out2", "");
3197   fs_.Create("out2.imp", "");
3198   fs_.Create("dd1-in",
3199 "ninja_dyndep_version = 1\n"
3200 "build out1 | out1.imp: dyndep\n"
3201 );
3202   fs_.Create("dd2-in", "");
3203   fs_.Create("dd2",
3204 "ninja_dyndep_version = 1\n"
3205 "build out2 | out2.imp: dyndep | out1.imp\n"
3206 );
3207 
3208   // During the build dd1 should be built and loaded.  Then dd2 should
3209   // be built and loaded.  Loading dd2 should cause the builder to
3210   // recognize that out2 needs to be built even though it was originally
3211   // clean without dyndep info.
3212 
3213   string err;
3214   EXPECT_TRUE(builder_.AddTarget("out2", &err));
3215   ASSERT_EQ("", err);
3216   EXPECT_TRUE(builder_.Build(&err));
3217   EXPECT_EQ("", err);
3218   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3219   EXPECT_EQ("cp dd1-in dd1", command_runner_.commands_ran_[0]);
3220   EXPECT_EQ("touch out1 out1.imp", command_runner_.commands_ran_[1]);
3221   EXPECT_EQ("touch out2 out2.imp", command_runner_.commands_ran_[2]);
3222 }
3223 
TEST_F(BuildTest,DyndepTwoLevelDiscoveredReady)3224 TEST_F(BuildTest, DyndepTwoLevelDiscoveredReady) {
3225   // Verify that a dyndep file can discover a new input whose
3226   // edge also has a dyndep file that is ready to load immediately.
3227   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
3228 "rule touch\n"
3229 "  command = touch $out\n"
3230 "rule cp\n"
3231 "  command = cp $in $out\n"
3232 "build dd0: cp dd0-in\n"
3233 "build dd1: cp dd1-in\n"
3234 "build in: touch\n"
3235 "build tmp: touch || dd0\n"
3236 "  dyndep = dd0\n"
3237 "build out: touch || dd1\n"
3238 "  dyndep = dd1\n"
3239   ));
3240   fs_.Create("dd1-in",
3241 "ninja_dyndep_version = 1\n"
3242 "build out: dyndep | tmp\n"
3243 );
3244   fs_.Create("dd0-in", "");
3245   fs_.Create("dd0",
3246 "ninja_dyndep_version = 1\n"
3247 "build tmp: dyndep | in\n"
3248 );
3249   fs_.Tick();
3250   fs_.Create("out", "");
3251 
3252   string err;
3253   EXPECT_TRUE(builder_.AddTarget("out", &err));
3254   EXPECT_EQ("", err);
3255 
3256   EXPECT_TRUE(builder_.Build(&err));
3257   EXPECT_EQ("", err);
3258   ASSERT_EQ(4u, command_runner_.commands_ran_.size());
3259   EXPECT_EQ("cp dd1-in dd1", command_runner_.commands_ran_[0]);
3260   EXPECT_EQ("touch in", command_runner_.commands_ran_[1]);
3261   EXPECT_EQ("touch tmp", command_runner_.commands_ran_[2]);
3262   EXPECT_EQ("touch out", command_runner_.commands_ran_[3]);
3263 }
3264 
TEST_F(BuildTest,DyndepTwoLevelDiscoveredDirty)3265 TEST_F(BuildTest, DyndepTwoLevelDiscoveredDirty) {
3266   // Verify that a dyndep file can discover a new input whose
3267   // edge also has a dyndep file that needs to be built.
3268   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
3269 "rule touch\n"
3270 "  command = touch $out\n"
3271 "rule cp\n"
3272 "  command = cp $in $out\n"
3273 "build dd0: cp dd0-in\n"
3274 "build dd1: cp dd1-in\n"
3275 "build in: touch\n"
3276 "build tmp: touch || dd0\n"
3277 "  dyndep = dd0\n"
3278 "build out: touch || dd1\n"
3279 "  dyndep = dd1\n"
3280   ));
3281   fs_.Create("dd1-in",
3282 "ninja_dyndep_version = 1\n"
3283 "build out: dyndep | tmp\n"
3284 );
3285   fs_.Create("dd0-in",
3286 "ninja_dyndep_version = 1\n"
3287 "build tmp: dyndep | in\n"
3288 );
3289   fs_.Tick();
3290   fs_.Create("out", "");
3291 
3292   string err;
3293   EXPECT_TRUE(builder_.AddTarget("out", &err));
3294   EXPECT_EQ("", err);
3295 
3296   EXPECT_TRUE(builder_.Build(&err));
3297   EXPECT_EQ("", err);
3298   ASSERT_EQ(5u, command_runner_.commands_ran_.size());
3299   EXPECT_EQ("cp dd1-in dd1", command_runner_.commands_ran_[0]);
3300   EXPECT_EQ("cp dd0-in dd0", command_runner_.commands_ran_[1]);
3301   EXPECT_EQ("touch in", command_runner_.commands_ran_[2]);
3302   EXPECT_EQ("touch tmp", command_runner_.commands_ran_[3]);
3303   EXPECT_EQ("touch out", command_runner_.commands_ran_[4]);
3304 }
3305