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