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 <assert.h>
18 
19 #include "build_log.h"
20 #include "deps_log.h"
21 #include "graph.h"
22 #include "status.h"
23 #include "test.h"
24 
25 using namespace std;
26 
28  static bool cmp(const Edge* a, const Edge* b) {
29  return a->outputs_[0]->path() < b->outputs_[0]->path();
30  }
31 };
32 
33 /// Fixture for tests involving Plan.
34 // Though Plan doesn't use State, it's useful to have one around
35 // to create Nodes and Edges.
38 
39  /// Because FindWork does not return Edges in any sort of predictable order,
40  // provide a means to get available Edges in order and in a format which is
41  // easy to write tests around.
42  void FindWorkSorted(deque<Edge*>* ret, int count) {
43  for (int i = 0; i < count; ++i) {
44  ASSERT_TRUE(plan_.more_to_do());
45  Edge* edge = plan_.FindWork();
46  ASSERT_TRUE(edge);
47  ret->push_back(edge);
48  }
49  ASSERT_FALSE(plan_.FindWork());
50  sort(ret->begin(), ret->end(), CompareEdgesByOutput::cmp);
51  }
52 
53  void TestPoolWithDepthOne(const char *test_case);
54 };
55 
56 TEST_F(PlanTest, Basic) {
58 "build out: cat mid\n"
59 "build mid: cat in\n"));
60  GetNode("mid")->MarkDirty();
61  GetNode("out")->MarkDirty();
62  string err;
63  EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
64  ASSERT_EQ("", err);
65  ASSERT_TRUE(plan_.more_to_do());
66 
67  Edge* edge = plan_.FindWork();
68  ASSERT_TRUE(edge);
69  ASSERT_EQ("in", edge->inputs_[0]->path());
70  ASSERT_EQ("mid", edge->outputs_[0]->path());
71 
72  ASSERT_FALSE(plan_.FindWork());
73 
74  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
75  ASSERT_EQ("", err);
76 
77  edge = plan_.FindWork();
78  ASSERT_TRUE(edge);
79  ASSERT_EQ("mid", edge->inputs_[0]->path());
80  ASSERT_EQ("out", edge->outputs_[0]->path());
81 
82  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
83  ASSERT_EQ("", err);
84 
85  ASSERT_FALSE(plan_.more_to_do());
86  edge = plan_.FindWork();
87  ASSERT_EQ(0, edge);
88 }
89 
90 // Test that two outputs from one rule can be handled as inputs to the next.
91 TEST_F(PlanTest, DoubleOutputDirect) {
93 "build out: cat mid1 mid2\n"
94 "build mid1 mid2: cat in\n"));
95  GetNode("mid1")->MarkDirty();
96  GetNode("mid2")->MarkDirty();
97  GetNode("out")->MarkDirty();
98 
99  string err;
100  EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
101  ASSERT_EQ("", err);
102  ASSERT_TRUE(plan_.more_to_do());
103 
104  Edge* edge;
105  edge = plan_.FindWork();
106  ASSERT_TRUE(edge); // cat in
107  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
108  ASSERT_EQ("", err);
109 
110  edge = plan_.FindWork();
111  ASSERT_TRUE(edge); // cat mid1 mid2
112  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
113  ASSERT_EQ("", err);
114 
115  edge = plan_.FindWork();
116  ASSERT_FALSE(edge); // done
117 }
118 
119 // Test that two outputs from one rule can eventually be routed to another.
120 TEST_F(PlanTest, DoubleOutputIndirect) {
122 "build out: cat b1 b2\n"
123 "build b1: cat a1\n"
124 "build b2: cat a2\n"
125 "build a1 a2: cat in\n"));
126  GetNode("a1")->MarkDirty();
127  GetNode("a2")->MarkDirty();
128  GetNode("b1")->MarkDirty();
129  GetNode("b2")->MarkDirty();
130  GetNode("out")->MarkDirty();
131  string err;
132  EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
133  ASSERT_EQ("", err);
134  ASSERT_TRUE(plan_.more_to_do());
135 
136  Edge* edge;
137  edge = plan_.FindWork();
138  ASSERT_TRUE(edge); // cat in
139  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
140  ASSERT_EQ("", err);
141 
142  edge = plan_.FindWork();
143  ASSERT_TRUE(edge); // cat a1
144  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
145  ASSERT_EQ("", err);
146 
147  edge = plan_.FindWork();
148  ASSERT_TRUE(edge); // cat a2
149  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
150  ASSERT_EQ("", err);
151 
152  edge = plan_.FindWork();
153  ASSERT_TRUE(edge); // cat b1 b2
154  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
155  ASSERT_EQ("", err);
156 
157  edge = plan_.FindWork();
158  ASSERT_FALSE(edge); // done
159 }
160 
161 // Test that two edges from one output can both execute.
162 TEST_F(PlanTest, DoubleDependent) {
164 "build out: cat a1 a2\n"
165 "build a1: cat mid\n"
166 "build a2: cat mid\n"
167 "build mid: cat in\n"));
168  GetNode("mid")->MarkDirty();
169  GetNode("a1")->MarkDirty();
170  GetNode("a2")->MarkDirty();
171  GetNode("out")->MarkDirty();
172 
173  string err;
174  EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
175  ASSERT_EQ("", err);
176  ASSERT_TRUE(plan_.more_to_do());
177 
178  Edge* edge;
179  edge = plan_.FindWork();
180  ASSERT_TRUE(edge); // cat in
181  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
182  ASSERT_EQ("", err);
183 
184  edge = plan_.FindWork();
185  ASSERT_TRUE(edge); // cat mid
186  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
187  ASSERT_EQ("", err);
188 
189  edge = plan_.FindWork();
190  ASSERT_TRUE(edge); // cat mid
191  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
192  ASSERT_EQ("", err);
193 
194  edge = plan_.FindWork();
195  ASSERT_TRUE(edge); // cat a1 a2
196  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
197  ASSERT_EQ("", err);
198 
199  edge = plan_.FindWork();
200  ASSERT_FALSE(edge); // done
201 }
202 
203 void PlanTest::TestPoolWithDepthOne(const char* test_case) {
204  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_, test_case));
205  GetNode("out1")->MarkDirty();
206  GetNode("out2")->MarkDirty();
207  string err;
208  EXPECT_TRUE(plan_.AddTarget(GetNode("out1"), &err));
209  ASSERT_EQ("", err);
210  EXPECT_TRUE(plan_.AddTarget(GetNode("out2"), &err));
211  ASSERT_EQ("", err);
212  ASSERT_TRUE(plan_.more_to_do());
213 
214  Edge* edge = plan_.FindWork();
215  ASSERT_TRUE(edge);
216  ASSERT_EQ("in", edge->inputs_[0]->path());
217  ASSERT_EQ("out1", edge->outputs_[0]->path());
218 
219  // This will be false since poolcat is serialized
220  ASSERT_FALSE(plan_.FindWork());
221 
222  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
223  ASSERT_EQ("", err);
224 
225  edge = plan_.FindWork();
226  ASSERT_TRUE(edge);
227  ASSERT_EQ("in", edge->inputs_[0]->path());
228  ASSERT_EQ("out2", edge->outputs_[0]->path());
229 
230  ASSERT_FALSE(plan_.FindWork());
231 
232  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
233  ASSERT_EQ("", err);
234 
235  ASSERT_FALSE(plan_.more_to_do());
236  edge = plan_.FindWork();
237  ASSERT_EQ(0, edge);
238 }
239 
240 TEST_F(PlanTest, PoolWithDepthOne) {
241  TestPoolWithDepthOne(
242 "pool foobar\n"
243 " depth = 1\n"
244 "rule poolcat\n"
245 " command = cat $in > $out\n"
246 " pool = foobar\n"
247 "build out1: poolcat in\n"
248 "build out2: poolcat in\n");
249 }
250 
251 TEST_F(PlanTest, ConsolePool) {
252  TestPoolWithDepthOne(
253 "rule poolcat\n"
254 " command = cat $in > $out\n"
255 " pool = console\n"
256 "build out1: poolcat in\n"
257 "build out2: poolcat in\n");
258 }
259 
260 TEST_F(PlanTest, PoolsWithDepthTwo) {
262 "pool foobar\n"
263 " depth = 2\n"
264 "pool bazbin\n"
265 " depth = 2\n"
266 "rule foocat\n"
267 " command = cat $in > $out\n"
268 " pool = foobar\n"
269 "rule bazcat\n"
270 " command = cat $in > $out\n"
271 " pool = bazbin\n"
272 "build out1: foocat in\n"
273 "build out2: foocat in\n"
274 "build out3: foocat in\n"
275 "build outb1: bazcat in\n"
276 "build outb2: bazcat in\n"
277 "build outb3: bazcat in\n"
278 " pool =\n"
279 "build allTheThings: cat out1 out2 out3 outb1 outb2 outb3\n"
280 ));
281  // Mark all the out* nodes dirty
282  for (int i = 0; i < 3; ++i) {
283  GetNode("out" + string(1, '1' + static_cast<char>(i)))->MarkDirty();
284  GetNode("outb" + string(1, '1' + static_cast<char>(i)))->MarkDirty();
285  }
286  GetNode("allTheThings")->MarkDirty();
287 
288  string err;
289  EXPECT_TRUE(plan_.AddTarget(GetNode("allTheThings"), &err));
290  ASSERT_EQ("", err);
291 
292  deque<Edge*> edges;
293  FindWorkSorted(&edges, 5);
294 
295  for (int i = 0; i < 4; ++i) {
296  Edge *edge = edges[i];
297  ASSERT_EQ("in", edge->inputs_[0]->path());
298  string base_name(i < 2 ? "out" : "outb");
299  ASSERT_EQ(base_name + string(1, '1' + (i % 2)), edge->outputs_[0]->path());
300  }
301 
302  // outb3 is exempt because it has an empty pool
303  Edge* edge = edges[4];
304  ASSERT_TRUE(edge);
305  ASSERT_EQ("in", edge->inputs_[0]->path());
306  ASSERT_EQ("outb3", edge->outputs_[0]->path());
307 
308  // finish out1
309  plan_.EdgeFinished(edges.front(), Plan::kEdgeSucceeded, &err);
310  ASSERT_EQ("", err);
311  edges.pop_front();
312 
313  // out3 should be available
314  Edge* out3 = plan_.FindWork();
315  ASSERT_TRUE(out3);
316  ASSERT_EQ("in", out3->inputs_[0]->path());
317  ASSERT_EQ("out3", out3->outputs_[0]->path());
318 
319  ASSERT_FALSE(plan_.FindWork());
320 
321  plan_.EdgeFinished(out3, Plan::kEdgeSucceeded, &err);
322  ASSERT_EQ("", err);
323 
324  ASSERT_FALSE(plan_.FindWork());
325 
326  for (deque<Edge*>::iterator it = edges.begin(); it != edges.end(); ++it) {
327  plan_.EdgeFinished(*it, Plan::kEdgeSucceeded, &err);
328  ASSERT_EQ("", err);
329  }
330 
331  Edge* last = plan_.FindWork();
332  ASSERT_TRUE(last);
333  ASSERT_EQ("allTheThings", last->outputs_[0]->path());
334 
335  plan_.EdgeFinished(last, Plan::kEdgeSucceeded, &err);
336  ASSERT_EQ("", err);
337 
338  ASSERT_FALSE(plan_.more_to_do());
339  ASSERT_FALSE(plan_.FindWork());
340 }
341 
342 TEST_F(PlanTest, PoolWithRedundantEdges) {
344  "pool compile\n"
345  " depth = 1\n"
346  "rule gen_foo\n"
347  " command = touch foo.cpp\n"
348  "rule gen_bar\n"
349  " command = touch bar.cpp\n"
350  "rule echo\n"
351  " command = echo $out > $out\n"
352  "build foo.cpp.obj: echo foo.cpp || foo.cpp\n"
353  " pool = compile\n"
354  "build bar.cpp.obj: echo bar.cpp || bar.cpp\n"
355  " pool = compile\n"
356  "build libfoo.a: echo foo.cpp.obj bar.cpp.obj\n"
357  "build foo.cpp: gen_foo\n"
358  "build bar.cpp: gen_bar\n"
359  "build all: phony libfoo.a\n"));
360  GetNode("foo.cpp")->MarkDirty();
361  GetNode("foo.cpp.obj")->MarkDirty();
362  GetNode("bar.cpp")->MarkDirty();
363  GetNode("bar.cpp.obj")->MarkDirty();
364  GetNode("libfoo.a")->MarkDirty();
365  GetNode("all")->MarkDirty();
366  string err;
367  EXPECT_TRUE(plan_.AddTarget(GetNode("all"), &err));
368  ASSERT_EQ("", err);
369  ASSERT_TRUE(plan_.more_to_do());
370 
371  Edge* edge = NULL;
372 
373  deque<Edge*> initial_edges;
374  FindWorkSorted(&initial_edges, 2);
375 
376  edge = initial_edges[1]; // Foo first
377  ASSERT_EQ("foo.cpp", edge->outputs_[0]->path());
378  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
379  ASSERT_EQ("", err);
380 
381  edge = plan_.FindWork();
382  ASSERT_TRUE(edge);
383  ASSERT_FALSE(plan_.FindWork());
384  ASSERT_EQ("foo.cpp", edge->inputs_[0]->path());
385  ASSERT_EQ("foo.cpp", edge->inputs_[1]->path());
386  ASSERT_EQ("foo.cpp.obj", edge->outputs_[0]->path());
387  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
388  ASSERT_EQ("", err);
389 
390  edge = initial_edges[0]; // Now for bar
391  ASSERT_EQ("bar.cpp", edge->outputs_[0]->path());
392  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
393  ASSERT_EQ("", err);
394 
395  edge = plan_.FindWork();
396  ASSERT_TRUE(edge);
397  ASSERT_FALSE(plan_.FindWork());
398  ASSERT_EQ("bar.cpp", edge->inputs_[0]->path());
399  ASSERT_EQ("bar.cpp", edge->inputs_[1]->path());
400  ASSERT_EQ("bar.cpp.obj", edge->outputs_[0]->path());
401  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
402  ASSERT_EQ("", err);
403 
404  edge = plan_.FindWork();
405  ASSERT_TRUE(edge);
406  ASSERT_FALSE(plan_.FindWork());
407  ASSERT_EQ("foo.cpp.obj", edge->inputs_[0]->path());
408  ASSERT_EQ("bar.cpp.obj", edge->inputs_[1]->path());
409  ASSERT_EQ("libfoo.a", edge->outputs_[0]->path());
410  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
411  ASSERT_EQ("", err);
412 
413  edge = plan_.FindWork();
414  ASSERT_TRUE(edge);
415  ASSERT_FALSE(plan_.FindWork());
416  ASSERT_EQ("libfoo.a", edge->inputs_[0]->path());
417  ASSERT_EQ("all", edge->outputs_[0]->path());
418  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
419  ASSERT_EQ("", err);
420 
421  edge = plan_.FindWork();
422  ASSERT_FALSE(edge);
423  ASSERT_FALSE(plan_.more_to_do());
424 }
425 
426 TEST_F(PlanTest, PoolWithFailingEdge) {
428  "pool foobar\n"
429  " depth = 1\n"
430  "rule poolcat\n"
431  " command = cat $in > $out\n"
432  " pool = foobar\n"
433  "build out1: poolcat in\n"
434  "build out2: poolcat in\n"));
435  GetNode("out1")->MarkDirty();
436  GetNode("out2")->MarkDirty();
437  string err;
438  EXPECT_TRUE(plan_.AddTarget(GetNode("out1"), &err));
439  ASSERT_EQ("", err);
440  EXPECT_TRUE(plan_.AddTarget(GetNode("out2"), &err));
441  ASSERT_EQ("", err);
442  ASSERT_TRUE(plan_.more_to_do());
443 
444  Edge* edge = plan_.FindWork();
445  ASSERT_TRUE(edge);
446  ASSERT_EQ("in", edge->inputs_[0]->path());
447  ASSERT_EQ("out1", edge->outputs_[0]->path());
448 
449  // This will be false since poolcat is serialized
450  ASSERT_FALSE(plan_.FindWork());
451 
452  plan_.EdgeFinished(edge, Plan::kEdgeFailed, &err);
453  ASSERT_EQ("", err);
454 
455  edge = plan_.FindWork();
456  ASSERT_TRUE(edge);
457  ASSERT_EQ("in", edge->inputs_[0]->path());
458  ASSERT_EQ("out2", edge->outputs_[0]->path());
459 
460  ASSERT_FALSE(plan_.FindWork());
461 
462  plan_.EdgeFinished(edge, Plan::kEdgeFailed, &err);
463  ASSERT_EQ("", err);
464 
465  ASSERT_TRUE(plan_.more_to_do()); // Jobs have failed
466  edge = plan_.FindWork();
467  ASSERT_EQ(0, edge);
468 }
469 
470 /// Fake implementation of CommandRunner, useful for tests.
473  max_active_edges_(1), fs_(fs) {}
474 
475  // CommandRunner impl
476  virtual bool CanRunMore() const;
477  virtual bool StartCommand(Edge* edge);
478  virtual bool WaitForCommand(Result* result);
479  virtual vector<Edge*> GetActiveEdges();
480  virtual void Abort();
481 
482  vector<string> commands_ran_;
483  vector<Edge*> active_edges_;
486 };
487 
489  BuildTest() : config_(MakeConfig()), command_runner_(&fs_), status_(config_),
490  builder_(&state_, config_, NULL, NULL, &fs_, &status_, 0) {
491  }
492 
493  explicit BuildTest(DepsLog* log)
494  : config_(MakeConfig()), command_runner_(&fs_), status_(config_),
495  builder_(&state_, config_, NULL, log, &fs_, &status_, 0) {}
496 
497  virtual void SetUp() {
499 
500  builder_.command_runner_.reset(&command_runner_);
501  AssertParse(&state_,
502 "build cat1: cat in1\n"
503 "build cat2: cat in1 in2\n"
504 "build cat12: cat cat1 cat2\n");
505 
506  fs_.Create("in1", "");
507  fs_.Create("in2", "");
508  }
509 
511  builder_.command_runner_.release();
512  }
513 
514  virtual bool IsPathDead(StringPiece s) const { return false; }
515 
516  /// Rebuild target in the 'working tree' (fs_).
517  /// State of command_runner_ and logs contents (if specified) ARE MODIFIED.
518  /// Handy to check for NOOP builds, and higher-level rebuild tests.
519  void RebuildTarget(const string& target, const char* manifest,
520  const char* log_path = NULL, const char* deps_path = NULL,
521  State* state = NULL);
522 
523  // Mark a path dirty.
524  void Dirty(const string& path);
525 
527  BuildConfig config;
528  config.verbosity = BuildConfig::QUIET;
529  return config;
530  }
531 
537 };
538 
539 void BuildTest::RebuildTarget(const string& target, const char* manifest,
540  const char* log_path, const char* deps_path,
541  State* state) {
542  State local_state, *pstate = &local_state;
543  if (state)
544  pstate = state;
545  ASSERT_NO_FATAL_FAILURE(AddCatRule(pstate));
546  AssertParse(pstate, manifest);
547 
548  string err;
549  BuildLog build_log, *pbuild_log = NULL;
550  if (log_path) {
551  ASSERT_TRUE(build_log.Load(log_path, &err));
552  ASSERT_TRUE(build_log.OpenForWrite(log_path, *this, &err));
553  ASSERT_EQ("", err);
554  pbuild_log = &build_log;
555  }
556 
557  DepsLog deps_log, *pdeps_log = NULL;
558  if (deps_path) {
559  ASSERT_TRUE(deps_log.Load(deps_path, pstate, &err));
560  ASSERT_TRUE(deps_log.OpenForWrite(deps_path, &err));
561  ASSERT_EQ("", err);
562  pdeps_log = &deps_log;
563  }
564 
565  Builder builder(pstate, config_, pbuild_log, pdeps_log, &fs_, &status_, 0);
566  EXPECT_TRUE(builder.AddTarget(target, &err));
567 
568  command_runner_.commands_ran_.clear();
569  builder.command_runner_.reset(&command_runner_);
570  if (!builder.AlreadyUpToDate()) {
571  bool build_res = builder.Build(&err);
572  EXPECT_TRUE(build_res);
573  }
574  builder.command_runner_.release();
575 }
576 
578  return active_edges_.size() < max_active_edges_;
579 }
580 
582  assert(active_edges_.size() < max_active_edges_);
583  assert(find(active_edges_.begin(), active_edges_.end(), edge)
584  == active_edges_.end());
585  commands_ran_.push_back(edge->EvaluateCommand());
586  if (edge->rule().name() == "cat" ||
587  edge->rule().name() == "cat_rsp" ||
588  edge->rule().name() == "cat_rsp_out" ||
589  edge->rule().name() == "cc" ||
590  edge->rule().name() == "cp_multi_msvc" ||
591  edge->rule().name() == "cp_multi_gcc" ||
592  edge->rule().name() == "touch" ||
593  edge->rule().name() == "touch-interrupt" ||
594  edge->rule().name() == "touch-fail-tick2") {
595  for (vector<Node*>::iterator out = edge->outputs_.begin();
596  out != edge->outputs_.end(); ++out) {
597  fs_->Create((*out)->path(), "");
598  }
599  } else if (edge->rule().name() == "true" ||
600  edge->rule().name() == "fail" ||
601  edge->rule().name() == "interrupt" ||
602  edge->rule().name() == "console") {
603  // Don't do anything.
604  } else if (edge->rule().name() == "cp") {
605  assert(!edge->inputs_.empty());
606  assert(edge->outputs_.size() == 1);
607  string content;
608  string err;
609  if (fs_->ReadFile(edge->inputs_[0]->path(), &content, &err) ==
611  fs_->WriteFile(edge->outputs_[0]->path(), content);
612  } else if (edge->rule().name() == "touch-implicit-dep-out") {
613  string dep = edge->GetBinding("test_dependency");
614  fs_->Create(dep, "");
615  fs_->Tick();
616  for (vector<Node*>::iterator out = edge->outputs_.begin();
617  out != edge->outputs_.end(); ++out) {
618  fs_->Create((*out)->path(), "");
619  }
620  } else if (edge->rule().name() == "touch-out-implicit-dep") {
621  string dep = edge->GetBinding("test_dependency");
622  for (vector<Node*>::iterator out = edge->outputs_.begin();
623  out != edge->outputs_.end(); ++out) {
624  fs_->Create((*out)->path(), "");
625  }
626  fs_->Tick();
627  fs_->Create(dep, "");
628  } else if (edge->rule().name() == "generate-depfile") {
629  string dep = edge->GetBinding("test_dependency");
630  string depfile = edge->GetUnescapedDepfile();
631  string contents;
632  for (vector<Node*>::iterator out = edge->outputs_.begin();
633  out != edge->outputs_.end(); ++out) {
634  contents += (*out)->path() + ": " + dep + "\n";
635  fs_->Create((*out)->path(), "");
636  }
637  fs_->Create(depfile, contents);
638  } else {
639  printf("unknown command\n");
640  return false;
641  }
642 
643  active_edges_.push_back(edge);
644 
645  // Allow tests to control the order by the name of the first output.
646  sort(active_edges_.begin(), active_edges_.end(),
648 
649  return true;
650 }
651 
653  if (active_edges_.empty())
654  return false;
655 
656  // All active edges were already completed immediately when started,
657  // so we can pick any edge here. Pick the last edge. Tests can
658  // control the order of edges by the name of the first output.
659  vector<Edge*>::iterator edge_iter = active_edges_.end() - 1;
660 
661  Edge* edge = *edge_iter;
662  result->edge = edge;
663 
664  if (edge->rule().name() == "interrupt" ||
665  edge->rule().name() == "touch-interrupt") {
666  result->status = ExitInterrupted;
667  return true;
668  }
669 
670  if (edge->rule().name() == "console") {
671  if (edge->use_console())
672  result->status = ExitSuccess;
673  else
674  result->status = ExitFailure;
675  active_edges_.erase(edge_iter);
676  return true;
677  }
678 
679  if (edge->rule().name() == "cp_multi_msvc") {
680  const std::string prefix = edge->GetBinding("msvc_deps_prefix");
681  for (std::vector<Node*>::iterator in = edge->inputs_.begin();
682  in != edge->inputs_.end(); ++in) {
683  result->output += prefix + (*in)->path() + '\n';
684  }
685  }
686 
687  if (edge->rule().name() == "fail" ||
688  (edge->rule().name() == "touch-fail-tick2" && fs_->now_ == 2))
689  result->status = ExitFailure;
690  else
691  result->status = ExitSuccess;
692 
693  // Provide a way for test cases to verify when an edge finishes that
694  // some other edge is still active. This is useful for test cases
695  // covering behavior involving multiple active edges.
696  const string& verify_active_edge = edge->GetBinding("verify_active_edge");
697  if (!verify_active_edge.empty()) {
698  bool verify_active_edge_found = false;
699  for (vector<Edge*>::iterator i = active_edges_.begin();
700  i != active_edges_.end(); ++i) {
701  if (!(*i)->outputs_.empty() &&
702  (*i)->outputs_[0]->path() == verify_active_edge) {
703  verify_active_edge_found = true;
704  }
705  }
706  EXPECT_TRUE(verify_active_edge_found);
707  }
708 
709  active_edges_.erase(edge_iter);
710  return true;
711 }
712 
714  return active_edges_;
715 }
716 
718  active_edges_.clear();
719 }
720 
721 void BuildTest::Dirty(const string& path) {
722  Node* node = GetNode(path);
723  node->MarkDirty();
724 
725  // If it's an input file, mark that we've already stat()ed it and
726  // it's missing.
727  if (!node->in_edge())
728  node->MarkMissing();
729 }
730 
731 TEST_F(BuildTest, NoWork) {
732  string err;
733  EXPECT_TRUE(builder_.AlreadyUpToDate());
734 }
735 
736 TEST_F(BuildTest, OneStep) {
737  // Given a dirty target with one ready input,
738  // we should rebuild the target.
739  Dirty("cat1");
740  string err;
741  EXPECT_TRUE(builder_.AddTarget("cat1", &err));
742  ASSERT_EQ("", err);
743  EXPECT_TRUE(builder_.Build(&err));
744  ASSERT_EQ("", err);
745 
746  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
747  EXPECT_EQ("cat in1 > cat1", command_runner_.commands_ran_[0]);
748 }
749 
750 TEST_F(BuildTest, OneStep2) {
751  // Given a target with one dirty input,
752  // we should rebuild the target.
753  Dirty("cat1");
754  string err;
755  EXPECT_TRUE(builder_.AddTarget("cat1", &err));
756  ASSERT_EQ("", err);
757  EXPECT_TRUE(builder_.Build(&err));
758  EXPECT_EQ("", err);
759 
760  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
761  EXPECT_EQ("cat in1 > cat1", command_runner_.commands_ran_[0]);
762 }
763 
764 TEST_F(BuildTest, TwoStep) {
765  string err;
766  EXPECT_TRUE(builder_.AddTarget("cat12", &err));
767  ASSERT_EQ("", err);
768  EXPECT_TRUE(builder_.Build(&err));
769  EXPECT_EQ("", err);
770  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
771  // Depending on how the pointers work out, we could've ran
772  // the first two commands in either order.
773  EXPECT_TRUE((command_runner_.commands_ran_[0] == "cat in1 > cat1" &&
774  command_runner_.commands_ran_[1] == "cat in1 in2 > cat2") ||
775  (command_runner_.commands_ran_[1] == "cat in1 > cat1" &&
776  command_runner_.commands_ran_[0] == "cat in1 in2 > cat2"));
777 
778  EXPECT_EQ("cat cat1 cat2 > cat12", command_runner_.commands_ran_[2]);
779 
780  fs_.Tick();
781 
782  // Modifying in2 requires rebuilding one intermediate file
783  // and the final file.
784  fs_.Create("in2", "");
785  state_.Reset();
786  EXPECT_TRUE(builder_.AddTarget("cat12", &err));
787  ASSERT_EQ("", err);
788  EXPECT_TRUE(builder_.Build(&err));
789  ASSERT_EQ("", err);
790  ASSERT_EQ(5u, command_runner_.commands_ran_.size());
791  EXPECT_EQ("cat in1 in2 > cat2", command_runner_.commands_ran_[3]);
792  EXPECT_EQ("cat cat1 cat2 > cat12", command_runner_.commands_ran_[4]);
793 }
794 
795 TEST_F(BuildTest, TwoOutputs) {
797 "rule touch\n"
798 " command = touch $out\n"
799 "build out1 out2: touch in.txt\n"));
800 
801  fs_.Create("in.txt", "");
802 
803  string err;
804  EXPECT_TRUE(builder_.AddTarget("out1", &err));
805  ASSERT_EQ("", err);
806  EXPECT_TRUE(builder_.Build(&err));
807  EXPECT_EQ("", err);
808  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
809  EXPECT_EQ("touch out1 out2", command_runner_.commands_ran_[0]);
810 }
811 
812 TEST_F(BuildTest, ImplicitOutput) {
814 "rule touch\n"
815 " command = touch $out $out.imp\n"
816 "build out | out.imp: touch in.txt\n"));
817  fs_.Create("in.txt", "");
818 
819  string err;
820  EXPECT_TRUE(builder_.AddTarget("out.imp", &err));
821  ASSERT_EQ("", err);
822  EXPECT_TRUE(builder_.Build(&err));
823  EXPECT_EQ("", err);
824  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
825  EXPECT_EQ("touch out out.imp", command_runner_.commands_ran_[0]);
826 }
827 
828 // Test case from
829 // https://github.com/ninja-build/ninja/issues/148
830 TEST_F(BuildTest, MultiOutIn) {
832 "rule touch\n"
833 " command = touch $out\n"
834 "build in1 otherfile: touch in\n"
835 "build out: touch in | in1\n"));
836 
837  fs_.Create("in", "");
838  fs_.Tick();
839  fs_.Create("in1", "");
840 
841  string err;
842  EXPECT_TRUE(builder_.AddTarget("out", &err));
843  ASSERT_EQ("", err);
844  EXPECT_TRUE(builder_.Build(&err));
845  EXPECT_EQ("", err);
846 }
847 
848 TEST_F(BuildTest, Chain) {
850 "build c2: cat c1\n"
851 "build c3: cat c2\n"
852 "build c4: cat c3\n"
853 "build c5: cat c4\n"));
854 
855  fs_.Create("c1", "");
856 
857  string err;
858  EXPECT_TRUE(builder_.AddTarget("c5", &err));
859  ASSERT_EQ("", err);
860  EXPECT_TRUE(builder_.Build(&err));
861  EXPECT_EQ("", err);
862  ASSERT_EQ(4u, command_runner_.commands_ran_.size());
863 
864  err.clear();
865  command_runner_.commands_ran_.clear();
866  state_.Reset();
867  EXPECT_TRUE(builder_.AddTarget("c5", &err));
868  ASSERT_EQ("", err);
869  EXPECT_TRUE(builder_.AlreadyUpToDate());
870 
871  fs_.Tick();
872 
873  fs_.Create("c3", "");
874  err.clear();
875  command_runner_.commands_ran_.clear();
876  state_.Reset();
877  EXPECT_TRUE(builder_.AddTarget("c5", &err));
878  ASSERT_EQ("", err);
879  EXPECT_FALSE(builder_.AlreadyUpToDate());
880  EXPECT_TRUE(builder_.Build(&err));
881  ASSERT_EQ(2u, command_runner_.commands_ran_.size()); // 3->4, 4->5
882 }
883 
884 TEST_F(BuildTest, MissingInput) {
885  // Input is referenced by build file, but no rule for it.
886  string err;
887  Dirty("in1");
888  EXPECT_FALSE(builder_.AddTarget("cat1", &err));
889  EXPECT_EQ("'in1', needed by 'cat1', missing and no known rule to make it",
890  err);
891 }
892 
893 TEST_F(BuildTest, MissingTarget) {
894  // Target is not referenced by build file.
895  string err;
896  EXPECT_FALSE(builder_.AddTarget("meow", &err));
897  EXPECT_EQ("unknown target: 'meow'", err);
898 }
899 
900 TEST_F(BuildTest, MissingInputTarget) {
901  // Target is a missing input file
902  string err;
903  Dirty("in1");
904  EXPECT_FALSE(builder_.AddTarget("in1", &err));
905  EXPECT_EQ("'in1' missing and no known rule to make it", err);
906 }
907 
908 TEST_F(BuildTest, MakeDirs) {
909  string err;
910 
911 #ifdef _WIN32
913  "build subdir\\dir2\\file: cat in1\n"));
914 #else
916  "build subdir/dir2/file: cat in1\n"));
917 #endif
918  EXPECT_TRUE(builder_.AddTarget("subdir/dir2/file", &err));
919 
920  EXPECT_EQ("", err);
921  EXPECT_TRUE(builder_.Build(&err));
922  ASSERT_EQ("", err);
923  ASSERT_EQ(2u, fs_.directories_made_.size());
924  EXPECT_EQ("subdir", fs_.directories_made_[0]);
925  EXPECT_EQ("subdir/dir2", fs_.directories_made_[1]);
926 }
927 
928 TEST_F(BuildTest, DepFileMissing) {
929  string err;
931 "rule cc\n command = cc $in\n depfile = $out.d\n"
932 "build fo$ o.o: cc foo.c\n"));
933  fs_.Create("foo.c", "");
934 
935  EXPECT_TRUE(builder_.AddTarget("fo o.o", &err));
936  ASSERT_EQ("", err);
937  ASSERT_EQ(1u, fs_.files_read_.size());
938  EXPECT_EQ("fo o.o.d", fs_.files_read_[0]);
939 }
940 
941 TEST_F(BuildTest, DepFileOK) {
942  string err;
943  int orig_edges = state_.edges_.size();
945 "rule cc\n command = cc $in\n depfile = $out.d\n"
946 "build foo.o: cc foo.c\n"));
947  Edge* edge = state_.edges_.back();
948 
949  fs_.Create("foo.c", "");
950  GetNode("bar.h")->MarkDirty(); // Mark bar.h as missing.
951  fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
952  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
953  ASSERT_EQ("", err);
954  ASSERT_EQ(1u, fs_.files_read_.size());
955  EXPECT_EQ("foo.o.d", fs_.files_read_[0]);
956 
957  // Expect three new edges: one generating foo.o, and two more from
958  // loading the depfile.
959  ASSERT_EQ(orig_edges + 3, (int)state_.edges_.size());
960  // Expect our edge to now have three inputs: foo.c and two headers.
961  ASSERT_EQ(3u, edge->inputs_.size());
962 
963  // Expect the command line we generate to only use the original input.
964  ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
965 }
966 
967 TEST_F(BuildTest, DepFileParseError) {
968  string err;
970 "rule cc\n command = cc $in\n depfile = $out.d\n"
971 "build foo.o: cc foo.c\n"));
972  fs_.Create("foo.c", "");
973  fs_.Create("foo.o.d", "randomtext\n");
974  EXPECT_FALSE(builder_.AddTarget("foo.o", &err));
975  EXPECT_EQ("foo.o.d: expected ':' in depfile", err);
976 }
977 
978 TEST_F(BuildTest, EncounterReadyTwice) {
979  string err;
981 "rule touch\n"
982 " command = touch $out\n"
983 "build c: touch\n"
984 "build b: touch || c\n"
985 "build a: touch | b || c\n"));
986 
987  vector<Edge*> c_out = GetNode("c")->out_edges();
988  ASSERT_EQ(2u, c_out.size());
989  EXPECT_EQ("b", c_out[0]->outputs_[0]->path());
990  EXPECT_EQ("a", c_out[1]->outputs_[0]->path());
991 
992  fs_.Create("b", "");
993  EXPECT_TRUE(builder_.AddTarget("a", &err));
994  ASSERT_EQ("", err);
995 
996  EXPECT_TRUE(builder_.Build(&err));
997  ASSERT_EQ("", err);
998  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
999 }
1000 
1001 TEST_F(BuildTest, OrderOnlyDeps) {
1002  string err;
1004 "rule cc\n command = cc $in\n depfile = $out.d\n"
1005 "build foo.o: cc foo.c || otherfile\n"));
1006  Edge* edge = state_.edges_.back();
1007 
1008  fs_.Create("foo.c", "");
1009  fs_.Create("otherfile", "");
1010  fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
1011  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
1012  ASSERT_EQ("", err);
1013 
1014  // One explicit, two implicit, one order only.
1015  ASSERT_EQ(4u, edge->inputs_.size());
1016  EXPECT_EQ(2, edge->implicit_deps_);
1017  EXPECT_EQ(1, edge->order_only_deps_);
1018  // Verify the inputs are in the order we expect
1019  // (explicit then implicit then orderonly).
1020  EXPECT_EQ("foo.c", edge->inputs_[0]->path());
1021  EXPECT_EQ("blah.h", edge->inputs_[1]->path());
1022  EXPECT_EQ("bar.h", edge->inputs_[2]->path());
1023  EXPECT_EQ("otherfile", edge->inputs_[3]->path());
1024 
1025  // Expect the command line we generate to only use the original input.
1026  ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
1027 
1028  // explicit dep dirty, expect a rebuild.
1029  EXPECT_TRUE(builder_.Build(&err));
1030  ASSERT_EQ("", err);
1031  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1032 
1033  fs_.Tick();
1034 
1035  // Recreate the depfile, as it should have been deleted by the build.
1036  fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
1037 
1038  // implicit dep dirty, expect a rebuild.
1039  fs_.Create("blah.h", "");
1040  fs_.Create("bar.h", "");
1041  command_runner_.commands_ran_.clear();
1042  state_.Reset();
1043  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
1044  EXPECT_TRUE(builder_.Build(&err));
1045  ASSERT_EQ("", err);
1046  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1047 
1048  fs_.Tick();
1049 
1050  // Recreate the depfile, as it should have been deleted by the build.
1051  fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
1052 
1053  // order only dep dirty, no rebuild.
1054  fs_.Create("otherfile", "");
1055  command_runner_.commands_ran_.clear();
1056  state_.Reset();
1057  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
1058  EXPECT_EQ("", err);
1059  EXPECT_TRUE(builder_.AlreadyUpToDate());
1060 
1061  // implicit dep missing, expect rebuild.
1062  fs_.RemoveFile("bar.h");
1063  command_runner_.commands_ran_.clear();
1064  state_.Reset();
1065  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
1066  EXPECT_TRUE(builder_.Build(&err));
1067  ASSERT_EQ("", err);
1068  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1069 }
1070 
1071 TEST_F(BuildTest, RebuildOrderOnlyDeps) {
1072  string err;
1074 "rule cc\n command = cc $in\n"
1075 "rule true\n command = true\n"
1076 "build oo.h: cc oo.h.in\n"
1077 "build foo.o: cc foo.c || oo.h\n"));
1078 
1079  fs_.Create("foo.c", "");
1080  fs_.Create("oo.h.in", "");
1081 
1082  // foo.o and order-only dep dirty, build both.
1083  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
1084  EXPECT_TRUE(builder_.Build(&err));
1085  ASSERT_EQ("", err);
1086  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1087 
1088  // all clean, no rebuild.
1089  command_runner_.commands_ran_.clear();
1090  state_.Reset();
1091  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
1092  EXPECT_EQ("", err);
1093  EXPECT_TRUE(builder_.AlreadyUpToDate());
1094 
1095  // order-only dep missing, build it only.
1096  fs_.RemoveFile("oo.h");
1097  command_runner_.commands_ran_.clear();
1098  state_.Reset();
1099  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
1100  EXPECT_TRUE(builder_.Build(&err));
1101  ASSERT_EQ("", err);
1102  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1103  ASSERT_EQ("cc oo.h.in", command_runner_.commands_ran_[0]);
1104 
1105  fs_.Tick();
1106 
1107  // order-only dep dirty, build it only.
1108  fs_.Create("oo.h.in", "");
1109  command_runner_.commands_ran_.clear();
1110  state_.Reset();
1111  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
1112  EXPECT_TRUE(builder_.Build(&err));
1113  ASSERT_EQ("", err);
1114  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1115  ASSERT_EQ("cc oo.h.in", command_runner_.commands_ran_[0]);
1116 }
1117 
1118 #ifdef _WIN32
1119 TEST_F(BuildTest, DepFileCanonicalize) {
1120  string err;
1121  int orig_edges = state_.edges_.size();
1123 "rule cc\n command = cc $in\n depfile = $out.d\n"
1124 "build gen/stuff\\things/foo.o: cc x\\y/z\\foo.c\n"));
1125  Edge* edge = state_.edges_.back();
1126 
1127  fs_.Create("x/y/z/foo.c", "");
1128  GetNode("bar.h")->MarkDirty(); // Mark bar.h as missing.
1129  // Note, different slashes from manifest.
1130  fs_.Create("gen/stuff\\things/foo.o.d",
1131  "gen\\stuff\\things\\foo.o: blah.h bar.h\n");
1132  EXPECT_TRUE(builder_.AddTarget("gen/stuff/things/foo.o", &err));
1133  ASSERT_EQ("", err);
1134  ASSERT_EQ(1u, fs_.files_read_.size());
1135  // The depfile path does not get Canonicalize as it seems unnecessary.
1136  EXPECT_EQ("gen/stuff\\things/foo.o.d", fs_.files_read_[0]);
1137 
1138  // Expect three new edges: one generating foo.o, and two more from
1139  // loading the depfile.
1140  ASSERT_EQ(orig_edges + 3, (int)state_.edges_.size());
1141  // Expect our edge to now have three inputs: foo.c and two headers.
1142  ASSERT_EQ(3u, edge->inputs_.size());
1143 
1144  // Expect the command line we generate to only use the original input, and
1145  // using the slashes from the manifest.
1146  ASSERT_EQ("cc x\\y/z\\foo.c", edge->EvaluateCommand());
1147 }
1148 #endif
1149 
1151  string err;
1153 "build out: cat bar.cc\n"
1154 "build all: phony out\n"));
1155  fs_.Create("bar.cc", "");
1156 
1157  EXPECT_TRUE(builder_.AddTarget("all", &err));
1158  ASSERT_EQ("", err);
1159 
1160  // Only one command to run, because phony runs no command.
1161  EXPECT_FALSE(builder_.AlreadyUpToDate());
1162  EXPECT_TRUE(builder_.Build(&err));
1163  ASSERT_EQ("", err);
1164  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1165 }
1166 
1167 TEST_F(BuildTest, PhonyNoWork) {
1168  string err;
1170 "build out: cat bar.cc\n"
1171 "build all: phony out\n"));
1172  fs_.Create("bar.cc", "");
1173  fs_.Create("out", "");
1174 
1175  EXPECT_TRUE(builder_.AddTarget("all", &err));
1176  ASSERT_EQ("", err);
1177  EXPECT_TRUE(builder_.AlreadyUpToDate());
1178 }
1179 
1180 // Test a self-referencing phony. Ideally this should not work, but
1181 // ninja 1.7 and below tolerated and CMake 2.8.12.x and 3.0.x both
1182 // incorrectly produce it. We tolerate it for compatibility.
1183 TEST_F(BuildTest, PhonySelfReference) {
1184  string err;
1186 "build a: phony a\n"));
1187 
1188  EXPECT_TRUE(builder_.AddTarget("a", &err));
1189  ASSERT_EQ("", err);
1190  EXPECT_TRUE(builder_.AlreadyUpToDate());
1191 }
1192 
1193 // There are 6 different cases for phony rules:
1194 //
1195 // 1. output edge does not exist, inputs are not real
1196 // 2. output edge does not exist, no inputs
1197 // 3. output edge does not exist, inputs are real, newest mtime is M
1198 // 4. output edge is real, inputs are not real
1199 // 5. output edge is real, no inputs
1200 // 6. output edge is real, inputs are real, newest mtime is M
1201 //
1202 // Expected results :
1203 // 1. Edge is marked as clean, mtime is newest mtime of dependents.
1204 // Touching inputs will cause dependents to rebuild.
1205 // 2. Edge is marked as dirty, causing dependent edges to always rebuild
1206 // 3. Edge is marked as clean, mtime is newest mtime of dependents.
1207 // Touching inputs will cause dependents to rebuild.
1208 // 4. Edge is marked as clean, mtime is newest mtime of dependents.
1209 // Touching inputs will cause dependents to rebuild.
1210 // 5. Edge is marked as dirty, causing dependent edges to always rebuild
1211 // 6. Edge is marked as clean, mtime is newest mtime of dependents.
1212 // Touching inputs will cause dependents to rebuild.
1213 void TestPhonyUseCase(BuildTest* t, int i) {
1214  State& state_ = t->state_;
1215  Builder& builder_ = t->builder_;
1216  FakeCommandRunner& command_runner_ = t->command_runner_;
1217  VirtualFileSystem& fs_ = t->fs_;
1218 
1219  string err;
1221 "rule touch\n"
1222 " command = touch $out\n"
1223 "build notreal: phony blank\n"
1224 "build phony1: phony notreal\n"
1225 "build phony2: phony\n"
1226 "build phony3: phony blank\n"
1227 "build phony4: phony notreal\n"
1228 "build phony5: phony\n"
1229 "build phony6: phony blank\n"
1230 "\n"
1231 "build test1: touch phony1\n"
1232 "build test2: touch phony2\n"
1233 "build test3: touch phony3\n"
1234 "build test4: touch phony4\n"
1235 "build test5: touch phony5\n"
1236 "build test6: touch phony6\n"
1237 ));
1238 
1239  // Set up test.
1240  builder_.command_runner_.release(); // BuildTest owns the CommandRunner
1241  builder_.command_runner_.reset(&command_runner_);
1242 
1243  fs_.Create("blank", ""); // a "real" file
1244  EXPECT_TRUE(builder_.AddTarget("test1", &err));
1245  ASSERT_EQ("", err);
1246  EXPECT_TRUE(builder_.AddTarget("test2", &err));
1247  ASSERT_EQ("", err);
1248  EXPECT_TRUE(builder_.AddTarget("test3", &err));
1249  ASSERT_EQ("", err);
1250  EXPECT_TRUE(builder_.AddTarget("test4", &err));
1251  ASSERT_EQ("", err);
1252  EXPECT_TRUE(builder_.AddTarget("test5", &err));
1253  ASSERT_EQ("", err);
1254  EXPECT_TRUE(builder_.AddTarget("test6", &err));
1255  ASSERT_EQ("", err);
1256  EXPECT_TRUE(builder_.Build(&err));
1257  ASSERT_EQ("", err);
1258 
1259  string ci;
1260  ci += static_cast<char>('0' + i);
1261 
1262  // Tests 1, 3, 4, and 6 should rebuild when the input is updated.
1263  if (i != 2 && i != 5) {
1264  Node* testNode = t->GetNode("test" + ci);
1265  Node* phonyNode = t->GetNode("phony" + ci);
1266  Node* inputNode = t->GetNode("blank");
1267 
1268  state_.Reset();
1269  TimeStamp startTime = fs_.now_;
1270 
1271  // Build number 1
1272  EXPECT_TRUE(builder_.AddTarget("test" + ci, &err));
1273  ASSERT_EQ("", err);
1274  if (!builder_.AlreadyUpToDate())
1275  EXPECT_TRUE(builder_.Build(&err));
1276  ASSERT_EQ("", err);
1277 
1278  // Touch the input file
1279  state_.Reset();
1280  command_runner_.commands_ran_.clear();
1281  fs_.Tick();
1282  fs_.Create("blank", ""); // a "real" file
1283  EXPECT_TRUE(builder_.AddTarget("test" + ci, &err));
1284  ASSERT_EQ("", err);
1285 
1286  // Second build, expect testN edge to be rebuilt
1287  // and phonyN node's mtime to be updated.
1288  EXPECT_FALSE(builder_.AlreadyUpToDate());
1289  EXPECT_TRUE(builder_.Build(&err));
1290  ASSERT_EQ("", err);
1291  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1292  EXPECT_EQ(string("touch test") + ci, command_runner_.commands_ran_[0]);
1293  EXPECT_TRUE(builder_.AlreadyUpToDate());
1294 
1295  TimeStamp inputTime = inputNode->mtime();
1296 
1297  EXPECT_FALSE(phonyNode->exists());
1298  EXPECT_FALSE(phonyNode->dirty());
1299 
1300  EXPECT_GT(phonyNode->mtime(), startTime);
1301  EXPECT_EQ(phonyNode->mtime(), inputTime);
1302  ASSERT_TRUE(testNode->Stat(&fs_, &err));
1303  EXPECT_TRUE(testNode->exists());
1304  EXPECT_GT(testNode->mtime(), startTime);
1305  } else {
1306  // Tests 2 and 5: Expect dependents to always rebuild.
1307 
1308  state_.Reset();
1309  command_runner_.commands_ran_.clear();
1310  fs_.Tick();
1311  command_runner_.commands_ran_.clear();
1312  EXPECT_TRUE(builder_.AddTarget("test" + ci, &err));
1313  ASSERT_EQ("", err);
1314  EXPECT_FALSE(builder_.AlreadyUpToDate());
1315  EXPECT_TRUE(builder_.Build(&err));
1316  ASSERT_EQ("", err);
1317  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1318  EXPECT_EQ("touch test" + ci, command_runner_.commands_ran_[0]);
1319 
1320  state_.Reset();
1321  command_runner_.commands_ran_.clear();
1322  EXPECT_TRUE(builder_.AddTarget("test" + ci, &err));
1323  ASSERT_EQ("", err);
1324  EXPECT_FALSE(builder_.AlreadyUpToDate());
1325  EXPECT_TRUE(builder_.Build(&err));
1326  ASSERT_EQ("", err);
1327  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1328  EXPECT_EQ("touch test" + ci, command_runner_.commands_ran_[0]);
1329  }
1330 }
1331 
1332 TEST_F(BuildTest, PhonyUseCase1) { TestPhonyUseCase(this, 1); }
1333 TEST_F(BuildTest, PhonyUseCase2) { TestPhonyUseCase(this, 2); }
1334 TEST_F(BuildTest, PhonyUseCase3) { TestPhonyUseCase(this, 3); }
1335 TEST_F(BuildTest, PhonyUseCase4) { TestPhonyUseCase(this, 4); }
1336 TEST_F(BuildTest, PhonyUseCase5) { TestPhonyUseCase(this, 5); }
1337 TEST_F(BuildTest, PhonyUseCase6) { TestPhonyUseCase(this, 6); }
1338 
1341 "rule fail\n"
1342 " command = fail\n"
1343 "build out1: fail\n"));
1344 
1345  string err;
1346  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1347  ASSERT_EQ("", err);
1348 
1349  EXPECT_FALSE(builder_.Build(&err));
1350  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1351  ASSERT_EQ("subcommand failed", err);
1352 }
1353 
1354 TEST_F(BuildTest, SwallowFailures) {
1356 "rule fail\n"
1357 " command = fail\n"
1358 "build out1: fail\n"
1359 "build out2: fail\n"
1360 "build out3: fail\n"
1361 "build all: phony out1 out2 out3\n"));
1362 
1363  // Swallow two failures, die on the third.
1364  config_.failures_allowed = 3;
1365 
1366  string err;
1367  EXPECT_TRUE(builder_.AddTarget("all", &err));
1368  ASSERT_EQ("", err);
1369 
1370  EXPECT_FALSE(builder_.Build(&err));
1371  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1372  ASSERT_EQ("subcommands failed", err);
1373 }
1374 
1375 TEST_F(BuildTest, SwallowFailuresLimit) {
1377 "rule fail\n"
1378 " command = fail\n"
1379 "build out1: fail\n"
1380 "build out2: fail\n"
1381 "build out3: fail\n"
1382 "build final: cat out1 out2 out3\n"));
1383 
1384  // Swallow ten failures; we should stop before building final.
1385  config_.failures_allowed = 11;
1386 
1387  string err;
1388  EXPECT_TRUE(builder_.AddTarget("final", &err));
1389  ASSERT_EQ("", err);
1390 
1391  EXPECT_FALSE(builder_.Build(&err));
1392  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1393  ASSERT_EQ("cannot make progress due to previous errors", err);
1394 }
1395 
1396 TEST_F(BuildTest, SwallowFailuresPool) {
1398 "pool failpool\n"
1399 " depth = 1\n"
1400 "rule fail\n"
1401 " command = fail\n"
1402 " pool = failpool\n"
1403 "build out1: fail\n"
1404 "build out2: fail\n"
1405 "build out3: fail\n"
1406 "build final: cat out1 out2 out3\n"));
1407 
1408  // Swallow ten failures; we should stop before building final.
1409  config_.failures_allowed = 11;
1410 
1411  string err;
1412  EXPECT_TRUE(builder_.AddTarget("final", &err));
1413  ASSERT_EQ("", err);
1414 
1415  EXPECT_FALSE(builder_.Build(&err));
1416  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1417  ASSERT_EQ("cannot make progress due to previous errors", err);
1418 }
1419 
1420 TEST_F(BuildTest, PoolEdgesReadyButNotWanted) {
1421  fs_.Create("x", "");
1422 
1423  const char* manifest =
1424  "pool some_pool\n"
1425  " depth = 4\n"
1426  "rule touch\n"
1427  " command = touch $out\n"
1428  " pool = some_pool\n"
1429  "rule cc\n"
1430  " command = touch grit\n"
1431  "\n"
1432  "build B.d.stamp: cc | x\n"
1433  "build C.stamp: touch B.d.stamp\n"
1434  "build final.stamp: touch || C.stamp\n";
1435 
1436  RebuildTarget("final.stamp", manifest);
1437 
1438  fs_.RemoveFile("B.d.stamp");
1439 
1440  State save_state;
1441  RebuildTarget("final.stamp", manifest, NULL, NULL, &save_state);
1442  EXPECT_GE(save_state.LookupPool("some_pool")->current_use(), 0);
1443 }
1444 
1445 struct BuildWithLogTest : public BuildTest {
1447  builder_.SetBuildLog(&build_log_);
1448  }
1449 
1451 };
1452 
1453 TEST_F(BuildWithLogTest, ImplicitGeneratedOutOfDate) {
1455 "rule touch\n"
1456 " command = touch $out\n"
1457 " generator = 1\n"
1458 "build out.imp: touch | in\n"));
1459  fs_.Create("out.imp", "");
1460  fs_.Tick();
1461  fs_.Create("in", "");
1462 
1463  string err;
1464 
1465  EXPECT_TRUE(builder_.AddTarget("out.imp", &err));
1466  EXPECT_FALSE(builder_.AlreadyUpToDate());
1467 
1468  EXPECT_TRUE(GetNode("out.imp")->dirty());
1469 }
1470 
1471 TEST_F(BuildWithLogTest, ImplicitGeneratedOutOfDate2) {
1473 "rule touch-implicit-dep-out\n"
1474 " command = touch $test_dependency ; sleep 1 ; touch $out\n"
1475 " generator = 1\n"
1476 "build out.imp: touch-implicit-dep-out | inimp inimp2\n"
1477 " test_dependency = inimp\n"));
1478  fs_.Create("inimp", "");
1479  fs_.Create("out.imp", "");
1480  fs_.Tick();
1481  fs_.Create("inimp2", "");
1482  fs_.Tick();
1483 
1484  string err;
1485 
1486  EXPECT_TRUE(builder_.AddTarget("out.imp", &err));
1487  EXPECT_FALSE(builder_.AlreadyUpToDate());
1488 
1489  EXPECT_TRUE(builder_.Build(&err));
1490  EXPECT_TRUE(builder_.AlreadyUpToDate());
1491 
1492  command_runner_.commands_ran_.clear();
1493  state_.Reset();
1494  builder_.Cleanup();
1495  builder_.plan_.Reset();
1496 
1497  EXPECT_TRUE(builder_.AddTarget("out.imp", &err));
1498  EXPECT_TRUE(builder_.AlreadyUpToDate());
1499  EXPECT_FALSE(GetNode("out.imp")->dirty());
1500 }
1501 
1502 TEST_F(BuildWithLogTest, NotInLogButOnDisk) {
1504 "rule cc\n"
1505 " command = cc\n"
1506 "build out1: cc in\n"));
1507 
1508  // Create input/output that would be considered up to date when
1509  // not considering the command line hash.
1510  fs_.Create("in", "");
1511  fs_.Create("out1", "");
1512  string err;
1513 
1514  // Because it's not in the log, it should not be up-to-date until
1515  // we build again.
1516  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1517  EXPECT_FALSE(builder_.AlreadyUpToDate());
1518 
1519  command_runner_.commands_ran_.clear();
1520  state_.Reset();
1521 
1522  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1523  EXPECT_TRUE(builder_.Build(&err));
1524  EXPECT_TRUE(builder_.AlreadyUpToDate());
1525 }
1526 
1527 TEST_F(BuildWithLogTest, RebuildAfterFailure) {
1529 "rule touch-fail-tick2\n"
1530 " command = touch-fail-tick2\n"
1531 "build out1: touch-fail-tick2 in\n"));
1532 
1533  string err;
1534 
1535  fs_.Create("in", "");
1536 
1537  // Run once successfully to get out1 in the log
1538  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1539  EXPECT_TRUE(builder_.Build(&err));
1540  EXPECT_EQ("", err);
1541  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1542 
1543  command_runner_.commands_ran_.clear();
1544  state_.Reset();
1545  builder_.Cleanup();
1546  builder_.plan_.Reset();
1547 
1548  fs_.Tick();
1549  fs_.Create("in", "");
1550 
1551  // Run again with a failure that updates the output file timestamp
1552  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1553  EXPECT_FALSE(builder_.Build(&err));
1554  EXPECT_EQ("subcommand failed", err);
1555  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1556 
1557  command_runner_.commands_ran_.clear();
1558  state_.Reset();
1559  builder_.Cleanup();
1560  builder_.plan_.Reset();
1561 
1562  fs_.Tick();
1563 
1564  // Run again, should rerun even though the output file is up to date on disk
1565  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1566  EXPECT_FALSE(builder_.AlreadyUpToDate());
1567  EXPECT_TRUE(builder_.Build(&err));
1568  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1569  EXPECT_EQ("", err);
1570 }
1571 
1572 TEST_F(BuildWithLogTest, RebuildWithNoInputs) {
1574 "rule touch\n"
1575 " command = touch\n"
1576 "build out1: touch\n"
1577 "build out2: touch in\n"));
1578 
1579  string err;
1580 
1581  fs_.Create("in", "");
1582 
1583  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1584  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1585  EXPECT_TRUE(builder_.Build(&err));
1586  EXPECT_EQ("", err);
1587  EXPECT_EQ(2u, command_runner_.commands_ran_.size());
1588 
1589  command_runner_.commands_ran_.clear();
1590  state_.Reset();
1591 
1592  fs_.Tick();
1593 
1594  fs_.Create("in", "");
1595 
1596  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1597  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1598  EXPECT_TRUE(builder_.Build(&err));
1599  EXPECT_EQ("", err);
1600  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1601 }
1602 
1603 TEST_F(BuildWithLogTest, RestatTest) {
1605 "rule true\n"
1606 " command = true\n"
1607 " restat = 1\n"
1608 "rule cc\n"
1609 " command = cc\n"
1610 " restat = 1\n"
1611 "build out1: cc in\n"
1612 "build out2: true out1\n"
1613 "build out3: cat out2\n"));
1614 
1615  fs_.Create("out1", "");
1616  fs_.Create("out2", "");
1617  fs_.Create("out3", "");
1618 
1619  fs_.Tick();
1620 
1621  fs_.Create("in", "");
1622 
1623  // Do a pre-build so that there's commands in the log for the outputs,
1624  // otherwise, the lack of an entry in the build log will cause out3 to rebuild
1625  // regardless of restat.
1626  string err;
1627  EXPECT_TRUE(builder_.AddTarget("out3", &err));
1628  ASSERT_EQ("", err);
1629  EXPECT_TRUE(builder_.Build(&err));
1630  ASSERT_EQ("", err);
1631  EXPECT_EQ(3u, command_runner_.commands_ran_.size());
1632  EXPECT_EQ(3u, builder_.plan_.command_edge_count());
1633  command_runner_.commands_ran_.clear();
1634  state_.Reset();
1635 
1636  fs_.Tick();
1637 
1638  fs_.Create("in", "");
1639  // "cc" touches out1, so we should build out2. But because "true" does not
1640  // touch out2, we should cancel the build of out3.
1641  EXPECT_TRUE(builder_.AddTarget("out3", &err));
1642  ASSERT_EQ("", err);
1643  EXPECT_TRUE(builder_.Build(&err));
1644  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1645 
1646  // If we run again, it should be a no-op, because the build log has recorded
1647  // that we've already built out2 with an input timestamp of 2 (from out1).
1648  command_runner_.commands_ran_.clear();
1649  state_.Reset();
1650  EXPECT_TRUE(builder_.AddTarget("out3", &err));
1651  ASSERT_EQ("", err);
1652  EXPECT_TRUE(builder_.AlreadyUpToDate());
1653 
1654  fs_.Tick();
1655 
1656  fs_.Create("in", "");
1657 
1658  // The build log entry should not, however, prevent us from rebuilding out2
1659  // if out1 changes.
1660  command_runner_.commands_ran_.clear();
1661  state_.Reset();
1662  EXPECT_TRUE(builder_.AddTarget("out3", &err));
1663  ASSERT_EQ("", err);
1664  EXPECT_TRUE(builder_.Build(&err));
1665  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1666 }
1667 
1668 TEST_F(BuildWithLogTest, RestatMissingFile) {
1669  // If a restat rule doesn't create its output, and the output didn't
1670  // exist before the rule was run, consider that behavior equivalent
1671  // to a rule that doesn't modify its existent output file.
1672 
1674 "rule true\n"
1675 " command = true\n"
1676 " restat = 1\n"
1677 "rule cc\n"
1678 " command = cc\n"
1679 "build out1: true in\n"
1680 "build out2: cc out1\n"));
1681 
1682  fs_.Create("in", "");
1683  fs_.Create("out2", "");
1684 
1685  // Do a pre-build so that there's commands in the log for the outputs,
1686  // otherwise, the lack of an entry in the build log will cause out2 to rebuild
1687  // regardless of restat.
1688  string err;
1689  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1690  ASSERT_EQ("", err);
1691  EXPECT_TRUE(builder_.Build(&err));
1692  ASSERT_EQ("", err);
1693  command_runner_.commands_ran_.clear();
1694  state_.Reset();
1695 
1696  fs_.Tick();
1697  fs_.Create("in", "");
1698  fs_.Create("out2", "");
1699 
1700  // Run a build, expect only the first command to run.
1701  // It doesn't touch its output (due to being the "true" command), so
1702  // we shouldn't run the dependent build.
1703  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1704  ASSERT_EQ("", err);
1705  EXPECT_TRUE(builder_.Build(&err));
1706  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1707 }
1708 
1709 TEST_F(BuildWithLogTest, RestatSingleDependentOutputDirty) {
1711  "rule true\n"
1712  " command = true\n"
1713  " restat = 1\n"
1714  "rule touch\n"
1715  " command = touch\n"
1716  "build out1: true in\n"
1717  "build out2 out3: touch out1\n"
1718  "build out4: touch out2\n"
1719  ));
1720 
1721  // Create the necessary files
1722  fs_.Create("in", "");
1723 
1724  string err;
1725  EXPECT_TRUE(builder_.AddTarget("out4", &err));
1726  ASSERT_EQ("", err);
1727  EXPECT_TRUE(builder_.Build(&err));
1728  ASSERT_EQ("", err);
1729  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1730 
1731  fs_.Tick();
1732  fs_.Create("in", "");
1733  fs_.RemoveFile("out3");
1734 
1735  // Since "in" is missing, out1 will be built. Since "out3" is missing,
1736  // out2 and out3 will be built even though "in" is not touched when built.
1737  // Then, since out2 is rebuilt, out4 should be rebuilt -- the restat on the
1738  // "true" rule should not lead to the "touch" edge writing out2 and out3 being
1739  // cleard.
1740  command_runner_.commands_ran_.clear();
1741  state_.Reset();
1742  EXPECT_TRUE(builder_.AddTarget("out4", &err));
1743  ASSERT_EQ("", err);
1744  EXPECT_TRUE(builder_.Build(&err));
1745  ASSERT_EQ("", err);
1746  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1747 }
1748 
1749 // Test scenario, in which an input file is removed, but output isn't changed
1750 // https://github.com/ninja-build/ninja/issues/295
1751 TEST_F(BuildWithLogTest, RestatMissingInput) {
1753  "rule true\n"
1754  " command = true\n"
1755  " depfile = $out.d\n"
1756  " restat = 1\n"
1757  "rule cc\n"
1758  " command = cc\n"
1759  "build out1: true in\n"
1760  "build out2: cc out1\n"));
1761 
1762  // Create all necessary files
1763  fs_.Create("in", "");
1764 
1765  // The implicit dependencies and the depfile itself
1766  // are newer than the output
1767  TimeStamp restat_mtime = fs_.Tick();
1768  fs_.Create("out1.d", "out1: will.be.deleted restat.file\n");
1769  fs_.Create("will.be.deleted", "");
1770  fs_.Create("restat.file", "");
1771 
1772  // Run the build, out1 and out2 get built
1773  string err;
1774  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1775  ASSERT_EQ("", err);
1776  EXPECT_TRUE(builder_.Build(&err));
1777  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1778 
1779  // See that an entry in the logfile is created, capturing
1780  // the right mtime
1781  BuildLog::LogEntry* log_entry = build_log_.LookupByOutput("out1");
1782  ASSERT_TRUE(NULL != log_entry);
1783  ASSERT_EQ(restat_mtime, log_entry->mtime);
1784 
1785  // Now remove a file, referenced from depfile, so that target becomes
1786  // dirty, but the output does not change
1787  fs_.RemoveFile("will.be.deleted");
1788 
1789  // Trigger the build again - only out1 gets built
1790  command_runner_.commands_ran_.clear();
1791  state_.Reset();
1792  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1793  ASSERT_EQ("", err);
1794  EXPECT_TRUE(builder_.Build(&err));
1795  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1796 
1797  // Check that the logfile entry remains correctly set
1798  log_entry = build_log_.LookupByOutput("out1");
1799  ASSERT_TRUE(NULL != log_entry);
1800  ASSERT_EQ(restat_mtime, log_entry->mtime);
1801 }
1802 
1803 TEST_F(BuildWithLogTest, GeneratedPlainDepfileMtime) {
1805 "rule generate-depfile\n"
1806 " command = touch $out ; echo \"$out: $test_dependency\" > $depfile\n"
1807 "build out: generate-depfile\n"
1808 " test_dependency = inimp\n"
1809 " depfile = out.d\n"));
1810  fs_.Create("inimp", "");
1811  fs_.Tick();
1812 
1813  string err;
1814 
1815  EXPECT_TRUE(builder_.AddTarget("out", &err));
1816  EXPECT_FALSE(builder_.AlreadyUpToDate());
1817 
1818  EXPECT_TRUE(builder_.Build(&err));
1819  EXPECT_TRUE(builder_.AlreadyUpToDate());
1820 
1821  command_runner_.commands_ran_.clear();
1822  state_.Reset();
1823  builder_.Cleanup();
1824  builder_.plan_.Reset();
1825 
1826  EXPECT_TRUE(builder_.AddTarget("out", &err));
1827  EXPECT_TRUE(builder_.AlreadyUpToDate());
1828 }
1829 
1832  config_.dry_run = true;
1833  }
1834 };
1835 
1836 TEST_F(BuildDryRun, AllCommandsShown) {
1838 "rule true\n"
1839 " command = true\n"
1840 " restat = 1\n"
1841 "rule cc\n"
1842 " command = cc\n"
1843 " restat = 1\n"
1844 "build out1: cc in\n"
1845 "build out2: true out1\n"
1846 "build out3: cat out2\n"));
1847 
1848  fs_.Create("out1", "");
1849  fs_.Create("out2", "");
1850  fs_.Create("out3", "");
1851 
1852  fs_.Tick();
1853 
1854  fs_.Create("in", "");
1855 
1856  // "cc" touches out1, so we should build out2. But because "true" does not
1857  // touch out2, we should cancel the build of out3.
1858  string err;
1859  EXPECT_TRUE(builder_.AddTarget("out3", &err));
1860  ASSERT_EQ("", err);
1861  EXPECT_TRUE(builder_.Build(&err));
1862  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1863 }
1864 
1865 // Test that RSP files are created when & where appropriate and deleted after
1866 // successful execution.
1867 TEST_F(BuildTest, RspFileSuccess)
1868 {
1870  "rule cat_rsp\n"
1871  " command = cat $rspfile > $out\n"
1872  " rspfile = $rspfile\n"
1873  " rspfile_content = $long_command\n"
1874  "rule cat_rsp_out\n"
1875  " command = cat $rspfile > $out\n"
1876  " rspfile = $out.rsp\n"
1877  " rspfile_content = $long_command\n"
1878  "build out1: cat in\n"
1879  "build out2: cat_rsp in\n"
1880  " rspfile = out 2.rsp\n"
1881  " long_command = Some very long command\n"
1882  "build out$ 3: cat_rsp_out in\n"
1883  " long_command = Some very long command\n"));
1884 
1885  fs_.Create("out1", "");
1886  fs_.Create("out2", "");
1887  fs_.Create("out 3", "");
1888 
1889  fs_.Tick();
1890 
1891  fs_.Create("in", "");
1892 
1893  string err;
1894  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1895  ASSERT_EQ("", err);
1896  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1897  ASSERT_EQ("", err);
1898  EXPECT_TRUE(builder_.AddTarget("out 3", &err));
1899  ASSERT_EQ("", err);
1900 
1901  size_t files_created = fs_.files_created_.size();
1902  size_t files_removed = fs_.files_removed_.size();
1903 
1904  EXPECT_TRUE(builder_.Build(&err));
1905  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1906 
1907  // The RSP files were created
1908  ASSERT_EQ(files_created + 2, fs_.files_created_.size());
1909  ASSERT_EQ(1u, fs_.files_created_.count("out 2.rsp"));
1910  ASSERT_EQ(1u, fs_.files_created_.count("out 3.rsp"));
1911 
1912  // The RSP files were removed
1913  ASSERT_EQ(files_removed + 2, fs_.files_removed_.size());
1914  ASSERT_EQ(1u, fs_.files_removed_.count("out 2.rsp"));
1915  ASSERT_EQ(1u, fs_.files_removed_.count("out 3.rsp"));
1916 }
1917 
1918 // Test that RSP file is created but not removed for commands, which fail
1919 TEST_F(BuildTest, RspFileFailure) {
1921  "rule fail\n"
1922  " command = fail\n"
1923  " rspfile = $rspfile\n"
1924  " rspfile_content = $long_command\n"
1925  "build out: fail in\n"
1926  " rspfile = out.rsp\n"
1927  " long_command = Another very long command\n"));
1928 
1929  fs_.Create("out", "");
1930  fs_.Tick();
1931  fs_.Create("in", "");
1932 
1933  string err;
1934  EXPECT_TRUE(builder_.AddTarget("out", &err));
1935  ASSERT_EQ("", err);
1936 
1937  size_t files_created = fs_.files_created_.size();
1938  size_t files_removed = fs_.files_removed_.size();
1939 
1940  EXPECT_FALSE(builder_.Build(&err));
1941  ASSERT_EQ("subcommand failed", err);
1942  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1943 
1944  // The RSP file was created
1945  ASSERT_EQ(files_created + 1, fs_.files_created_.size());
1946  ASSERT_EQ(1u, fs_.files_created_.count("out.rsp"));
1947 
1948  // The RSP file was NOT removed
1949  ASSERT_EQ(files_removed, fs_.files_removed_.size());
1950  ASSERT_EQ(0u, fs_.files_removed_.count("out.rsp"));
1951 
1952  // The RSP file contains what it should
1953  ASSERT_EQ("Another very long command", fs_.files_["out.rsp"].contents);
1954 }
1955 
1956 // Test that contents of the RSP file behaves like a regular part of
1957 // command line, i.e. triggers a rebuild if changed
1958 TEST_F(BuildWithLogTest, RspFileCmdLineChange) {
1960  "rule cat_rsp\n"
1961  " command = cat $rspfile > $out\n"
1962  " rspfile = $rspfile\n"
1963  " rspfile_content = $long_command\n"
1964  "build out: cat_rsp in\n"
1965  " rspfile = out.rsp\n"
1966  " long_command = Original very long command\n"));
1967 
1968  fs_.Create("out", "");
1969  fs_.Tick();
1970  fs_.Create("in", "");
1971 
1972  string err;
1973  EXPECT_TRUE(builder_.AddTarget("out", &err));
1974  ASSERT_EQ("", err);
1975 
1976  // 1. Build for the 1st time (-> populate log)
1977  EXPECT_TRUE(builder_.Build(&err));
1978  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1979 
1980  // 2. Build again (no change)
1981  command_runner_.commands_ran_.clear();
1982  state_.Reset();
1983  EXPECT_TRUE(builder_.AddTarget("out", &err));
1984  EXPECT_EQ("", err);
1985  ASSERT_TRUE(builder_.AlreadyUpToDate());
1986 
1987  // 3. Alter the entry in the logfile
1988  // (to simulate a change in the command line between 2 builds)
1989  BuildLog::LogEntry* log_entry = build_log_.LookupByOutput("out");
1990  ASSERT_TRUE(NULL != log_entry);
1992  "cat out.rsp > out;rspfile=Original very long command",
1993  log_entry->command_hash));
1994  log_entry->command_hash++; // Change the command hash to something else.
1995  // Now expect the target to be rebuilt
1996  command_runner_.commands_ran_.clear();
1997  state_.Reset();
1998  EXPECT_TRUE(builder_.AddTarget("out", &err));
1999  EXPECT_EQ("", err);
2000  EXPECT_TRUE(builder_.Build(&err));
2001  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
2002 }
2003 
2004 TEST_F(BuildTest, InterruptCleanup) {
2006 "rule interrupt\n"
2007 " command = interrupt\n"
2008 "rule touch-interrupt\n"
2009 " command = touch-interrupt\n"
2010 "build out1: interrupt in1\n"
2011 "build out2: touch-interrupt in2\n"));
2012 
2013  fs_.Create("out1", "");
2014  fs_.Create("out2", "");
2015  fs_.Tick();
2016  fs_.Create("in1", "");
2017  fs_.Create("in2", "");
2018 
2019  // An untouched output of an interrupted command should be retained.
2020  string err;
2021  EXPECT_TRUE(builder_.AddTarget("out1", &err));
2022  EXPECT_EQ("", err);
2023  EXPECT_FALSE(builder_.Build(&err));
2024  EXPECT_EQ("interrupted by user", err);
2025  builder_.Cleanup();
2026  EXPECT_GT(fs_.Stat("out1", &err), 0);
2027  err = "";
2028 
2029  // A touched output of an interrupted command should be deleted.
2030  EXPECT_TRUE(builder_.AddTarget("out2", &err));
2031  EXPECT_EQ("", err);
2032  EXPECT_FALSE(builder_.Build(&err));
2033  EXPECT_EQ("interrupted by user", err);
2034  builder_.Cleanup();
2035  EXPECT_EQ(0, fs_.Stat("out2", &err));
2036 }
2037 
2038 TEST_F(BuildTest, StatFailureAbortsBuild) {
2039  const string kTooLongToStat(400, 'i');
2041 ("build " + kTooLongToStat + ": cat in\n").c_str()));
2042  fs_.Create("in", "");
2043 
2044  // This simulates a stat failure:
2045  fs_.files_[kTooLongToStat].mtime = -1;
2046  fs_.files_[kTooLongToStat].stat_error = "stat failed";
2047 
2048  string err;
2049  EXPECT_FALSE(builder_.AddTarget(kTooLongToStat, &err));
2050  EXPECT_EQ("stat failed", err);
2051 }
2052 
2053 TEST_F(BuildTest, PhonyWithNoInputs) {
2055 "build nonexistent: phony\n"
2056 "build out1: cat || nonexistent\n"
2057 "build out2: cat nonexistent\n"));
2058  fs_.Create("out1", "");
2059  fs_.Create("out2", "");
2060 
2061  // out1 should be up to date even though its input is dirty, because its
2062  // order-only dependency has nothing to do.
2063  string err;
2064  EXPECT_TRUE(builder_.AddTarget("out1", &err));
2065  ASSERT_EQ("", err);
2066  EXPECT_TRUE(builder_.AlreadyUpToDate());
2067 
2068  // out2 should still be out of date though, because its input is dirty.
2069  err.clear();
2070  command_runner_.commands_ran_.clear();
2071  state_.Reset();
2072  EXPECT_TRUE(builder_.AddTarget("out2", &err));
2073  ASSERT_EQ("", err);
2074  EXPECT_TRUE(builder_.Build(&err));
2075  EXPECT_EQ("", err);
2076  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2077 }
2078 
2079 TEST_F(BuildTest, DepsGccWithEmptyDepfileErrorsOut) {
2081 "rule cc\n"
2082 " command = cc\n"
2083 " deps = gcc\n"
2084 "build out: cc\n"));
2085  Dirty("out");
2086 
2087  string err;
2088  EXPECT_TRUE(builder_.AddTarget("out", &err));
2089  ASSERT_EQ("", err);
2090  EXPECT_FALSE(builder_.AlreadyUpToDate());
2091 
2092  EXPECT_FALSE(builder_.Build(&err));
2093  ASSERT_EQ("subcommand failed", err);
2094  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2095 }
2096 
2097 TEST_F(BuildTest, StatusFormatElapsed) {
2098  status_.BuildStarted();
2099  // Before any task is done, the elapsed time must be zero.
2100  EXPECT_EQ("[%/e0.000]",
2101  status_.FormatProgressStatus("[%%/e%e]", 0));
2102 }
2103 
2104 TEST_F(BuildTest, StatusFormatReplacePlaceholder) {
2105  EXPECT_EQ("[%/s0/t0/r0/u0/f0]",
2106  status_.FormatProgressStatus("[%%/s%s/t%t/r%r/u%u/f%f]", 0));
2107 }
2108 
2109 TEST_F(BuildTest, FailedDepsParse) {
2111 "build bad_deps.o: cat in1\n"
2112 " deps = gcc\n"
2113 " depfile = in1.d\n"));
2114 
2115  string err;
2116  EXPECT_TRUE(builder_.AddTarget("bad_deps.o", &err));
2117  ASSERT_EQ("", err);
2118 
2119  // These deps will fail to parse, as they should only have one
2120  // path to the left of the colon.
2121  fs_.Create("in1.d", "AAA BBB");
2122 
2123  EXPECT_FALSE(builder_.Build(&err));
2124  EXPECT_EQ("subcommand failed", err);
2125 }
2126 
2129  }
2130 
2132  log_.Close();
2133  }
2134 
2135  virtual void SetUp() {
2136  BuildTest::SetUp();
2137 
2138  temp_dir_.CreateAndEnter("BuildWithQueryDepsLogTest");
2139 
2140  std::string err;
2141  ASSERT_TRUE(log_.OpenForWrite("ninja_deps", &err));
2142  ASSERT_EQ("", err);
2143  }
2144 
2146 
2148 };
2149 
2150 /// Test a MSVC-style deps log with multiple outputs.
2151 TEST_F(BuildWithQueryDepsLogTest, TwoOutputsDepFileMSVC) {
2153 "rule cp_multi_msvc\n"
2154 " command = echo 'using $in' && for file in $out; do cp $in $$file; done\n"
2155 " deps = msvc\n"
2156 " msvc_deps_prefix = using \n"
2157 "build out1 out2: cp_multi_msvc in1\n"));
2158 
2159  std::string err;
2160  EXPECT_TRUE(builder_.AddTarget("out1", &err));
2161  ASSERT_EQ("", err);
2162  EXPECT_TRUE(builder_.Build(&err));
2163  EXPECT_EQ("", err);
2164  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2165  EXPECT_EQ("echo 'using in1' && for file in out1 out2; do cp in1 $file; done", command_runner_.commands_ran_[0]);
2166 
2167  Node* out1_node = state_.LookupNode("out1");
2168  DepsLog::Deps* out1_deps = log_.GetDeps(out1_node);
2169  EXPECT_EQ(1, out1_deps->node_count);
2170  EXPECT_EQ("in1", out1_deps->nodes[0]->path());
2171 
2172  Node* out2_node = state_.LookupNode("out2");
2173  DepsLog::Deps* out2_deps = log_.GetDeps(out2_node);
2174  EXPECT_EQ(1, out2_deps->node_count);
2175  EXPECT_EQ("in1", out2_deps->nodes[0]->path());
2176 }
2177 
2178 /// Test a GCC-style deps log with multiple outputs.
2179 TEST_F(BuildWithQueryDepsLogTest, TwoOutputsDepFileGCCOneLine) {
2181 "rule cp_multi_gcc\n"
2182 " command = echo '$out: $in' > in.d && for file in $out; do cp in1 $$file; done\n"
2183 " deps = gcc\n"
2184 " depfile = in.d\n"
2185 "build out1 out2: cp_multi_gcc in1 in2\n"));
2186 
2187  std::string err;
2188  EXPECT_TRUE(builder_.AddTarget("out1", &err));
2189  ASSERT_EQ("", err);
2190  fs_.Create("in.d", "out1 out2: in1 in2");
2191  EXPECT_TRUE(builder_.Build(&err));
2192  EXPECT_EQ("", err);
2193  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2194  EXPECT_EQ("echo 'out1 out2: in1 in2' > in.d && for file in out1 out2; do cp in1 $file; done", command_runner_.commands_ran_[0]);
2195 
2196  Node* out1_node = state_.LookupNode("out1");
2197  DepsLog::Deps* out1_deps = log_.GetDeps(out1_node);
2198  EXPECT_EQ(2, out1_deps->node_count);
2199  EXPECT_EQ("in1", out1_deps->nodes[0]->path());
2200  EXPECT_EQ("in2", out1_deps->nodes[1]->path());
2201 
2202  Node* out2_node = state_.LookupNode("out2");
2203  DepsLog::Deps* out2_deps = log_.GetDeps(out2_node);
2204  EXPECT_EQ(2, out2_deps->node_count);
2205  EXPECT_EQ("in1", out2_deps->nodes[0]->path());
2206  EXPECT_EQ("in2", out2_deps->nodes[1]->path());
2207 }
2208 
2209 /// Test a GCC-style deps log with multiple outputs using a line per input.
2210 TEST_F(BuildWithQueryDepsLogTest, TwoOutputsDepFileGCCMultiLineInput) {
2212 "rule cp_multi_gcc\n"
2213 " command = echo '$out: in1\\n$out: in2' > in.d && for file in $out; do cp in1 $$file; done\n"
2214 " deps = gcc\n"
2215 " depfile = in.d\n"
2216 "build out1 out2: cp_multi_gcc in1 in2\n"));
2217 
2218  std::string err;
2219  EXPECT_TRUE(builder_.AddTarget("out1", &err));
2220  ASSERT_EQ("", err);
2221  fs_.Create("in.d", "out1 out2: in1\nout1 out2: in2");
2222  EXPECT_TRUE(builder_.Build(&err));
2223  EXPECT_EQ("", err);
2224  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2225  EXPECT_EQ("echo 'out1 out2: in1\\nout1 out2: in2' > in.d && for file in out1 out2; do cp in1 $file; done", command_runner_.commands_ran_[0]);
2226 
2227  Node* out1_node = state_.LookupNode("out1");
2228  DepsLog::Deps* out1_deps = log_.GetDeps(out1_node);
2229  EXPECT_EQ(2, out1_deps->node_count);
2230  EXPECT_EQ("in1", out1_deps->nodes[0]->path());
2231  EXPECT_EQ("in2", out1_deps->nodes[1]->path());
2232 
2233  Node* out2_node = state_.LookupNode("out2");
2234  DepsLog::Deps* out2_deps = log_.GetDeps(out2_node);
2235  EXPECT_EQ(2, out2_deps->node_count);
2236  EXPECT_EQ("in1", out2_deps->nodes[0]->path());
2237  EXPECT_EQ("in2", out2_deps->nodes[1]->path());
2238 }
2239 
2240 /// Test a GCC-style deps log with multiple outputs using a line per output.
2241 TEST_F(BuildWithQueryDepsLogTest, TwoOutputsDepFileGCCMultiLineOutput) {
2243 "rule cp_multi_gcc\n"
2244 " command = echo 'out1: $in\\nout2: $in' > in.d && for file in $out; do cp in1 $$file; done\n"
2245 " deps = gcc\n"
2246 " depfile = in.d\n"
2247 "build out1 out2: cp_multi_gcc in1 in2\n"));
2248 
2249  std::string err;
2250  EXPECT_TRUE(builder_.AddTarget("out1", &err));
2251  ASSERT_EQ("", err);
2252  fs_.Create("in.d", "out1: in1 in2\nout2: in1 in2");
2253  EXPECT_TRUE(builder_.Build(&err));
2254  EXPECT_EQ("", err);
2255  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2256  EXPECT_EQ("echo 'out1: in1 in2\\nout2: in1 in2' > in.d && for file in out1 out2; do cp in1 $file; done", command_runner_.commands_ran_[0]);
2257 
2258  Node* out1_node = state_.LookupNode("out1");
2259  DepsLog::Deps* out1_deps = log_.GetDeps(out1_node);
2260  EXPECT_EQ(2, out1_deps->node_count);
2261  EXPECT_EQ("in1", out1_deps->nodes[0]->path());
2262  EXPECT_EQ("in2", out1_deps->nodes[1]->path());
2263 
2264  Node* out2_node = state_.LookupNode("out2");
2265  DepsLog::Deps* out2_deps = log_.GetDeps(out2_node);
2266  EXPECT_EQ(2, out2_deps->node_count);
2267  EXPECT_EQ("in1", out2_deps->nodes[0]->path());
2268  EXPECT_EQ("in2", out2_deps->nodes[1]->path());
2269 }
2270 
2271 /// Test a GCC-style deps log with multiple outputs mentioning only the main output.
2272 TEST_F(BuildWithQueryDepsLogTest, TwoOutputsDepFileGCCOnlyMainOutput) {
2274 "rule cp_multi_gcc\n"
2275 " command = echo 'out1: $in' > in.d && for file in $out; do cp in1 $$file; done\n"
2276 " deps = gcc\n"
2277 " depfile = in.d\n"
2278 "build out1 out2: cp_multi_gcc in1 in2\n"));
2279 
2280  std::string err;
2281  EXPECT_TRUE(builder_.AddTarget("out1", &err));
2282  ASSERT_EQ("", err);
2283  fs_.Create("in.d", "out1: in1 in2");
2284  EXPECT_TRUE(builder_.Build(&err));
2285  EXPECT_EQ("", err);
2286  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2287  EXPECT_EQ("echo 'out1: in1 in2' > in.d && for file in out1 out2; do cp in1 $file; done", command_runner_.commands_ran_[0]);
2288 
2289  Node* out1_node = state_.LookupNode("out1");
2290  DepsLog::Deps* out1_deps = log_.GetDeps(out1_node);
2291  EXPECT_EQ(2, out1_deps->node_count);
2292  EXPECT_EQ("in1", out1_deps->nodes[0]->path());
2293  EXPECT_EQ("in2", out1_deps->nodes[1]->path());
2294 
2295  Node* out2_node = state_.LookupNode("out2");
2296  DepsLog::Deps* out2_deps = log_.GetDeps(out2_node);
2297  EXPECT_EQ(2, out2_deps->node_count);
2298  EXPECT_EQ("in1", out2_deps->nodes[0]->path());
2299  EXPECT_EQ("in2", out2_deps->nodes[1]->path());
2300 }
2301 
2302 /// Test a GCC-style deps log with multiple outputs mentioning only the secondary output.
2303 TEST_F(BuildWithQueryDepsLogTest, TwoOutputsDepFileGCCOnlySecondaryOutput) {
2304  // Note: This ends up short-circuiting the node creation due to the primary
2305  // output not being present, but it should still work.
2307 "rule cp_multi_gcc\n"
2308 " command = echo 'out2: $in' > in.d && for file in $out; do cp in1 $$file; done\n"
2309 " deps = gcc\n"
2310 " depfile = in.d\n"
2311 "build out1 out2: cp_multi_gcc in1 in2\n"));
2312 
2313  std::string err;
2314  EXPECT_TRUE(builder_.AddTarget("out1", &err));
2315  ASSERT_EQ("", err);
2316  fs_.Create("in.d", "out2: in1 in2");
2317  EXPECT_TRUE(builder_.Build(&err));
2318  EXPECT_EQ("", err);
2319  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2320  EXPECT_EQ("echo 'out2: in1 in2' > in.d && for file in out1 out2; do cp in1 $file; done", command_runner_.commands_ran_[0]);
2321 
2322  Node* out1_node = state_.LookupNode("out1");
2323  DepsLog::Deps* out1_deps = log_.GetDeps(out1_node);
2324  EXPECT_EQ(2, out1_deps->node_count);
2325  EXPECT_EQ("in1", out1_deps->nodes[0]->path());
2326  EXPECT_EQ("in2", out1_deps->nodes[1]->path());
2327 
2328  Node* out2_node = state_.LookupNode("out2");
2329  DepsLog::Deps* out2_deps = log_.GetDeps(out2_node);
2330  EXPECT_EQ(2, out2_deps->node_count);
2331  EXPECT_EQ("in1", out2_deps->nodes[0]->path());
2332  EXPECT_EQ("in2", out2_deps->nodes[1]->path());
2333 }
2334 
2335 /// Tests of builds involving deps logs necessarily must span
2336 /// multiple builds. We reuse methods on BuildTest but not the
2337 /// builder_ it sets up, because we want pristine objects for
2338 /// each build.
2341 
2342  virtual void SetUp() {
2343  BuildTest::SetUp();
2344 
2345  temp_dir_.CreateAndEnter("BuildWithDepsLogTest");
2346  }
2347 
2348  virtual void TearDown() {
2349  temp_dir_.Cleanup();
2350  }
2351 
2353 
2354  /// Shadow parent class builder_ so we don't accidentally use it.
2355  void* builder_;
2356 };
2357 
2358 /// Run a straightforward build where the deps log is used.
2359 TEST_F(BuildWithDepsLogTest, Straightforward) {
2360  string err;
2361  // Note: in1 was created by the superclass SetUp().
2362  const char* manifest =
2363  "build out: cat in1\n"
2364  " deps = gcc\n"
2365  " depfile = in1.d\n";
2366  {
2367  State state;
2368  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2369  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2370 
2371  // Run the build once, everything should be ok.
2372  DepsLog deps_log;
2373  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2374  ASSERT_EQ("", err);
2375 
2376  Builder builder(&state, config_, NULL, &deps_log, &fs_, &status_, 0);
2377  builder.command_runner_.reset(&command_runner_);
2378  EXPECT_TRUE(builder.AddTarget("out", &err));
2379  ASSERT_EQ("", err);
2380  fs_.Create("in1.d", "out: in2");
2381  EXPECT_TRUE(builder.Build(&err));
2382  EXPECT_EQ("", err);
2383 
2384  // The deps file should have been removed.
2385  EXPECT_EQ(0, fs_.Stat("in1.d", &err));
2386  // Recreate it for the next step.
2387  fs_.Create("in1.d", "out: in2");
2388  deps_log.Close();
2389  builder.command_runner_.release();
2390  }
2391 
2392  {
2393  State state;
2394  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2395  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2396 
2397  // Touch the file only mentioned in the deps.
2398  fs_.Tick();
2399  fs_.Create("in2", "");
2400 
2401  // Run the build again.
2402  DepsLog deps_log;
2403  ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
2404  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2405 
2406  Builder builder(&state, config_, NULL, &deps_log, &fs_, &status_, 0);
2407  builder.command_runner_.reset(&command_runner_);
2408  command_runner_.commands_ran_.clear();
2409  EXPECT_TRUE(builder.AddTarget("out", &err));
2410  ASSERT_EQ("", err);
2411  EXPECT_TRUE(builder.Build(&err));
2412  EXPECT_EQ("", err);
2413 
2414  // We should have rebuilt the output due to in2 being
2415  // out of date.
2416  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
2417 
2418  builder.command_runner_.release();
2419  }
2420 }
2421 
2422 /// Verify that obsolete dependency info causes a rebuild.
2423 /// 1) Run a successful build where everything has time t, record deps.
2424 /// 2) Move input/output to time t+1 -- despite files in alignment,
2425 /// should still need to rebuild due to deps at older time.
2427  string err;
2428  // Note: in1 was created by the superclass SetUp().
2429  const char* manifest =
2430  "build out: cat in1\n"
2431  " deps = gcc\n"
2432  " depfile = in1.d\n";
2433  {
2434  // Run an ordinary build that gathers dependencies.
2435  fs_.Create("in1", "");
2436  fs_.Create("in1.d", "out: ");
2437 
2438  State state;
2439  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2440  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2441 
2442  // Run the build once, everything should be ok.
2443  DepsLog deps_log;
2444  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2445  ASSERT_EQ("", err);
2446 
2447  Builder builder(&state, config_, NULL, &deps_log, &fs_, &status_, 0);
2448  builder.command_runner_.reset(&command_runner_);
2449  EXPECT_TRUE(builder.AddTarget("out", &err));
2450  ASSERT_EQ("", err);
2451  EXPECT_TRUE(builder.Build(&err));
2452  EXPECT_EQ("", err);
2453 
2454  deps_log.Close();
2455  builder.command_runner_.release();
2456  }
2457 
2458  // Push all files one tick forward so that only the deps are out
2459  // of date.
2460  fs_.Tick();
2461  fs_.Create("in1", "");
2462  fs_.Create("out", "");
2463 
2464  // The deps file should have been removed, so no need to timestamp it.
2465  EXPECT_EQ(0, fs_.Stat("in1.d", &err));
2466 
2467  {
2468  State state;
2469  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2470  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2471 
2472  DepsLog deps_log;
2473  ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
2474  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2475 
2476  Builder builder(&state, config_, NULL, &deps_log, &fs_, &status_, 0);
2477  builder.command_runner_.reset(&command_runner_);
2478  command_runner_.commands_ran_.clear();
2479  EXPECT_TRUE(builder.AddTarget("out", &err));
2480  ASSERT_EQ("", err);
2481 
2482  // Recreate the deps file here because the build expects them to exist.
2483  fs_.Create("in1.d", "out: ");
2484 
2485  EXPECT_TRUE(builder.Build(&err));
2486  EXPECT_EQ("", err);
2487 
2488  // We should have rebuilt the output due to the deps being
2489  // out of date.
2490  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
2491 
2492  builder.command_runner_.release();
2493  }
2494 }
2495 
2496 TEST_F(BuildWithDepsLogTest, DepsIgnoredInDryRun) {
2497  const char* manifest =
2498  "build out: cat in1\n"
2499  " deps = gcc\n"
2500  " depfile = in1.d\n";
2501 
2502  fs_.Create("out", "");
2503  fs_.Tick();
2504  fs_.Create("in1", "");
2505 
2506  State state;
2507  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2508  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2509 
2510  // The deps log is NULL in dry runs.
2511  config_.dry_run = true;
2512  Builder builder(&state, config_, NULL, NULL, &fs_, &status_, 0);
2513  builder.command_runner_.reset(&command_runner_);
2514  command_runner_.commands_ran_.clear();
2515 
2516  string err;
2517  EXPECT_TRUE(builder.AddTarget("out", &err));
2518  ASSERT_EQ("", err);
2519  EXPECT_TRUE(builder.Build(&err));
2520  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2521 
2522  builder.command_runner_.release();
2523 }
2524 
2525 /// Check that a restat rule generating a header cancels compilations correctly.
2526 TEST_F(BuildTest, RestatDepfileDependency) {
2528 "rule true\n"
2529 " command = true\n" // Would be "write if out-of-date" in reality.
2530 " restat = 1\n"
2531 "build header.h: true header.in\n"
2532 "build out: cat in1\n"
2533 " depfile = in1.d\n"));
2534 
2535  fs_.Create("header.h", "");
2536  fs_.Create("in1.d", "out: header.h");
2537  fs_.Tick();
2538  fs_.Create("header.in", "");
2539 
2540  string err;
2541  EXPECT_TRUE(builder_.AddTarget("out", &err));
2542  ASSERT_EQ("", err);
2543  EXPECT_TRUE(builder_.Build(&err));
2544  EXPECT_EQ("", err);
2545 }
2546 
2547 /// Check that a restat rule generating a header cancels compilations correctly,
2548 /// depslog case.
2549 TEST_F(BuildWithDepsLogTest, RestatDepfileDependencyDepsLog) {
2550  string err;
2551  // Note: in1 was created by the superclass SetUp().
2552  const char* manifest =
2553  "rule true\n"
2554  " command = true\n" // Would be "write if out-of-date" in reality.
2555  " restat = 1\n"
2556  "build header.h: true header.in\n"
2557  "build out: cat in1\n"
2558  " deps = gcc\n"
2559  " depfile = in1.d\n";
2560  {
2561  State state;
2562  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2563  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2564 
2565  // Run the build once, everything should be ok.
2566  DepsLog deps_log;
2567  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2568  ASSERT_EQ("", err);
2569 
2570  Builder builder(&state, config_, NULL, &deps_log, &fs_, &status_, 0);
2571  builder.command_runner_.reset(&command_runner_);
2572  EXPECT_TRUE(builder.AddTarget("out", &err));
2573  ASSERT_EQ("", err);
2574  fs_.Create("in1.d", "out: header.h");
2575  EXPECT_TRUE(builder.Build(&err));
2576  EXPECT_EQ("", err);
2577 
2578  deps_log.Close();
2579  builder.command_runner_.release();
2580  }
2581 
2582  {
2583  State state;
2584  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2585  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2586 
2587  // Touch the input of the restat rule.
2588  fs_.Tick();
2589  fs_.Create("header.in", "");
2590 
2591  // Run the build again.
2592  DepsLog deps_log;
2593  ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
2594  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2595 
2596  Builder builder(&state, config_, NULL, &deps_log, &fs_, &status_, 0);
2597  builder.command_runner_.reset(&command_runner_);
2598  command_runner_.commands_ran_.clear();
2599  EXPECT_TRUE(builder.AddTarget("out", &err));
2600  ASSERT_EQ("", err);
2601  EXPECT_TRUE(builder.Build(&err));
2602  EXPECT_EQ("", err);
2603 
2604  // Rule "true" should have run again, but the build of "out" should have
2605  // been cancelled due to restat propagating through the depfile header.
2606  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
2607 
2608  builder.command_runner_.release();
2609  }
2610 }
2611 
2612 TEST_F(BuildWithDepsLogTest, DepFileOKDepsLog) {
2613  string err;
2614  const char* manifest =
2615  "rule cc\n command = cc $in\n depfile = $out.d\n deps = gcc\n"
2616  "build fo$ o.o: cc foo.c\n";
2617 
2618  fs_.Create("foo.c", "");
2619 
2620  {
2621  State state;
2622  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2623 
2624  // Run the build once, everything should be ok.
2625  DepsLog deps_log;
2626  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2627  ASSERT_EQ("", err);
2628 
2629  Builder builder(&state, config_, NULL, &deps_log, &fs_, &status_, 0);
2630  builder.command_runner_.reset(&command_runner_);
2631  EXPECT_TRUE(builder.AddTarget("fo o.o", &err));
2632  ASSERT_EQ("", err);
2633  fs_.Create("fo o.o.d", "fo\\ o.o: blah.h bar.h\n");
2634  EXPECT_TRUE(builder.Build(&err));
2635  EXPECT_EQ("", err);
2636 
2637  deps_log.Close();
2638  builder.command_runner_.release();
2639  }
2640 
2641  {
2642  State state;
2643  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2644 
2645  DepsLog deps_log;
2646  ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
2647  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2648  ASSERT_EQ("", err);
2649 
2650  Builder builder(&state, config_, NULL, &deps_log, &fs_, &status_, 0);
2651  builder.command_runner_.reset(&command_runner_);
2652 
2653  Edge* edge = state.edges_.back();
2654 
2655  state.GetNode("bar.h", 0)->MarkDirty(); // Mark bar.h as missing.
2656  EXPECT_TRUE(builder.AddTarget("fo o.o", &err));
2657  ASSERT_EQ("", err);
2658 
2659  // Expect three new edges: one generating fo o.o, and two more from
2660  // loading the depfile.
2661  ASSERT_EQ(3u, state.edges_.size());
2662  // Expect our edge to now have three inputs: foo.c and two headers.
2663  ASSERT_EQ(3u, edge->inputs_.size());
2664 
2665  // Expect the command line we generate to only use the original input.
2666  ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
2667 
2668  deps_log.Close();
2669  builder.command_runner_.release();
2670  }
2671 }
2672 
2673 TEST_F(BuildWithDepsLogTest, DiscoveredDepDuringBuildChanged) {
2674  string err;
2675  const char* manifest =
2676  "rule touch-out-implicit-dep\n"
2677  " command = touch $out ; sleep 1 ; touch $test_dependency\n"
2678  "rule generate-depfile\n"
2679  " command = touch $out ; echo \"$out: $test_dependency\" > $depfile\n"
2680  "build out1: touch-out-implicit-dep in1\n"
2681  " test_dependency = inimp\n"
2682  "build out2: generate-depfile in1 || out1\n"
2683  " test_dependency = inimp\n"
2684  " depfile = out2.d\n"
2685  " deps = gcc\n";
2686 
2687  fs_.Create("in1", "");
2688  fs_.Tick();
2689 
2690  BuildLog build_log;
2691 
2692  {
2693  State state;
2694  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2695 
2696  DepsLog deps_log;
2697  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2698  ASSERT_EQ("", err);
2699 
2700  Builder builder(&state, config_, &build_log, &deps_log, &fs_, &status_, 0);
2701  builder.command_runner_.reset(&command_runner_);
2702  EXPECT_TRUE(builder.AddTarget("out2", &err));
2703  EXPECT_FALSE(builder.AlreadyUpToDate());
2704 
2705  EXPECT_TRUE(builder.Build(&err));
2706  EXPECT_TRUE(builder.AlreadyUpToDate());
2707 
2708  deps_log.Close();
2709  builder.command_runner_.release();
2710  }
2711 
2712  fs_.Tick();
2713  fs_.Create("in1", "");
2714 
2715  {
2716  State state;
2717  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2718 
2719  DepsLog deps_log;
2720  ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
2721  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2722  ASSERT_EQ("", err);
2723 
2724  Builder builder(&state, config_, &build_log, &deps_log, &fs_, &status_, 0);
2725  builder.command_runner_.reset(&command_runner_);
2726  EXPECT_TRUE(builder.AddTarget("out2", &err));
2727  EXPECT_FALSE(builder.AlreadyUpToDate());
2728 
2729  EXPECT_TRUE(builder.Build(&err));
2730  EXPECT_TRUE(builder.AlreadyUpToDate());
2731 
2732  deps_log.Close();
2733  builder.command_runner_.release();
2734  }
2735 
2736  fs_.Tick();
2737 
2738  {
2739  State state;
2740  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2741 
2742  DepsLog deps_log;
2743  ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
2744  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2745  ASSERT_EQ("", err);
2746 
2747  Builder builder(&state, config_, &build_log, &deps_log, &fs_, &status_, 0);
2748  builder.command_runner_.reset(&command_runner_);
2749  EXPECT_TRUE(builder.AddTarget("out2", &err));
2750  EXPECT_TRUE(builder.AlreadyUpToDate());
2751 
2752  deps_log.Close();
2753  builder.command_runner_.release();
2754  }
2755 }
2756 
2757 #ifdef _WIN32
2758 TEST_F(BuildWithDepsLogTest, DepFileDepsLogCanonicalize) {
2759  string err;
2760  const char* manifest =
2761  "rule cc\n command = cc $in\n depfile = $out.d\n deps = gcc\n"
2762  "build a/b\\c\\d/e/fo$ o.o: cc x\\y/z\\foo.c\n";
2763 
2764  fs_.Create("x/y/z/foo.c", "");
2765 
2766  {
2767  State state;
2768  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2769 
2770  // Run the build once, everything should be ok.
2771  DepsLog deps_log;
2772  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2773  ASSERT_EQ("", err);
2774 
2775  Builder builder(&state, config_, NULL, &deps_log, &fs_, &status_, 0);
2776  builder.command_runner_.reset(&command_runner_);
2777  EXPECT_TRUE(builder.AddTarget("a/b/c/d/e/fo o.o", &err));
2778  ASSERT_EQ("", err);
2779  // Note, different slashes from manifest.
2780  fs_.Create("a/b\\c\\d/e/fo o.o.d",
2781  "a\\b\\c\\d\\e\\fo\\ o.o: blah.h bar.h\n");
2782  EXPECT_TRUE(builder.Build(&err));
2783  EXPECT_EQ("", err);
2784 
2785  deps_log.Close();
2786  builder.command_runner_.release();
2787  }
2788 
2789  {
2790  State state;
2791  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2792 
2793  DepsLog deps_log;
2794  ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
2795  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2796  ASSERT_EQ("", err);
2797 
2798  Builder builder(&state, config_, NULL, &deps_log, &fs_, &status_, 0);
2799  builder.command_runner_.reset(&command_runner_);
2800 
2801  Edge* edge = state.edges_.back();
2802 
2803  state.GetNode("bar.h", 0)->MarkDirty(); // Mark bar.h as missing.
2804  EXPECT_TRUE(builder.AddTarget("a/b/c/d/e/fo o.o", &err));
2805  ASSERT_EQ("", err);
2806 
2807  // Expect three new edges: one generating fo o.o, and two more from
2808  // loading the depfile.
2809  ASSERT_EQ(3u, state.edges_.size());
2810  // Expect our edge to now have three inputs: foo.c and two headers.
2811  ASSERT_EQ(3u, edge->inputs_.size());
2812 
2813  // Expect the command line we generate to only use the original input.
2814  // Note, slashes from manifest, not .d.
2815  ASSERT_EQ("cc x\\y/z\\foo.c", edge->EvaluateCommand());
2816 
2817  deps_log.Close();
2818  builder.command_runner_.release();
2819  }
2820 }
2821 #endif
2822 
2823 /// Check that a restat rule doesn't clear an edge if the depfile is missing.
2824 /// Follows from: https://github.com/ninja-build/ninja/issues/603
2825 TEST_F(BuildTest, RestatMissingDepfile) {
2826 const char* manifest =
2827 "rule true\n"
2828 " command = true\n" // Would be "write if out-of-date" in reality.
2829 " restat = 1\n"
2830 "build header.h: true header.in\n"
2831 "build out: cat header.h\n"
2832 " depfile = out.d\n";
2833 
2834  fs_.Create("header.h", "");
2835  fs_.Tick();
2836  fs_.Create("out", "");
2837  fs_.Create("header.in", "");
2838 
2839  // Normally, only 'header.h' would be rebuilt, as
2840  // its rule doesn't touch the output and has 'restat=1' set.
2841  // But we are also missing the depfile for 'out',
2842  // which should force its command to run anyway!
2843  RebuildTarget("out", manifest);
2844  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
2845 }
2846 
2847 /// Check that a restat rule doesn't clear an edge if the deps are missing.
2848 /// https://github.com/ninja-build/ninja/issues/603
2849 TEST_F(BuildWithDepsLogTest, RestatMissingDepfileDepslog) {
2850  string err;
2851  const char* manifest =
2852 "rule true\n"
2853 " command = true\n" // Would be "write if out-of-date" in reality.
2854 " restat = 1\n"
2855 "build header.h: true header.in\n"
2856 "build out: cat header.h\n"
2857 " deps = gcc\n"
2858 " depfile = out.d\n";
2859 
2860  // Build once to populate ninja deps logs from out.d
2861  fs_.Create("header.in", "");
2862  fs_.Create("out.d", "out: header.h");
2863  fs_.Create("header.h", "");
2864 
2865  RebuildTarget("out", manifest, "build_log", "ninja_deps");
2866  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
2867 
2868  // Sanity: this rebuild should be NOOP
2869  RebuildTarget("out", manifest, "build_log", "ninja_deps");
2870  ASSERT_EQ(0u, command_runner_.commands_ran_.size());
2871 
2872  // Touch 'header.in', blank dependencies log (create a different one).
2873  // Building header.h triggers 'restat' outputs cleanup.
2874  // Validate that out is rebuilt netherless, as deps are missing.
2875  fs_.Tick();
2876  fs_.Create("header.in", "");
2877 
2878  // (switch to a new blank deps_log "ninja_deps2")
2879  RebuildTarget("out", manifest, "build_log", "ninja_deps2");
2880  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
2881 
2882  // Sanity: this build should be NOOP
2883  RebuildTarget("out", manifest, "build_log", "ninja_deps2");
2884  ASSERT_EQ(0u, command_runner_.commands_ran_.size());
2885 
2886  // Check that invalidating deps by target timestamp also works here
2887  // Repeat the test but touch target instead of blanking the log.
2888  fs_.Tick();
2889  fs_.Create("header.in", "");
2890  fs_.Create("out", "");
2891  RebuildTarget("out", manifest, "build_log", "ninja_deps2");
2892  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
2893 
2894  // And this build should be NOOP again
2895  RebuildTarget("out", manifest, "build_log", "ninja_deps2");
2896  ASSERT_EQ(0u, command_runner_.commands_ran_.size());
2897 }
2898 
2899 TEST_F(BuildTest, WrongOutputInDepfileCausesRebuild) {
2900  string err;
2901  const char* manifest =
2902 "rule cc\n"
2903 " command = cc $in\n"
2904 " depfile = $out.d\n"
2905 "build foo.o: cc foo.c\n";
2906 
2907  fs_.Create("foo.c", "");
2908  fs_.Create("foo.o", "");
2909  fs_.Create("header.h", "");
2910  fs_.Create("foo.o.d", "bar.o.d: header.h\n");
2911 
2912  RebuildTarget("foo.o", manifest, "build_log", "ninja_deps");
2913  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2914 }
2915 
2916 TEST_F(BuildTest, Console) {
2918 "rule console\n"
2919 " command = console\n"
2920 " pool = console\n"
2921 "build cons: console in.txt\n"));
2922 
2923  fs_.Create("in.txt", "");
2924 
2925  string err;
2926  EXPECT_TRUE(builder_.AddTarget("cons", &err));
2927  ASSERT_EQ("", err);
2928  EXPECT_TRUE(builder_.Build(&err));
2929  EXPECT_EQ("", err);
2930  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2931 }
2932 
2933 TEST_F(BuildTest, DyndepMissingAndNoRule) {
2934  // Verify that we can diagnose when a dyndep file is missing and
2935  // has no rule to build it.
2937 "rule touch\n"
2938 " command = touch $out\n"
2939 "build out: touch || dd\n"
2940 " dyndep = dd\n"
2941 ));
2942 
2943  string err;
2944  EXPECT_FALSE(builder_.AddTarget("out", &err));
2945  EXPECT_EQ("loading 'dd': No such file or directory", err);
2946 }
2947 
2948 TEST_F(BuildTest, DyndepReadyImplicitConnection) {
2949  // Verify that a dyndep file can be loaded immediately to discover
2950  // that one edge has an implicit output that is also an implicit
2951  // input of another edge.
2953 "rule touch\n"
2954 " command = touch $out $out.imp\n"
2955 "build tmp: touch || dd\n"
2956 " dyndep = dd\n"
2957 "build out: touch || dd\n"
2958 " dyndep = dd\n"
2959 ));
2960  fs_.Create("dd",
2961 "ninja_dyndep_version = 1\n"
2962 "build out | out.imp: dyndep | tmp.imp\n"
2963 "build tmp | tmp.imp: dyndep\n"
2964 );
2965 
2966  string err;
2967  EXPECT_TRUE(builder_.AddTarget("out", &err));
2968  ASSERT_EQ("", err);
2969  EXPECT_TRUE(builder_.Build(&err));
2970  EXPECT_EQ("", err);
2971  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
2972  EXPECT_EQ("touch tmp tmp.imp", command_runner_.commands_ran_[0]);
2973  EXPECT_EQ("touch out out.imp", command_runner_.commands_ran_[1]);
2974 }
2975 
2976 TEST_F(BuildTest, DyndepReadySyntaxError) {
2977  // Verify that a dyndep file can be loaded immediately to discover
2978  // and reject a syntax error in it.
2980 "rule touch\n"
2981 " command = touch $out\n"
2982 "build out: touch || dd\n"
2983 " dyndep = dd\n"
2984 ));
2985  fs_.Create("dd",
2986 "build out: dyndep\n"
2987 );
2988 
2989  string err;
2990  EXPECT_FALSE(builder_.AddTarget("out", &err));
2991  EXPECT_EQ("dd:1: expected 'ninja_dyndep_version = ...'\n", err);
2992 }
2993 
2994 TEST_F(BuildTest, DyndepReadyCircular) {
2995  // Verify that a dyndep file can be loaded immediately to discover
2996  // and reject a circular dependency.
2998 "rule r\n"
2999 " command = unused\n"
3000 "build out: r in || dd\n"
3001 " dyndep = dd\n"
3002 "build in: r circ\n"
3003  ));
3004  fs_.Create("dd",
3005 "ninja_dyndep_version = 1\n"
3006 "build out | circ: dyndep\n"
3007  );
3008  fs_.Create("out", "");
3009 
3010  string err;
3011  EXPECT_FALSE(builder_.AddTarget("out", &err));
3012  EXPECT_EQ("dependency cycle: circ -> in -> circ", err);
3013 }
3014 
3015 TEST_F(BuildTest, DyndepBuild) {
3016  // Verify that a dyndep file can be built and loaded to discover nothing.
3018 "rule touch\n"
3019 " command = touch $out\n"
3020 "rule cp\n"
3021 " command = cp $in $out\n"
3022 "build dd: cp dd-in\n"
3023 "build out: touch || dd\n"
3024 " dyndep = dd\n"
3025 ));
3026  fs_.Create("dd-in",
3027 "ninja_dyndep_version = 1\n"
3028 "build out: dyndep\n"
3029 );
3030 
3031  string err;
3032  EXPECT_TRUE(builder_.AddTarget("out", &err));
3033  EXPECT_EQ("", err);
3034 
3035  size_t files_created = fs_.files_created_.size();
3036  EXPECT_TRUE(builder_.Build(&err));
3037  EXPECT_EQ("", err);
3038 
3039  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
3040  EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
3041  EXPECT_EQ("touch out", command_runner_.commands_ran_[1]);
3042  ASSERT_EQ(2u, fs_.files_read_.size());
3043  EXPECT_EQ("dd-in", fs_.files_read_[0]);
3044  EXPECT_EQ("dd", fs_.files_read_[1]);
3045  ASSERT_EQ(2u + files_created, fs_.files_created_.size());
3046  EXPECT_EQ(1u, fs_.files_created_.count("dd"));
3047  EXPECT_EQ(1u, fs_.files_created_.count("out"));
3048 }
3049 
3050 TEST_F(BuildTest, DyndepBuildSyntaxError) {
3051  // Verify that a dyndep file can be built and loaded to discover
3052  // and reject a syntax error in it.
3054 "rule touch\n"
3055 " command = touch $out\n"
3056 "rule cp\n"
3057 " command = cp $in $out\n"
3058 "build dd: cp dd-in\n"
3059 "build out: touch || dd\n"
3060 " dyndep = dd\n"
3061 ));
3062  fs_.Create("dd-in",
3063 "build out: dyndep\n"
3064 );
3065 
3066  string err;
3067  EXPECT_TRUE(builder_.AddTarget("out", &err));
3068  EXPECT_EQ("", err);
3069 
3070  EXPECT_FALSE(builder_.Build(&err));
3071  EXPECT_EQ("dd:1: expected 'ninja_dyndep_version = ...'\n", err);
3072 }
3073 
3074 TEST_F(BuildTest, DyndepBuildUnrelatedOutput) {
3075  // Verify that a dyndep file can have dependents that do not specify
3076  // it as their dyndep binding.
3078 "rule touch\n"
3079 " command = touch $out\n"
3080 "rule cp\n"
3081 " command = cp $in $out\n"
3082 "build dd: cp dd-in\n"
3083 "build unrelated: touch || dd\n"
3084 "build out: touch unrelated || dd\n"
3085 " dyndep = dd\n"
3086  ));
3087  fs_.Create("dd-in",
3088 "ninja_dyndep_version = 1\n"
3089 "build out: dyndep\n"
3090 );
3091  fs_.Tick();
3092  fs_.Create("out", "");
3093 
3094  string err;
3095  EXPECT_TRUE(builder_.AddTarget("out", &err));
3096  EXPECT_EQ("", err);
3097 
3098  EXPECT_TRUE(builder_.Build(&err));
3099  EXPECT_EQ("", err);
3100  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3101  EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
3102  EXPECT_EQ("touch unrelated", command_runner_.commands_ran_[1]);
3103  EXPECT_EQ("touch out", command_runner_.commands_ran_[2]);
3104 }
3105 
3106 TEST_F(BuildTest, DyndepBuildDiscoverNewOutput) {
3107  // Verify that a dyndep file can be built and loaded to discover
3108  // a new output of an edge.
3110 "rule touch\n"
3111 " command = touch $out $out.imp\n"
3112 "rule cp\n"
3113 " command = cp $in $out\n"
3114 "build dd: cp dd-in\n"
3115 "build out: touch in || dd\n"
3116 " dyndep = dd\n"
3117  ));
3118  fs_.Create("in", "");
3119  fs_.Create("dd-in",
3120 "ninja_dyndep_version = 1\n"
3121 "build out | out.imp: dyndep\n"
3122 );
3123  fs_.Tick();
3124  fs_.Create("out", "");
3125 
3126  string err;
3127  EXPECT_TRUE(builder_.AddTarget("out", &err));
3128  EXPECT_EQ("", err);
3129 
3130  EXPECT_TRUE(builder_.Build(&err));
3131  EXPECT_EQ("", err);
3132  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
3133  EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
3134  EXPECT_EQ("touch out out.imp", command_runner_.commands_ran_[1]);
3135 }
3136 
3137 TEST_F(BuildTest, DyndepBuildDiscoverNewOutputWithMultipleRules1) {
3138  // Verify that a dyndep file can be built and loaded to discover
3139  // a new output of an edge that is already the output of another edge.
3141 "rule touch\n"
3142 " command = touch $out $out.imp\n"
3143 "rule cp\n"
3144 " command = cp $in $out\n"
3145 "build dd: cp dd-in\n"
3146 "build out1 | out-twice.imp: touch in\n"
3147 "build out2: touch in || dd\n"
3148 " dyndep = dd\n"
3149  ));
3150  fs_.Create("in", "");
3151  fs_.Create("dd-in",
3152 "ninja_dyndep_version = 1\n"
3153 "build out2 | out-twice.imp: dyndep\n"
3154 );
3155  fs_.Tick();
3156  fs_.Create("out1", "");
3157  fs_.Create("out2", "");
3158 
3159  string err;
3160  EXPECT_TRUE(builder_.AddTarget("out1", &err));
3161  EXPECT_TRUE(builder_.AddTarget("out2", &err));
3162  EXPECT_EQ("", err);
3163 
3164  EXPECT_FALSE(builder_.Build(&err));
3165  EXPECT_EQ("multiple rules generate out-twice.imp", err);
3166 }
3167 
3168 TEST_F(BuildTest, DyndepBuildDiscoverNewOutputWithMultipleRules2) {
3169  // Verify that a dyndep file can be built and loaded to discover
3170  // a new output of an edge that is already the output of another
3171  // edge also discovered by dyndep.
3173 "rule touch\n"
3174 " command = touch $out $out.imp\n"
3175 "rule cp\n"
3176 " command = cp $in $out\n"
3177 "build dd1: cp dd1-in\n"
3178 "build out1: touch || dd1\n"
3179 " dyndep = dd1\n"
3180 "build dd2: cp dd2-in || dd1\n" // make order predictable for test
3181 "build out2: touch || dd2\n"
3182 " dyndep = dd2\n"
3183 ));
3184  fs_.Create("out1", "");
3185  fs_.Create("out2", "");
3186  fs_.Create("dd1-in",
3187 "ninja_dyndep_version = 1\n"
3188 "build out1 | out-twice.imp: dyndep\n"
3189 );
3190  fs_.Create("dd2-in", "");
3191  fs_.Create("dd2",
3192 "ninja_dyndep_version = 1\n"
3193 "build out2 | out-twice.imp: dyndep\n"
3194 );
3195  fs_.Tick();
3196  fs_.Create("out1", "");
3197  fs_.Create("out2", "");
3198 
3199  string err;
3200  EXPECT_TRUE(builder_.AddTarget("out1", &err));
3201  EXPECT_TRUE(builder_.AddTarget("out2", &err));
3202  EXPECT_EQ("", err);
3203 
3204  EXPECT_FALSE(builder_.Build(&err));
3205  EXPECT_EQ("multiple rules generate out-twice.imp", err);
3206 }
3207 
3208 TEST_F(BuildTest, DyndepBuildDiscoverNewInput) {
3209  // Verify that a dyndep file can be built and loaded to discover
3210  // a new input to an edge.
3212 "rule touch\n"
3213 " command = touch $out\n"
3214 "rule cp\n"
3215 " command = cp $in $out\n"
3216 "build dd: cp dd-in\n"
3217 "build in: touch\n"
3218 "build out: touch || dd\n"
3219 " dyndep = dd\n"
3220  ));
3221  fs_.Create("dd-in",
3222 "ninja_dyndep_version = 1\n"
3223 "build out: dyndep | in\n"
3224 );
3225  fs_.Tick();
3226  fs_.Create("out", "");
3227 
3228  string err;
3229  EXPECT_TRUE(builder_.AddTarget("out", &err));
3230  EXPECT_EQ("", err);
3231 
3232  EXPECT_TRUE(builder_.Build(&err));
3233  EXPECT_EQ("", err);
3234  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3235  EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
3236  EXPECT_EQ("touch in", command_runner_.commands_ran_[1]);
3237  EXPECT_EQ("touch out", command_runner_.commands_ran_[2]);
3238 }
3239 
3240 TEST_F(BuildTest, DyndepBuildDiscoverNewInputWithValidation) {
3241  // Verify that a dyndep file cannot contain the |@ validation
3242  // syntax.
3244 "rule touch\n"
3245 " command = touch $out\n"
3246 "rule cp\n"
3247 " command = cp $in $out\n"
3248 "build dd: cp dd-in\n"
3249 "build out: touch || dd\n"
3250 " dyndep = dd\n"
3251 ));
3252  fs_.Create("dd-in",
3253 "ninja_dyndep_version = 1\n"
3254 "build out: dyndep |@ validation\n"
3255 );
3256 
3257  string err;
3258  EXPECT_TRUE(builder_.AddTarget("out", &err));
3259  EXPECT_EQ("", err);
3260 
3261  EXPECT_FALSE(builder_.Build(&err));
3262 
3263  string err_first_line = err.substr(0, err.find("\n"));
3264  EXPECT_EQ("dd:2: expected newline, got '|@'", err_first_line);
3265 }
3266 
3267 TEST_F(BuildTest, DyndepBuildDiscoverNewInputWithTransitiveValidation) {
3268  // Verify that a dyndep file can be built and loaded to discover
3269  // a new input to an edge that has a validation edge.
3271 "rule touch\n"
3272 " command = touch $out\n"
3273 "rule cp\n"
3274 " command = cp $in $out\n"
3275 "build dd: cp dd-in\n"
3276 "build in: touch |@ validation\n"
3277 "build validation: touch in out\n"
3278 "build out: touch || dd\n"
3279 " dyndep = dd\n"
3280  ));
3281  fs_.Create("dd-in",
3282 "ninja_dyndep_version = 1\n"
3283 "build out: dyndep | in\n"
3284 );
3285  fs_.Tick();
3286  fs_.Create("out", "");
3287 
3288  string err;
3289  EXPECT_TRUE(builder_.AddTarget("out", &err));
3290  EXPECT_EQ("", err);
3291 
3292  EXPECT_TRUE(builder_.Build(&err));
3293  EXPECT_EQ("", err);
3294  ASSERT_EQ(4u, command_runner_.commands_ran_.size());
3295  EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
3296  EXPECT_EQ("touch in", command_runner_.commands_ran_[1]);
3297  EXPECT_EQ("touch out", command_runner_.commands_ran_[2]);
3298  EXPECT_EQ("touch validation", command_runner_.commands_ran_[3]);
3299 }
3300 
3301 TEST_F(BuildTest, DyndepBuildDiscoverImplicitConnection) {
3302  // Verify that a dyndep file can be built and loaded to discover
3303  // that one edge has an implicit output that is also an implicit
3304  // input of another edge.
3306 "rule touch\n"
3307 " command = touch $out $out.imp\n"
3308 "rule cp\n"
3309 " command = cp $in $out\n"
3310 "build dd: cp dd-in\n"
3311 "build tmp: touch || dd\n"
3312 " dyndep = dd\n"
3313 "build out: touch || dd\n"
3314 " dyndep = dd\n"
3315 ));
3316  fs_.Create("dd-in",
3317 "ninja_dyndep_version = 1\n"
3318 "build out | out.imp: dyndep | tmp.imp\n"
3319 "build tmp | tmp.imp: dyndep\n"
3320 );
3321 
3322  string err;
3323  EXPECT_TRUE(builder_.AddTarget("out", &err));
3324  ASSERT_EQ("", err);
3325  EXPECT_TRUE(builder_.Build(&err));
3326  EXPECT_EQ("", err);
3327  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3328  EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
3329  EXPECT_EQ("touch tmp tmp.imp", command_runner_.commands_ran_[1]);
3330  EXPECT_EQ("touch out out.imp", command_runner_.commands_ran_[2]);
3331 }
3332 
3333 TEST_F(BuildTest, DyndepBuildDiscoverOutputAndDepfileInput) {
3334  // Verify that a dyndep file can be built and loaded to discover
3335  // that one edge has an implicit output that is also reported by
3336  // a depfile as an input of another edge.
3338 "rule touch\n"
3339 " command = touch $out $out.imp\n"
3340 "rule cp\n"
3341 " command = cp $in $out\n"
3342 "build dd: cp dd-in\n"
3343 "build tmp: touch || dd\n"
3344 " dyndep = dd\n"
3345 "build out: cp tmp\n"
3346 " depfile = out.d\n"
3347 ));
3348  fs_.Create("out.d", "out: tmp.imp\n");
3349  fs_.Create("dd-in",
3350 "ninja_dyndep_version = 1\n"
3351 "build tmp | tmp.imp: dyndep\n"
3352 );
3353 
3354  string err;
3355  EXPECT_TRUE(builder_.AddTarget("out", &err));
3356  ASSERT_EQ("", err);
3357 
3358  // Loading the depfile gave tmp.imp a phony input edge.
3359  ASSERT_TRUE(GetNode("tmp.imp")->in_edge()->is_phony());
3360 
3361  EXPECT_TRUE(builder_.Build(&err));
3362  EXPECT_EQ("", err);
3363 
3364  // Loading the dyndep file gave tmp.imp a real input edge.
3365  ASSERT_FALSE(GetNode("tmp.imp")->in_edge()->is_phony());
3366 
3367  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3368  EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
3369  EXPECT_EQ("touch tmp tmp.imp", command_runner_.commands_ran_[1]);
3370  EXPECT_EQ("cp tmp out", command_runner_.commands_ran_[2]);
3371  EXPECT_EQ(1u, fs_.files_created_.count("tmp.imp"));
3372  EXPECT_TRUE(builder_.AlreadyUpToDate());
3373 }
3374 
3375 TEST_F(BuildTest, DyndepBuildDiscoverNowWantEdge) {
3376  // Verify that a dyndep file can be built and loaded to discover
3377  // that an edge is actually wanted due to a missing implicit output.
3379 "rule touch\n"
3380 " command = touch $out $out.imp\n"
3381 "rule cp\n"
3382 " command = cp $in $out\n"
3383 "build dd: cp dd-in\n"
3384 "build tmp: touch || dd\n"
3385 " dyndep = dd\n"
3386 "build out: touch tmp || dd\n"
3387 " dyndep = dd\n"
3388 ));
3389  fs_.Create("tmp", "");
3390  fs_.Create("out", "");
3391  fs_.Create("dd-in",
3392 "ninja_dyndep_version = 1\n"
3393 "build out: dyndep\n"
3394 "build tmp | tmp.imp: dyndep\n"
3395 );
3396 
3397  string err;
3398  EXPECT_TRUE(builder_.AddTarget("out", &err));
3399  ASSERT_EQ("", err);
3400  EXPECT_TRUE(builder_.Build(&err));
3401  EXPECT_EQ("", err);
3402  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3403  EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
3404  EXPECT_EQ("touch tmp tmp.imp", command_runner_.commands_ran_[1]);
3405  EXPECT_EQ("touch out out.imp", command_runner_.commands_ran_[2]);
3406 }
3407 
3408 TEST_F(BuildTest, DyndepBuildDiscoverNowWantEdgeAndDependent) {
3409  // Verify that a dyndep file can be built and loaded to discover
3410  // that an edge and a dependent are actually wanted.
3412 "rule touch\n"
3413 " command = touch $out $out.imp\n"
3414 "rule cp\n"
3415 " command = cp $in $out\n"
3416 "build dd: cp dd-in\n"
3417 "build tmp: touch || dd\n"
3418 " dyndep = dd\n"
3419 "build out: touch tmp\n"
3420 ));
3421  fs_.Create("tmp", "");
3422  fs_.Create("out", "");
3423  fs_.Create("dd-in",
3424 "ninja_dyndep_version = 1\n"
3425 "build tmp | tmp.imp: dyndep\n"
3426 );
3427 
3428  string err;
3429  EXPECT_TRUE(builder_.AddTarget("out", &err));
3430  ASSERT_EQ("", err);
3431  EXPECT_TRUE(builder_.Build(&err));
3432  EXPECT_EQ("", err);
3433  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3434  EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
3435  EXPECT_EQ("touch tmp tmp.imp", command_runner_.commands_ran_[1]);
3436  EXPECT_EQ("touch out out.imp", command_runner_.commands_ran_[2]);
3437 }
3438 
3439 TEST_F(BuildTest, DyndepBuildDiscoverCircular) {
3440  // Verify that a dyndep file can be built and loaded to discover
3441  // and reject a circular dependency.
3443 "rule r\n"
3444 " command = unused\n"
3445 "rule cp\n"
3446 " command = cp $in $out\n"
3447 "build dd: cp dd-in\n"
3448 "build out: r in || dd\n"
3449 " depfile = out.d\n"
3450 " dyndep = dd\n"
3451 "build in: r || dd\n"
3452 " dyndep = dd\n"
3453  ));
3454  fs_.Create("out.d", "out: inimp\n");
3455  fs_.Create("dd-in",
3456 "ninja_dyndep_version = 1\n"
3457 "build out | circ: dyndep\n"
3458 "build in: dyndep | circ\n"
3459  );
3460  fs_.Create("out", "");
3461 
3462  string err;
3463  EXPECT_TRUE(builder_.AddTarget("out", &err));
3464  EXPECT_EQ("", err);
3465 
3466  EXPECT_FALSE(builder_.Build(&err));
3467  // Depending on how the pointers in Plan::ready_ work out, we could have
3468  // discovered the cycle from either starting point.
3469  EXPECT_TRUE(err == "dependency cycle: circ -> in -> circ" ||
3470  err == "dependency cycle: in -> circ -> in");
3471 }
3472 
3473 TEST_F(BuildWithLogTest, DyndepBuildDiscoverRestat) {
3474  // Verify that a dyndep file can be built and loaded to discover
3475  // that an edge has a restat binding.
3477 "rule true\n"
3478 " command = true\n"
3479 "rule cp\n"
3480 " command = cp $in $out\n"
3481 "build dd: cp dd-in\n"
3482 "build out1: true in || dd\n"
3483 " dyndep = dd\n"
3484 "build out2: cat out1\n"));
3485 
3486  fs_.Create("out1", "");
3487  fs_.Create("out2", "");
3488  fs_.Create("dd-in",
3489 "ninja_dyndep_version = 1\n"
3490 "build out1: dyndep\n"
3491 " restat = 1\n"
3492 );
3493  fs_.Tick();
3494  fs_.Create("in", "");
3495 
3496  // Do a pre-build so that there's commands in the log for the outputs,
3497  // otherwise, the lack of an entry in the build log will cause "out2" to
3498  // rebuild regardless of restat.
3499  string err;
3500  EXPECT_TRUE(builder_.AddTarget("out2", &err));
3501  ASSERT_EQ("", err);
3502  EXPECT_TRUE(builder_.Build(&err));
3503  ASSERT_EQ("", err);
3504  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3505  EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
3506  EXPECT_EQ("true", command_runner_.commands_ran_[1]);
3507  EXPECT_EQ("cat out1 > out2", command_runner_.commands_ran_[2]);
3508 
3509  command_runner_.commands_ran_.clear();
3510  state_.Reset();
3511  fs_.Tick();
3512  fs_.Create("in", "");
3513 
3514  // We touched "in", so we should build "out1". But because "true" does not
3515  // touch "out1", we should cancel the build of "out2".
3516  EXPECT_TRUE(builder_.AddTarget("out2", &err));
3517  ASSERT_EQ("", err);
3518  EXPECT_TRUE(builder_.Build(&err));
3519  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
3520  EXPECT_EQ("true", command_runner_.commands_ran_[0]);
3521 }
3522 
3523 TEST_F(BuildTest, DyndepBuildDiscoverScheduledEdge) {
3524  // Verify that a dyndep file can be built and loaded to discover a
3525  // new input that itself is an output from an edge that has already
3526  // been scheduled but not finished. We should not re-schedule it.
3528 "rule touch\n"
3529 " command = touch $out $out.imp\n"
3530 "rule cp\n"
3531 " command = cp $in $out\n"
3532 "build out1 | out1.imp: touch\n"
3533 "build zdd: cp zdd-in\n"
3534 " verify_active_edge = out1\n" // verify out1 is active when zdd is finished
3535 "build out2: cp out1 || zdd\n"
3536 " dyndep = zdd\n"
3537 ));
3538  fs_.Create("zdd-in",
3539 "ninja_dyndep_version = 1\n"
3540 "build out2: dyndep | out1.imp\n"
3541 );
3542 
3543  // Enable concurrent builds so that we can load the dyndep file
3544  // while another edge is still active.
3545  command_runner_.max_active_edges_ = 2;
3546 
3547  // During the build "out1" and "zdd" should be built concurrently.
3548  // The fake command runner will finish these in reverse order
3549  // of the names of the first outputs, so "zdd" will finish first
3550  // and we will load the dyndep file while the edge for "out1" is
3551  // still active. This will add a new dependency on "out1.imp",
3552  // also produced by the active edge. The builder should not
3553  // re-schedule the already-active edge.
3554 
3555  string err;
3556  EXPECT_TRUE(builder_.AddTarget("out1", &err));
3557  EXPECT_TRUE(builder_.AddTarget("out2", &err));
3558  ASSERT_EQ("", err);
3559  EXPECT_TRUE(builder_.Build(&err));
3560  EXPECT_EQ("", err);
3561  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3562  // Depending on how the pointers in Plan::ready_ work out, the first
3563  // two commands may have run in either order.
3564  EXPECT_TRUE((command_runner_.commands_ran_[0] == "touch out1 out1.imp" &&
3565  command_runner_.commands_ran_[1] == "cp zdd-in zdd") ||
3566  (command_runner_.commands_ran_[1] == "touch out1 out1.imp" &&
3567  command_runner_.commands_ran_[0] == "cp zdd-in zdd"));
3568  EXPECT_EQ("cp out1 out2", command_runner_.commands_ran_[2]);
3569 }
3570 
3571 TEST_F(BuildTest, DyndepTwoLevelDirect) {
3572  // Verify that a clean dyndep file can depend on a dirty dyndep file
3573  // and be loaded properly after the dirty one is built and loaded.
3575 "rule touch\n"
3576 " command = touch $out $out.imp\n"
3577 "rule cp\n"
3578 " command = cp $in $out\n"
3579 "build dd1: cp dd1-in\n"
3580 "build out1 | out1.imp: touch || dd1\n"
3581 " dyndep = dd1\n"
3582 "build dd2: cp dd2-in || dd1\n" // direct order-only dep on dd1
3583 "build out2: touch || dd2\n"
3584 " dyndep = dd2\n"
3585 ));
3586  fs_.Create("out1.imp", "");
3587  fs_.Create("out2", "");
3588  fs_.Create("out2.imp", "");
3589  fs_.Create("dd1-in",
3590 "ninja_dyndep_version = 1\n"
3591 "build out1: dyndep\n"
3592 );
3593  fs_.Create("dd2-in", "");
3594  fs_.Create("dd2",
3595 "ninja_dyndep_version = 1\n"
3596 "build out2 | out2.imp: dyndep | out1.imp\n"
3597 );
3598 
3599  // During the build dd1 should be built and loaded. The RecomputeDirty
3600  // called as a result of loading dd1 should not cause dd2 to be loaded
3601  // because the builder will never get a chance to update the build plan
3602  // to account for dd2. Instead dd2 should only be later loaded once the
3603  // builder recognizes that it is now ready (as its order-only dependency
3604  // on dd1 has been satisfied). This test case verifies that each dyndep
3605  // file is loaded to update the build graph independently.
3606 
3607  string err;
3608  EXPECT_TRUE(builder_.AddTarget("out2", &err));
3609  ASSERT_EQ("", err);
3610  EXPECT_TRUE(builder_.Build(&err));
3611  EXPECT_EQ("", err);
3612  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3613  EXPECT_EQ("cp dd1-in dd1", command_runner_.commands_ran_[0]);
3614  EXPECT_EQ("touch out1 out1.imp", command_runner_.commands_ran_[1]);
3615  EXPECT_EQ("touch out2 out2.imp", command_runner_.commands_ran_[2]);
3616 }
3617 
3618 TEST_F(BuildTest, DyndepTwoLevelIndirect) {
3619  // Verify that dyndep files can add to an edge new implicit inputs that
3620  // correspond to implicit outputs added to other edges by other dyndep
3621  // files on which they (order-only) depend.
3623 "rule touch\n"
3624 " command = touch $out $out.imp\n"
3625 "rule cp\n"
3626 " command = cp $in $out\n"
3627 "build dd1: cp dd1-in\n"
3628 "build out1: touch || dd1\n"
3629 " dyndep = dd1\n"
3630 "build dd2: cp dd2-in || out1\n" // indirect order-only dep on dd1
3631 "build out2: touch || dd2\n"
3632 " dyndep = dd2\n"
3633 ));
3634  fs_.Create("out1.imp", "");
3635  fs_.Create("out2", "");
3636  fs_.Create("out2.imp", "");
3637  fs_.Create("dd1-in",
3638 "ninja_dyndep_version = 1\n"
3639 "build out1 | out1.imp: dyndep\n"
3640 );
3641  fs_.Create("dd2-in", "");
3642  fs_.Create("dd2",
3643 "ninja_dyndep_version = 1\n"
3644 "build out2 | out2.imp: dyndep | out1.imp\n"
3645 );
3646 
3647  // During the build dd1 should be built and loaded. Then dd2 should
3648  // be built and loaded. Loading dd2 should cause the builder to
3649  // recognize that out2 needs to be built even though it was originally
3650  // clean without dyndep info.
3651 
3652  string err;
3653  EXPECT_TRUE(builder_.AddTarget("out2", &err));
3654  ASSERT_EQ("", err);
3655  EXPECT_TRUE(builder_.Build(&err));
3656  EXPECT_EQ("", err);
3657  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3658  EXPECT_EQ("cp dd1-in dd1", command_runner_.commands_ran_[0]);
3659  EXPECT_EQ("touch out1 out1.imp", command_runner_.commands_ran_[1]);
3660  EXPECT_EQ("touch out2 out2.imp", command_runner_.commands_ran_[2]);
3661 }
3662 
3663 TEST_F(BuildTest, DyndepTwoLevelDiscoveredReady) {
3664  // Verify that a dyndep file can discover a new input whose
3665  // edge also has a dyndep file that is ready to load immediately.
3667 "rule touch\n"
3668 " command = touch $out\n"
3669 "rule cp\n"
3670 " command = cp $in $out\n"
3671 "build dd0: cp dd0-in\n"
3672 "build dd1: cp dd1-in\n"
3673 "build in: touch\n"
3674 "build tmp: touch || dd0\n"
3675 " dyndep = dd0\n"
3676 "build out: touch || dd1\n"
3677 " dyndep = dd1\n"
3678  ));
3679  fs_.Create("dd1-in",
3680 "ninja_dyndep_version = 1\n"
3681 "build out: dyndep | tmp\n"
3682 );
3683  fs_.Create("dd0-in", "");
3684  fs_.Create("dd0",
3685 "ninja_dyndep_version = 1\n"
3686 "build tmp: dyndep | in\n"
3687 );
3688  fs_.Tick();
3689  fs_.Create("out", "");
3690 
3691  string err;
3692  EXPECT_TRUE(builder_.AddTarget("out", &err));
3693  EXPECT_EQ("", err);
3694 
3695  EXPECT_TRUE(builder_.Build(&err));
3696  EXPECT_EQ("", err);
3697  ASSERT_EQ(4u, command_runner_.commands_ran_.size());
3698  EXPECT_EQ("cp dd1-in dd1", command_runner_.commands_ran_[0]);
3699  EXPECT_EQ("touch in", command_runner_.commands_ran_[1]);
3700  EXPECT_EQ("touch tmp", command_runner_.commands_ran_[2]);
3701  EXPECT_EQ("touch out", command_runner_.commands_ran_[3]);
3702 }
3703 
3704 TEST_F(BuildTest, DyndepTwoLevelDiscoveredDirty) {
3705  // Verify that a dyndep file can discover a new input whose
3706  // edge also has a dyndep file that needs to be built.
3708 "rule touch\n"
3709 " command = touch $out\n"
3710 "rule cp\n"
3711 " command = cp $in $out\n"
3712 "build dd0: cp dd0-in\n"
3713 "build dd1: cp dd1-in\n"
3714 "build in: touch\n"
3715 "build tmp: touch || dd0\n"
3716 " dyndep = dd0\n"
3717 "build out: touch || dd1\n"
3718 " dyndep = dd1\n"
3719  ));
3720  fs_.Create("dd1-in",
3721 "ninja_dyndep_version = 1\n"
3722 "build out: dyndep | tmp\n"
3723 );
3724  fs_.Create("dd0-in",
3725 "ninja_dyndep_version = 1\n"
3726 "build tmp: dyndep | in\n"
3727 );
3728  fs_.Tick();
3729  fs_.Create("out", "");
3730 
3731  string err;
3732  EXPECT_TRUE(builder_.AddTarget("out", &err));
3733  EXPECT_EQ("", err);
3734 
3735  EXPECT_TRUE(builder_.Build(&err));
3736  EXPECT_EQ("", err);
3737  ASSERT_EQ(5u, command_runner_.commands_ran_.size());
3738  EXPECT_EQ("cp dd1-in dd1", command_runner_.commands_ran_[0]);
3739  EXPECT_EQ("cp dd0-in dd0", command_runner_.commands_ran_[1]);
3740  EXPECT_EQ("touch in", command_runner_.commands_ran_[2]);
3741  EXPECT_EQ("touch tmp", command_runner_.commands_ran_[3]);
3742  EXPECT_EQ("touch out", command_runner_.commands_ran_[4]);
3743 }
3744 
3745 TEST_F(BuildTest, Validation) {
3747  "build out: cat in |@ validate\n"
3748  "build validate: cat in2\n"));
3749 
3750  fs_.Create("in", "");
3751  fs_.Create("in2", "");
3752 
3753  string err;
3754  EXPECT_TRUE(builder_.AddTarget("out", &err));
3755  EXPECT_EQ("", err);
3756 
3757  EXPECT_TRUE(builder_.Build(&err));
3758  EXPECT_EQ("", err);
3759 
3760  EXPECT_EQ(2u, command_runner_.commands_ran_.size());
3761 
3762  // Test touching "in" only rebuilds "out" ("validate" doesn't depend on
3763  // "out").
3764  fs_.Tick();
3765  fs_.Create("in", "");
3766 
3767  err.clear();
3768  command_runner_.commands_ran_.clear();
3769  state_.Reset();
3770  EXPECT_TRUE(builder_.AddTarget("out", &err));
3771  ASSERT_EQ("", err);
3772 
3773  EXPECT_TRUE(builder_.Build(&err));
3774  EXPECT_EQ("", err);
3775 
3776  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
3777  EXPECT_EQ("cat in > out", command_runner_.commands_ran_[0]);
3778 
3779  // Test touching "in2" only rebuilds "validate" ("out" doesn't depend on
3780  // "validate").
3781  fs_.Tick();
3782  fs_.Create("in2", "");
3783 
3784  err.clear();
3785  command_runner_.commands_ran_.clear();
3786  state_.Reset();
3787  EXPECT_TRUE(builder_.AddTarget("out", &err));
3788  ASSERT_EQ("", err);
3789 
3790  EXPECT_TRUE(builder_.Build(&err));
3791  EXPECT_EQ("", err);
3792 
3793  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
3794  EXPECT_EQ("cat in2 > validate", command_runner_.commands_ran_[0]);
3795 }
3796 
3797 TEST_F(BuildTest, ValidationDependsOnOutput) {
3799  "build out: cat in |@ validate\n"
3800  "build validate: cat in2 | out\n"));
3801 
3802  fs_.Create("in", "");
3803  fs_.Create("in2", "");
3804 
3805  string err;
3806  EXPECT_TRUE(builder_.AddTarget("out", &err));
3807  EXPECT_EQ("", err);
3808 
3809  EXPECT_TRUE(builder_.Build(&err));
3810  EXPECT_EQ("", err);
3811 
3812  EXPECT_EQ(2u, command_runner_.commands_ran_.size());
3813 
3814  // Test touching "in" rebuilds "out" and "validate".
3815  fs_.Tick();
3816  fs_.Create("in", "");
3817 
3818  err.clear();
3819  command_runner_.commands_ran_.clear();
3820  state_.Reset();
3821  EXPECT_TRUE(builder_.AddTarget("out", &err));
3822  ASSERT_EQ("", err);
3823 
3824  EXPECT_TRUE(builder_.Build(&err));
3825  EXPECT_EQ("", err);
3826 
3827  EXPECT_EQ(2u, command_runner_.commands_ran_.size());
3828 
3829  // Test touching "in2" only rebuilds "validate" ("out" doesn't depend on
3830  // "validate").
3831  fs_.Tick();
3832  fs_.Create("in2", "");
3833 
3834  err.clear();
3835  command_runner_.commands_ran_.clear();
3836  state_.Reset();
3837  EXPECT_TRUE(builder_.AddTarget("out", &err));
3838  ASSERT_EQ("", err);
3839 
3840  EXPECT_TRUE(builder_.Build(&err));
3841  EXPECT_EQ("", err);
3842 
3843  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
3844  EXPECT_EQ("cat in2 > validate", command_runner_.commands_ran_[0]);
3845 }
3846 
3847 TEST_F(BuildWithDepsLogTest, ValidationThroughDepfile) {
3848  const char* manifest =
3849  "build out: cat in |@ validate\n"
3850  "build validate: cat in2 | out\n"
3851  "build out2: cat in3\n"
3852  " deps = gcc\n"
3853  " depfile = out2.d\n";
3854 
3855  string err;
3856 
3857  {
3858  fs_.Create("in", "");
3859  fs_.Create("in2", "");
3860  fs_.Create("in3", "");
3861  fs_.Create("out2.d", "out: out");
3862 
3863  State state;
3864  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
3865  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
3866 
3867  DepsLog deps_log;
3868  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
3869  ASSERT_EQ("", err);
3870 
3871  Builder builder(&state, config_, NULL, &deps_log, &fs_, &status_, 0);
3872  builder.command_runner_.reset(&command_runner_);
3873 
3874  EXPECT_TRUE(builder.AddTarget("out2", &err));
3875  ASSERT_EQ("", err);
3876 
3877  EXPECT_TRUE(builder.Build(&err));
3878  EXPECT_EQ("", err);
3879 
3880  // On the first build, only the out2 command is run.
3881  ASSERT_EQ(command_runner_.commands_ran_.size(), 1);
3882  EXPECT_EQ("cat in3 > out2", command_runner_.commands_ran_[0]);
3883 
3884  // The deps file should have been removed.
3885  EXPECT_EQ(0, fs_.Stat("out2.d", &err));
3886 
3887  deps_log.Close();
3888  builder.command_runner_.release();
3889  }
3890 
3891  fs_.Tick();
3892  command_runner_.commands_ran_.clear();
3893 
3894  {
3895  fs_.Create("in2", "");
3896  fs_.Create("in3", "");
3897 
3898  State state;
3899  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
3900  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
3901 
3902  DepsLog deps_log;
3903  ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
3904  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
3905  ASSERT_EQ("", err);
3906 
3907  Builder builder(&state, config_, NULL, &deps_log, &fs_, &status_, 0);
3908  builder.command_runner_.reset(&command_runner_);
3909 
3910  EXPECT_TRUE(builder.AddTarget("out2", &err));
3911  ASSERT_EQ("", err);
3912 
3913  EXPECT_TRUE(builder.Build(&err));
3914  EXPECT_EQ("", err);
3915 
3916  // The out and validate actions should have been run as well as out2.
3917  ASSERT_EQ(command_runner_.commands_ran_.size(), 3);
3918  // out has to run first, as both out2 and validate depend on it.
3919  EXPECT_EQ("cat in > out", command_runner_.commands_ran_[0]);
3920 
3921  deps_log.Close();
3922  builder.command_runner_.release();
3923  }
3924 }
3925 
3926 TEST_F(BuildTest, ValidationCircular) {
3928  "build out: cat in |@ out2\n"
3929  "build out2: cat in2 |@ out\n"));
3930 
3931  fs_.Create("in", "");
3932  fs_.Create("in2", "");
3933 
3934  string err;
3935  EXPECT_TRUE(builder_.AddTarget("out", &err));
3936  EXPECT_EQ("", err);
3937 
3938  EXPECT_TRUE(builder_.Build(&err));
3939  EXPECT_EQ("", err);
3940 
3941  EXPECT_EQ(2u, command_runner_.commands_ran_.size());
3942 
3943  // Test touching "in" rebuilds "out".
3944  fs_.Tick();
3945  fs_.Create("in", "");
3946 
3947  err.clear();
3948  command_runner_.commands_ran_.clear();
3949  state_.Reset();
3950  EXPECT_TRUE(builder_.AddTarget("out", &err));
3951  ASSERT_EQ("", err);
3952 
3953  EXPECT_TRUE(builder_.Build(&err));
3954  EXPECT_EQ("", err);
3955 
3956  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
3957  EXPECT_EQ("cat in > out", command_runner_.commands_ran_[0]);
3958 
3959  // Test touching "in2" rebuilds "out2".
3960  fs_.Tick();
3961  fs_.Create("in2", "");
3962 
3963  err.clear();
3964  command_runner_.commands_ran_.clear();
3965  state_.Reset();
3966  EXPECT_TRUE(builder_.AddTarget("out", &err));
3967  ASSERT_EQ("", err);
3968 
3969  EXPECT_TRUE(builder_.Build(&err));
3970  EXPECT_EQ("", err);
3971 
3972  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
3973  EXPECT_EQ("cat in2 > out2", command_runner_.commands_ran_[0]);
3974 }
3975 
3976 TEST_F(BuildTest, ValidationWithCircularDependency) {
3978  "build out: cat in |@ validate\n"
3979  "build validate: cat validate_in | out\n"
3980  "build validate_in: cat validate\n"));
3981 
3982  fs_.Create("in", "");
3983 
3984  string err;
3985  EXPECT_FALSE(builder_.AddTarget("out", &err));
3986  EXPECT_EQ("dependency cycle: validate -> validate_in -> validate", err);
3987 }
bool OpenForWrite(const std::string &path, const BuildLogUser &user, std::string *err)
Prepares writing to the log file without actually opening it - that will happen when/if it&#39;s needed...
Definition: build_log.cc:131
void Reset()
Reset state.
Definition: state.cc:182
FakeCommandRunner command_runner_
Definition: build_test.cc:533
bool Build(std::string *err)
Run the build.
Definition: build.cc:599
BuildConfig config_
Definition: build_test.cc:532
An implementation of DiskInterface that uses an in-memory representation of disk state.
Definition: test.h:134
CommandRunner is an interface that wraps running the build subcommands.
Definition: build.h:136
bool Stat(DiskInterface *disk_interface, std::string *err)
Return false on error.
Definition: graph.cc:34
std::auto_ptr< CommandRunner > command_runner_
Definition: build.h:219
Verbosity verbosity
Definition: build.h:167
LoadStatus Load(const std::string &path, std::string *err)
Load the on-disk log.
Definition: build_log.cc:261
FakeCommandRunner(VirtualFileSystem *fs)
Definition: build_test.cc:472
BuildLog build_log_
Definition: build_test.cc:1450
int order_only_deps_
Definition: graph.h:229
void AssertParse(State *state, const char *input, ManifestParserOptions opts)
Definition: test.cc:100
int implicit_deps_
Definition: graph.h:228
int Tick()
Tick "time" forwards; subsequent file operations will be newer than previous ones.
Definition: test.h:142
BuildConfig MakeConfig()
Definition: build_test.cc:526
void TestPoolWithDepthOne(const char *test_case)
Definition: build_test.cc:203
#define EXPECT_GE(a, b)
Definition: test.h:72
Plan stores the state of a build plan: what we intend to build, which steps we&#39;re ready to execute...
Definition: build.h:40
Edge * in_edge() const
Definition: graph.h:104
Node * GetNode(StringPiece path, uint64_t slash_bits)
Definition: state.cc:96
void * builder_
Shadow parent class builder_ so we don&#39;t accidentally use it.
Definition: build_test.cc:2355
The result of waiting for a command.
Definition: build.h:142
StringPiece represents a slice of a string whose memory is managed externally.
Definition: string_piece.h:25
const std::string & name() const
Definition: eval_env.h:62
#define EXPECT_TRUE(a)
Definition: test.h:76
virtual void SetUp()
Definition: test.h:36
Information about a node in the dependency graph: the file, whether it&#39;s dirty, mtime, etc.
Definition: graph.h:39
Edge * FindWork()
Definition: build.cc:151
vector< Edge * > active_edges_
Definition: build_test.cc:483
void Create(const std::string &path, const std::string &contents)
"Create" a file with contents.
Definition: test.cc:145
#define EXPECT_FALSE(a)
Definition: test.h:78
virtual bool IsPathDead(StringPiece s) const
Return if a given output is no longer part of the build manifest.
Definition: build_test.cc:514
std::string output
Definition: build.h:146
Fixture for tests involving Plan.
Definition: build_test.cc:36
Node ** nodes
Definition: deps_log.h:85
int now_
A simple fake timestamp for file operations.
Definition: test.h:169
std::vector< Node * > outputs_
Definition: graph.h:204
Node * GetNode(const std::string &path)
Short way to get a Node by its path from state_.
Definition: test.cc:95
virtual vector< Edge * > GetActiveEdges()
Definition: build_test.cc:713
Implementation of the Status interface that prints the status as human-readable strings to stdout...
Definition: status.h:44
An edge in the dependency graph; links between Nodes using Rules.
Definition: graph.h:164
Store a log of every command ran for every build.
Definition: build_log.h:43
LoadStatus Load(const std::string &path, State *state, std::string *err)
Definition: deps_log.cc:152
A base test fixture that includes a State object with a builtin "cat" rule.
Definition: test.h:113
const std::string & path() const
Definition: graph.h:86
size_t max_active_edges_
Definition: build_test.cc:484
void MarkDirty()
Definition: graph.h:99
Plan plan_
Definition: build_test.cc:37
BuildTest(DepsLog *log)
Definition: build_test.cc:493
As build commands run they can output extra dependency information (e.g.
Definition: deps_log.h:68
int current_use() const
Definition: state.h:48
void TestPhonyUseCase(BuildTest *t, int i)
Definition: build_test.cc:1213
TEST_F(PlanTest, Basic)
Definition: build_test.cc:56
Tests of builds involving deps logs necessarily must span multiple builds.
Definition: build_test.cc:2339
#define EXPECT_EQ(a, b)
Definition: test.h:64
virtual bool WaitForCommand(Result *result)
Wait for a command to complete, or return false if interrupted.
Definition: build_test.cc:652
#define ASSERT_FALSE(a)
Definition: test.h:95
void MarkMissing()
Mark the Node as already-stat()ed and missing.
Definition: graph.h:71
int node_count
Definition: deps_log.h:84
virtual void TearDown()
Definition: build_test.cc:2348
Node * AddTarget(const std::string &name, std::string *err)
bool dirty() const
Definition: graph.h:97
Fake implementation of CommandRunner, useful for tests.
Definition: build_test.cc:471
void RebuildTarget(const string &target, const char *manifest, const char *log_path=NULL, const char *deps_path=NULL, State *state=NULL)
Rebuild target in the &#39;working tree&#39; (fs_).
Definition: build_test.cc:539
ScopedTempDir temp_dir_
Definition: build_test.cc:2352
ExitStatus status
Definition: build.h:145
StatusPrinter status_
Definition: build_test.cc:535
virtual void SetUp()
Definition: build_test.cc:497
int64_t TimeStamp
Definition: timestamp.h:31
virtual void Abort()
Definition: build_test.cc:717
Pool * LookupPool(const std::string &pool_name)
Definition: state.cc:79
VirtualFileSystem * fs_
Definition: build_test.cc:485
bool OpenForWrite(const std::string &path, std::string *err)
Definition: deps_log.cc:48
std::vector< Node * > inputs_
Definition: graph.h:203
#define ASSERT_EQ(a, b)
Definition: test.h:81
void Close()
Definition: deps_log.cc:145
std::string GetUnescapedDepfile() const
Like GetBinding("depfile"), but without shell escaping.
Definition: graph.cc:500
void FindWorkSorted(deque< Edge *> *ret, int count)
Because FindWork does not return Edges in any sort of predictable order,.
Definition: build_test.cc:42
static bool cmp(const Edge *a, const Edge *b)
Definition: build_test.cc:28
Builder wraps the build process: starting commands, updating status.
Definition: build.h:178
virtual bool CanRunMore() const
Definition: build_test.cc:577
std::string GetBinding(const std::string &key) const
Returns the shell-escaped value of |key|.
Definition: graph.cc:491
TimeStamp mtime() const
Definition: graph.h:95
virtual bool StartCommand(Edge *edge)
Definition: build_test.cc:581
#define EXPECT_GT(a, b)
Definition: test.h:68
#define ASSERT_NO_FATAL_FAILURE(a)
Definition: test.h:97
const Rule & rule() const
Definition: graph.h:215
VirtualFileSystem fs_
Definition: build_test.cc:534
std::string EvaluateCommand(bool incl_rsp_file=false) const
Expand all variables in a command and return it as a string.
Definition: graph.cc:481
Builder builder_
Definition: build_test.cc:536
Options (e.g. verbosity, parallelism) passed to a build.
Definition: build.h:157
Global state (file status) for a single run.
Definition: state.h:92
std::vector< Edge * > edges_
All the edges of the graph.
Definition: state.h:133
void Dirty(const string &path)
Definition: build_test.cc:721
#define ASSERT_TRUE(a)
Definition: test.h:93
bool use_console() const
Definition: graph.cc:547
bool more_to_do() const
Returns true if there&#39;s more work to be done.
Definition: build.h:53
bool AlreadyUpToDate() const
Returns true if the build targets are already up to date.
Definition: build.cc:595
bool exists() const
Definition: graph.h:78
virtual void SetUp()
Definition: build_test.cc:2342
vector< string > commands_ran_
Definition: build_test.cc:482
void AssertHash(const char *expected, uint64_t actual)
Definition: test.cc:109
Can answer questions about the manifest for the BuildLog.
Definition: build_log.h:30