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