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