Simplify.
[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   if (!builder.AlreadyUpToDate()) {
491     bool build_res = builder.Build(&err);
492     EXPECT_TRUE(build_res) << "builder.Build(&err)";
493   }
494   builder.command_runner_.release();
495 }
496
497 bool FakeCommandRunner::CanRunMore() {
498   // Only run one at a time.
499   return last_command_ == NULL;
500 }
501
502 bool FakeCommandRunner::StartCommand(Edge* edge) {
503   assert(!last_command_);
504   commands_ran_.push_back(edge->EvaluateCommand());
505   if (edge->rule().name() == "cat"  ||
506       edge->rule().name() == "cat_rsp" ||
507       edge->rule().name() == "cc" ||
508       edge->rule().name() == "touch" ||
509       edge->rule().name() == "touch-interrupt") {
510     for (vector<Node*>::iterator out = edge->outputs_.begin();
511          out != edge->outputs_.end(); ++out) {
512       fs_->Create((*out)->path(), "");
513     }
514   } else if (edge->rule().name() == "true" ||
515              edge->rule().name() == "fail" ||
516              edge->rule().name() == "interrupt") {
517     // Don't do anything.
518   } else {
519     printf("unknown command\n");
520     return false;
521   }
522
523   last_command_ = edge;
524   return true;
525 }
526
527 bool FakeCommandRunner::WaitForCommand(Result* result) {
528   if (!last_command_)
529     return false;
530
531   Edge* edge = last_command_;
532   result->edge = edge;
533
534   if (edge->rule().name() == "interrupt" ||
535       edge->rule().name() == "touch-interrupt") {
536     result->status = ExitInterrupted;
537     return true;
538   }
539
540   if (edge->rule().name() == "fail")
541     result->status = ExitFailure;
542   else
543     result->status = ExitSuccess;
544   last_command_ = NULL;
545   return true;
546 }
547
548 vector<Edge*> FakeCommandRunner::GetActiveEdges() {
549   vector<Edge*> edges;
550   if (last_command_)
551     edges.push_back(last_command_);
552   return edges;
553 }
554
555 void FakeCommandRunner::Abort() {
556   last_command_ = NULL;
557 }
558
559 void BuildTest::Dirty(const string& path) {
560   Node* node = GetNode(path);
561   node->MarkDirty();
562
563   // If it's an input file, mark that we've already stat()ed it and
564   // it's missing.
565   if (!node->in_edge())
566     node->MarkMissing();
567 }
568
569 TEST_F(BuildTest, NoWork) {
570   string err;
571   EXPECT_TRUE(builder_.AlreadyUpToDate());
572 }
573
574 TEST_F(BuildTest, OneStep) {
575   // Given a dirty target with one ready input,
576   // we should rebuild the target.
577   Dirty("cat1");
578   string err;
579   EXPECT_TRUE(builder_.AddTarget("cat1", &err));
580   ASSERT_EQ("", err);
581   EXPECT_TRUE(builder_.Build(&err));
582   ASSERT_EQ("", err);
583
584   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
585   EXPECT_EQ("cat in1 > cat1", command_runner_.commands_ran_[0]);
586 }
587
588 TEST_F(BuildTest, OneStep2) {
589   // Given a target with one dirty input,
590   // we should rebuild the target.
591   Dirty("cat1");
592   string err;
593   EXPECT_TRUE(builder_.AddTarget("cat1", &err));
594   ASSERT_EQ("", err);
595   EXPECT_TRUE(builder_.Build(&err));
596   EXPECT_EQ("", err);
597
598   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
599   EXPECT_EQ("cat in1 > cat1", command_runner_.commands_ran_[0]);
600 }
601
602 TEST_F(BuildTest, TwoStep) {
603   string err;
604   EXPECT_TRUE(builder_.AddTarget("cat12", &err));
605   ASSERT_EQ("", err);
606   EXPECT_TRUE(builder_.Build(&err));
607   EXPECT_EQ("", err);
608   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
609   // Depending on how the pointers work out, we could've ran
610   // the first two commands in either order.
611   EXPECT_TRUE((command_runner_.commands_ran_[0] == "cat in1 > cat1" &&
612                command_runner_.commands_ran_[1] == "cat in1 in2 > cat2") ||
613               (command_runner_.commands_ran_[1] == "cat in1 > cat1" &&
614                command_runner_.commands_ran_[0] == "cat in1 in2 > cat2"));
615
616   EXPECT_EQ("cat cat1 cat2 > cat12", command_runner_.commands_ran_[2]);
617
618   fs_.Tick();
619
620   // Modifying in2 requires rebuilding one intermediate file
621   // and the final file.
622   fs_.Create("in2", "");
623   state_.Reset();
624   EXPECT_TRUE(builder_.AddTarget("cat12", &err));
625   ASSERT_EQ("", err);
626   EXPECT_TRUE(builder_.Build(&err));
627   ASSERT_EQ("", err);
628   ASSERT_EQ(5u, command_runner_.commands_ran_.size());
629   EXPECT_EQ("cat in1 in2 > cat2", command_runner_.commands_ran_[3]);
630   EXPECT_EQ("cat cat1 cat2 > cat12", command_runner_.commands_ran_[4]);
631 }
632
633 TEST_F(BuildTest, TwoOutputs) {
634   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
635 "rule touch\n"
636 "  command = touch $out\n"
637 "build out1 out2: touch in.txt\n"));
638
639   fs_.Create("in.txt", "");
640
641   string err;
642   EXPECT_TRUE(builder_.AddTarget("out1", &err));
643   ASSERT_EQ("", err);
644   EXPECT_TRUE(builder_.Build(&err));
645   EXPECT_EQ("", err);
646   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
647   EXPECT_EQ("touch out1 out2", command_runner_.commands_ran_[0]);
648 }
649
650 // Test case from
651 //   https://github.com/martine/ninja/issues/148
652 TEST_F(BuildTest, MultiOutIn) {
653   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
654 "rule touch\n"
655 "  command = touch $out\n"
656 "build in1 otherfile: touch in\n"
657 "build out: touch in | in1\n"));
658
659   fs_.Create("in", "");
660   fs_.Tick();
661   fs_.Create("in1", "");
662
663   string err;
664   EXPECT_TRUE(builder_.AddTarget("out", &err));
665   ASSERT_EQ("", err);
666   EXPECT_TRUE(builder_.Build(&err));
667   EXPECT_EQ("", err);
668 }
669
670 TEST_F(BuildTest, Chain) {
671   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
672 "build c2: cat c1\n"
673 "build c3: cat c2\n"
674 "build c4: cat c3\n"
675 "build c5: cat c4\n"));
676
677   fs_.Create("c1", "");
678
679   string err;
680   EXPECT_TRUE(builder_.AddTarget("c5", &err));
681   ASSERT_EQ("", err);
682   EXPECT_TRUE(builder_.Build(&err));
683   EXPECT_EQ("", err);
684   ASSERT_EQ(4u, command_runner_.commands_ran_.size());
685
686   err.clear();
687   command_runner_.commands_ran_.clear();
688   state_.Reset();
689   EXPECT_TRUE(builder_.AddTarget("c5", &err));
690   ASSERT_EQ("", err);
691   EXPECT_TRUE(builder_.AlreadyUpToDate());
692
693   fs_.Tick();
694
695   fs_.Create("c3", "");
696   err.clear();
697   command_runner_.commands_ran_.clear();
698   state_.Reset();
699   EXPECT_TRUE(builder_.AddTarget("c5", &err));
700   ASSERT_EQ("", err);
701   EXPECT_FALSE(builder_.AlreadyUpToDate());
702   EXPECT_TRUE(builder_.Build(&err));
703   ASSERT_EQ(2u, command_runner_.commands_ran_.size());  // 3->4, 4->5
704 }
705
706 TEST_F(BuildTest, MissingInput) {
707   // Input is referenced by build file, but no rule for it.
708   string err;
709   Dirty("in1");
710   EXPECT_FALSE(builder_.AddTarget("cat1", &err));
711   EXPECT_EQ("'in1', needed by 'cat1', missing and no known rule to make it",
712             err);
713 }
714
715 TEST_F(BuildTest, MissingTarget) {
716   // Target is not referenced by build file.
717   string err;
718   EXPECT_FALSE(builder_.AddTarget("meow", &err));
719   EXPECT_EQ("unknown target: 'meow'", err);
720 }
721
722 TEST_F(BuildTest, MakeDirs) {
723   string err;
724
725 #ifdef _WIN32
726   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
727                                       "build subdir\\dir2\\file: cat in1\n"));
728   EXPECT_TRUE(builder_.AddTarget("subdir\\dir2\\file", &err));
729 #else
730   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
731                                       "build subdir/dir2/file: cat in1\n"));
732   EXPECT_TRUE(builder_.AddTarget("subdir/dir2/file", &err));
733 #endif
734
735   EXPECT_EQ("", err);
736   EXPECT_TRUE(builder_.Build(&err));
737   ASSERT_EQ("", err);
738   ASSERT_EQ(2u, fs_.directories_made_.size());
739   EXPECT_EQ("subdir", fs_.directories_made_[0]);
740 #ifdef _WIN32
741   EXPECT_EQ("subdir\\dir2", fs_.directories_made_[1]);
742 #else
743   EXPECT_EQ("subdir/dir2", fs_.directories_made_[1]);
744 #endif
745 }
746
747 TEST_F(BuildTest, DepFileMissing) {
748   string err;
749   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
750 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
751 "build foo.o: cc foo.c\n"));
752   fs_.Create("foo.c", "");
753
754   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
755   ASSERT_EQ("", err);
756   ASSERT_EQ(1u, fs_.files_read_.size());
757   EXPECT_EQ("foo.o.d", fs_.files_read_[0]);
758 }
759
760 TEST_F(BuildTest, DepFileOK) {
761   string err;
762   int orig_edges = state_.edges_.size();
763   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
764 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
765 "build foo.o: cc foo.c\n"));
766   Edge* edge = state_.edges_.back();
767
768   fs_.Create("foo.c", "");
769   GetNode("bar.h")->MarkDirty();  // Mark bar.h as missing.
770   fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
771   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
772   ASSERT_EQ("", err);
773   ASSERT_EQ(1u, fs_.files_read_.size());
774   EXPECT_EQ("foo.o.d", fs_.files_read_[0]);
775
776   // Expect three new edges: one generating foo.o, and two more from
777   // loading the depfile.
778   ASSERT_EQ(orig_edges + 3, (int)state_.edges_.size());
779   // Expect our edge to now have three inputs: foo.c and two headers.
780   ASSERT_EQ(3u, edge->inputs_.size());
781
782   // Expect the command line we generate to only use the original input.
783   ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
784 }
785
786 TEST_F(BuildTest, DepFileParseError) {
787   string err;
788   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
789 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
790 "build foo.o: cc foo.c\n"));
791   fs_.Create("foo.c", "");
792   fs_.Create("foo.o.d", "randomtext\n");
793   EXPECT_FALSE(builder_.AddTarget("foo.o", &err));
794   EXPECT_EQ("expected depfile 'foo.o.d' to mention 'foo.o', got 'randomtext'",
795             err);
796 }
797
798 TEST_F(BuildTest, OrderOnlyDeps) {
799   string err;
800   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
801 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
802 "build foo.o: cc foo.c || otherfile\n"));
803   Edge* edge = state_.edges_.back();
804
805   fs_.Create("foo.c", "");
806   fs_.Create("otherfile", "");
807   fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
808   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
809   ASSERT_EQ("", err);
810
811   // One explicit, two implicit, one order only.
812   ASSERT_EQ(4u, edge->inputs_.size());
813   EXPECT_EQ(2, edge->implicit_deps_);
814   EXPECT_EQ(1, edge->order_only_deps_);
815   // Verify the inputs are in the order we expect
816   // (explicit then implicit then orderonly).
817   EXPECT_EQ("foo.c", edge->inputs_[0]->path());
818   EXPECT_EQ("blah.h", edge->inputs_[1]->path());
819   EXPECT_EQ("bar.h", edge->inputs_[2]->path());
820   EXPECT_EQ("otherfile", edge->inputs_[3]->path());
821
822   // Expect the command line we generate to only use the original input.
823   ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
824
825   // explicit dep dirty, expect a rebuild.
826   EXPECT_TRUE(builder_.Build(&err));
827   ASSERT_EQ("", err);
828   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
829
830   fs_.Tick();
831
832   // Recreate the depfile, as it should have been deleted by the build.
833   fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
834
835   // implicit dep dirty, expect a rebuild.
836   fs_.Create("blah.h", "");
837   fs_.Create("bar.h", "");
838   command_runner_.commands_ran_.clear();
839   state_.Reset();
840   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
841   EXPECT_TRUE(builder_.Build(&err));
842   ASSERT_EQ("", err);
843   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
844
845   fs_.Tick();
846
847   // Recreate the depfile, as it should have been deleted by the build.
848   fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
849
850   // order only dep dirty, no rebuild.
851   fs_.Create("otherfile", "");
852   command_runner_.commands_ran_.clear();
853   state_.Reset();
854   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
855   EXPECT_EQ("", err);
856   EXPECT_TRUE(builder_.AlreadyUpToDate());
857
858   // implicit dep missing, expect rebuild.
859   fs_.RemoveFile("bar.h");
860   command_runner_.commands_ran_.clear();
861   state_.Reset();
862   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
863   EXPECT_TRUE(builder_.Build(&err));
864   ASSERT_EQ("", err);
865   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
866 }
867
868 TEST_F(BuildTest, RebuildOrderOnlyDeps) {
869   string err;
870   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
871 "rule cc\n  command = cc $in\n"
872 "rule true\n  command = true\n"
873 "build oo.h: cc oo.h.in\n"
874 "build foo.o: cc foo.c || oo.h\n"));
875
876   fs_.Create("foo.c", "");
877   fs_.Create("oo.h.in", "");
878
879   // foo.o and order-only dep dirty, build both.
880   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
881   EXPECT_TRUE(builder_.Build(&err));
882   ASSERT_EQ("", err);
883   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
884
885   // all clean, no rebuild.
886   command_runner_.commands_ran_.clear();
887   state_.Reset();
888   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
889   EXPECT_EQ("", err);
890   EXPECT_TRUE(builder_.AlreadyUpToDate());
891
892   // order-only dep missing, build it only.
893   fs_.RemoveFile("oo.h");
894   command_runner_.commands_ran_.clear();
895   state_.Reset();
896   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
897   EXPECT_TRUE(builder_.Build(&err));
898   ASSERT_EQ("", err);
899   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
900   ASSERT_EQ("cc oo.h.in", command_runner_.commands_ran_[0]);
901
902   fs_.Tick();
903
904   // order-only dep dirty, build it only.
905   fs_.Create("oo.h.in", "");
906   command_runner_.commands_ran_.clear();
907   state_.Reset();
908   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
909   EXPECT_TRUE(builder_.Build(&err));
910   ASSERT_EQ("", err);
911   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
912   ASSERT_EQ("cc oo.h.in", command_runner_.commands_ran_[0]);
913 }
914
915 TEST_F(BuildTest, Phony) {
916   string err;
917   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
918 "build out: cat bar.cc\n"
919 "build all: phony out\n"));
920   fs_.Create("bar.cc", "");
921
922   EXPECT_TRUE(builder_.AddTarget("all", &err));
923   ASSERT_EQ("", err);
924
925   // Only one command to run, because phony runs no command.
926   EXPECT_FALSE(builder_.AlreadyUpToDate());
927   EXPECT_TRUE(builder_.Build(&err));
928   ASSERT_EQ("", err);
929   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
930 }
931
932 TEST_F(BuildTest, PhonyNoWork) {
933   string err;
934   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
935 "build out: cat bar.cc\n"
936 "build all: phony out\n"));
937   fs_.Create("bar.cc", "");
938   fs_.Create("out", "");
939
940   EXPECT_TRUE(builder_.AddTarget("all", &err));
941   ASSERT_EQ("", err);
942   EXPECT_TRUE(builder_.AlreadyUpToDate());
943 }
944
945 TEST_F(BuildTest, Fail) {
946   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
947 "rule fail\n"
948 "  command = fail\n"
949 "build out1: fail\n"));
950
951   string err;
952   EXPECT_TRUE(builder_.AddTarget("out1", &err));
953   ASSERT_EQ("", err);
954
955   EXPECT_FALSE(builder_.Build(&err));
956   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
957   ASSERT_EQ("subcommand failed", err);
958 }
959
960 TEST_F(BuildTest, SwallowFailures) {
961   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
962 "rule fail\n"
963 "  command = fail\n"
964 "build out1: fail\n"
965 "build out2: fail\n"
966 "build out3: fail\n"
967 "build all: phony out1 out2 out3\n"));
968
969   // Swallow two failures, die on the third.
970   config_.failures_allowed = 3;
971
972   string err;
973   EXPECT_TRUE(builder_.AddTarget("all", &err));
974   ASSERT_EQ("", err);
975
976   EXPECT_FALSE(builder_.Build(&err));
977   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
978   ASSERT_EQ("subcommands failed", err);
979 }
980
981 TEST_F(BuildTest, SwallowFailuresLimit) {
982   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
983 "rule fail\n"
984 "  command = fail\n"
985 "build out1: fail\n"
986 "build out2: fail\n"
987 "build out3: fail\n"
988 "build final: cat out1 out2 out3\n"));
989
990   // Swallow ten failures; we should stop before building final.
991   config_.failures_allowed = 11;
992
993   string err;
994   EXPECT_TRUE(builder_.AddTarget("final", &err));
995   ASSERT_EQ("", err);
996
997   EXPECT_FALSE(builder_.Build(&err));
998   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
999   ASSERT_EQ("cannot make progress due to previous errors", err);
1000 }
1001
1002 struct BuildWithLogTest : public BuildTest {
1003   BuildWithLogTest() {
1004     builder_.SetBuildLog(&build_log_);
1005   }
1006
1007   BuildLog build_log_;
1008 };
1009
1010 TEST_F(BuildWithLogTest, NotInLogButOnDisk) {
1011   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1012 "rule cc\n"
1013 "  command = cc\n"
1014 "build out1: cc in\n"));
1015
1016   // Create input/output that would be considered up to date when
1017   // not considering the command line hash.
1018   fs_.Create("in", "");
1019   fs_.Create("out1", "");
1020   string err;
1021
1022   // Because it's not in the log, it should not be up-to-date until
1023   // we build again.
1024   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1025   EXPECT_FALSE(builder_.AlreadyUpToDate());
1026
1027   command_runner_.commands_ran_.clear();
1028   state_.Reset();
1029
1030   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1031   EXPECT_TRUE(builder_.Build(&err));
1032   EXPECT_TRUE(builder_.AlreadyUpToDate());
1033 }
1034
1035 TEST_F(BuildWithLogTest, RestatTest) {
1036   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1037 "rule true\n"
1038 "  command = true\n"
1039 "  restat = 1\n"
1040 "rule cc\n"
1041 "  command = cc\n"
1042 "  restat = 1\n"
1043 "build out1: cc in\n"
1044 "build out2: true out1\n"
1045 "build out3: cat out2\n"));
1046
1047   fs_.Create("out1", "");
1048   fs_.Create("out2", "");
1049   fs_.Create("out3", "");
1050
1051   fs_.Tick();
1052
1053   fs_.Create("in", "");
1054
1055   // Do a pre-build so that there's commands in the log for the outputs,
1056   // otherwise, the lack of an entry in the build log will cause out3 to rebuild
1057   // regardless of restat.
1058   string err;
1059   EXPECT_TRUE(builder_.AddTarget("out3", &err));
1060   ASSERT_EQ("", err);
1061   EXPECT_TRUE(builder_.Build(&err));
1062   ASSERT_EQ("", err);
1063   EXPECT_EQ("[3/3]", builder_.status_->FormatProgressStatus("[%s/%t]"));
1064   command_runner_.commands_ran_.clear();
1065   state_.Reset();
1066
1067   fs_.Tick();
1068
1069   fs_.Create("in", "");
1070   // "cc" touches out1, so we should build out2.  But because "true" does not
1071   // touch out2, we should cancel the build of out3.
1072   EXPECT_TRUE(builder_.AddTarget("out3", &err));
1073   ASSERT_EQ("", err);
1074   EXPECT_TRUE(builder_.Build(&err));
1075   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1076
1077   // If we run again, it should be a no-op, because the build log has recorded
1078   // that we've already built out2 with an input timestamp of 2 (from out1).
1079   command_runner_.commands_ran_.clear();
1080   state_.Reset();
1081   EXPECT_TRUE(builder_.AddTarget("out3", &err));
1082   ASSERT_EQ("", err);
1083   EXPECT_TRUE(builder_.AlreadyUpToDate());
1084
1085   fs_.Tick();
1086
1087   fs_.Create("in", "");
1088
1089   // The build log entry should not, however, prevent us from rebuilding out2
1090   // if out1 changes.
1091   command_runner_.commands_ran_.clear();
1092   state_.Reset();
1093   EXPECT_TRUE(builder_.AddTarget("out3", &err));
1094   ASSERT_EQ("", err);
1095   EXPECT_TRUE(builder_.Build(&err));
1096   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1097 }
1098
1099 TEST_F(BuildWithLogTest, RestatMissingFile) {
1100   // If a restat rule doesn't create its output, and the output didn't
1101   // exist before the rule was run, consider that behavior equivalent
1102   // to a rule that doesn't modify its existent output file.
1103
1104   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1105 "rule true\n"
1106 "  command = true\n"
1107 "  restat = 1\n"
1108 "rule cc\n"
1109 "  command = cc\n"
1110 "build out1: true in\n"
1111 "build out2: cc out1\n"));
1112
1113   fs_.Create("in", "");
1114   fs_.Create("out2", "");
1115
1116   // Do a pre-build so that there's commands in the log for the outputs,
1117   // otherwise, the lack of an entry in the build log will cause out2 to rebuild
1118   // regardless of restat.
1119   string err;
1120   EXPECT_TRUE(builder_.AddTarget("out2", &err));
1121   ASSERT_EQ("", err);
1122   EXPECT_TRUE(builder_.Build(&err));
1123   ASSERT_EQ("", err);
1124   command_runner_.commands_ran_.clear();
1125   state_.Reset();
1126
1127   fs_.Tick();
1128   fs_.Create("in", "");
1129   fs_.Create("out2", "");
1130
1131   // Run a build, expect only the first command to run.
1132   // It doesn't touch its output (due to being the "true" command), so
1133   // we shouldn't run the dependent build.
1134   EXPECT_TRUE(builder_.AddTarget("out2", &err));
1135   ASSERT_EQ("", err);
1136   EXPECT_TRUE(builder_.Build(&err));
1137   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1138 }
1139
1140 TEST_F(BuildWithLogTest, RestatSingleDependentOutputDirty) {
1141   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1142     "rule true\n"
1143     "  command = true\n"
1144     "  restat = 1\n"
1145     "rule touch\n"
1146     "  command = touch\n"
1147     "build out1: true in\n"
1148     "build out2 out3: touch out1\n"
1149     "build out4: touch out2\n"
1150     ));
1151
1152   // Create the necessary files
1153   fs_.Create("in", "");
1154
1155   string err;
1156   EXPECT_TRUE(builder_.AddTarget("out4", &err));
1157   ASSERT_EQ("", err);
1158   EXPECT_TRUE(builder_.Build(&err));
1159   ASSERT_EQ("", err);
1160   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1161
1162   fs_.Tick();
1163   fs_.Create("in", "");
1164   fs_.RemoveFile("out3");
1165
1166   // Since "in" is missing, out1 will be built. Since "out3" is missing,
1167   // out2 and out3 will be built even though "in" is not touched when built.
1168   // Then, since out2 is rebuilt, out4 should be rebuilt -- the restat on the
1169   // "true" rule should not lead to the "touch" edge writing out2 and out3 being
1170   // cleard.
1171   command_runner_.commands_ran_.clear();
1172   state_.Reset();
1173   EXPECT_TRUE(builder_.AddTarget("out4", &err));
1174   ASSERT_EQ("", err);
1175   EXPECT_TRUE(builder_.Build(&err));
1176   ASSERT_EQ("", err);
1177   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1178 }
1179
1180 // Test scenario, in which an input file is removed, but output isn't changed
1181 // https://github.com/martine/ninja/issues/295
1182 TEST_F(BuildWithLogTest, RestatMissingInput) {
1183   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1184     "rule true\n"
1185     "  command = true\n"
1186     "  depfile = $out.d\n"
1187     "  restat = 1\n"
1188     "rule cc\n"
1189     "  command = cc\n"
1190     "build out1: true in\n"
1191     "build out2: cc out1\n"));
1192
1193   // Create all necessary files
1194   fs_.Create("in", "");
1195
1196   // The implicit dependencies and the depfile itself
1197   // are newer than the output
1198   TimeStamp restat_mtime = fs_.Tick();
1199   fs_.Create("out1.d", "out1: will.be.deleted restat.file\n");
1200   fs_.Create("will.be.deleted", "");
1201   fs_.Create("restat.file", "");
1202
1203   // Run the build, out1 and out2 get built
1204   string err;
1205   EXPECT_TRUE(builder_.AddTarget("out2", &err));
1206   ASSERT_EQ("", err);
1207   EXPECT_TRUE(builder_.Build(&err));
1208   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1209
1210   // See that an entry in the logfile is created, capturing
1211   // the right mtime
1212   BuildLog::LogEntry* log_entry = build_log_.LookupByOutput("out1");
1213   ASSERT_TRUE(NULL != log_entry);
1214   ASSERT_EQ(restat_mtime, log_entry->restat_mtime);
1215
1216   // Now remove a file, referenced from depfile, so that target becomes
1217   // dirty, but the output does not change
1218   fs_.RemoveFile("will.be.deleted");
1219
1220   // Trigger the build again - only out1 gets built
1221   command_runner_.commands_ran_.clear();
1222   state_.Reset();
1223   EXPECT_TRUE(builder_.AddTarget("out2", &err));
1224   ASSERT_EQ("", err);
1225   EXPECT_TRUE(builder_.Build(&err));
1226   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1227
1228   // Check that the logfile entry remains correctly set
1229   log_entry = build_log_.LookupByOutput("out1");
1230   ASSERT_TRUE(NULL != log_entry);
1231   ASSERT_EQ(restat_mtime, log_entry->restat_mtime);
1232 }
1233
1234 struct BuildDryRun : public BuildWithLogTest {
1235   BuildDryRun() {
1236     config_.dry_run = true;
1237   }
1238 };
1239
1240 TEST_F(BuildDryRun, AllCommandsShown) {
1241   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1242 "rule true\n"
1243 "  command = true\n"
1244 "  restat = 1\n"
1245 "rule cc\n"
1246 "  command = cc\n"
1247 "  restat = 1\n"
1248 "build out1: cc in\n"
1249 "build out2: true out1\n"
1250 "build out3: cat out2\n"));
1251
1252   fs_.Create("out1", "");
1253   fs_.Create("out2", "");
1254   fs_.Create("out3", "");
1255
1256   fs_.Tick();
1257
1258   fs_.Create("in", "");
1259
1260   // "cc" touches out1, so we should build out2.  But because "true" does not
1261   // touch out2, we should cancel the build of out3.
1262   string err;
1263   EXPECT_TRUE(builder_.AddTarget("out3", &err));
1264   ASSERT_EQ("", err);
1265   EXPECT_TRUE(builder_.Build(&err));
1266   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1267 }
1268
1269 // Test that RSP files are created when & where appropriate and deleted after
1270 // successful execution.
1271 TEST_F(BuildTest, RspFileSuccess)
1272 {
1273   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1274     "rule cat_rsp\n"
1275     "  command = cat $rspfile > $out\n"
1276     "  rspfile = $rspfile\n"
1277     "  rspfile_content = $long_command\n"
1278     "build out1: cat in\n"
1279     "build out2: cat_rsp in\n"
1280     "  rspfile = out2.rsp\n"
1281     "  long_command = Some very long command\n"));
1282
1283   fs_.Create("out1", "");
1284   fs_.Create("out2", "");
1285   fs_.Create("out3", "");
1286
1287   fs_.Tick();
1288
1289   fs_.Create("in", "");
1290
1291   string err;
1292   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1293   ASSERT_EQ("", err);
1294   EXPECT_TRUE(builder_.AddTarget("out2", &err));
1295   ASSERT_EQ("", err);
1296
1297   size_t files_created = fs_.files_created_.size();
1298   size_t files_removed = fs_.files_removed_.size();
1299
1300   EXPECT_TRUE(builder_.Build(&err));
1301   ASSERT_EQ(2u, command_runner_.commands_ran_.size()); // cat + cat_rsp
1302
1303   // The RSP file was created
1304   ASSERT_EQ(files_created + 1, fs_.files_created_.size());
1305   ASSERT_EQ(1u, fs_.files_created_.count("out2.rsp"));
1306
1307   // The RSP file was removed
1308   ASSERT_EQ(files_removed + 1, fs_.files_removed_.size());
1309   ASSERT_EQ(1u, fs_.files_removed_.count("out2.rsp"));
1310 }
1311
1312 // Test that RSP file is created but not removed for commands, which fail
1313 TEST_F(BuildTest, RspFileFailure) {
1314   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1315     "rule fail\n"
1316     "  command = fail\n"
1317     "  rspfile = $rspfile\n"
1318     "  rspfile_content = $long_command\n"
1319     "build out: fail in\n"
1320     "  rspfile = out.rsp\n"
1321     "  long_command = Another very long command\n"));
1322
1323   fs_.Create("out", "");
1324   fs_.Tick();
1325   fs_.Create("in", "");
1326
1327   string err;
1328   EXPECT_TRUE(builder_.AddTarget("out", &err));
1329   ASSERT_EQ("", err);
1330
1331   size_t files_created = fs_.files_created_.size();
1332   size_t files_removed = fs_.files_removed_.size();
1333
1334   EXPECT_FALSE(builder_.Build(&err));
1335   ASSERT_EQ("subcommand failed", err);
1336   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1337
1338   // The RSP file was created
1339   ASSERT_EQ(files_created + 1, fs_.files_created_.size());
1340   ASSERT_EQ(1u, fs_.files_created_.count("out.rsp"));
1341
1342   // The RSP file was NOT removed
1343   ASSERT_EQ(files_removed, fs_.files_removed_.size());
1344   ASSERT_EQ(0u, fs_.files_removed_.count("out.rsp"));
1345
1346   // The RSP file contains what it should
1347   ASSERT_EQ("Another very long command", fs_.files_["out.rsp"].contents);
1348 }
1349
1350 // Test that contens of the RSP file behaves like a regular part of
1351 // command line, i.e. triggers a rebuild if changed
1352 TEST_F(BuildWithLogTest, RspFileCmdLineChange) {
1353   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1354     "rule cat_rsp\n"
1355     "  command = cat $rspfile > $out\n"
1356     "  rspfile = $rspfile\n"
1357     "  rspfile_content = $long_command\n"
1358     "build out: cat_rsp in\n"
1359     "  rspfile = out.rsp\n"
1360     "  long_command = Original very long command\n"));
1361
1362   fs_.Create("out", "");
1363   fs_.Tick();
1364   fs_.Create("in", "");
1365
1366   string err;
1367   EXPECT_TRUE(builder_.AddTarget("out", &err));
1368   ASSERT_EQ("", err);
1369
1370   // 1. Build for the 1st time (-> populate log)
1371   EXPECT_TRUE(builder_.Build(&err));
1372   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1373
1374   // 2. Build again (no change)
1375   command_runner_.commands_ran_.clear();
1376   state_.Reset();
1377   EXPECT_TRUE(builder_.AddTarget("out", &err));
1378   EXPECT_EQ("", err);
1379   ASSERT_TRUE(builder_.AlreadyUpToDate());
1380
1381   // 3. Alter the entry in the logfile
1382   // (to simulate a change in the command line between 2 builds)
1383   BuildLog::LogEntry* log_entry = build_log_.LookupByOutput("out");
1384   ASSERT_TRUE(NULL != log_entry);
1385   ASSERT_NO_FATAL_FAILURE(AssertHash(
1386         "cat out.rsp > out;rspfile=Original very long command",
1387         log_entry->command_hash));
1388   log_entry->command_hash++;  // Change the command hash to something else.
1389   // Now expect the target to be rebuilt
1390   command_runner_.commands_ran_.clear();
1391   state_.Reset();
1392   EXPECT_TRUE(builder_.AddTarget("out", &err));
1393   EXPECT_EQ("", err);
1394   EXPECT_TRUE(builder_.Build(&err));
1395   EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1396 }
1397
1398 TEST_F(BuildTest, InterruptCleanup) {
1399   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1400 "rule interrupt\n"
1401 "  command = interrupt\n"
1402 "rule touch-interrupt\n"
1403 "  command = touch-interrupt\n"
1404 "build out1: interrupt in1\n"
1405 "build out2: touch-interrupt in2\n"));
1406
1407   fs_.Create("out1", "");
1408   fs_.Create("out2", "");
1409   fs_.Tick();
1410   fs_.Create("in1", "");
1411   fs_.Create("in2", "");
1412
1413   // An untouched output of an interrupted command should be retained.
1414   string err;
1415   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1416   EXPECT_EQ("", err);
1417   EXPECT_FALSE(builder_.Build(&err));
1418   EXPECT_EQ("interrupted by user", err);
1419   builder_.Cleanup();
1420   EXPECT_GT(fs_.Stat("out1"), 0);
1421   err = "";
1422
1423   // A touched output of an interrupted command should be deleted.
1424   EXPECT_TRUE(builder_.AddTarget("out2", &err));
1425   EXPECT_EQ("", err);
1426   EXPECT_FALSE(builder_.Build(&err));
1427   EXPECT_EQ("interrupted by user", err);
1428   builder_.Cleanup();
1429   EXPECT_EQ(0, fs_.Stat("out2"));
1430 }
1431
1432 TEST_F(BuildTest, PhonyWithNoInputs) {
1433   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1434 "build nonexistent: phony\n"
1435 "build out1: cat || nonexistent\n"
1436 "build out2: cat nonexistent\n"));
1437   fs_.Create("out1", "");
1438   fs_.Create("out2", "");
1439
1440   // out1 should be up to date even though its input is dirty, because its
1441   // order-only dependency has nothing to do.
1442   string err;
1443   EXPECT_TRUE(builder_.AddTarget("out1", &err));
1444   ASSERT_EQ("", err);
1445   EXPECT_TRUE(builder_.AlreadyUpToDate());
1446
1447   // out2 should still be out of date though, because its input is dirty.
1448   err.clear();
1449   command_runner_.commands_ran_.clear();
1450   state_.Reset();
1451   EXPECT_TRUE(builder_.AddTarget("out2", &err));
1452   ASSERT_EQ("", err);
1453   EXPECT_TRUE(builder_.Build(&err));
1454   EXPECT_EQ("", err);
1455   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1456 }
1457
1458 TEST_F(BuildTest, DepsGccWithEmptyDepfileErrorsOut) {
1459   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1460 "rule cc\n"
1461 "  command = cc\n"
1462 "  deps = gcc\n"
1463 "build out: cc\n"));
1464   Dirty("out");
1465
1466   string err;
1467   EXPECT_TRUE(builder_.AddTarget("out", &err));
1468   ASSERT_EQ("", err);
1469   EXPECT_FALSE(builder_.AlreadyUpToDate());
1470
1471   EXPECT_FALSE(builder_.Build(&err));
1472   ASSERT_EQ("subcommand failed", err);
1473   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1474 }
1475
1476 TEST_F(BuildTest, StatusFormatReplacePlaceholder) {
1477   EXPECT_EQ("[%/s0/t0/r0/u0/f0]",
1478             status_.FormatProgressStatus("[%%/s%s/t%t/r%r/u%u/f%f]"));
1479 }
1480
1481 TEST_F(BuildTest, FailedDepsParse) {
1482   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1483 "build bad_deps.o: cat in1\n"
1484 "  deps = gcc\n"
1485 "  depfile = in1.d\n"));
1486
1487   string err;
1488   EXPECT_TRUE(builder_.AddTarget("bad_deps.o", &err));
1489   ASSERT_EQ("", err);
1490
1491   // These deps will fail to parse, as they should only have one
1492   // path to the left of the colon.
1493   fs_.Create("in1.d", "AAA BBB");
1494
1495   EXPECT_FALSE(builder_.Build(&err));
1496   EXPECT_EQ("subcommand failed", err);
1497 }
1498
1499 /// Tests of builds involving deps logs necessarily must span
1500 /// multiple builds.  We reuse methods on BuildTest but not the
1501 /// builder_ it sets up, because we want pristine objects for
1502 /// each build.
1503 struct BuildWithDepsLogTest : public BuildTest {
1504   BuildWithDepsLogTest() {}
1505
1506   virtual void SetUp() {
1507     BuildTest::SetUp();
1508
1509     temp_dir_.CreateAndEnter("BuildWithDepsLogTest");
1510   }
1511
1512   virtual void TearDown() {
1513     temp_dir_.Cleanup();
1514   }
1515
1516   ScopedTempDir temp_dir_;
1517
1518   /// Shadow parent class builder_ so we don't accidentally use it.
1519   void* builder_;
1520 };
1521
1522 /// Run a straightforwad build where the deps log is used.
1523 TEST_F(BuildWithDepsLogTest, Straightforward) {
1524   string err;
1525   // Note: in1 was created by the superclass SetUp().
1526   const char* manifest =
1527       "build out: cat in1\n"
1528       "  deps = gcc\n"
1529       "  depfile = in1.d\n";
1530   {
1531     State state;
1532     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1533     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1534
1535     // Run the build once, everything should be ok.
1536     DepsLog deps_log;
1537     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1538     ASSERT_EQ("", err);
1539
1540     Builder builder(&state, config_, NULL, &deps_log, &fs_);
1541     builder.command_runner_.reset(&command_runner_);
1542     EXPECT_TRUE(builder.AddTarget("out", &err));
1543     ASSERT_EQ("", err);
1544     fs_.Create("in1.d", "out: in2");
1545     EXPECT_TRUE(builder.Build(&err));
1546     EXPECT_EQ("", err);
1547
1548     // The deps file should have been removed.
1549     EXPECT_EQ(0, fs_.Stat("in1.d"));
1550     // Recreate it for the next step.
1551     fs_.Create("in1.d", "out: in2");
1552     deps_log.Close();
1553     builder.command_runner_.release();
1554   }
1555
1556   {
1557     State state;
1558     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1559     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1560
1561     // Touch the file only mentioned in the deps.
1562     fs_.Tick();
1563     fs_.Create("in2", "");
1564
1565     // Run the build again.
1566     DepsLog deps_log;
1567     ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
1568     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1569
1570     Builder builder(&state, config_, NULL, &deps_log, &fs_);
1571     builder.command_runner_.reset(&command_runner_);
1572     command_runner_.commands_ran_.clear();
1573     EXPECT_TRUE(builder.AddTarget("out", &err));
1574     ASSERT_EQ("", err);
1575     EXPECT_TRUE(builder.Build(&err));
1576     EXPECT_EQ("", err);
1577
1578     // We should have rebuilt the output due to in2 being
1579     // out of date.
1580     EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1581
1582     builder.command_runner_.release();
1583   }
1584 }
1585
1586 /// Verify that obsolete dependency info causes a rebuild.
1587 /// 1) Run a successful build where everything has time t, record deps.
1588 /// 2) Move input/output to time t+1 -- despite files in alignment,
1589 ///    should still need to rebuild due to deps at older time.
1590 TEST_F(BuildWithDepsLogTest, ObsoleteDeps) {
1591   string err;
1592   // Note: in1 was created by the superclass SetUp().
1593   const char* manifest =
1594       "build out: cat in1\n"
1595       "  deps = gcc\n"
1596       "  depfile = in1.d\n";
1597   {
1598     // Run an ordinary build that gathers dependencies.
1599     fs_.Create("in1", "");
1600     fs_.Create("in1.d", "out: ");
1601
1602     State state;
1603     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1604     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1605
1606     // Run the build once, everything should be ok.
1607     DepsLog deps_log;
1608     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1609     ASSERT_EQ("", err);
1610
1611     Builder builder(&state, config_, NULL, &deps_log, &fs_);
1612     builder.command_runner_.reset(&command_runner_);
1613     EXPECT_TRUE(builder.AddTarget("out", &err));
1614     ASSERT_EQ("", err);
1615     EXPECT_TRUE(builder.Build(&err));
1616     EXPECT_EQ("", err);
1617
1618     deps_log.Close();
1619     builder.command_runner_.release();
1620   }
1621
1622   // Push all files one tick forward so that only the deps are out
1623   // of date.
1624   fs_.Tick();
1625   fs_.Create("in1", "");
1626   fs_.Create("out", "");
1627
1628   // The deps file should have been removed, so no need to timestamp it.
1629   EXPECT_EQ(0, fs_.Stat("in1.d"));
1630
1631   {
1632     State state;
1633     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1634     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1635
1636     DepsLog deps_log;
1637     ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
1638     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1639
1640     Builder builder(&state, config_, NULL, &deps_log, &fs_);
1641     builder.command_runner_.reset(&command_runner_);
1642     command_runner_.commands_ran_.clear();
1643     EXPECT_TRUE(builder.AddTarget("out", &err));
1644     ASSERT_EQ("", err);
1645
1646     // Recreate the deps file here because the build expects them to exist.
1647     fs_.Create("in1.d", "out: ");
1648
1649     EXPECT_TRUE(builder.Build(&err));
1650     EXPECT_EQ("", err);
1651
1652     // We should have rebuilt the output due to the deps being
1653     // out of date.
1654     EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1655
1656     builder.command_runner_.release();
1657   }
1658 }
1659
1660 TEST_F(BuildWithDepsLogTest, DepsIgnoredInDryRun) {
1661   const char* manifest =
1662       "build out: cat in1\n"
1663       "  deps = gcc\n"
1664       "  depfile = in1.d\n";
1665
1666   fs_.Create("out", "");
1667   fs_.Tick();
1668   fs_.Create("in1", "");
1669
1670   State state;
1671   ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1672   ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1673
1674   // The deps log is NULL in dry runs.
1675   config_.dry_run = true;
1676   Builder builder(&state, config_, NULL, NULL, &fs_);
1677   builder.command_runner_.reset(&command_runner_);
1678   command_runner_.commands_ran_.clear();
1679
1680   string err;
1681   EXPECT_TRUE(builder.AddTarget("out", &err));
1682   ASSERT_EQ("", err);
1683   EXPECT_TRUE(builder.Build(&err));
1684   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1685
1686   builder.command_runner_.release();
1687 }
1688
1689 /// Check that a restat rule generating a header cancels compilations correctly.
1690 TEST_F(BuildTest, RestatDepfileDependency) {
1691   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1692 "rule true\n"
1693 "  command = true\n"  // Would be "write if out-of-date" in reality.
1694 "  restat = 1\n"
1695 "build header.h: true header.in\n"
1696 "build out: cat in1\n"
1697 "  depfile = in1.d\n"));
1698
1699   fs_.Create("header.h", "");
1700   fs_.Create("in1.d", "out: header.h");
1701   fs_.Tick();
1702   fs_.Create("header.in", "");
1703
1704   string err;
1705   EXPECT_TRUE(builder_.AddTarget("out", &err));
1706   ASSERT_EQ("", err);
1707   EXPECT_TRUE(builder_.Build(&err));
1708   EXPECT_EQ("", err);
1709 }
1710
1711 /// Check that a restat rule generating a header cancels compilations correctly,
1712 /// depslog case.
1713 TEST_F(BuildWithDepsLogTest, RestatDepfileDependencyDepsLog) {
1714   string err;
1715   // Note: in1 was created by the superclass SetUp().
1716   const char* manifest =
1717       "rule true\n"
1718       "  command = true\n"  // Would be "write if out-of-date" in reality.
1719       "  restat = 1\n"
1720       "build header.h: true header.in\n"
1721       "build out: cat in1\n"
1722       "  deps = gcc\n"
1723       "  depfile = in1.d\n";
1724   {
1725     State state;
1726     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1727     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1728
1729     // Run the build once, everything should be ok.
1730     DepsLog deps_log;
1731     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1732     ASSERT_EQ("", err);
1733
1734     Builder builder(&state, config_, NULL, &deps_log, &fs_);
1735     builder.command_runner_.reset(&command_runner_);
1736     EXPECT_TRUE(builder.AddTarget("out", &err));
1737     ASSERT_EQ("", err);
1738     fs_.Create("in1.d", "out: header.h");
1739     EXPECT_TRUE(builder.Build(&err));
1740     EXPECT_EQ("", err);
1741
1742     deps_log.Close();
1743     builder.command_runner_.release();
1744   }
1745
1746   {
1747     State state;
1748     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1749     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1750
1751     // Touch the input of the restat rule.
1752     fs_.Tick();
1753     fs_.Create("header.in", "");
1754
1755     // Run the build again.
1756     DepsLog deps_log;
1757     ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
1758     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1759
1760     Builder builder(&state, config_, NULL, &deps_log, &fs_);
1761     builder.command_runner_.reset(&command_runner_);
1762     command_runner_.commands_ran_.clear();
1763     EXPECT_TRUE(builder.AddTarget("out", &err));
1764     ASSERT_EQ("", err);
1765     EXPECT_TRUE(builder.Build(&err));
1766     EXPECT_EQ("", err);
1767
1768     // Rule "true" should have run again, but the build of "out" should have
1769     // been cancelled due to restat propagating through the depfile header.
1770     EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1771
1772     builder.command_runner_.release();
1773   }
1774 }
1775
1776 TEST_F(BuildWithDepsLogTest, DepFileOKDepsLog) {
1777   string err;
1778   const char* manifest =
1779       "rule cc\n  command = cc $in\n  depfile = $out.d\n  deps = gcc\n"
1780       "build foo.o: cc foo.c\n";
1781
1782   fs_.Create("foo.c", "");
1783
1784   {
1785     State state;
1786     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1787
1788     // Run the build once, everything should be ok.
1789     DepsLog deps_log;
1790     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1791     ASSERT_EQ("", err);
1792
1793     Builder builder(&state, config_, NULL, &deps_log, &fs_);
1794     builder.command_runner_.reset(&command_runner_);
1795     EXPECT_TRUE(builder.AddTarget("foo.o", &err));
1796     ASSERT_EQ("", err);
1797     fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
1798     EXPECT_TRUE(builder.Build(&err));
1799     EXPECT_EQ("", err);
1800
1801     deps_log.Close();
1802     builder.command_runner_.release();
1803   }
1804
1805   {
1806     State state;
1807     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1808
1809     DepsLog deps_log;
1810     ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
1811     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1812     ASSERT_EQ("", err);
1813
1814     Builder builder(&state, config_, NULL, &deps_log, &fs_);
1815     builder.command_runner_.reset(&command_runner_);
1816
1817     Edge* edge = state.edges_.back();
1818
1819     state.GetNode("bar.h")->MarkDirty();  // Mark bar.h as missing.
1820     EXPECT_TRUE(builder.AddTarget("foo.o", &err));
1821     ASSERT_EQ("", err);
1822
1823     // Expect three new edges: one generating foo.o, and two more from
1824     // loading the depfile.
1825     ASSERT_EQ(3u, state.edges_.size());
1826     // Expect our edge to now have three inputs: foo.c and two headers.
1827     ASSERT_EQ(3u, edge->inputs_.size());
1828
1829     // Expect the command line we generate to only use the original input.
1830     ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
1831
1832     deps_log.Close();
1833     builder.command_runner_.release();
1834   }
1835 }
1836
1837 /// Check that a restat rule doesn't clear an edge if the depfile is missing.
1838 /// Follows from: https://github.com/martine/ninja/issues/603
1839 TEST_F(BuildTest, RestatMissingDepfile) {
1840 const char* manifest =
1841 "rule true\n"
1842 "  command = true\n"  // Would be "write if out-of-date" in reality.
1843 "  restat = 1\n"
1844 "build header.h: true header.in\n"
1845 "build out: cat header.h\n"
1846 "  depfile = out.d\n";
1847
1848   fs_.Create("header.h", "");
1849   fs_.Tick();
1850   fs_.Create("out", "");
1851   fs_.Create("header.in", "");
1852
1853   // Normally, only 'header.h' would be rebuilt, as
1854   // its rule doesn't touch the output and has 'restat=1' set.
1855   // But we are also missing the depfile for 'out',
1856   // which should force its command to run anyway!
1857   RebuildTarget("out", manifest);
1858   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1859 }
1860
1861 /// Check that a restat rule doesn't clear an edge if the deps are missing.
1862 /// https://github.com/martine/ninja/issues/603
1863 TEST_F(BuildWithDepsLogTest, RestatMissingDepfileDepslog) {
1864   string err;
1865   const char* manifest =
1866 "rule true\n"
1867 "  command = true\n"  // Would be "write if out-of-date" in reality.
1868 "  restat = 1\n"
1869 "build header.h: true header.in\n"
1870 "build out: cat header.h\n"
1871 "  deps = gcc\n"
1872 "  depfile = out.d\n";
1873
1874   // Build once to populate ninja deps logs from out.d
1875   fs_.Create("header.in", "");
1876   fs_.Create("out.d", "out: header.h");
1877   fs_.Create("header.h", "");
1878
1879   RebuildTarget("out", manifest, "build_log", "ninja_deps");
1880   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1881
1882   // Sanity: this rebuild should be NOOP
1883   RebuildTarget("out", manifest, "build_log", "ninja_deps");
1884   ASSERT_EQ(0u, command_runner_.commands_ran_.size());
1885
1886   // Touch 'header.in', blank dependencies log (create a different one).
1887   // Building header.h triggers 'restat' outputs cleanup.
1888   // Validate that out is rebuilt netherless, as deps are missing.
1889   fs_.Tick();
1890   fs_.Create("header.in", "");
1891
1892   // (switch to a new blank deps_log "ninja_deps2")
1893   RebuildTarget("out", manifest, "build_log", "ninja_deps2");
1894   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1895
1896   // Sanity: this build should be NOOP
1897   RebuildTarget("out", manifest, "build_log", "ninja_deps2");
1898   ASSERT_EQ(0u, command_runner_.commands_ran_.size());
1899
1900   // Check that invalidating deps by target timestamp also works here
1901   // Repeat the test but touch target instead of blanking the log.
1902   fs_.Tick();
1903   fs_.Create("header.in", "");
1904   fs_.Create("out", "");
1905   RebuildTarget("out", manifest, "build_log", "ninja_deps2");
1906   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1907
1908   // And this build should be NOOP again
1909   RebuildTarget("out", manifest, "build_log", "ninja_deps2");
1910   ASSERT_EQ(0u, command_runner_.commands_ran_.size());
1911 }