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