Ninja
build_test.cc
Go to the documentation of this file.
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.
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.
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_;
428 };
429 
432  builder_(&state_, config_, NULL, NULL, &fs_),
433  status_(config_) {
434  }
435 
436  virtual void SetUp() {
437  StateTestWithBuiltinRules::SetUp();
438 
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 
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 
466  BuildConfig config;
467  config.verbosity = BuildConfig::QUIET;
468  return config;
469  }
470 
475 
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 
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 
515  // Only run one at a time.
516  return last_command_ == NULL;
517 }
518 
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 
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 
577  vector<Edge*> edges;
578  if (last_command_)
579  edges.push_back(last_command_);
580  return edges;
581 }
582 
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 
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 {
1033  }
1034 
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 
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.
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 
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.
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 }
FakeCommandRunner command_runner_
Definition: build_test.cc:472
BuildConfig config_
Definition: build_test.cc:471
An implementation of DiskInterface that uses an in-memory representation of disk state.
Definition: test.h:49
CommandRunner is an interface that wraps running the build subcommands.
Definition: build.h:103
Verbosity verbosity
Definition: build.h:133
FakeCommandRunner(VirtualFileSystem *fs)
Definition: build_test.cc:415
BuildLog build_log_
Definition: build_test.cc:1035
int order_only_deps_
Definition: graph.h:182
vector< Edge * > edges_
All the edges of the graph.
Definition: state.h:129
Node * GetNode(const string &path)
Short way to get a Node by its path from state_.
Definition: test.cc:86
int implicit_deps_
Definition: graph.h:181
BuildConfig MakeConfig()
Definition: build_test.cc:465
void TestPoolWithDepthOne(const char *test_case)
Definition: build_test.cc:202
Plan stores the state of a build plan: what we intend to build, which steps we're ready to execute...
Definition: build.h:41
bool more_to_do() const
Returns true if there's more work to be done.
Definition: build.h:54
Node * GetNode(StringPiece path)
Definition: state.cc:114
void * builder_
Shadow parent class builder_ so we don't accidentally use it.
Definition: build_test.cc:1557
The result of waiting for a command.
Definition: build.h:109
StringPiece represents a slice of a string whose memory is managed externally.
Definition: string_piece.h:27
bool AddTarget(Node *node, string *err)
Add a target to our plan (including all its dependencies).
Definition: build.cc:263
Information about a node in the dependency graph: the file, whether it's dirty, mtime, etc.
Definition: graph.h:35
Edge * FindWork()
Definition: build.cc:339
Edge * in_edge() const
Definition: graph.h:80
Fixture for tests involving Plan.
Definition: build_test.cc:25
virtual vector< Edge * > GetActiveEdges()
Definition: build_test.cc:576
int TimeStamp
Definition: timestamp.h:22
void AssertParse(State *state, const char *input)
Definition: test.cc:90
void Create(const string &path, const string &contents)
"Create" a file with contents.
Definition: test.cc:101
An edge in the dependency graph; links between Nodes using Rules.
Definition: graph.h:137
Store a log of every command ran for every build.
Definition: build_log.h:42
string EvaluateCommand(bool incl_rsp_file=false)
Expand all variables in a command and return it as a string.
Definition: graph.cc:273
bool AlreadyUpToDate() const
Returns true if the build targets are already up to date.
Definition: build.cc:591
A base test fixture that includes a State object with a builtin "cat" rule.
Definition: test.h:30
void MarkDirty()
Definition: graph.h:78
void RebuildTarget(const string &target, const char *manifest, const char *log_path=NULL, const char *deps_path=NULL)
Rebuild target in the 'working tree' (fs_).
Definition: build_test.cc:479
Plan plan_
Definition: build_test.cc:26
void EdgeFinished(Edge *edge)
Mark an edge as done building.
Definition: build.cc:370
void AddCatRule(State *state)
Add a "cat" rule to state.
Definition: test.cc:80
vector< Node * > inputs_
Definition: graph.h:162
As build commands run they can output extra dependency information (e.g.
Definition: deps_log.h:66
void FindWorkSorted(deque< Edge * > *ret, int count)
Because FindWork does not return Edges in any sort of predictable order,.
Definition: build_test.cc:31
virtual bool IsPathDead(StringPiece s) const
Return if a given output no longer part of the build manifest.
Definition: build_test.cc:453
bool OpenForWrite(const string &path, const BuildLogUser &user, string *err)
Definition: build_log.cc:111
bool OpenForWrite(const string &path, string *err)
Definition: deps_log.cc:43
TEST_F(PlanTest, Basic)
Definition: build_test.cc:51
Tests of builds involving deps logs necessarily must span multiple builds.
Definition: build_test.cc:1541
virtual bool WaitForCommand(Result *result)
Wait for a command to complete, or return false if interrupted.
Definition: build_test.cc:546
void MarkMissing()
Mark the Node as already-stat()ed and missing.
Definition: graph.h:61
virtual void TearDown()
Definition: build_test.cc:1550
bool Load(const string &path, State *state, string *err)
Definition: deps_log.cc:164
Fake implementation of CommandRunner, useful for tests.
Definition: build_test.cc:414
bool use_console() const
Definition: graph.cc:327
ScopedTempDir temp_dir_
Definition: build_test.cc:1554
ExitStatus status
Definition: build.h:112
virtual void SetUp()
Definition: build_test.cc:436
virtual bool CanRunMore()
Definition: build_test.cc:514
virtual void Abort()
Definition: build_test.cc:583
auto_ptr< CommandRunner > command_runner_
Definition: build.h:179
VirtualFileSystem * fs_
Definition: build_test.cc:427
void SetBuildLog(BuildLog *log)
Used for tests.
Definition: build.h:172
void Close()
Definition: deps_log.cc:158
Builder wraps the build process: starting commands, updating status.
Definition: build.h:143
Tracks the status of a build: completion fraction, printing updates.
Definition: build.h:196
void Cleanup()
Clean up the temporary directory.
Definition: test.cc:169
virtual bool StartCommand(Edge *edge)
Definition: build_test.cc:519
VirtualFileSystem fs_
Definition: build_test.cc:473
void CreateAndEnter(const string &name)
Create a temporary directory and chdir into it.
Definition: test.cc:147
Builder builder_
Definition: build_test.cc:474
Options (e.g. verbosity, parallelism) passed to a build.
Definition: build.h:124
Global state (file status, loaded rules) for a single run.
Definition: state.h:83
const string & name() const
Definition: graph.h:119
void Dirty(const string &path)
Definition: build_test.cc:587
BuildStatus status_
Definition: build_test.cc:476
bool Load(const string &path, string *err)
Load the on-disk log.
Definition: build_log.cc:225
bool Build(string *err)
Run the build.
Definition: build.cc:595
const Rule & rule() const
Definition: graph.h:168
virtual void SetUp()
Definition: build_test.cc:1544
vector< string > commands_ran_
Definition: build_test.cc:425
void AssertHash(const char *expected, uint64_t actual)
Definition: test.cc:97
Node * AddTarget(const string &name, string *err)
Definition: build.cc:565
bool dry_run
Definition: build.h:134
Can answer questions about the manifest for the BuildLog.
Definition: build_log.h:29
vector< Node * > outputs_
Definition: graph.h:163