Merge pull request #654 from rgeary1/buildTestFix
[platform/upstream/ninja.git] / src / build_test.cc
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 "build_log.h"
18 #include "deps_log.h"
19 #include "graph.h"
20 #include "test.h"
21
22 /// Fixture for tests involving Plan.
23 // Though Plan doesn't use State, it's useful to have one around
24 // to create Nodes and Edges.
25 struct PlanTest : public StateTestWithBuiltinRules {
26   Plan plan_;
27
28   /// Because FindWork does not return Edges in any sort of predictable order,
29   // provide a means to get available Edges in order and in a format which is
30   // easy to write tests around.
31   void FindWorkSorted(deque<Edge*>* ret, int count) {
32     struct CompareEdgesByOutput {
33       static bool cmp(const Edge* a, const Edge* b) {
34         return a->outputs_[0]->path() < b->outputs_[0]->path();
35       }
36     };
37
38     for (int i = 0; i < count; ++i) {
39       ASSERT_TRUE(plan_.more_to_do());
40       Edge* edge = plan_.FindWork();
41       ASSERT_TRUE(edge);
42       ret->push_back(edge);
43     }
44     ASSERT_FALSE(plan_.FindWork());
45     sort(ret->begin(), ret->end(), CompareEdgesByOutput::cmp);
46   }
47 };
48
49 TEST_F(PlanTest, Basic) {
50   AssertParse(&state_,
51 "build out: cat mid\n"
52 "build mid: cat in\n");
53   GetNode("mid")->MarkDirty();
54   GetNode("out")->MarkDirty();
55   string err;
56   EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
57   ASSERT_EQ("", err);
58   ASSERT_TRUE(plan_.more_to_do());
59
60   Edge* edge = plan_.FindWork();
61   ASSERT_TRUE(edge);
62   ASSERT_EQ("in",  edge->inputs_[0]->path());
63   ASSERT_EQ("mid", edge->outputs_[0]->path());
64
65   ASSERT_FALSE(plan_.FindWork());
66
67   plan_.EdgeFinished(edge);
68
69   edge = plan_.FindWork();
70   ASSERT_TRUE(edge);
71   ASSERT_EQ("mid", edge->inputs_[0]->path());
72   ASSERT_EQ("out", edge->outputs_[0]->path());
73
74   plan_.EdgeFinished(edge);
75
76   ASSERT_FALSE(plan_.more_to_do());
77   edge = plan_.FindWork();
78   ASSERT_EQ(0, edge);
79 }
80
81 // Test that two outputs from one rule can be handled as inputs to the next.
82 TEST_F(PlanTest, DoubleOutputDirect) {
83   AssertParse(&state_,
84 "build out: cat mid1 mid2\n"
85 "build mid1 mid2: cat in\n");
86   GetNode("mid1")->MarkDirty();
87   GetNode("mid2")->MarkDirty();
88   GetNode("out")->MarkDirty();
89
90   string err;
91   EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
92   ASSERT_EQ("", err);
93   ASSERT_TRUE(plan_.more_to_do());
94
95   Edge* edge;
96   edge = plan_.FindWork();
97   ASSERT_TRUE(edge);  // cat in
98   plan_.EdgeFinished(edge);
99
100   edge = plan_.FindWork();
101   ASSERT_TRUE(edge);  // cat mid1 mid2
102   plan_.EdgeFinished(edge);
103
104   edge = plan_.FindWork();
105   ASSERT_FALSE(edge);  // done
106 }
107
108 // Test that two outputs from one rule can eventually be routed to another.
109 TEST_F(PlanTest, DoubleOutputIndirect) {
110   AssertParse(&state_,
111 "build out: cat b1 b2\n"
112 "build b1: cat a1\n"
113 "build b2: cat a2\n"
114 "build a1 a2: cat in\n");
115   GetNode("a1")->MarkDirty();
116   GetNode("a2")->MarkDirty();
117   GetNode("b1")->MarkDirty();
118   GetNode("b2")->MarkDirty();
119   GetNode("out")->MarkDirty();
120   string err;
121   EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
122   ASSERT_EQ("", err);
123   ASSERT_TRUE(plan_.more_to_do());
124
125   Edge* edge;
126   edge = plan_.FindWork();
127   ASSERT_TRUE(edge);  // cat in
128   plan_.EdgeFinished(edge);
129
130   edge = plan_.FindWork();
131   ASSERT_TRUE(edge);  // cat a1
132   plan_.EdgeFinished(edge);
133
134   edge = plan_.FindWork();
135   ASSERT_TRUE(edge);  // cat a2
136   plan_.EdgeFinished(edge);
137
138   edge = plan_.FindWork();
139   ASSERT_TRUE(edge);  // cat b1 b2
140   plan_.EdgeFinished(edge);
141
142   edge = plan_.FindWork();
143   ASSERT_FALSE(edge);  // done
144 }
145
146 // Test that two edges from one output can both execute.
147 TEST_F(PlanTest, DoubleDependent) {
148   AssertParse(&state_,
149 "build out: cat a1 a2\n"
150 "build a1: cat mid\n"
151 "build a2: cat mid\n"
152 "build mid: cat in\n");
153   GetNode("mid")->MarkDirty();
154   GetNode("a1")->MarkDirty();
155   GetNode("a2")->MarkDirty();
156   GetNode("out")->MarkDirty();
157
158   string err;
159   EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
160   ASSERT_EQ("", err);
161   ASSERT_TRUE(plan_.more_to_do());
162
163   Edge* edge;
164   edge = plan_.FindWork();
165   ASSERT_TRUE(edge);  // cat in
166   plan_.EdgeFinished(edge);
167
168   edge = plan_.FindWork();
169   ASSERT_TRUE(edge);  // cat mid
170   plan_.EdgeFinished(edge);
171
172   edge = plan_.FindWork();
173   ASSERT_TRUE(edge);  // cat mid
174   plan_.EdgeFinished(edge);
175
176   edge = plan_.FindWork();
177   ASSERT_TRUE(edge);  // cat a1 a2
178   plan_.EdgeFinished(edge);
179
180   edge = plan_.FindWork();
181   ASSERT_FALSE(edge);  // done
182 }
183
184 TEST_F(PlanTest, DependencyCycle) {
185   AssertParse(&state_,
186 "build out: cat mid\n"
187 "build mid: cat in\n"
188 "build in: cat pre\n"
189 "build pre: cat out\n");
190   GetNode("out")->MarkDirty();
191   GetNode("mid")->MarkDirty();
192   GetNode("in")->MarkDirty();
193   GetNode("pre")->MarkDirty();
194
195   string err;
196   EXPECT_FALSE(plan_.AddTarget(GetNode("out"), &err));
197   ASSERT_EQ("dependency cycle: out -> mid -> in -> pre -> out", err);
198 }
199
200 TEST_F(PlanTest, PoolWithDepthOne) {
201   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
202 "pool foobar\n"
203 "  depth = 1\n"
204 "rule poolcat\n"
205 "  command = cat $in > $out\n"
206 "  pool = foobar\n"
207 "build out1: poolcat in\n"
208 "build out2: poolcat in\n"));
209   GetNode("out1")->MarkDirty();
210   GetNode("out2")->MarkDirty();
211   string err;
212   EXPECT_TRUE(plan_.AddTarget(GetNode("out1"), &err));
213   ASSERT_EQ("", err);
214   EXPECT_TRUE(plan_.AddTarget(GetNode("out2"), &err));
215   ASSERT_EQ("", err);
216   ASSERT_TRUE(plan_.more_to_do());
217
218   Edge* edge = plan_.FindWork();
219   ASSERT_TRUE(edge);
220   ASSERT_EQ("in",  edge->inputs_[0]->path());
221   ASSERT_EQ("out1", edge->outputs_[0]->path());
222
223   // This will be false since poolcat is serialized
224   ASSERT_FALSE(plan_.FindWork());
225
226   plan_.EdgeFinished(edge);
227
228   edge = plan_.FindWork();
229   ASSERT_TRUE(edge);
230   ASSERT_EQ("in", edge->inputs_[0]->path());
231   ASSERT_EQ("out2", edge->outputs_[0]->path());
232
233   ASSERT_FALSE(plan_.FindWork());
234
235   plan_.EdgeFinished(edge);
236
237   ASSERT_FALSE(plan_.more_to_do());
238   edge = plan_.FindWork();
239   ASSERT_EQ(0, edge);
240 }
241
242 TEST_F(PlanTest, PoolsWithDepthTwo) {
243   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
244 "pool foobar\n"
245 "  depth = 2\n"
246 "pool bazbin\n"
247 "  depth = 2\n"
248 "rule foocat\n"
249 "  command = cat $in > $out\n"
250 "  pool = foobar\n"
251 "rule bazcat\n"
252 "  command = cat $in > $out\n"
253 "  pool = bazbin\n"
254 "build out1: foocat in\n"
255 "build out2: foocat in\n"
256 "build out3: foocat in\n"
257 "build outb1: bazcat in\n"
258 "build outb2: bazcat in\n"
259 "build outb3: bazcat in\n"
260 "  pool =\n"
261 "build allTheThings: cat out1 out2 out3 outb1 outb2 outb3\n"
262 ));
263   // Mark all the out* nodes dirty
264   for (int i = 0; i < 3; ++i) {
265     GetNode("out" + string(1, '1' + static_cast<char>(i)))->MarkDirty();
266     GetNode("outb" + string(1, '1' + static_cast<char>(i)))->MarkDirty();
267   }
268   GetNode("allTheThings")->MarkDirty();
269
270   string err;
271   EXPECT_TRUE(plan_.AddTarget(GetNode("allTheThings"), &err));
272   ASSERT_EQ("", err);
273
274   deque<Edge*> edges;
275   FindWorkSorted(&edges, 5);
276
277   for (int i = 0; i < 4; ++i) {
278     Edge *edge = edges[i];
279     ASSERT_EQ("in",  edge->inputs_[0]->path());
280     string base_name(i < 2 ? "out" : "outb");
281     ASSERT_EQ(base_name + string(1, '1' + (i % 2)), edge->outputs_[0]->path());
282   }
283
284   // outb3 is exempt because it has an empty pool
285   Edge* edge = edges[4];
286   ASSERT_TRUE(edge);
287   ASSERT_EQ("in",  edge->inputs_[0]->path());
288   ASSERT_EQ("outb3", edge->outputs_[0]->path());
289
290   // finish out1
291   plan_.EdgeFinished(edges.front());
292   edges.pop_front();
293
294   // out3 should be available
295   Edge* out3 = plan_.FindWork();
296   ASSERT_TRUE(out3);
297   ASSERT_EQ("in",  out3->inputs_[0]->path());
298   ASSERT_EQ("out3", out3->outputs_[0]->path());
299
300   ASSERT_FALSE(plan_.FindWork());
301
302   plan_.EdgeFinished(out3);
303
304   ASSERT_FALSE(plan_.FindWork());
305
306   for (deque<Edge*>::iterator it = edges.begin(); it != edges.end(); ++it) {
307     plan_.EdgeFinished(*it);
308   }
309
310   Edge* last = plan_.FindWork();
311   ASSERT_TRUE(last);
312   ASSERT_EQ("allTheThings", last->outputs_[0]->path());
313
314   plan_.EdgeFinished(last);
315
316   ASSERT_FALSE(plan_.more_to_do());
317   ASSERT_FALSE(plan_.FindWork());
318 }
319
320 TEST_F(PlanTest, PoolWithRedundantEdges) {
321   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
322     "pool compile\n"
323     "  depth = 1\n"
324     "rule gen_foo\n"
325     "  command = touch foo.cpp\n"
326     "rule gen_bar\n"
327     "  command = touch bar.cpp\n"
328     "rule echo\n"
329     "  command = echo $out > $out\n"
330     "build foo.cpp.obj: echo foo.cpp || foo.cpp\n"
331     "  pool = compile\n"
332     "build bar.cpp.obj: echo bar.cpp || bar.cpp\n"
333     "  pool = compile\n"
334     "build libfoo.a: echo foo.cpp.obj bar.cpp.obj\n"
335     "build foo.cpp: gen_foo\n"
336     "build bar.cpp: gen_bar\n"
337     "build all: phony libfoo.a\n"));
338   GetNode("foo.cpp")->MarkDirty();
339   GetNode("foo.cpp.obj")->MarkDirty();
340   GetNode("bar.cpp")->MarkDirty();
341   GetNode("bar.cpp.obj")->MarkDirty();
342   GetNode("libfoo.a")->MarkDirty();
343   GetNode("all")->MarkDirty();
344   string err;
345   EXPECT_TRUE(plan_.AddTarget(GetNode("all"), &err));
346   ASSERT_EQ("", err);
347   ASSERT_TRUE(plan_.more_to_do());
348
349   Edge* edge = NULL;
350
351   deque<Edge*> initial_edges;
352   FindWorkSorted(&initial_edges, 2);
353
354   edge = initial_edges[1];  // Foo first
355   ASSERT_EQ("foo.cpp", edge->outputs_[0]->path());
356   plan_.EdgeFinished(edge);
357
358   edge = plan_.FindWork();
359   ASSERT_TRUE(edge);
360   ASSERT_FALSE(plan_.FindWork());
361   ASSERT_EQ("foo.cpp", edge->inputs_[0]->path());
362   ASSERT_EQ("foo.cpp", edge->inputs_[1]->path());
363   ASSERT_EQ("foo.cpp.obj", edge->outputs_[0]->path());
364   plan_.EdgeFinished(edge);
365
366   edge = initial_edges[0];  // Now for bar
367   ASSERT_EQ("bar.cpp", edge->outputs_[0]->path());
368   plan_.EdgeFinished(edge);
369
370   edge = plan_.FindWork();
371   ASSERT_TRUE(edge);
372   ASSERT_FALSE(plan_.FindWork());
373   ASSERT_EQ("bar.cpp", edge->inputs_[0]->path());
374   ASSERT_EQ("bar.cpp", edge->inputs_[1]->path());
375   ASSERT_EQ("bar.cpp.obj", edge->outputs_[0]->path());
376   plan_.EdgeFinished(edge);
377
378   edge = plan_.FindWork();
379   ASSERT_TRUE(edge);
380   ASSERT_FALSE(plan_.FindWork());
381   ASSERT_EQ("foo.cpp.obj", edge->inputs_[0]->path());
382   ASSERT_EQ("bar.cpp.obj", edge->inputs_[1]->path());
383   ASSERT_EQ("libfoo.a", edge->outputs_[0]->path());
384   plan_.EdgeFinished(edge);
385
386   edge = plan_.FindWork();
387   ASSERT_TRUE(edge);
388   ASSERT_FALSE(plan_.FindWork());
389   ASSERT_EQ("libfoo.a", edge->inputs_[0]->path());
390   ASSERT_EQ("all", edge->outputs_[0]->path());
391   plan_.EdgeFinished(edge);
392
393   edge = plan_.FindWork();
394   ASSERT_FALSE(edge);
395   ASSERT_FALSE(plan_.more_to_do());
396 }
397
398 /// Fake implementation of CommandRunner, useful for tests.
399 struct FakeCommandRunner : public CommandRunner {
400   explicit FakeCommandRunner(VirtualFileSystem* fs) :
401       last_command_(NULL), fs_(fs) {}
402
403   // CommandRunner impl
404   virtual bool CanRunMore();
405   virtual bool StartCommand(Edge* edge);
406   virtual bool WaitForCommand(Result* result);
407   virtual vector<Edge*> GetActiveEdges();
408   virtual void Abort();
409
410   vector<string> commands_ran_;
411   Edge* last_command_;
412   VirtualFileSystem* fs_;
413 };
414
415 struct BuildTest : public StateTestWithBuiltinRules {
416   BuildTest() : config_(MakeConfig()), command_runner_(&fs_),
417                 builder_(&state_, config_, NULL, NULL, &fs_),
418                 status_(config_) {
419   }
420
421   virtual void SetUp() {
422     StateTestWithBuiltinRules::SetUp();
423
424     builder_.command_runner_.reset(&command_runner_);
425     AssertParse(&state_,
426 "build cat1: cat in1\n"
427 "build cat2: cat in1 in2\n"
428 "build cat12: cat cat1 cat2\n");
429
430     fs_.Create("in1", "");
431     fs_.Create("in2", "");
432   }
433
434   ~BuildTest() {
435     builder_.command_runner_.release();
436   }
437
438   /// Rebuild target in the 'working tree' (fs_).
439   /// State of command_runner_ and logs contents (if specified) ARE MODIFIED.
440   /// Handy to check for NOOP builds, and higher-level rebuild tests.
441   void RebuildTarget(const string& target, const char* manifest,
442                      const char* log_path = NULL,
443                      const char* deps_path = NULL);
444
445   // Mark a path dirty.
446   void Dirty(const string& path);
447
448   BuildConfig MakeConfig() {
449     BuildConfig config;
450     config.verbosity = BuildConfig::QUIET;
451     return config;
452   }
453
454   BuildConfig config_;
455   FakeCommandRunner command_runner_;
456   VirtualFileSystem fs_;
457   Builder builder_;
458
459   BuildStatus status_;
460 };
461
462 void BuildTest::RebuildTarget(const string& target, const char* manifest,
463                               const char* log_path, const char* deps_path) {
464   State state;
465   ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
466   AssertParse(&state, manifest);
467
468   string err;
469   BuildLog build_log, *pbuild_log = NULL;
470   if (log_path) {
471     ASSERT_TRUE(build_log.Load(log_path, &err));
472     ASSERT_TRUE(build_log.OpenForWrite(log_path, &err));
473     ASSERT_EQ("", err);
474     pbuild_log = &build_log;
475   }
476
477   DepsLog deps_log, *pdeps_log = NULL;
478   if (deps_path) {
479     ASSERT_TRUE(deps_log.Load(deps_path, &state, &err));
480     ASSERT_TRUE(deps_log.OpenForWrite(deps_path, &err));
481     ASSERT_EQ("", err);
482     pdeps_log = &deps_log;
483   }
484
485   Builder builder(&state, config_, pbuild_log, pdeps_log, &fs_);
486   EXPECT_TRUE(builder.AddTarget(target, &err));
487
488   command_runner_.commands_ran_.clear();
489   builder.command_runner_.reset(&command_runner_);
490   bool build_res = true;
491   if (!builder.AlreadyUpToDate()) {
492     build_res = builder.Build(&err);
493   }
494   builder.command_runner_.release();
495   EXPECT_TRUE(build_res) << "builder.Build(&err)";
496 }
497
498 bool FakeCommandRunner::CanRunMore() {
499   // Only run one at a time.
500   return last_command_ == NULL;
501 }
502
503 bool FakeCommandRunner::StartCommand(Edge* edge) {
504   assert(!last_command_);
505   commands_ran_.push_back(edge->EvaluateCommand());
506   if (edge->rule().name() == "cat"  ||
507       edge->rule().name() == "cat_rsp" ||
508       edge->rule().name() == "cc" ||
509       edge->rule().name() == "touch" ||
510       edge->rule().name() == "touch-interrupt") {
511     for (vector<Node*>::iterator out = edge->outputs_.begin();
512          out != edge->outputs_.end(); ++out) {
513       fs_->Create((*out)->path(), "");
514     }
515   } else if (edge->rule().name() == "true" ||
516              edge->rule().name() == "fail" ||
517              edge->rule().name() == "interrupt") {
518     // Don't do anything.
519   } else {
520     printf("unknown command\n");
521     return false;
522   }
523
524   last_command_ = edge;
525   return true;
526 }
527
528 bool FakeCommandRunner::WaitForCommand(Result* result) {
529   if (!last_command_)
530     return false;
531
532   Edge* edge = last_command_;
533   result->edge = edge;
534
535   if (edge->rule().name() == "interrupt" ||
536       edge->rule().name() == "touch-interrupt") {
537     result->status = ExitInterrupted;
538     return true;
539   }
540
541   if (edge->rule().name() == "fail")
542     result->status = ExitFailure;
543   else
544     result->status = ExitSuccess;
545   last_command_ = NULL;
546   return true;
547 }
548
549 vector<Edge*> FakeCommandRunner::GetActiveEdges() {
550   vector<Edge*> edges;
551   if (last_command_)
552     edges.push_back(last_command_);
553   return edges;
554 }
555
556 void FakeCommandRunner::Abort() {
557   last_command_ = NULL;
558 }
559
560 void BuildTest::Dirty(const string& path) {
561   Node* node = GetNode(path);
562   node->MarkDirty();
563
564   // If it's an input file, mark that we've already stat()ed it and
565   // it's missing.
566   if (!node->in_edge())
567     node->MarkMissing();
568 }
569
570 TEST_F(BuildTest, NoWork) {
571   string err;
572   EXPECT_TRUE(builder_.AlreadyUpToDate());
573 }
574
575 TEST_F(BuildTest, OneStep) {
576   // Given a dirty target with one ready input,
577   // we should rebuild the target.
578   Dirty("cat1");
579   string err;
580   EXPECT_TRUE(builder_.AddTarget("cat1", &err));
581   ASSERT_EQ("", err);
582   EXPECT_TRUE(builder_.Build(&err));
583   ASSERT_EQ("", err);
584
585   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
586   EXPECT_EQ("cat in1 > cat1", command_runner_.commands_ran_[0]);
587 }
588
589 TEST_F(BuildTest, OneStep2) {
590   // Given a target with one dirty input,
591   // we should rebuild the target.
592   Dirty("cat1");
593   string err;
594   EXPECT_TRUE(builder_.AddTarget("cat1", &err));
595   ASSERT_EQ("", err);
596   EXPECT_TRUE(builder_.Build(&err));
597   EXPECT_EQ("", err);
598
599   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
600   EXPECT_EQ("cat in1 > cat1", command_runner_.commands_ran_[0]);
601 }
602
603 TEST_F(BuildTest, TwoStep) {
604   string err;
605   EXPECT_TRUE(builder_.AddTarget("cat12", &err));
606   ASSERT_EQ("", err);
607   EXPECT_TRUE(builder_.Build(&err));
608   EXPECT_EQ("", err);
609   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
610   // Depending on how the pointers work out, we could've ran
611   // the first two commands in either order.
612   EXPECT_TRUE((command_runner_.commands_ran_[0] == "cat in1 > cat1" &&
613                command_runner_.commands_ran_[1] == "cat in1 in2 > cat2") ||
614               (command_runner_.commands_ran_[1] == "cat in1 > cat1" &&
615                command_runner_.commands_ran_[0] == "cat in1 in2 > cat2"));
616
617   EXPECT_EQ("cat cat1 cat2 > cat12", command_runner_.commands_ran_[2]);
618
619   fs_.Tick();
620
621   // Modifying in2 requires rebuilding one intermediate file
622   // and the final file.
623   fs_.Create("in2", "");
624   state_.Reset();
625   EXPECT_TRUE(builder_.AddTarget("cat12", &err));
626   ASSERT_EQ("", err);
627   EXPECT_TRUE(builder_.Build(&err));
628   ASSERT_EQ("", err);
629   ASSERT_EQ(5u, command_runner_.commands_ran_.size());
630   EXPECT_EQ("cat in1 in2 > cat2", command_runner_.commands_ran_[3]);
631   EXPECT_EQ("cat cat1 cat2 > cat12", command_runner_.commands_ran_[4]);
632 }
633
634 TEST_F(BuildTest, TwoOutputs) {
635   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
636 "rule touch\n"
637 "  command = touch $out\n"
638 "build out1 out2: touch in.txt\n"));
639
640   fs_.Create("in.txt", "");
641
642   string err;
643   EXPECT_TRUE(builder_.AddTarget("out1", &err));
644   ASSERT_EQ("", err);
645   EXPECT_TRUE(builder_.Build(&err));
646   EXPECT_EQ("", err);
647   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
648   EXPECT_EQ("touch out1 out2", command_runner_.commands_ran_[0]);
649 }
650
651 // Test case from
652 //   https://github.com/martine/ninja/issues/148
653 TEST_F(BuildTest, MultiOutIn) {
654   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
655 "rule touch\n"
656 "  command = touch $out\n"
657 "build in1 otherfile: touch in\n"
658 "build out: touch in | in1\n"));
659
660   fs_.Create("in", "");
661   fs_.Tick();
662   fs_.Create("in1", "");
663
664   string err;
665   EXPECT_TRUE(builder_.AddTarget("out", &err));
666   ASSERT_EQ("", err);
667   EXPECT_TRUE(builder_.Build(&err));
668   EXPECT_EQ("", err);
669 }
670
671 TEST_F(BuildTest, Chain) {
672   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
673 "build c2: cat c1\n"
674 "build c3: cat c2\n"
675 "build c4: cat c3\n"
676 "build c5: cat c4\n"));
677
678   fs_.Create("c1", "");
679
680   string err;
681   EXPECT_TRUE(builder_.AddTarget("c5", &err));
682   ASSERT_EQ("", err);
683   EXPECT_TRUE(builder_.Build(&err));
684   EXPECT_EQ("", err);
685   ASSERT_EQ(4u, command_runner_.commands_ran_.size());
686
687   err.clear();
688   command_runner_.commands_ran_.clear();
689   state_.Reset();
690   EXPECT_TRUE(builder_.AddTarget("c5", &err));
691   ASSERT_EQ("", err);
692   EXPECT_TRUE(builder_.AlreadyUpToDate());
693
694   fs_.Tick();
695
696   fs_.Create("c3", "");
697   err.clear();
698   command_runner_.commands_ran_.clear();
699   state_.Reset();
700   EXPECT_TRUE(builder_.AddTarget("c5", &err));
701   ASSERT_EQ("", err);
702   EXPECT_FALSE(builder_.AlreadyUpToDate());
703   EXPECT_TRUE(builder_.Build(&err));
704   ASSERT_EQ(2u, command_runner_.commands_ran_.size());  // 3->4, 4->5
705 }
706
707 TEST_F(BuildTest, MissingInput) {
708   // Input is referenced by build file, but no rule for it.
709   string err;
710   Dirty("in1");
711   EXPECT_FALSE(builder_.AddTarget("cat1", &err));
712   EXPECT_EQ("'in1', needed by 'cat1', missing and no known rule to make it",
713             err);
714 }
715
716 TEST_F(BuildTest, MissingTarget) {
717   // Target is not referenced by build file.
718   string err;
719   EXPECT_FALSE(builder_.AddTarget("meow", &err));
720   EXPECT_EQ("unknown target: 'meow'", err);
721 }
722
723 TEST_F(BuildTest, MakeDirs) {
724   string err;
725
726 #ifdef _WIN32
727   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
728                                       "build subdir\\dir2\\file: cat in1\n"));
729   EXPECT_TRUE(builder_.AddTarget("subdir\\dir2\\file", &err));
730 #else
731   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
732                                       "build subdir/dir2/file: cat in1\n"));
733   EXPECT_TRUE(builder_.AddTarget("subdir/dir2/file", &err));
734 #endif
735
736   EXPECT_EQ("", err);
737   EXPECT_TRUE(builder_.Build(&err));
738   ASSERT_EQ("", err);
739   ASSERT_EQ(2u, fs_.directories_made_.size());
740   EXPECT_EQ("subdir", fs_.directories_made_[0]);
741 #ifdef _WIN32
742   EXPECT_EQ("subdir\\dir2", fs_.directories_made_[1]);
743 #else
744   EXPECT_EQ("subdir/dir2", fs_.directories_made_[1]);
745 #endif
746 }
747
748 TEST_F(BuildTest, DepFileMissing) {
749   string err;
750   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
751 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
752 "build foo.o: cc foo.c\n"));
753   fs_.Create("foo.c", "");
754
755   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
756   ASSERT_EQ("", err);
757   ASSERT_EQ(1u, fs_.files_read_.size());
758   EXPECT_EQ("foo.o.d", fs_.files_read_[0]);
759 }
760
761 TEST_F(BuildTest, DepFileOK) {
762   string err;
763   int orig_edges = state_.edges_.size();
764   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
765 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
766 "build foo.o: cc foo.c\n"));
767   Edge* edge = state_.edges_.back();
768
769   fs_.Create("foo.c", "");
770   GetNode("bar.h")->MarkDirty();  // Mark bar.h as missing.
771   fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
772   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
773   ASSERT_EQ("", err);
774   ASSERT_EQ(1u, fs_.files_read_.size());
775   EXPECT_EQ("foo.o.d", fs_.files_read_[0]);
776
777   // Expect three new edges: one generating foo.o, and two more from
778   // loading the depfile.
779   ASSERT_EQ(orig_edges + 3, (int)state_.edges_.size());
780   // Expect our edge to now have three inputs: foo.c and two headers.
781   ASSERT_EQ(3u, edge->inputs_.size());
782
783   // Expect the command line we generate to only use the original input.
784   ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
785 }
786
787 TEST_F(BuildTest, DepFileParseError) {
788   string err;
789   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
790 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
791 "build foo.o: cc foo.c\n"));
792   fs_.Create("foo.c", "");
793   fs_.Create("foo.o.d", "randomtext\n");
794   EXPECT_FALSE(builder_.AddTarget("foo.o", &err));
795   EXPECT_EQ("expected depfile 'foo.o.d' to mention 'foo.o', got 'randomtext'",
796             err);
797 }
798
799 TEST_F(BuildTest, OrderOnlyDeps) {
800   string err;
801   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
802 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
803 "build foo.o: cc foo.c || otherfile\n"));
804   Edge* edge = state_.edges_.back();
805
806   fs_.Create("foo.c", "");
807   fs_.Create("otherfile", "");
808   fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
809   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
810   ASSERT_EQ("", err);
811
812   // One explicit, two implicit, one order only.
813   ASSERT_EQ(4u, edge->inputs_.size());
814   EXPECT_EQ(2, edge->implicit_deps_);
815   EXPECT_EQ(1, edge->order_only_deps_);
816   // Verify the inputs are in the order we expect
817   // (explicit then implicit then orderonly).
818   EXPECT_EQ("foo.c", edge->inputs_[0]->path());
819   EXPECT_EQ("blah.h", edge->inputs_[1]->path());
820   EXPECT_EQ("bar.h", edge->inputs_[2]->path());
821   EXPECT_EQ("otherfile", edge->inputs_[3]->path());
822
823   // Expect the command line we generate to only use the original input.
824   ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
825
826   // explicit dep dirty, expect a rebuild.
827   EXPECT_TRUE(builder_.Build(&err));
828   ASSERT_EQ("", err);
829   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
830
831   fs_.Tick();
832
833   // Recreate the depfile, as it should have been deleted by the build.
834   fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
835
836   // implicit dep dirty, expect a rebuild.
837   fs_.Create("blah.h", "");
838   fs_.Create("bar.h", "");
839   command_runner_.commands_ran_.clear();
840   state_.Reset();
841   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
842   EXPECT_TRUE(builder_.Build(&err));
843   ASSERT_EQ("", err);
844   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
845
846   fs_.Tick();
847
848   // Recreate the depfile, as it should have been deleted by the build.
849   fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
850
851   // order only dep dirty, no rebuild.
852   fs_.Create("otherfile", "");
853   command_runner_.commands_ran_.clear();
854   state_.Reset();
855   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
856   EXPECT_EQ("", err);
857   EXPECT_TRUE(builder_.AlreadyUpToDate());
858
859   // implicit dep missing, expect rebuild.
860   fs_.RemoveFile("bar.h");
861   command_runner_.commands_ran_.clear();
862   state_.Reset();
863   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
864   EXPECT_TRUE(builder_.Build(&err));
865   ASSERT_EQ("", err);
866   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
867 }
868
869 TEST_F(BuildTest, RebuildOrderOnlyDeps) {
870   string err;
871   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
872 "rule cc\n  command = cc $in\n"
873 "rule true\n  command = true\n"
874 "build oo.h: cc oo.h.in\n"
875 "build foo.o: cc foo.c || oo.h\n"));
876
877   fs_.Create("foo.c", "");
878   fs_.Create("oo.h.in", "");
879
880   // foo.o and order-only dep dirty, build both.
881   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
882   EXPECT_TRUE(builder_.Build(&err));
883   ASSERT_EQ("", err);
884   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
885
886   // all clean, no rebuild.
887   command_runner_.commands_ran_.clear();
888   state_.Reset();
889   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
890   EXPECT_EQ("", err);
891   EXPECT_TRUE(builder_.AlreadyUpToDate());
892
893   // order-only dep missing, build it only.
894   fs_.RemoveFile("oo.h");
895   command_runner_.commands_ran_.clear();
896   state_.Reset();
897   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
898   EXPECT_TRUE(builder_.Build(&err));
899   ASSERT_EQ("", err);
900   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
901   ASSERT_EQ("cc oo.h.in", command_runner_.commands_ran_[0]);
902
903   fs_.Tick();
904
905   // order-only dep dirty, build it only.
906   fs_.Create("oo.h.in", "");
907   command_runner_.commands_ran_.clear();
908   state_.Reset();
909   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
910   EXPECT_TRUE(builder_.Build(&err));
911   ASSERT_EQ("", err);
912   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
913   ASSERT_EQ("cc oo.h.in", command_runner_.commands_ran_[0]);
914 }
915
916 TEST_F(BuildTest, Phony) {
917   string err;
918   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
919 "build out: cat bar.cc\n"
920 "build all: phony out\n"));
921   fs_.Create("bar.cc", "");
922
923   EXPECT_TRUE(builder_.AddTarget("all", &err));
924   ASSERT_EQ("", err);
925
926   // Only one command to run, because phony runs no command.
927   EXPECT_FALSE(builder_.AlreadyUpToDate());
928   EXPECT_TRUE(builder_.Build(&err));
929   ASSERT_EQ("", err);
930   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
931 }
932
933 TEST_F(BuildTest, PhonyNoWork) {
934   string err;
935   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
936 "build out: cat bar.cc\n"
937 "build all: phony out\n"));
938   fs_.Create("bar.cc", "");
939   fs_.Create("out", "");
940
941   EXPECT_TRUE(builder_.AddTarget("all", &err));
942   ASSERT_EQ("", err);
943   EXPECT_TRUE(builder_.AlreadyUpToDate());
944 }
945
946 TEST_F(BuildTest, Fail) {
947   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
948 "rule fail\n"
949 "  command = fail\n"
950 "build out1: fail\n"));
951
952   string err;
953   EXPECT_TRUE(builder_.AddTarget("out1", &err));
954   ASSERT_EQ("", err);
955
956   EXPECT_FALSE(builder_.Build(&err));
957   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
958   ASSERT_EQ("subcommand failed", err);
959 }
960
961 TEST_F(BuildTest, SwallowFailures) {
962   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
963 "rule fail\n"
964 "  command = fail\n"
965 "build out1: fail\n"
966 "build out2: fail\n"
967 "build out3: fail\n"
968 "build all: phony out1 out2 out3\n"));
969
970   // Swallow two failures, die on the third.
971   config_.failures_allowed = 3;
972
973   string err;
974   EXPECT_TRUE(builder_.AddTarget("all", &err));
975   ASSERT_EQ("", err);
976
977   EXPECT_FALSE(builder_.Build(&err));
978   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
979   ASSERT_EQ("subcommands failed", err);
980 }
981
982 TEST_F(BuildTest, SwallowFailuresLimit) {
983   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
984 "rule fail\n"
985 "  command = fail\n"
986 "build out1: fail\n"
987 "build out2: fail\n"
988 "build out3: fail\n"
989 "build final: cat out1 out2 out3\n"));
990
991   // Swallow ten failures; we should stop before building final.
992   config_.failures_allowed = 11;
993
994   string err;
995   EXPECT_TRUE(builder_.AddTarget("final", &err));
996   ASSERT_EQ("", err);
997
998   EXPECT_FALSE(builder_.Build(&err));
999   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1000   ASSERT_EQ("cannot make progress due to previous errors", err);
1001 }
1002
1003 struct BuildWithLogTest : public BuildTest {
1004   BuildWithLogTest() {
1005     builder_.SetBuildLog(&build_log_);
1006   }
1007
1008   BuildLog build_log_;
1009 };
1010
1011 TEST_F(BuildWithLogTest, NotInLogButOnDisk) {
1012   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1013 "rule cc\n"
1014 "  command = cc\n"
1015 "build out1: cc in\n"));
1016
1017   // Create input/output that would be considered up to date when
1018   // not considering the command line hash.
1019   fs_.Create("in", "");
1020   fs_.Create("out1", "");
1021   string err;
1022
1023   // Because it's not in the log, it should not be up-to-date until
1024   // we build again.
1025   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1026   EXPECT_FALSE(builder_.AlreadyUpToDate());
1027
1028   command_runner_.commands_ran_.clear();
1029   state_.Reset();
1030
1031   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1032   EXPECT_TRUE(builder_.Build(&err));
1033   EXPECT_TRUE(builder_.AlreadyUpToDate());
1034 }
1035
1036 TEST_F(BuildWithLogTest, RestatTest) {
1037   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1038 "rule true\n"
1039 "  command = true\n"
1040 "  restat = 1\n"
1041 "rule cc\n"
1042 "  command = cc\n"
1043 "  restat = 1\n"
1044 "build out1: cc in\n"
1045 "build out2: true out1\n"
1046 "build out3: cat out2\n"));
1047
1048   fs_.Create("out1", "");
1049   fs_.Create("out2", "");
1050   fs_.Create("out3", "");
1051
1052   fs_.Tick();
1053
1054   fs_.Create("in", "");
1055
1056   // Do a pre-build so that there's commands in the log for the outputs,
1057   // otherwise, the lack of an entry in the build log will cause out3 to rebuild
1058   // regardless of restat.
1059   string err;
1060   EXPECT_TRUE(builder_.AddTarget("out3", &err));
1061   ASSERT_EQ("", err);
1062   EXPECT_TRUE(builder_.Build(&err));
1063   ASSERT_EQ("", err);
1064   EXPECT_EQ("[3/3]", builder_.status_->FormatProgressStatus("[%s/%t]"));
1065   command_runner_.commands_ran_.clear();
1066   state_.Reset();
1067
1068   fs_.Tick();
1069
1070   fs_.Create("in", "");
1071   // "cc" touches out1, so we should build out2.  But because "true" does not
1072   // touch out2, we should cancel the build of out3.
1073   EXPECT_TRUE(builder_.AddTarget("out3", &err));
1074   ASSERT_EQ("", err);
1075   EXPECT_TRUE(builder_.Build(&err));
1076   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1077
1078   // If we run again, it should be a no-op, because the build log has recorded
1079   // that we've already built out2 with an input timestamp of 2 (from out1).
1080   command_runner_.commands_ran_.clear();
1081   state_.Reset();
1082   EXPECT_TRUE(builder_.AddTarget("out3", &err));
1083   ASSERT_EQ("", err);
1084   EXPECT_TRUE(builder_.AlreadyUpToDate());
1085
1086   fs_.Tick();
1087
1088   fs_.Create("in", "");
1089
1090   // The build log entry should not, however, prevent us from rebuilding out2
1091   // if out1 changes.
1092   command_runner_.commands_ran_.clear();
1093   state_.Reset();
1094   EXPECT_TRUE(builder_.AddTarget("out3", &err));
1095   ASSERT_EQ("", err);
1096   EXPECT_TRUE(builder_.Build(&err));
1097   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1098 }
1099
1100 TEST_F(BuildWithLogTest, RestatMissingFile) {
1101   // If a restat rule doesn't create its output, and the output didn't
1102   // exist before the rule was run, consider that behavior equivalent
1103   // to a rule that doesn't modify its existent output file.
1104
1105   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1106 "rule true\n"
1107 "  command = true\n"
1108 "  restat = 1\n"
1109 "rule cc\n"
1110 "  command = cc\n"
1111 "build out1: true in\n"
1112 "build out2: cc out1\n"));
1113
1114   fs_.Create("in", "");
1115   fs_.Create("out2", "");
1116
1117   // Do a pre-build so that there's commands in the log for the outputs,
1118   // otherwise, the lack of an entry in the build log will cause out2 to rebuild
1119   // regardless of restat.
1120   string err;
1121   EXPECT_TRUE(builder_.AddTarget("out2", &err));
1122   ASSERT_EQ("", err);
1123   EXPECT_TRUE(builder_.Build(&err));
1124   ASSERT_EQ("", err);
1125   command_runner_.commands_ran_.clear();
1126   state_.Reset();
1127
1128   fs_.Tick();
1129   fs_.Create("in", "");
1130   fs_.Create("out2", "");
1131
1132   // Run a build, expect only the first command to run.
1133   // It doesn't touch its output (due to being the "true" command), so
1134   // we shouldn't run the dependent build.
1135   EXPECT_TRUE(builder_.AddTarget("out2", &err));
1136   ASSERT_EQ("", err);
1137   EXPECT_TRUE(builder_.Build(&err));
1138   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1139 }
1140
1141 TEST_F(BuildWithLogTest, RestatSingleDependentOutputDirty) {
1142   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1143     "rule true\n"
1144     "  command = true\n"
1145     "  restat = 1\n"
1146     "rule touch\n"
1147     "  command = touch\n"
1148     "build out1: true in\n"
1149     "build out2 out3: touch out1\n"
1150     "build out4: touch out2\n"
1151     ));
1152
1153   // Create the necessary files
1154   fs_.Create("in", "");
1155
1156   string err;
1157   EXPECT_TRUE(builder_.AddTarget("out4", &err));
1158   ASSERT_EQ("", err);
1159   EXPECT_TRUE(builder_.Build(&err));
1160   ASSERT_EQ("", err);
1161   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1162
1163   fs_.Tick();
1164   fs_.Create("in", "");
1165   fs_.RemoveFile("out3");
1166
1167   // Since "in" is missing, out1 will be built. Since "out3" is missing,
1168   // out2 and out3 will be built even though "in" is not touched when built.
1169   // Then, since out2 is rebuilt, out4 should be rebuilt -- the restat on the
1170   // "true" rule should not lead to the "touch" edge writing out2 and out3 being
1171   // cleard.
1172   command_runner_.commands_ran_.clear();
1173   state_.Reset();
1174   EXPECT_TRUE(builder_.AddTarget("out4", &err));
1175   ASSERT_EQ("", err);
1176   EXPECT_TRUE(builder_.Build(&err));
1177   ASSERT_EQ("", err);
1178   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1179 }
1180
1181 // Test scenario, in which an input file is removed, but output isn't changed
1182 // https://github.com/martine/ninja/issues/295
1183 TEST_F(BuildWithLogTest, RestatMissingInput) {
1184   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1185     "rule true\n"
1186     "  command = true\n"
1187     "  depfile = $out.d\n"
1188     "  restat = 1\n"
1189     "rule cc\n"
1190     "  command = cc\n"
1191     "build out1: true in\n"
1192     "build out2: cc out1\n"));
1193
1194   // Create all necessary files
1195   fs_.Create("in", "");
1196
1197   // The implicit dependencies and the depfile itself
1198   // are newer than the output
1199   TimeStamp restat_mtime = fs_.Tick();
1200   fs_.Create("out1.d", "out1: will.be.deleted restat.file\n");
1201   fs_.Create("will.be.deleted", "");
1202   fs_.Create("restat.file", "");
1203
1204   // Run the build, out1 and out2 get built
1205   string err;
1206   EXPECT_TRUE(builder_.AddTarget("out2", &err));
1207   ASSERT_EQ("", err);
1208   EXPECT_TRUE(builder_.Build(&err));
1209   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1210
1211   // See that an entry in the logfile is created, capturing
1212   // the right mtime
1213   BuildLog::LogEntry* log_entry = build_log_.LookupByOutput("out1");
1214   ASSERT_TRUE(NULL != log_entry);
1215   ASSERT_EQ(restat_mtime, log_entry->restat_mtime);
1216
1217   // Now remove a file, referenced from depfile, so that target becomes
1218   // dirty, but the output does not change
1219   fs_.RemoveFile("will.be.deleted");
1220
1221   // Trigger the build again - only out1 gets built
1222   command_runner_.commands_ran_.clear();
1223   state_.Reset();
1224   EXPECT_TRUE(builder_.AddTarget("out2", &err));
1225   ASSERT_EQ("", err);
1226   EXPECT_TRUE(builder_.Build(&err));
1227   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1228
1229   // Check that the logfile entry remains correctly set
1230   log_entry = build_log_.LookupByOutput("out1");
1231   ASSERT_TRUE(NULL != log_entry);
1232   ASSERT_EQ(restat_mtime, log_entry->restat_mtime);
1233 }
1234
1235 struct BuildDryRun : public BuildWithLogTest {
1236   BuildDryRun() {
1237     config_.dry_run = true;
1238   }
1239 };
1240
1241 TEST_F(BuildDryRun, AllCommandsShown) {
1242   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1243 "rule true\n"
1244 "  command = true\n"
1245 "  restat = 1\n"
1246 "rule cc\n"
1247 "  command = cc\n"
1248 "  restat = 1\n"
1249 "build out1: cc in\n"
1250 "build out2: true out1\n"
1251 "build out3: cat out2\n"));
1252
1253   fs_.Create("out1", "");
1254   fs_.Create("out2", "");
1255   fs_.Create("out3", "");
1256
1257   fs_.Tick();
1258
1259   fs_.Create("in", "");
1260
1261   // "cc" touches out1, so we should build out2.  But because "true" does not
1262   // touch out2, we should cancel the build of out3.
1263   string err;
1264   EXPECT_TRUE(builder_.AddTarget("out3", &err));
1265   ASSERT_EQ("", err);
1266   EXPECT_TRUE(builder_.Build(&err));
1267   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1268 }
1269
1270 // Test that RSP files are created when & where appropriate and deleted after
1271 // successful execution.
1272 TEST_F(BuildTest, RspFileSuccess)
1273 {
1274   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1275     "rule cat_rsp\n"
1276     "  command = cat $rspfile > $out\n"
1277     "  rspfile = $rspfile\n"
1278     "  rspfile_content = $long_command\n"
1279     "build out1: cat in\n"
1280     "build out2: cat_rsp in\n"
1281     "  rspfile = out2.rsp\n"
1282     "  long_command = Some very long command\n"));
1283
1284   fs_.Create("out1", "");
1285   fs_.Create("out2", "");
1286   fs_.Create("out3", "");
1287
1288   fs_.Tick();
1289
1290   fs_.Create("in", "");
1291
1292   string err;
1293   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1294   ASSERT_EQ("", err);
1295   EXPECT_TRUE(builder_.AddTarget("out2", &err));
1296   ASSERT_EQ("", err);
1297
1298   size_t files_created = fs_.files_created_.size();
1299   size_t files_removed = fs_.files_removed_.size();
1300
1301   EXPECT_TRUE(builder_.Build(&err));
1302   ASSERT_EQ(2u, command_runner_.commands_ran_.size()); // cat + cat_rsp
1303
1304   // The RSP file was created
1305   ASSERT_EQ(files_created + 1, fs_.files_created_.size());
1306   ASSERT_EQ(1u, fs_.files_created_.count("out2.rsp"));
1307
1308   // The RSP file was removed
1309   ASSERT_EQ(files_removed + 1, fs_.files_removed_.size());
1310   ASSERT_EQ(1u, fs_.files_removed_.count("out2.rsp"));
1311 }
1312
1313 // Test that RSP file is created but not removed for commands, which fail
1314 TEST_F(BuildTest, RspFileFailure) {
1315   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1316     "rule fail\n"
1317     "  command = fail\n"
1318     "  rspfile = $rspfile\n"
1319     "  rspfile_content = $long_command\n"
1320     "build out: fail in\n"
1321     "  rspfile = out.rsp\n"
1322     "  long_command = Another very long command\n"));
1323
1324   fs_.Create("out", "");
1325   fs_.Tick();
1326   fs_.Create("in", "");
1327
1328   string err;
1329   EXPECT_TRUE(builder_.AddTarget("out", &err));
1330   ASSERT_EQ("", err);
1331
1332   size_t files_created = fs_.files_created_.size();
1333   size_t files_removed = fs_.files_removed_.size();
1334
1335   EXPECT_FALSE(builder_.Build(&err));
1336   ASSERT_EQ("subcommand failed", err);
1337   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1338
1339   // The RSP file was created
1340   ASSERT_EQ(files_created + 1, fs_.files_created_.size());
1341   ASSERT_EQ(1u, fs_.files_created_.count("out.rsp"));
1342
1343   // The RSP file was NOT removed
1344   ASSERT_EQ(files_removed, fs_.files_removed_.size());
1345   ASSERT_EQ(0u, fs_.files_removed_.count("out.rsp"));
1346
1347   // The RSP file contains what it should
1348   ASSERT_EQ("Another very long command", fs_.files_["out.rsp"].contents);
1349 }
1350
1351 // Test that contens of the RSP file behaves like a regular part of
1352 // command line, i.e. triggers a rebuild if changed
1353 TEST_F(BuildWithLogTest, RspFileCmdLineChange) {
1354   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1355     "rule cat_rsp\n"
1356     "  command = cat $rspfile > $out\n"
1357     "  rspfile = $rspfile\n"
1358     "  rspfile_content = $long_command\n"
1359     "build out: cat_rsp in\n"
1360     "  rspfile = out.rsp\n"
1361     "  long_command = Original very long command\n"));
1362
1363   fs_.Create("out", "");
1364   fs_.Tick();
1365   fs_.Create("in", "");
1366
1367   string err;
1368   EXPECT_TRUE(builder_.AddTarget("out", &err));
1369   ASSERT_EQ("", err);
1370
1371   // 1. Build for the 1st time (-> populate log)
1372   EXPECT_TRUE(builder_.Build(&err));
1373   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1374
1375   // 2. Build again (no change)
1376   command_runner_.commands_ran_.clear();
1377   state_.Reset();
1378   EXPECT_TRUE(builder_.AddTarget("out", &err));
1379   EXPECT_EQ("", err);
1380   ASSERT_TRUE(builder_.AlreadyUpToDate());
1381
1382   // 3. Alter the entry in the logfile
1383   // (to simulate a change in the command line between 2 builds)
1384   BuildLog::LogEntry* log_entry = build_log_.LookupByOutput("out");
1385   ASSERT_TRUE(NULL != log_entry);
1386   ASSERT_NO_FATAL_FAILURE(AssertHash(
1387         "cat out.rsp > out;rspfile=Original very long command",
1388         log_entry->command_hash));
1389   log_entry->command_hash++;  // Change the command hash to something else.
1390   // Now expect the target to be rebuilt
1391   command_runner_.commands_ran_.clear();
1392   state_.Reset();
1393   EXPECT_TRUE(builder_.AddTarget("out", &err));
1394   EXPECT_EQ("", err);
1395   EXPECT_TRUE(builder_.Build(&err));
1396   EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1397 }
1398
1399 TEST_F(BuildTest, InterruptCleanup) {
1400   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1401 "rule interrupt\n"
1402 "  command = interrupt\n"
1403 "rule touch-interrupt\n"
1404 "  command = touch-interrupt\n"
1405 "build out1: interrupt in1\n"
1406 "build out2: touch-interrupt in2\n"));
1407
1408   fs_.Create("out1", "");
1409   fs_.Create("out2", "");
1410   fs_.Tick();
1411   fs_.Create("in1", "");
1412   fs_.Create("in2", "");
1413
1414   // An untouched output of an interrupted command should be retained.
1415   string err;
1416   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1417   EXPECT_EQ("", err);
1418   EXPECT_FALSE(builder_.Build(&err));
1419   EXPECT_EQ("interrupted by user", err);
1420   builder_.Cleanup();
1421   EXPECT_GT(fs_.Stat("out1"), 0);
1422   err = "";
1423
1424   // A touched output of an interrupted command should be deleted.
1425   EXPECT_TRUE(builder_.AddTarget("out2", &err));
1426   EXPECT_EQ("", err);
1427   EXPECT_FALSE(builder_.Build(&err));
1428   EXPECT_EQ("interrupted by user", err);
1429   builder_.Cleanup();
1430   EXPECT_EQ(0, fs_.Stat("out2"));
1431 }
1432
1433 TEST_F(BuildTest, PhonyWithNoInputs) {
1434   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1435 "build nonexistent: phony\n"
1436 "build out1: cat || nonexistent\n"
1437 "build out2: cat nonexistent\n"));
1438   fs_.Create("out1", "");
1439   fs_.Create("out2", "");
1440
1441   // out1 should be up to date even though its input is dirty, because its
1442   // order-only dependency has nothing to do.
1443   string err;
1444   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1445   ASSERT_EQ("", err);
1446   EXPECT_TRUE(builder_.AlreadyUpToDate());
1447
1448   // out2 should still be out of date though, because its input is dirty.
1449   err.clear();
1450   command_runner_.commands_ran_.clear();
1451   state_.Reset();
1452   EXPECT_TRUE(builder_.AddTarget("out2", &err));
1453   ASSERT_EQ("", err);
1454   EXPECT_TRUE(builder_.Build(&err));
1455   EXPECT_EQ("", err);
1456   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1457 }
1458
1459 TEST_F(BuildTest, DepsGccWithEmptyDepfileErrorsOut) {
1460   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1461 "rule cc\n"
1462 "  command = cc\n"
1463 "  deps = gcc\n"
1464 "build out: cc\n"));
1465   Dirty("out");
1466
1467   string err;
1468   EXPECT_TRUE(builder_.AddTarget("out", &err));
1469   ASSERT_EQ("", err);
1470   EXPECT_FALSE(builder_.AlreadyUpToDate());
1471
1472   EXPECT_FALSE(builder_.Build(&err));
1473   ASSERT_EQ("subcommand failed", err);
1474   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1475 }
1476
1477 TEST_F(BuildTest, StatusFormatReplacePlaceholder) {
1478   EXPECT_EQ("[%/s0/t0/r0/u0/f0]",
1479             status_.FormatProgressStatus("[%%/s%s/t%t/r%r/u%u/f%f]"));
1480 }
1481
1482 TEST_F(BuildTest, FailedDepsParse) {
1483   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1484 "build bad_deps.o: cat in1\n"
1485 "  deps = gcc\n"
1486 "  depfile = in1.d\n"));
1487
1488   string err;
1489   EXPECT_TRUE(builder_.AddTarget("bad_deps.o", &err));
1490   ASSERT_EQ("", err);
1491
1492   // These deps will fail to parse, as they should only have one
1493   // path to the left of the colon.
1494   fs_.Create("in1.d", "AAA BBB");
1495
1496   EXPECT_FALSE(builder_.Build(&err));
1497   EXPECT_EQ("subcommand failed", err);
1498 }
1499
1500 /// Tests of builds involving deps logs necessarily must span
1501 /// multiple builds.  We reuse methods on BuildTest but not the
1502 /// builder_ it sets up, because we want pristine objects for
1503 /// each build.
1504 struct BuildWithDepsLogTest : public BuildTest {
1505   BuildWithDepsLogTest() {}
1506
1507   virtual void SetUp() {
1508     BuildTest::SetUp();
1509
1510     temp_dir_.CreateAndEnter("BuildWithDepsLogTest");
1511   }
1512
1513   virtual void TearDown() {
1514     temp_dir_.Cleanup();
1515   }
1516
1517   ScopedTempDir temp_dir_;
1518
1519   /// Shadow parent class builder_ so we don't accidentally use it.
1520   void* builder_;
1521 };
1522
1523 /// Run a straightforwad build where the deps log is used.
1524 TEST_F(BuildWithDepsLogTest, Straightforward) {
1525   string err;
1526   // Note: in1 was created by the superclass SetUp().
1527   const char* manifest =
1528       "build out: cat in1\n"
1529       "  deps = gcc\n"
1530       "  depfile = in1.d\n";
1531   {
1532     State state;
1533     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1534     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1535
1536     // Run the build once, everything should be ok.
1537     DepsLog deps_log;
1538     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1539     ASSERT_EQ("", err);
1540
1541     Builder builder(&state, config_, NULL, &deps_log, &fs_);
1542     builder.command_runner_.reset(&command_runner_);
1543     EXPECT_TRUE(builder.AddTarget("out", &err));
1544     ASSERT_EQ("", err);
1545     fs_.Create("in1.d", "out: in2");
1546     EXPECT_TRUE(builder.Build(&err));
1547     EXPECT_EQ("", err);
1548
1549     // The deps file should have been removed.
1550     EXPECT_EQ(0, fs_.Stat("in1.d"));
1551     // Recreate it for the next step.
1552     fs_.Create("in1.d", "out: in2");
1553     deps_log.Close();
1554     builder.command_runner_.release();
1555   }
1556
1557   {
1558     State state;
1559     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1560     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1561
1562     // Touch the file only mentioned in the deps.
1563     fs_.Tick();
1564     fs_.Create("in2", "");
1565
1566     // Run the build again.
1567     DepsLog deps_log;
1568     ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
1569     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1570
1571     Builder builder(&state, config_, NULL, &deps_log, &fs_);
1572     builder.command_runner_.reset(&command_runner_);
1573     command_runner_.commands_ran_.clear();
1574     EXPECT_TRUE(builder.AddTarget("out", &err));
1575     ASSERT_EQ("", err);
1576     EXPECT_TRUE(builder.Build(&err));
1577     EXPECT_EQ("", err);
1578
1579     // We should have rebuilt the output due to in2 being
1580     // out of date.
1581     EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1582
1583     builder.command_runner_.release();
1584   }
1585 }
1586
1587 /// Verify that obsolete dependency info causes a rebuild.
1588 /// 1) Run a successful build where everything has time t, record deps.
1589 /// 2) Move input/output to time t+1 -- despite files in alignment,
1590 ///    should still need to rebuild due to deps at older time.
1591 TEST_F(BuildWithDepsLogTest, ObsoleteDeps) {
1592   string err;
1593   // Note: in1 was created by the superclass SetUp().
1594   const char* manifest =
1595       "build out: cat in1\n"
1596       "  deps = gcc\n"
1597       "  depfile = in1.d\n";
1598   {
1599     // Run an ordinary build that gathers dependencies.
1600     fs_.Create("in1", "");
1601     fs_.Create("in1.d", "out: ");
1602
1603     State state;
1604     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1605     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1606
1607     // Run the build once, everything should be ok.
1608     DepsLog deps_log;
1609     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1610     ASSERT_EQ("", err);
1611
1612     Builder builder(&state, config_, NULL, &deps_log, &fs_);
1613     builder.command_runner_.reset(&command_runner_);
1614     EXPECT_TRUE(builder.AddTarget("out", &err));
1615     ASSERT_EQ("", err);
1616     EXPECT_TRUE(builder.Build(&err));
1617     EXPECT_EQ("", err);
1618
1619     deps_log.Close();
1620     builder.command_runner_.release();
1621   }
1622
1623   // Push all files one tick forward so that only the deps are out
1624   // of date.
1625   fs_.Tick();
1626   fs_.Create("in1", "");
1627   fs_.Create("out", "");
1628
1629   // The deps file should have been removed, so no need to timestamp it.
1630   EXPECT_EQ(0, fs_.Stat("in1.d"));
1631
1632   {
1633     State state;
1634     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1635     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1636
1637     DepsLog deps_log;
1638     ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
1639     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1640
1641     Builder builder(&state, config_, NULL, &deps_log, &fs_);
1642     builder.command_runner_.reset(&command_runner_);
1643     command_runner_.commands_ran_.clear();
1644     EXPECT_TRUE(builder.AddTarget("out", &err));
1645     ASSERT_EQ("", err);
1646
1647     // Recreate the deps file here because the build expects them to exist.
1648     fs_.Create("in1.d", "out: ");
1649
1650     EXPECT_TRUE(builder.Build(&err));
1651     EXPECT_EQ("", err);
1652
1653     // We should have rebuilt the output due to the deps being
1654     // out of date.
1655     EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1656
1657     builder.command_runner_.release();
1658   }
1659 }
1660
1661 TEST_F(BuildWithDepsLogTest, DepsIgnoredInDryRun) {
1662   const char* manifest =
1663       "build out: cat in1\n"
1664       "  deps = gcc\n"
1665       "  depfile = in1.d\n";
1666
1667   fs_.Create("out", "");
1668   fs_.Tick();
1669   fs_.Create("in1", "");
1670
1671   State state;
1672   ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1673   ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1674
1675   // The deps log is NULL in dry runs.
1676   config_.dry_run = true;
1677   Builder builder(&state, config_, NULL, NULL, &fs_);
1678   builder.command_runner_.reset(&command_runner_);
1679   command_runner_.commands_ran_.clear();
1680
1681   string err;
1682   EXPECT_TRUE(builder.AddTarget("out", &err));
1683   ASSERT_EQ("", err);
1684   EXPECT_TRUE(builder.Build(&err));
1685   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1686
1687   builder.command_runner_.release();
1688 }
1689
1690 /// Check that a restat rule generating a header cancels compilations correctly.
1691 TEST_F(BuildTest, RestatDepfileDependency) {
1692   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1693 "rule true\n"
1694 "  command = true\n"  // Would be "write if out-of-date" in reality.
1695 "  restat = 1\n"
1696 "build header.h: true header.in\n"
1697 "build out: cat in1\n"
1698 "  depfile = in1.d\n"));
1699
1700   fs_.Create("header.h", "");
1701   fs_.Create("in1.d", "out: header.h");
1702   fs_.Tick();
1703   fs_.Create("header.in", "");
1704
1705   string err;
1706   EXPECT_TRUE(builder_.AddTarget("out", &err));
1707   ASSERT_EQ("", err);
1708   EXPECT_TRUE(builder_.Build(&err));
1709   EXPECT_EQ("", err);
1710 }
1711
1712 /// Check that a restat rule generating a header cancels compilations correctly,
1713 /// depslog case.
1714 TEST_F(BuildWithDepsLogTest, RestatDepfileDependencyDepsLog) {
1715   string err;
1716   // Note: in1 was created by the superclass SetUp().
1717   const char* manifest =
1718       "rule true\n"
1719       "  command = true\n"  // Would be "write if out-of-date" in reality.
1720       "  restat = 1\n"
1721       "build header.h: true header.in\n"
1722       "build out: cat in1\n"
1723       "  deps = gcc\n"
1724       "  depfile = in1.d\n";
1725   {
1726     State state;
1727     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1728     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1729
1730     // Run the build once, everything should be ok.
1731     DepsLog deps_log;
1732     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1733     ASSERT_EQ("", err);
1734
1735     Builder builder(&state, config_, NULL, &deps_log, &fs_);
1736     builder.command_runner_.reset(&command_runner_);
1737     EXPECT_TRUE(builder.AddTarget("out", &err));
1738     ASSERT_EQ("", err);
1739     fs_.Create("in1.d", "out: header.h");
1740     EXPECT_TRUE(builder.Build(&err));
1741     EXPECT_EQ("", err);
1742
1743     deps_log.Close();
1744     builder.command_runner_.release();
1745   }
1746
1747   {
1748     State state;
1749     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1750     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1751
1752     // Touch the input of the restat rule.
1753     fs_.Tick();
1754     fs_.Create("header.in", "");
1755
1756     // Run the build again.
1757     DepsLog deps_log;
1758     ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
1759     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1760
1761     Builder builder(&state, config_, NULL, &deps_log, &fs_);
1762     builder.command_runner_.reset(&command_runner_);
1763     command_runner_.commands_ran_.clear();
1764     EXPECT_TRUE(builder.AddTarget("out", &err));
1765     ASSERT_EQ("", err);
1766     EXPECT_TRUE(builder.Build(&err));
1767     EXPECT_EQ("", err);
1768
1769     // Rule "true" should have run again, but the build of "out" should have
1770     // been cancelled due to restat propagating through the depfile header.
1771     EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1772
1773     builder.command_runner_.release();
1774   }
1775 }
1776
1777 TEST_F(BuildWithDepsLogTest, DepFileOKDepsLog) {
1778   string err;
1779   const char* manifest =
1780       "rule cc\n  command = cc $in\n  depfile = $out.d\n  deps = gcc\n"
1781       "build foo.o: cc foo.c\n";
1782
1783   fs_.Create("foo.c", "");
1784
1785   {
1786     State state;
1787     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1788
1789     // Run the build once, everything should be ok.
1790     DepsLog deps_log;
1791     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1792     ASSERT_EQ("", err);
1793
1794     Builder builder(&state, config_, NULL, &deps_log, &fs_);
1795     builder.command_runner_.reset(&command_runner_);
1796     EXPECT_TRUE(builder.AddTarget("foo.o", &err));
1797     ASSERT_EQ("", err);
1798     fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
1799     EXPECT_TRUE(builder.Build(&err));
1800     EXPECT_EQ("", err);
1801
1802     deps_log.Close();
1803     builder.command_runner_.release();
1804   }
1805
1806   {
1807     State state;
1808     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1809
1810     DepsLog deps_log;
1811     ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
1812     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1813     ASSERT_EQ("", err);
1814
1815     Builder builder(&state, config_, NULL, &deps_log, &fs_);
1816     builder.command_runner_.reset(&command_runner_);
1817
1818     Edge* edge = state.edges_.back();
1819
1820     state.GetNode("bar.h")->MarkDirty();  // Mark bar.h as missing.
1821     EXPECT_TRUE(builder.AddTarget("foo.o", &err));
1822     ASSERT_EQ("", err);
1823
1824     // Expect three new edges: one generating foo.o, and two more from
1825     // loading the depfile.
1826     ASSERT_EQ(3u, state.edges_.size());
1827     // Expect our edge to now have three inputs: foo.c and two headers.
1828     ASSERT_EQ(3u, edge->inputs_.size());
1829
1830     // Expect the command line we generate to only use the original input.
1831     ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
1832
1833     deps_log.Close();
1834     builder.command_runner_.release();
1835   }
1836 }
1837
1838 /// Check that a restat rule doesn't clear an edge if the depfile is missing.
1839 /// Follows from: https://github.com/martine/ninja/issues/603
1840 TEST_F(BuildTest, RestatMissingDepfile) {
1841 const char* manifest =
1842 "rule true\n"
1843 "  command = true\n"  // Would be "write if out-of-date" in reality.
1844 "  restat = 1\n"
1845 "build header.h: true header.in\n"
1846 "build out: cat header.h\n"
1847 "  depfile = out.d\n";
1848
1849   fs_.Create("header.h", "");
1850   fs_.Tick();
1851   fs_.Create("out", "");
1852   fs_.Create("header.in", "");
1853
1854   // Normally, only 'header.h' would be rebuilt, as
1855   // its rule doesn't touch the output and has 'restat=1' set.
1856   // But we are also missing the depfile for 'out',
1857   // which should force its command to run anyway!
1858   RebuildTarget("out", manifest);
1859   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1860 }
1861
1862 /// Check that a restat rule doesn't clear an edge if the deps are missing.
1863 /// https://github.com/martine/ninja/issues/603
1864 TEST_F(BuildWithDepsLogTest, RestatMissingDepfileDepslog) {
1865   string err;
1866   const char* manifest =
1867 "rule true\n"
1868 "  command = true\n"  // Would be "write if out-of-date" in reality.
1869 "  restat = 1\n"
1870 "build header.h: true header.in\n"
1871 "build out: cat header.h\n"
1872 "  deps = gcc\n"
1873 "  depfile = out.d\n";
1874
1875   // Build once to populate ninja deps logs from out.d
1876   fs_.Create("header.in", "");
1877   fs_.Create("out.d", "out: header.h");
1878   fs_.Create("header.h", "");
1879
1880   RebuildTarget("out", manifest, "build_log", "ninja_deps");
1881   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1882
1883   // Sanity: this rebuild should be NOOP
1884   RebuildTarget("out", manifest, "build_log", "ninja_deps");
1885   ASSERT_EQ(0u, command_runner_.commands_ran_.size());
1886
1887   // Touch 'header.in', blank dependencies log (create a different one).
1888   // Building header.h triggers 'restat' outputs cleanup.
1889   // Validate that out is rebuilt netherless, as deps are missing.
1890   fs_.Tick();
1891   fs_.Create("header.in", "");
1892
1893   // (switch to a new blank deps_log "ninja_deps2")
1894   RebuildTarget("out", manifest, "build_log", "ninja_deps2");
1895   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1896
1897   // Sanity: this build should be NOOP
1898   RebuildTarget("out", manifest, "build_log", "ninja_deps2");
1899   ASSERT_EQ(0u, command_runner_.commands_ran_.size());
1900
1901   // Check that invalidating deps by target timestamp also works here
1902   // Repeat the test but touch target instead of blanking the log.
1903   fs_.Tick();
1904   fs_.Create("header.in", "");
1905   fs_.Create("out", "");
1906   RebuildTarget("out", manifest, "build_log", "ninja_deps2");
1907   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1908
1909   // And this build should be NOOP again
1910   RebuildTarget("out", manifest, "build_log", "ninja_deps2");
1911   ASSERT_EQ(0u, command_runner_.commands_ran_.size());
1912 }