Ninja
build_test.cc
Go to the documentation of this file.
00001 // Copyright 2011 Google Inc. All Rights Reserved.
00002 //
00003 // Licensed under the Apache License, Version 2.0 (the "License");
00004 // you may not use this file except in compliance with the License.
00005 // You may obtain a copy of the License at
00006 //
00007 //     http://www.apache.org/licenses/LICENSE-2.0
00008 //
00009 // Unless required by applicable law or agreed to in writing, software
00010 // distributed under the License is distributed on an "AS IS" BASIS,
00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012 // See the License for the specific language governing permissions and
00013 // limitations under the License.
00014 
00015 #include "build.h"
00016 
00017 #include "build_log.h"
00018 #include "deps_log.h"
00019 #include "graph.h"
00020 #include "test.h"
00021 
00022 /// Fixture for tests involving Plan.
00023 // Though Plan doesn't use State, it's useful to have one around
00024 // to create Nodes and Edges.
00025 struct PlanTest : public StateTestWithBuiltinRules {
00026   Plan plan_;
00027 
00028   /// Because FindWork does not return Edges in any sort of predictable order,
00029   // provide a means to get available Edges in order and in a format which is
00030   // easy to write tests around.
00031   void FindWorkSorted(deque<Edge*>* ret, int count) {
00032     struct CompareEdgesByOutput {
00033       static bool cmp(const Edge* a, const Edge* b) {
00034         return a->outputs_[0]->path() < b->outputs_[0]->path();
00035       }
00036     };
00037 
00038     for (int i = 0; i < count; ++i) {
00039       ASSERT_TRUE(plan_.more_to_do());
00040       Edge* edge = plan_.FindWork();
00041       ASSERT_TRUE(edge);
00042       ret->push_back(edge);
00043     }
00044     ASSERT_FALSE(plan_.FindWork());
00045     sort(ret->begin(), ret->end(), CompareEdgesByOutput::cmp);
00046   }
00047 };
00048 
00049 TEST_F(PlanTest, Basic) {
00050   AssertParse(&state_,
00051 "build out: cat mid\n"
00052 "build mid: cat in\n");
00053   GetNode("mid")->MarkDirty();
00054   GetNode("out")->MarkDirty();
00055   string err;
00056   EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
00057   ASSERT_EQ("", err);
00058   ASSERT_TRUE(plan_.more_to_do());
00059 
00060   Edge* edge = plan_.FindWork();
00061   ASSERT_TRUE(edge);
00062   ASSERT_EQ("in",  edge->inputs_[0]->path());
00063   ASSERT_EQ("mid", edge->outputs_[0]->path());
00064 
00065   ASSERT_FALSE(plan_.FindWork());
00066 
00067   plan_.EdgeFinished(edge);
00068 
00069   edge = plan_.FindWork();
00070   ASSERT_TRUE(edge);
00071   ASSERT_EQ("mid", edge->inputs_[0]->path());
00072   ASSERT_EQ("out", edge->outputs_[0]->path());
00073 
00074   plan_.EdgeFinished(edge);
00075 
00076   ASSERT_FALSE(plan_.more_to_do());
00077   edge = plan_.FindWork();
00078   ASSERT_EQ(0, edge);
00079 }
00080 
00081 // Test that two outputs from one rule can be handled as inputs to the next.
00082 TEST_F(PlanTest, DoubleOutputDirect) {
00083   AssertParse(&state_,
00084 "build out: cat mid1 mid2\n"
00085 "build mid1 mid2: cat in\n");
00086   GetNode("mid1")->MarkDirty();
00087   GetNode("mid2")->MarkDirty();
00088   GetNode("out")->MarkDirty();
00089 
00090   string err;
00091   EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
00092   ASSERT_EQ("", err);
00093   ASSERT_TRUE(plan_.more_to_do());
00094 
00095   Edge* edge;
00096   edge = plan_.FindWork();
00097   ASSERT_TRUE(edge);  // cat in
00098   plan_.EdgeFinished(edge);
00099 
00100   edge = plan_.FindWork();
00101   ASSERT_TRUE(edge);  // cat mid1 mid2
00102   plan_.EdgeFinished(edge);
00103 
00104   edge = plan_.FindWork();
00105   ASSERT_FALSE(edge);  // done
00106 }
00107 
00108 // Test that two outputs from one rule can eventually be routed to another.
00109 TEST_F(PlanTest, DoubleOutputIndirect) {
00110   AssertParse(&state_,
00111 "build out: cat b1 b2\n"
00112 "build b1: cat a1\n"
00113 "build b2: cat a2\n"
00114 "build a1 a2: cat in\n");
00115   GetNode("a1")->MarkDirty();
00116   GetNode("a2")->MarkDirty();
00117   GetNode("b1")->MarkDirty();
00118   GetNode("b2")->MarkDirty();
00119   GetNode("out")->MarkDirty();
00120   string err;
00121   EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
00122   ASSERT_EQ("", err);
00123   ASSERT_TRUE(plan_.more_to_do());
00124 
00125   Edge* edge;
00126   edge = plan_.FindWork();
00127   ASSERT_TRUE(edge);  // cat in
00128   plan_.EdgeFinished(edge);
00129 
00130   edge = plan_.FindWork();
00131   ASSERT_TRUE(edge);  // cat a1
00132   plan_.EdgeFinished(edge);
00133 
00134   edge = plan_.FindWork();
00135   ASSERT_TRUE(edge);  // cat a2
00136   plan_.EdgeFinished(edge);
00137 
00138   edge = plan_.FindWork();
00139   ASSERT_TRUE(edge);  // cat b1 b2
00140   plan_.EdgeFinished(edge);
00141 
00142   edge = plan_.FindWork();
00143   ASSERT_FALSE(edge);  // done
00144 }
00145 
00146 // Test that two edges from one output can both execute.
00147 TEST_F(PlanTest, DoubleDependent) {
00148   AssertParse(&state_,
00149 "build out: cat a1 a2\n"
00150 "build a1: cat mid\n"
00151 "build a2: cat mid\n"
00152 "build mid: cat in\n");
00153   GetNode("mid")->MarkDirty();
00154   GetNode("a1")->MarkDirty();
00155   GetNode("a2")->MarkDirty();
00156   GetNode("out")->MarkDirty();
00157 
00158   string err;
00159   EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
00160   ASSERT_EQ("", err);
00161   ASSERT_TRUE(plan_.more_to_do());
00162 
00163   Edge* edge;
00164   edge = plan_.FindWork();
00165   ASSERT_TRUE(edge);  // cat in
00166   plan_.EdgeFinished(edge);
00167 
00168   edge = plan_.FindWork();
00169   ASSERT_TRUE(edge);  // cat mid
00170   plan_.EdgeFinished(edge);
00171 
00172   edge = plan_.FindWork();
00173   ASSERT_TRUE(edge);  // cat mid
00174   plan_.EdgeFinished(edge);
00175 
00176   edge = plan_.FindWork();
00177   ASSERT_TRUE(edge);  // cat a1 a2
00178   plan_.EdgeFinished(edge);
00179 
00180   edge = plan_.FindWork();
00181   ASSERT_FALSE(edge);  // done
00182 }
00183 
00184 TEST_F(PlanTest, DependencyCycle) {
00185   AssertParse(&state_,
00186 "build out: cat mid\n"
00187 "build mid: cat in\n"
00188 "build in: cat pre\n"
00189 "build pre: cat out\n");
00190   GetNode("out")->MarkDirty();
00191   GetNode("mid")->MarkDirty();
00192   GetNode("in")->MarkDirty();
00193   GetNode("pre")->MarkDirty();
00194 
00195   string err;
00196   EXPECT_FALSE(plan_.AddTarget(GetNode("out"), &err));
00197   ASSERT_EQ("dependency cycle: out -> mid -> in -> pre -> out", err);
00198 }
00199 
00200 TEST_F(PlanTest, PoolWithDepthOne) {
00201   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00202 "pool foobar\n"
00203 "  depth = 1\n"
00204 "rule poolcat\n"
00205 "  command = cat $in > $out\n"
00206 "  pool = foobar\n"
00207 "build out1: poolcat in\n"
00208 "build out2: poolcat in\n"));
00209   GetNode("out1")->MarkDirty();
00210   GetNode("out2")->MarkDirty();
00211   string err;
00212   EXPECT_TRUE(plan_.AddTarget(GetNode("out1"), &err));
00213   ASSERT_EQ("", err);
00214   EXPECT_TRUE(plan_.AddTarget(GetNode("out2"), &err));
00215   ASSERT_EQ("", err);
00216   ASSERT_TRUE(plan_.more_to_do());
00217 
00218   Edge* edge = plan_.FindWork();
00219   ASSERT_TRUE(edge);
00220   ASSERT_EQ("in",  edge->inputs_[0]->path());
00221   ASSERT_EQ("out1", edge->outputs_[0]->path());
00222 
00223   // This will be false since poolcat is serialized
00224   ASSERT_FALSE(plan_.FindWork());
00225 
00226   plan_.EdgeFinished(edge);
00227 
00228   edge = plan_.FindWork();
00229   ASSERT_TRUE(edge);
00230   ASSERT_EQ("in", edge->inputs_[0]->path());
00231   ASSERT_EQ("out2", edge->outputs_[0]->path());
00232 
00233   ASSERT_FALSE(plan_.FindWork());
00234 
00235   plan_.EdgeFinished(edge);
00236 
00237   ASSERT_FALSE(plan_.more_to_do());
00238   edge = plan_.FindWork();
00239   ASSERT_EQ(0, edge);
00240 }
00241 
00242 TEST_F(PlanTest, PoolsWithDepthTwo) {
00243   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00244 "pool foobar\n"
00245 "  depth = 2\n"
00246 "pool bazbin\n"
00247 "  depth = 2\n"
00248 "rule foocat\n"
00249 "  command = cat $in > $out\n"
00250 "  pool = foobar\n"
00251 "rule bazcat\n"
00252 "  command = cat $in > $out\n"
00253 "  pool = bazbin\n"
00254 "build out1: foocat in\n"
00255 "build out2: foocat in\n"
00256 "build out3: foocat in\n"
00257 "build outb1: bazcat in\n"
00258 "build outb2: bazcat in\n"
00259 "build outb3: bazcat in\n"
00260 "  pool =\n"
00261 "build allTheThings: cat out1 out2 out3 outb1 outb2 outb3\n"
00262 ));
00263   // Mark all the out* nodes dirty
00264   for (int i = 0; i < 3; ++i) {
00265     GetNode("out" + string(1, '1' + static_cast<char>(i)))->MarkDirty();
00266     GetNode("outb" + string(1, '1' + static_cast<char>(i)))->MarkDirty();
00267   }
00268   GetNode("allTheThings")->MarkDirty();
00269 
00270   string err;
00271   EXPECT_TRUE(plan_.AddTarget(GetNode("allTheThings"), &err));
00272   ASSERT_EQ("", err);
00273 
00274   deque<Edge*> edges;
00275   FindWorkSorted(&edges, 5);
00276 
00277   for (int i = 0; i < 4; ++i) {
00278     Edge *edge = edges[i];
00279     ASSERT_EQ("in",  edge->inputs_[0]->path());
00280     string base_name(i < 2 ? "out" : "outb");
00281     ASSERT_EQ(base_name + string(1, '1' + (i % 2)), edge->outputs_[0]->path());
00282   }
00283 
00284   // outb3 is exempt because it has an empty pool
00285   Edge* edge = edges[4];
00286   ASSERT_TRUE(edge);
00287   ASSERT_EQ("in",  edge->inputs_[0]->path());
00288   ASSERT_EQ("outb3", edge->outputs_[0]->path());
00289 
00290   // finish out1
00291   plan_.EdgeFinished(edges.front());
00292   edges.pop_front();
00293 
00294   // out3 should be available
00295   Edge* out3 = plan_.FindWork();
00296   ASSERT_TRUE(out3);
00297   ASSERT_EQ("in",  out3->inputs_[0]->path());
00298   ASSERT_EQ("out3", out3->outputs_[0]->path());
00299 
00300   ASSERT_FALSE(plan_.FindWork());
00301 
00302   plan_.EdgeFinished(out3);
00303 
00304   ASSERT_FALSE(plan_.FindWork());
00305 
00306   for (deque<Edge*>::iterator it = edges.begin(); it != edges.end(); ++it) {
00307     plan_.EdgeFinished(*it);
00308   }
00309 
00310   Edge* last = plan_.FindWork();
00311   ASSERT_TRUE(last);
00312   ASSERT_EQ("allTheThings", last->outputs_[0]->path());
00313 
00314   plan_.EdgeFinished(last);
00315 
00316   ASSERT_FALSE(plan_.more_to_do());
00317   ASSERT_FALSE(plan_.FindWork());
00318 }
00319 
00320 TEST_F(PlanTest, PoolWithRedundantEdges) {
00321   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00322     "pool compile\n"
00323     "  depth = 1\n"
00324     "rule gen_foo\n"
00325     "  command = touch foo.cpp\n"
00326     "rule gen_bar\n"
00327     "  command = touch bar.cpp\n"
00328     "rule echo\n"
00329     "  command = echo $out > $out\n"
00330     "build foo.cpp.obj: echo foo.cpp || foo.cpp\n"
00331     "  pool = compile\n"
00332     "build bar.cpp.obj: echo bar.cpp || bar.cpp\n"
00333     "  pool = compile\n"
00334     "build libfoo.a: echo foo.cpp.obj bar.cpp.obj\n"
00335     "build foo.cpp: gen_foo\n"
00336     "build bar.cpp: gen_bar\n"
00337     "build all: phony libfoo.a\n"));
00338   GetNode("foo.cpp")->MarkDirty();
00339   GetNode("foo.cpp.obj")->MarkDirty();
00340   GetNode("bar.cpp")->MarkDirty();
00341   GetNode("bar.cpp.obj")->MarkDirty();
00342   GetNode("libfoo.a")->MarkDirty();
00343   GetNode("all")->MarkDirty();
00344   string err;
00345   EXPECT_TRUE(plan_.AddTarget(GetNode("all"), &err));
00346   ASSERT_EQ("", err);
00347   ASSERT_TRUE(plan_.more_to_do());
00348 
00349   Edge* edge = NULL;
00350 
00351   deque<Edge*> initial_edges;
00352   FindWorkSorted(&initial_edges, 2);
00353 
00354   edge = initial_edges[1];  // Foo first
00355   ASSERT_EQ("foo.cpp", edge->outputs_[0]->path());
00356   plan_.EdgeFinished(edge);
00357 
00358   edge = plan_.FindWork();
00359   ASSERT_TRUE(edge);
00360   ASSERT_FALSE(plan_.FindWork());
00361   ASSERT_EQ("foo.cpp", edge->inputs_[0]->path());
00362   ASSERT_EQ("foo.cpp", edge->inputs_[1]->path());
00363   ASSERT_EQ("foo.cpp.obj", edge->outputs_[0]->path());
00364   plan_.EdgeFinished(edge);
00365 
00366   edge = initial_edges[0];  // Now for bar
00367   ASSERT_EQ("bar.cpp", edge->outputs_[0]->path());
00368   plan_.EdgeFinished(edge);
00369 
00370   edge = plan_.FindWork();
00371   ASSERT_TRUE(edge);
00372   ASSERT_FALSE(plan_.FindWork());
00373   ASSERT_EQ("bar.cpp", edge->inputs_[0]->path());
00374   ASSERT_EQ("bar.cpp", edge->inputs_[1]->path());
00375   ASSERT_EQ("bar.cpp.obj", edge->outputs_[0]->path());
00376   plan_.EdgeFinished(edge);
00377 
00378   edge = plan_.FindWork();
00379   ASSERT_TRUE(edge);
00380   ASSERT_FALSE(plan_.FindWork());
00381   ASSERT_EQ("foo.cpp.obj", edge->inputs_[0]->path());
00382   ASSERT_EQ("bar.cpp.obj", edge->inputs_[1]->path());
00383   ASSERT_EQ("libfoo.a", edge->outputs_[0]->path());
00384   plan_.EdgeFinished(edge);
00385 
00386   edge = plan_.FindWork();
00387   ASSERT_TRUE(edge);
00388   ASSERT_FALSE(plan_.FindWork());
00389   ASSERT_EQ("libfoo.a", edge->inputs_[0]->path());
00390   ASSERT_EQ("all", edge->outputs_[0]->path());
00391   plan_.EdgeFinished(edge);
00392 
00393   edge = plan_.FindWork();
00394   ASSERT_FALSE(edge);
00395   ASSERT_FALSE(plan_.more_to_do());
00396 }
00397 
00398 /// Fake implementation of CommandRunner, useful for tests.
00399 struct FakeCommandRunner : public CommandRunner {
00400   explicit FakeCommandRunner(VirtualFileSystem* fs) :
00401       last_command_(NULL), fs_(fs) {}
00402 
00403   // CommandRunner impl
00404   virtual bool CanRunMore();
00405   virtual bool StartCommand(Edge* edge);
00406   virtual bool WaitForCommand(Result* result);
00407   virtual vector<Edge*> GetActiveEdges();
00408   virtual void Abort();
00409 
00410   vector<string> commands_ran_;
00411   Edge* last_command_;
00412   VirtualFileSystem* fs_;
00413 };
00414 
00415 struct BuildTest : public StateTestWithBuiltinRules {
00416   BuildTest() : config_(MakeConfig()), command_runner_(&fs_),
00417                 builder_(&state_, config_, NULL, NULL, &fs_),
00418                 status_(config_) {
00419   }
00420 
00421   virtual void SetUp() {
00422     StateTestWithBuiltinRules::SetUp();
00423 
00424     builder_.command_runner_.reset(&command_runner_);
00425     AssertParse(&state_,
00426 "build cat1: cat in1\n"
00427 "build cat2: cat in1 in2\n"
00428 "build cat12: cat cat1 cat2\n");
00429 
00430     fs_.Create("in1", "");
00431     fs_.Create("in2", "");
00432   }
00433 
00434   ~BuildTest() {
00435     builder_.command_runner_.release();
00436   }
00437 
00438   /// Rebuild target in the 'working tree' (fs_).
00439   /// State of command_runner_ and logs contents (if specified) ARE MODIFIED.
00440   /// Handy to check for NOOP builds, and higher-level rebuild tests.
00441   void RebuildTarget(const string& target, const char* manifest,
00442                      const char* log_path = NULL,
00443                      const char* deps_path = NULL);
00444 
00445   // Mark a path dirty.
00446   void Dirty(const string& path);
00447 
00448   BuildConfig MakeConfig() {
00449     BuildConfig config;
00450     config.verbosity = BuildConfig::QUIET;
00451     return config;
00452   }
00453 
00454   BuildConfig config_;
00455   FakeCommandRunner command_runner_;
00456   VirtualFileSystem fs_;
00457   Builder builder_;
00458 
00459   BuildStatus status_;
00460 };
00461 
00462 void BuildTest::RebuildTarget(const string& target, const char* manifest,
00463                               const char* log_path, const char* deps_path) {
00464   State state;
00465   ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
00466   AssertParse(&state, manifest);
00467 
00468   string err;
00469   BuildLog build_log, *pbuild_log = NULL;
00470   if (log_path) {
00471     ASSERT_TRUE(build_log.Load(log_path, &err));
00472     ASSERT_TRUE(build_log.OpenForWrite(log_path, &err));
00473     ASSERT_EQ("", err);
00474     pbuild_log = &build_log;
00475   }
00476 
00477   DepsLog deps_log, *pdeps_log = NULL;
00478   if (deps_path) {
00479     ASSERT_TRUE(deps_log.Load(deps_path, &state, &err));
00480     ASSERT_TRUE(deps_log.OpenForWrite(deps_path, &err));
00481     ASSERT_EQ("", err);
00482     pdeps_log = &deps_log;
00483   }
00484 
00485   Builder builder(&state, config_, pbuild_log, pdeps_log, &fs_);
00486   EXPECT_TRUE(builder.AddTarget(target, &err));
00487 
00488   command_runner_.commands_ran_.clear();
00489   builder.command_runner_.reset(&command_runner_);
00490   if (!builder.AlreadyUpToDate()) {
00491     bool build_res = builder.Build(&err);
00492     EXPECT_TRUE(build_res) << "builder.Build(&err)";
00493   }
00494   builder.command_runner_.release();
00495 }
00496 
00497 bool FakeCommandRunner::CanRunMore() {
00498   // Only run one at a time.
00499   return last_command_ == NULL;
00500 }
00501 
00502 bool FakeCommandRunner::StartCommand(Edge* edge) {
00503   assert(!last_command_);
00504   commands_ran_.push_back(edge->EvaluateCommand());
00505   if (edge->rule().name() == "cat"  ||
00506       edge->rule().name() == "cat_rsp" ||
00507       edge->rule().name() == "cc" ||
00508       edge->rule().name() == "touch" ||
00509       edge->rule().name() == "touch-interrupt") {
00510     for (vector<Node*>::iterator out = edge->outputs_.begin();
00511          out != edge->outputs_.end(); ++out) {
00512       fs_->Create((*out)->path(), "");
00513     }
00514   } else if (edge->rule().name() == "true" ||
00515              edge->rule().name() == "fail" ||
00516              edge->rule().name() == "interrupt") {
00517     // Don't do anything.
00518   } else {
00519     printf("unknown command\n");
00520     return false;
00521   }
00522 
00523   last_command_ = edge;
00524   return true;
00525 }
00526 
00527 bool FakeCommandRunner::WaitForCommand(Result* result) {
00528   if (!last_command_)
00529     return false;
00530 
00531   Edge* edge = last_command_;
00532   result->edge = edge;
00533 
00534   if (edge->rule().name() == "interrupt" ||
00535       edge->rule().name() == "touch-interrupt") {
00536     result->status = ExitInterrupted;
00537     return true;
00538   }
00539 
00540   if (edge->rule().name() == "fail")
00541     result->status = ExitFailure;
00542   else
00543     result->status = ExitSuccess;
00544   last_command_ = NULL;
00545   return true;
00546 }
00547 
00548 vector<Edge*> FakeCommandRunner::GetActiveEdges() {
00549   vector<Edge*> edges;
00550   if (last_command_)
00551     edges.push_back(last_command_);
00552   return edges;
00553 }
00554 
00555 void FakeCommandRunner::Abort() {
00556   last_command_ = NULL;
00557 }
00558 
00559 void BuildTest::Dirty(const string& path) {
00560   Node* node = GetNode(path);
00561   node->MarkDirty();
00562 
00563   // If it's an input file, mark that we've already stat()ed it and
00564   // it's missing.
00565   if (!node->in_edge())
00566     node->MarkMissing();
00567 }
00568 
00569 TEST_F(BuildTest, NoWork) {
00570   string err;
00571   EXPECT_TRUE(builder_.AlreadyUpToDate());
00572 }
00573 
00574 TEST_F(BuildTest, OneStep) {
00575   // Given a dirty target with one ready input,
00576   // we should rebuild the target.
00577   Dirty("cat1");
00578   string err;
00579   EXPECT_TRUE(builder_.AddTarget("cat1", &err));
00580   ASSERT_EQ("", err);
00581   EXPECT_TRUE(builder_.Build(&err));
00582   ASSERT_EQ("", err);
00583 
00584   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
00585   EXPECT_EQ("cat in1 > cat1", command_runner_.commands_ran_[0]);
00586 }
00587 
00588 TEST_F(BuildTest, OneStep2) {
00589   // Given a target with one dirty input,
00590   // we should rebuild the target.
00591   Dirty("cat1");
00592   string err;
00593   EXPECT_TRUE(builder_.AddTarget("cat1", &err));
00594   ASSERT_EQ("", err);
00595   EXPECT_TRUE(builder_.Build(&err));
00596   EXPECT_EQ("", err);
00597 
00598   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
00599   EXPECT_EQ("cat in1 > cat1", command_runner_.commands_ran_[0]);
00600 }
00601 
00602 TEST_F(BuildTest, TwoStep) {
00603   string err;
00604   EXPECT_TRUE(builder_.AddTarget("cat12", &err));
00605   ASSERT_EQ("", err);
00606   EXPECT_TRUE(builder_.Build(&err));
00607   EXPECT_EQ("", err);
00608   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
00609   // Depending on how the pointers work out, we could've ran
00610   // the first two commands in either order.
00611   EXPECT_TRUE((command_runner_.commands_ran_[0] == "cat in1 > cat1" &&
00612                command_runner_.commands_ran_[1] == "cat in1 in2 > cat2") ||
00613               (command_runner_.commands_ran_[1] == "cat in1 > cat1" &&
00614                command_runner_.commands_ran_[0] == "cat in1 in2 > cat2"));
00615 
00616   EXPECT_EQ("cat cat1 cat2 > cat12", command_runner_.commands_ran_[2]);
00617 
00618   fs_.Tick();
00619 
00620   // Modifying in2 requires rebuilding one intermediate file
00621   // and the final file.
00622   fs_.Create("in2", "");
00623   state_.Reset();
00624   EXPECT_TRUE(builder_.AddTarget("cat12", &err));
00625   ASSERT_EQ("", err);
00626   EXPECT_TRUE(builder_.Build(&err));
00627   ASSERT_EQ("", err);
00628   ASSERT_EQ(5u, command_runner_.commands_ran_.size());
00629   EXPECT_EQ("cat in1 in2 > cat2", command_runner_.commands_ran_[3]);
00630   EXPECT_EQ("cat cat1 cat2 > cat12", command_runner_.commands_ran_[4]);
00631 }
00632 
00633 TEST_F(BuildTest, TwoOutputs) {
00634   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00635 "rule touch\n"
00636 "  command = touch $out\n"
00637 "build out1 out2: touch in.txt\n"));
00638 
00639   fs_.Create("in.txt", "");
00640 
00641   string err;
00642   EXPECT_TRUE(builder_.AddTarget("out1", &err));
00643   ASSERT_EQ("", err);
00644   EXPECT_TRUE(builder_.Build(&err));
00645   EXPECT_EQ("", err);
00646   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
00647   EXPECT_EQ("touch out1 out2", command_runner_.commands_ran_[0]);
00648 }
00649 
00650 // Test case from
00651 //   https://github.com/martine/ninja/issues/148
00652 TEST_F(BuildTest, MultiOutIn) {
00653   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00654 "rule touch\n"
00655 "  command = touch $out\n"
00656 "build in1 otherfile: touch in\n"
00657 "build out: touch in | in1\n"));
00658 
00659   fs_.Create("in", "");
00660   fs_.Tick();
00661   fs_.Create("in1", "");
00662 
00663   string err;
00664   EXPECT_TRUE(builder_.AddTarget("out", &err));
00665   ASSERT_EQ("", err);
00666   EXPECT_TRUE(builder_.Build(&err));
00667   EXPECT_EQ("", err);
00668 }
00669 
00670 TEST_F(BuildTest, Chain) {
00671   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00672 "build c2: cat c1\n"
00673 "build c3: cat c2\n"
00674 "build c4: cat c3\n"
00675 "build c5: cat c4\n"));
00676 
00677   fs_.Create("c1", "");
00678 
00679   string err;
00680   EXPECT_TRUE(builder_.AddTarget("c5", &err));
00681   ASSERT_EQ("", err);
00682   EXPECT_TRUE(builder_.Build(&err));
00683   EXPECT_EQ("", err);
00684   ASSERT_EQ(4u, command_runner_.commands_ran_.size());
00685 
00686   err.clear();
00687   command_runner_.commands_ran_.clear();
00688   state_.Reset();
00689   EXPECT_TRUE(builder_.AddTarget("c5", &err));
00690   ASSERT_EQ("", err);
00691   EXPECT_TRUE(builder_.AlreadyUpToDate());
00692 
00693   fs_.Tick();
00694 
00695   fs_.Create("c3", "");
00696   err.clear();
00697   command_runner_.commands_ran_.clear();
00698   state_.Reset();
00699   EXPECT_TRUE(builder_.AddTarget("c5", &err));
00700   ASSERT_EQ("", err);
00701   EXPECT_FALSE(builder_.AlreadyUpToDate());
00702   EXPECT_TRUE(builder_.Build(&err));
00703   ASSERT_EQ(2u, command_runner_.commands_ran_.size());  // 3->4, 4->5
00704 }
00705 
00706 TEST_F(BuildTest, MissingInput) {
00707   // Input is referenced by build file, but no rule for it.
00708   string err;
00709   Dirty("in1");
00710   EXPECT_FALSE(builder_.AddTarget("cat1", &err));
00711   EXPECT_EQ("'in1', needed by 'cat1', missing and no known rule to make it",
00712             err);
00713 }
00714 
00715 TEST_F(BuildTest, MissingTarget) {
00716   // Target is not referenced by build file.
00717   string err;
00718   EXPECT_FALSE(builder_.AddTarget("meow", &err));
00719   EXPECT_EQ("unknown target: 'meow'", err);
00720 }
00721 
00722 TEST_F(BuildTest, MakeDirs) {
00723   string err;
00724 
00725 #ifdef _WIN32
00726   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00727                                       "build subdir\\dir2\\file: cat in1\n"));
00728   EXPECT_TRUE(builder_.AddTarget("subdir\\dir2\\file", &err));
00729 #else
00730   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00731                                       "build subdir/dir2/file: cat in1\n"));
00732   EXPECT_TRUE(builder_.AddTarget("subdir/dir2/file", &err));
00733 #endif
00734 
00735   EXPECT_EQ("", err);
00736   EXPECT_TRUE(builder_.Build(&err));
00737   ASSERT_EQ("", err);
00738   ASSERT_EQ(2u, fs_.directories_made_.size());
00739   EXPECT_EQ("subdir", fs_.directories_made_[0]);
00740 #ifdef _WIN32
00741   EXPECT_EQ("subdir\\dir2", fs_.directories_made_[1]);
00742 #else
00743   EXPECT_EQ("subdir/dir2", fs_.directories_made_[1]);
00744 #endif
00745 }
00746 
00747 TEST_F(BuildTest, DepFileMissing) {
00748   string err;
00749   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00750 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
00751 "build foo.o: cc foo.c\n"));
00752   fs_.Create("foo.c", "");
00753 
00754   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00755   ASSERT_EQ("", err);
00756   ASSERT_EQ(1u, fs_.files_read_.size());
00757   EXPECT_EQ("foo.o.d", fs_.files_read_[0]);
00758 }
00759 
00760 TEST_F(BuildTest, DepFileOK) {
00761   string err;
00762   int orig_edges = state_.edges_.size();
00763   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00764 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
00765 "build foo.o: cc foo.c\n"));
00766   Edge* edge = state_.edges_.back();
00767 
00768   fs_.Create("foo.c", "");
00769   GetNode("bar.h")->MarkDirty();  // Mark bar.h as missing.
00770   fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
00771   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00772   ASSERT_EQ("", err);
00773   ASSERT_EQ(1u, fs_.files_read_.size());
00774   EXPECT_EQ("foo.o.d", fs_.files_read_[0]);
00775 
00776   // Expect three new edges: one generating foo.o, and two more from
00777   // loading the depfile.
00778   ASSERT_EQ(orig_edges + 3, (int)state_.edges_.size());
00779   // Expect our edge to now have three inputs: foo.c and two headers.
00780   ASSERT_EQ(3u, edge->inputs_.size());
00781 
00782   // Expect the command line we generate to only use the original input.
00783   ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
00784 }
00785 
00786 TEST_F(BuildTest, DepFileParseError) {
00787   string err;
00788   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00789 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
00790 "build foo.o: cc foo.c\n"));
00791   fs_.Create("foo.c", "");
00792   fs_.Create("foo.o.d", "randomtext\n");
00793   EXPECT_FALSE(builder_.AddTarget("foo.o", &err));
00794   EXPECT_EQ("expected depfile 'foo.o.d' to mention 'foo.o', got 'randomtext'",
00795             err);
00796 }
00797 
00798 TEST_F(BuildTest, OrderOnlyDeps) {
00799   string err;
00800   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00801 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
00802 "build foo.o: cc foo.c || otherfile\n"));
00803   Edge* edge = state_.edges_.back();
00804 
00805   fs_.Create("foo.c", "");
00806   fs_.Create("otherfile", "");
00807   fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
00808   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00809   ASSERT_EQ("", err);
00810 
00811   // One explicit, two implicit, one order only.
00812   ASSERT_EQ(4u, edge->inputs_.size());
00813   EXPECT_EQ(2, edge->implicit_deps_);
00814   EXPECT_EQ(1, edge->order_only_deps_);
00815   // Verify the inputs are in the order we expect
00816   // (explicit then implicit then orderonly).
00817   EXPECT_EQ("foo.c", edge->inputs_[0]->path());
00818   EXPECT_EQ("blah.h", edge->inputs_[1]->path());
00819   EXPECT_EQ("bar.h", edge->inputs_[2]->path());
00820   EXPECT_EQ("otherfile", edge->inputs_[3]->path());
00821 
00822   // Expect the command line we generate to only use the original input.
00823   ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
00824 
00825   // explicit dep dirty, expect a rebuild.
00826   EXPECT_TRUE(builder_.Build(&err));
00827   ASSERT_EQ("", err);
00828   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
00829 
00830   fs_.Tick();
00831 
00832   // Recreate the depfile, as it should have been deleted by the build.
00833   fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
00834 
00835   // implicit dep dirty, expect a rebuild.
00836   fs_.Create("blah.h", "");
00837   fs_.Create("bar.h", "");
00838   command_runner_.commands_ran_.clear();
00839   state_.Reset();
00840   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00841   EXPECT_TRUE(builder_.Build(&err));
00842   ASSERT_EQ("", err);
00843   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
00844 
00845   fs_.Tick();
00846 
00847   // Recreate the depfile, as it should have been deleted by the build.
00848   fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
00849 
00850   // order only dep dirty, no rebuild.
00851   fs_.Create("otherfile", "");
00852   command_runner_.commands_ran_.clear();
00853   state_.Reset();
00854   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00855   EXPECT_EQ("", err);
00856   EXPECT_TRUE(builder_.AlreadyUpToDate());
00857 
00858   // implicit dep missing, expect rebuild.
00859   fs_.RemoveFile("bar.h");
00860   command_runner_.commands_ran_.clear();
00861   state_.Reset();
00862   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00863   EXPECT_TRUE(builder_.Build(&err));
00864   ASSERT_EQ("", err);
00865   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
00866 }
00867 
00868 TEST_F(BuildTest, RebuildOrderOnlyDeps) {
00869   string err;
00870   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00871 "rule cc\n  command = cc $in\n"
00872 "rule true\n  command = true\n"
00873 "build oo.h: cc oo.h.in\n"
00874 "build foo.o: cc foo.c || oo.h\n"));
00875 
00876   fs_.Create("foo.c", "");
00877   fs_.Create("oo.h.in", "");
00878 
00879   // foo.o and order-only dep dirty, build both.
00880   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00881   EXPECT_TRUE(builder_.Build(&err));
00882   ASSERT_EQ("", err);
00883   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
00884 
00885   // all clean, no rebuild.
00886   command_runner_.commands_ran_.clear();
00887   state_.Reset();
00888   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00889   EXPECT_EQ("", err);
00890   EXPECT_TRUE(builder_.AlreadyUpToDate());
00891 
00892   // order-only dep missing, build it only.
00893   fs_.RemoveFile("oo.h");
00894   command_runner_.commands_ran_.clear();
00895   state_.Reset();
00896   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00897   EXPECT_TRUE(builder_.Build(&err));
00898   ASSERT_EQ("", err);
00899   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
00900   ASSERT_EQ("cc oo.h.in", command_runner_.commands_ran_[0]);
00901 
00902   fs_.Tick();
00903 
00904   // order-only dep dirty, build it only.
00905   fs_.Create("oo.h.in", "");
00906   command_runner_.commands_ran_.clear();
00907   state_.Reset();
00908   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00909   EXPECT_TRUE(builder_.Build(&err));
00910   ASSERT_EQ("", err);
00911   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
00912   ASSERT_EQ("cc oo.h.in", command_runner_.commands_ran_[0]);
00913 }
00914 
00915 TEST_F(BuildTest, Phony) {
00916   string err;
00917   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00918 "build out: cat bar.cc\n"
00919 "build all: phony out\n"));
00920   fs_.Create("bar.cc", "");
00921 
00922   EXPECT_TRUE(builder_.AddTarget("all", &err));
00923   ASSERT_EQ("", err);
00924 
00925   // Only one command to run, because phony runs no command.
00926   EXPECT_FALSE(builder_.AlreadyUpToDate());
00927   EXPECT_TRUE(builder_.Build(&err));
00928   ASSERT_EQ("", err);
00929   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
00930 }
00931 
00932 TEST_F(BuildTest, PhonyNoWork) {
00933   string err;
00934   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00935 "build out: cat bar.cc\n"
00936 "build all: phony out\n"));
00937   fs_.Create("bar.cc", "");
00938   fs_.Create("out", "");
00939 
00940   EXPECT_TRUE(builder_.AddTarget("all", &err));
00941   ASSERT_EQ("", err);
00942   EXPECT_TRUE(builder_.AlreadyUpToDate());
00943 }
00944 
00945 TEST_F(BuildTest, Fail) {
00946   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00947 "rule fail\n"
00948 "  command = fail\n"
00949 "build out1: fail\n"));
00950 
00951   string err;
00952   EXPECT_TRUE(builder_.AddTarget("out1", &err));
00953   ASSERT_EQ("", err);
00954 
00955   EXPECT_FALSE(builder_.Build(&err));
00956   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
00957   ASSERT_EQ("subcommand failed", err);
00958 }
00959 
00960 TEST_F(BuildTest, SwallowFailures) {
00961   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00962 "rule fail\n"
00963 "  command = fail\n"
00964 "build out1: fail\n"
00965 "build out2: fail\n"
00966 "build out3: fail\n"
00967 "build all: phony out1 out2 out3\n"));
00968 
00969   // Swallow two failures, die on the third.
00970   config_.failures_allowed = 3;
00971 
00972   string err;
00973   EXPECT_TRUE(builder_.AddTarget("all", &err));
00974   ASSERT_EQ("", err);
00975 
00976   EXPECT_FALSE(builder_.Build(&err));
00977   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
00978   ASSERT_EQ("subcommands failed", err);
00979 }
00980 
00981 TEST_F(BuildTest, SwallowFailuresLimit) {
00982   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00983 "rule fail\n"
00984 "  command = fail\n"
00985 "build out1: fail\n"
00986 "build out2: fail\n"
00987 "build out3: fail\n"
00988 "build final: cat out1 out2 out3\n"));
00989 
00990   // Swallow ten failures; we should stop before building final.
00991   config_.failures_allowed = 11;
00992 
00993   string err;
00994   EXPECT_TRUE(builder_.AddTarget("final", &err));
00995   ASSERT_EQ("", err);
00996 
00997   EXPECT_FALSE(builder_.Build(&err));
00998   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
00999   ASSERT_EQ("cannot make progress due to previous errors", err);
01000 }
01001 
01002 struct BuildWithLogTest : public BuildTest {
01003   BuildWithLogTest() {
01004     builder_.SetBuildLog(&build_log_);
01005   }
01006 
01007   BuildLog build_log_;
01008 };
01009 
01010 TEST_F(BuildWithLogTest, NotInLogButOnDisk) {
01011   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
01012 "rule cc\n"
01013 "  command = cc\n"
01014 "build out1: cc in\n"));
01015 
01016   // Create input/output that would be considered up to date when
01017   // not considering the command line hash.
01018   fs_.Create("in", "");
01019   fs_.Create("out1", "");
01020   string err;
01021 
01022   // Because it's not in the log, it should not be up-to-date until
01023   // we build again.
01024   EXPECT_TRUE(builder_.AddTarget("out1", &err));
01025   EXPECT_FALSE(builder_.AlreadyUpToDate());
01026 
01027   command_runner_.commands_ran_.clear();
01028   state_.Reset();
01029 
01030   EXPECT_TRUE(builder_.AddTarget("out1", &err));
01031   EXPECT_TRUE(builder_.Build(&err));
01032   EXPECT_TRUE(builder_.AlreadyUpToDate());
01033 }
01034 
01035 TEST_F(BuildWithLogTest, RestatTest) {
01036   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
01037 "rule true\n"
01038 "  command = true\n"
01039 "  restat = 1\n"
01040 "rule cc\n"
01041 "  command = cc\n"
01042 "  restat = 1\n"
01043 "build out1: cc in\n"
01044 "build out2: true out1\n"
01045 "build out3: cat out2\n"));
01046 
01047   fs_.Create("out1", "");
01048   fs_.Create("out2", "");
01049   fs_.Create("out3", "");
01050 
01051   fs_.Tick();
01052 
01053   fs_.Create("in", "");
01054 
01055   // Do a pre-build so that there's commands in the log for the outputs,
01056   // otherwise, the lack of an entry in the build log will cause out3 to rebuild
01057   // regardless of restat.
01058   string err;
01059   EXPECT_TRUE(builder_.AddTarget("out3", &err));
01060   ASSERT_EQ("", err);
01061   EXPECT_TRUE(builder_.Build(&err));
01062   ASSERT_EQ("", err);
01063   EXPECT_EQ("[3/3]", builder_.status_->FormatProgressStatus("[%s/%t]"));
01064   command_runner_.commands_ran_.clear();
01065   state_.Reset();
01066 
01067   fs_.Tick();
01068 
01069   fs_.Create("in", "");
01070   // "cc" touches out1, so we should build out2.  But because "true" does not
01071   // touch out2, we should cancel the build of out3.
01072   EXPECT_TRUE(builder_.AddTarget("out3", &err));
01073   ASSERT_EQ("", err);
01074   EXPECT_TRUE(builder_.Build(&err));
01075   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
01076 
01077   // If we run again, it should be a no-op, because the build log has recorded
01078   // that we've already built out2 with an input timestamp of 2 (from out1).
01079   command_runner_.commands_ran_.clear();
01080   state_.Reset();
01081   EXPECT_TRUE(builder_.AddTarget("out3", &err));
01082   ASSERT_EQ("", err);
01083   EXPECT_TRUE(builder_.AlreadyUpToDate());
01084 
01085   fs_.Tick();
01086 
01087   fs_.Create("in", "");
01088 
01089   // The build log entry should not, however, prevent us from rebuilding out2
01090   // if out1 changes.
01091   command_runner_.commands_ran_.clear();
01092   state_.Reset();
01093   EXPECT_TRUE(builder_.AddTarget("out3", &err));
01094   ASSERT_EQ("", err);
01095   EXPECT_TRUE(builder_.Build(&err));
01096   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
01097 }
01098 
01099 TEST_F(BuildWithLogTest, RestatMissingFile) {
01100   // If a restat rule doesn't create its output, and the output didn't
01101   // exist before the rule was run, consider that behavior equivalent
01102   // to a rule that doesn't modify its existent output file.
01103 
01104   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
01105 "rule true\n"
01106 "  command = true\n"
01107 "  restat = 1\n"
01108 "rule cc\n"
01109 "  command = cc\n"
01110 "build out1: true in\n"
01111 "build out2: cc out1\n"));
01112 
01113   fs_.Create("in", "");
01114   fs_.Create("out2", "");
01115 
01116   // Do a pre-build so that there's commands in the log for the outputs,
01117   // otherwise, the lack of an entry in the build log will cause out2 to rebuild
01118   // regardless of restat.
01119   string err;
01120   EXPECT_TRUE(builder_.AddTarget("out2", &err));
01121   ASSERT_EQ("", err);
01122   EXPECT_TRUE(builder_.Build(&err));
01123   ASSERT_EQ("", err);
01124   command_runner_.commands_ran_.clear();
01125   state_.Reset();
01126 
01127   fs_.Tick();
01128   fs_.Create("in", "");
01129   fs_.Create("out2", "");
01130 
01131   // Run a build, expect only the first command to run.
01132   // It doesn't touch its output (due to being the "true" command), so
01133   // we shouldn't run the dependent build.
01134   EXPECT_TRUE(builder_.AddTarget("out2", &err));
01135   ASSERT_EQ("", err);
01136   EXPECT_TRUE(builder_.Build(&err));
01137   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
01138 }
01139 
01140 TEST_F(BuildWithLogTest, RestatSingleDependentOutputDirty) {
01141   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
01142     "rule true\n"
01143     "  command = true\n"
01144     "  restat = 1\n"
01145     "rule touch\n"
01146     "  command = touch\n"
01147     "build out1: true in\n"
01148     "build out2 out3: touch out1\n"
01149     "build out4: touch out2\n"
01150     ));
01151 
01152   // Create the necessary files
01153   fs_.Create("in", "");
01154 
01155   string err;
01156   EXPECT_TRUE(builder_.AddTarget("out4", &err));
01157   ASSERT_EQ("", err);
01158   EXPECT_TRUE(builder_.Build(&err));
01159   ASSERT_EQ("", err);
01160   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
01161 
01162   fs_.Tick();
01163   fs_.Create("in", "");
01164   fs_.RemoveFile("out3");
01165 
01166   // Since "in" is missing, out1 will be built. Since "out3" is missing,
01167   // out2 and out3 will be built even though "in" is not touched when built.
01168   // Then, since out2 is rebuilt, out4 should be rebuilt -- the restat on the
01169   // "true" rule should not lead to the "touch" edge writing out2 and out3 being
01170   // cleard.
01171   command_runner_.commands_ran_.clear();
01172   state_.Reset();
01173   EXPECT_TRUE(builder_.AddTarget("out4", &err));
01174   ASSERT_EQ("", err);
01175   EXPECT_TRUE(builder_.Build(&err));
01176   ASSERT_EQ("", err);
01177   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
01178 }
01179 
01180 // Test scenario, in which an input file is removed, but output isn't changed
01181 // https://github.com/martine/ninja/issues/295
01182 TEST_F(BuildWithLogTest, RestatMissingInput) {
01183   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
01184     "rule true\n"
01185     "  command = true\n"
01186     "  depfile = $out.d\n"
01187     "  restat = 1\n"
01188     "rule cc\n"
01189     "  command = cc\n"
01190     "build out1: true in\n"
01191     "build out2: cc out1\n"));
01192 
01193   // Create all necessary files
01194   fs_.Create("in", "");
01195 
01196   // The implicit dependencies and the depfile itself
01197   // are newer than the output
01198   TimeStamp restat_mtime = fs_.Tick();
01199   fs_.Create("out1.d", "out1: will.be.deleted restat.file\n");
01200   fs_.Create("will.be.deleted", "");
01201   fs_.Create("restat.file", "");
01202 
01203   // Run the build, out1 and out2 get built
01204   string err;
01205   EXPECT_TRUE(builder_.AddTarget("out2", &err));
01206   ASSERT_EQ("", err);
01207   EXPECT_TRUE(builder_.Build(&err));
01208   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
01209 
01210   // See that an entry in the logfile is created, capturing
01211   // the right mtime
01212   BuildLog::LogEntry* log_entry = build_log_.LookupByOutput("out1");
01213   ASSERT_TRUE(NULL != log_entry);
01214   ASSERT_EQ(restat_mtime, log_entry->restat_mtime);
01215 
01216   // Now remove a file, referenced from depfile, so that target becomes
01217   // dirty, but the output does not change
01218   fs_.RemoveFile("will.be.deleted");
01219 
01220   // Trigger the build again - only out1 gets built
01221   command_runner_.commands_ran_.clear();
01222   state_.Reset();
01223   EXPECT_TRUE(builder_.AddTarget("out2", &err));
01224   ASSERT_EQ("", err);
01225   EXPECT_TRUE(builder_.Build(&err));
01226   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
01227 
01228   // Check that the logfile entry remains correctly set
01229   log_entry = build_log_.LookupByOutput("out1");
01230   ASSERT_TRUE(NULL != log_entry);
01231   ASSERT_EQ(restat_mtime, log_entry->restat_mtime);
01232 }
01233 
01234 struct BuildDryRun : public BuildWithLogTest {
01235   BuildDryRun() {
01236     config_.dry_run = true;
01237   }
01238 };
01239 
01240 TEST_F(BuildDryRun, AllCommandsShown) {
01241   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
01242 "rule true\n"
01243 "  command = true\n"
01244 "  restat = 1\n"
01245 "rule cc\n"
01246 "  command = cc\n"
01247 "  restat = 1\n"
01248 "build out1: cc in\n"
01249 "build out2: true out1\n"
01250 "build out3: cat out2\n"));
01251 
01252   fs_.Create("out1", "");
01253   fs_.Create("out2", "");
01254   fs_.Create("out3", "");
01255 
01256   fs_.Tick();
01257 
01258   fs_.Create("in", "");
01259 
01260   // "cc" touches out1, so we should build out2.  But because "true" does not
01261   // touch out2, we should cancel the build of out3.
01262   string err;
01263   EXPECT_TRUE(builder_.AddTarget("out3", &err));
01264   ASSERT_EQ("", err);
01265   EXPECT_TRUE(builder_.Build(&err));
01266   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
01267 }
01268 
01269 // Test that RSP files are created when & where appropriate and deleted after
01270 // successful execution.
01271 TEST_F(BuildTest, RspFileSuccess)
01272 {
01273   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
01274     "rule cat_rsp\n"
01275     "  command = cat $rspfile > $out\n"
01276     "  rspfile = $rspfile\n"
01277     "  rspfile_content = $long_command\n"
01278     "build out1: cat in\n"
01279     "build out2: cat_rsp in\n"
01280     "  rspfile = out2.rsp\n"
01281     "  long_command = Some very long command\n"));
01282 
01283   fs_.Create("out1", "");
01284   fs_.Create("out2", "");
01285   fs_.Create("out3", "");
01286 
01287   fs_.Tick();
01288 
01289   fs_.Create("in", "");
01290 
01291   string err;
01292   EXPECT_TRUE(builder_.AddTarget("out1", &err));
01293   ASSERT_EQ("", err);
01294   EXPECT_TRUE(builder_.AddTarget("out2", &err));
01295   ASSERT_EQ("", err);
01296 
01297   size_t files_created = fs_.files_created_.size();
01298   size_t files_removed = fs_.files_removed_.size();
01299 
01300   EXPECT_TRUE(builder_.Build(&err));
01301   ASSERT_EQ(2u, command_runner_.commands_ran_.size()); // cat + cat_rsp
01302 
01303   // The RSP file was created
01304   ASSERT_EQ(files_created + 1, fs_.files_created_.size());
01305   ASSERT_EQ(1u, fs_.files_created_.count("out2.rsp"));
01306 
01307   // The RSP file was removed
01308   ASSERT_EQ(files_removed + 1, fs_.files_removed_.size());
01309   ASSERT_EQ(1u, fs_.files_removed_.count("out2.rsp"));
01310 }
01311 
01312 // Test that RSP file is created but not removed for commands, which fail
01313 TEST_F(BuildTest, RspFileFailure) {
01314   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
01315     "rule fail\n"
01316     "  command = fail\n"
01317     "  rspfile = $rspfile\n"
01318     "  rspfile_content = $long_command\n"
01319     "build out: fail in\n"
01320     "  rspfile = out.rsp\n"
01321     "  long_command = Another very long command\n"));
01322 
01323   fs_.Create("out", "");
01324   fs_.Tick();
01325   fs_.Create("in", "");
01326 
01327   string err;
01328   EXPECT_TRUE(builder_.AddTarget("out", &err));
01329   ASSERT_EQ("", err);
01330 
01331   size_t files_created = fs_.files_created_.size();
01332   size_t files_removed = fs_.files_removed_.size();
01333 
01334   EXPECT_FALSE(builder_.Build(&err));
01335   ASSERT_EQ("subcommand failed", err);
01336   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
01337 
01338   // The RSP file was created
01339   ASSERT_EQ(files_created + 1, fs_.files_created_.size());
01340   ASSERT_EQ(1u, fs_.files_created_.count("out.rsp"));
01341 
01342   // The RSP file was NOT removed
01343   ASSERT_EQ(files_removed, fs_.files_removed_.size());
01344   ASSERT_EQ(0u, fs_.files_removed_.count("out.rsp"));
01345 
01346   // The RSP file contains what it should
01347   ASSERT_EQ("Another very long command", fs_.files_["out.rsp"].contents);
01348 }
01349 
01350 // Test that contens of the RSP file behaves like a regular part of
01351 // command line, i.e. triggers a rebuild if changed
01352 TEST_F(BuildWithLogTest, RspFileCmdLineChange) {
01353   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
01354     "rule cat_rsp\n"
01355     "  command = cat $rspfile > $out\n"
01356     "  rspfile = $rspfile\n"
01357     "  rspfile_content = $long_command\n"
01358     "build out: cat_rsp in\n"
01359     "  rspfile = out.rsp\n"
01360     "  long_command = Original very long command\n"));
01361 
01362   fs_.Create("out", "");
01363   fs_.Tick();
01364   fs_.Create("in", "");
01365 
01366   string err;
01367   EXPECT_TRUE(builder_.AddTarget("out", &err));
01368   ASSERT_EQ("", err);
01369 
01370   // 1. Build for the 1st time (-> populate log)
01371   EXPECT_TRUE(builder_.Build(&err));
01372   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
01373 
01374   // 2. Build again (no change)
01375   command_runner_.commands_ran_.clear();
01376   state_.Reset();
01377   EXPECT_TRUE(builder_.AddTarget("out", &err));
01378   EXPECT_EQ("", err);
01379   ASSERT_TRUE(builder_.AlreadyUpToDate());
01380 
01381   // 3. Alter the entry in the logfile
01382   // (to simulate a change in the command line between 2 builds)
01383   BuildLog::LogEntry* log_entry = build_log_.LookupByOutput("out");
01384   ASSERT_TRUE(NULL != log_entry);
01385   ASSERT_NO_FATAL_FAILURE(AssertHash(
01386         "cat out.rsp > out;rspfile=Original very long command",
01387         log_entry->command_hash));
01388   log_entry->command_hash++;  // Change the command hash to something else.
01389   // Now expect the target to be rebuilt
01390   command_runner_.commands_ran_.clear();
01391   state_.Reset();
01392   EXPECT_TRUE(builder_.AddTarget("out", &err));
01393   EXPECT_EQ("", err);
01394   EXPECT_TRUE(builder_.Build(&err));
01395   EXPECT_EQ(1u, command_runner_.commands_ran_.size());
01396 }
01397 
01398 TEST_F(BuildTest, InterruptCleanup) {
01399   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
01400 "rule interrupt\n"
01401 "  command = interrupt\n"
01402 "rule touch-interrupt\n"
01403 "  command = touch-interrupt\n"
01404 "build out1: interrupt in1\n"
01405 "build out2: touch-interrupt in2\n"));
01406 
01407   fs_.Create("out1", "");
01408   fs_.Create("out2", "");
01409   fs_.Tick();
01410   fs_.Create("in1", "");
01411   fs_.Create("in2", "");
01412 
01413   // An untouched output of an interrupted command should be retained.
01414   string err;
01415   EXPECT_TRUE(builder_.AddTarget("out1", &err));
01416   EXPECT_EQ("", err);
01417   EXPECT_FALSE(builder_.Build(&err));
01418   EXPECT_EQ("interrupted by user", err);
01419   builder_.Cleanup();
01420   EXPECT_GT(fs_.Stat("out1"), 0);
01421   err = "";
01422 
01423   // A touched output of an interrupted command should be deleted.
01424   EXPECT_TRUE(builder_.AddTarget("out2", &err));
01425   EXPECT_EQ("", err);
01426   EXPECT_FALSE(builder_.Build(&err));
01427   EXPECT_EQ("interrupted by user", err);
01428   builder_.Cleanup();
01429   EXPECT_EQ(0, fs_.Stat("out2"));
01430 }
01431 
01432 TEST_F(BuildTest, PhonyWithNoInputs) {
01433   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
01434 "build nonexistent: phony\n"
01435 "build out1: cat || nonexistent\n"
01436 "build out2: cat nonexistent\n"));
01437   fs_.Create("out1", "");
01438   fs_.Create("out2", "");
01439 
01440   // out1 should be up to date even though its input is dirty, because its
01441   // order-only dependency has nothing to do.
01442   string err;
01443   EXPECT_TRUE(builder_.AddTarget("out1", &err));
01444   ASSERT_EQ("", err);
01445   EXPECT_TRUE(builder_.AlreadyUpToDate());
01446 
01447   // out2 should still be out of date though, because its input is dirty.
01448   err.clear();
01449   command_runner_.commands_ran_.clear();
01450   state_.Reset();
01451   EXPECT_TRUE(builder_.AddTarget("out2", &err));
01452   ASSERT_EQ("", err);
01453   EXPECT_TRUE(builder_.Build(&err));
01454   EXPECT_EQ("", err);
01455   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
01456 }
01457 
01458 TEST_F(BuildTest, DepsGccWithEmptyDepfileErrorsOut) {
01459   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
01460 "rule cc\n"
01461 "  command = cc\n"
01462 "  deps = gcc\n"
01463 "build out: cc\n"));
01464   Dirty("out");
01465 
01466   string err;
01467   EXPECT_TRUE(builder_.AddTarget("out", &err));
01468   ASSERT_EQ("", err);
01469   EXPECT_FALSE(builder_.AlreadyUpToDate());
01470 
01471   EXPECT_FALSE(builder_.Build(&err));
01472   ASSERT_EQ("subcommand failed", err);
01473   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
01474 }
01475 
01476 TEST_F(BuildTest, StatusFormatReplacePlaceholder) {
01477   EXPECT_EQ("[%/s0/t0/r0/u0/f0]",
01478             status_.FormatProgressStatus("[%%/s%s/t%t/r%r/u%u/f%f]"));
01479 }
01480 
01481 TEST_F(BuildTest, FailedDepsParse) {
01482   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
01483 "build bad_deps.o: cat in1\n"
01484 "  deps = gcc\n"
01485 "  depfile = in1.d\n"));
01486 
01487   string err;
01488   EXPECT_TRUE(builder_.AddTarget("bad_deps.o", &err));
01489   ASSERT_EQ("", err);
01490 
01491   // These deps will fail to parse, as they should only have one
01492   // path to the left of the colon.
01493   fs_.Create("in1.d", "AAA BBB");
01494 
01495   EXPECT_FALSE(builder_.Build(&err));
01496   EXPECT_EQ("subcommand failed", err);
01497 }
01498 
01499 /// Tests of builds involving deps logs necessarily must span
01500 /// multiple builds.  We reuse methods on BuildTest but not the
01501 /// builder_ it sets up, because we want pristine objects for
01502 /// each build.
01503 struct BuildWithDepsLogTest : public BuildTest {
01504   BuildWithDepsLogTest() {}
01505 
01506   virtual void SetUp() {
01507     BuildTest::SetUp();
01508 
01509     temp_dir_.CreateAndEnter("BuildWithDepsLogTest");
01510   }
01511 
01512   virtual void TearDown() {
01513     temp_dir_.Cleanup();
01514   }
01515 
01516   ScopedTempDir temp_dir_;
01517 
01518   /// Shadow parent class builder_ so we don't accidentally use it.
01519   void* builder_;
01520 };
01521 
01522 /// Run a straightforwad build where the deps log is used.
01523 TEST_F(BuildWithDepsLogTest, Straightforward) {
01524   string err;
01525   // Note: in1 was created by the superclass SetUp().
01526   const char* manifest =
01527       "build out: cat in1\n"
01528       "  deps = gcc\n"
01529       "  depfile = in1.d\n";
01530   {
01531     State state;
01532     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
01533     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
01534 
01535     // Run the build once, everything should be ok.
01536     DepsLog deps_log;
01537     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
01538     ASSERT_EQ("", err);
01539 
01540     Builder builder(&state, config_, NULL, &deps_log, &fs_);
01541     builder.command_runner_.reset(&command_runner_);
01542     EXPECT_TRUE(builder.AddTarget("out", &err));
01543     ASSERT_EQ("", err);
01544     fs_.Create("in1.d", "out: in2");
01545     EXPECT_TRUE(builder.Build(&err));
01546     EXPECT_EQ("", err);
01547 
01548     // The deps file should have been removed.
01549     EXPECT_EQ(0, fs_.Stat("in1.d"));
01550     // Recreate it for the next step.
01551     fs_.Create("in1.d", "out: in2");
01552     deps_log.Close();
01553     builder.command_runner_.release();
01554   }
01555 
01556   {
01557     State state;
01558     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
01559     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
01560 
01561     // Touch the file only mentioned in the deps.
01562     fs_.Tick();
01563     fs_.Create("in2", "");
01564 
01565     // Run the build again.
01566     DepsLog deps_log;
01567     ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
01568     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
01569 
01570     Builder builder(&state, config_, NULL, &deps_log, &fs_);
01571     builder.command_runner_.reset(&command_runner_);
01572     command_runner_.commands_ran_.clear();
01573     EXPECT_TRUE(builder.AddTarget("out", &err));
01574     ASSERT_EQ("", err);
01575     EXPECT_TRUE(builder.Build(&err));
01576     EXPECT_EQ("", err);
01577 
01578     // We should have rebuilt the output due to in2 being
01579     // out of date.
01580     EXPECT_EQ(1u, command_runner_.commands_ran_.size());
01581 
01582     builder.command_runner_.release();
01583   }
01584 }
01585 
01586 /// Verify that obsolete dependency info causes a rebuild.
01587 /// 1) Run a successful build where everything has time t, record deps.
01588 /// 2) Move input/output to time t+1 -- despite files in alignment,
01589 ///    should still need to rebuild due to deps at older time.
01590 TEST_F(BuildWithDepsLogTest, ObsoleteDeps) {
01591   string err;
01592   // Note: in1 was created by the superclass SetUp().
01593   const char* manifest =
01594       "build out: cat in1\n"
01595       "  deps = gcc\n"
01596       "  depfile = in1.d\n";
01597   {
01598     // Run an ordinary build that gathers dependencies.
01599     fs_.Create("in1", "");
01600     fs_.Create("in1.d", "out: ");
01601 
01602     State state;
01603     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
01604     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
01605 
01606     // Run the build once, everything should be ok.
01607     DepsLog deps_log;
01608     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
01609     ASSERT_EQ("", err);
01610 
01611     Builder builder(&state, config_, NULL, &deps_log, &fs_);
01612     builder.command_runner_.reset(&command_runner_);
01613     EXPECT_TRUE(builder.AddTarget("out", &err));
01614     ASSERT_EQ("", err);
01615     EXPECT_TRUE(builder.Build(&err));
01616     EXPECT_EQ("", err);
01617 
01618     deps_log.Close();
01619     builder.command_runner_.release();
01620   }
01621 
01622   // Push all files one tick forward so that only the deps are out
01623   // of date.
01624   fs_.Tick();
01625   fs_.Create("in1", "");
01626   fs_.Create("out", "");
01627 
01628   // The deps file should have been removed, so no need to timestamp it.
01629   EXPECT_EQ(0, fs_.Stat("in1.d"));
01630 
01631   {
01632     State state;
01633     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
01634     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
01635 
01636     DepsLog deps_log;
01637     ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
01638     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
01639 
01640     Builder builder(&state, config_, NULL, &deps_log, &fs_);
01641     builder.command_runner_.reset(&command_runner_);
01642     command_runner_.commands_ran_.clear();
01643     EXPECT_TRUE(builder.AddTarget("out", &err));
01644     ASSERT_EQ("", err);
01645 
01646     // Recreate the deps file here because the build expects them to exist.
01647     fs_.Create("in1.d", "out: ");
01648 
01649     EXPECT_TRUE(builder.Build(&err));
01650     EXPECT_EQ("", err);
01651 
01652     // We should have rebuilt the output due to the deps being
01653     // out of date.
01654     EXPECT_EQ(1u, command_runner_.commands_ran_.size());
01655 
01656     builder.command_runner_.release();
01657   }
01658 }
01659 
01660 TEST_F(BuildWithDepsLogTest, DepsIgnoredInDryRun) {
01661   const char* manifest =
01662       "build out: cat in1\n"
01663       "  deps = gcc\n"
01664       "  depfile = in1.d\n";
01665 
01666   fs_.Create("out", "");
01667   fs_.Tick();
01668   fs_.Create("in1", "");
01669 
01670   State state;
01671   ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
01672   ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
01673 
01674   // The deps log is NULL in dry runs.
01675   config_.dry_run = true;
01676   Builder builder(&state, config_, NULL, NULL, &fs_);
01677   builder.command_runner_.reset(&command_runner_);
01678   command_runner_.commands_ran_.clear();
01679 
01680   string err;
01681   EXPECT_TRUE(builder.AddTarget("out", &err));
01682   ASSERT_EQ("", err);
01683   EXPECT_TRUE(builder.Build(&err));
01684   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
01685 
01686   builder.command_runner_.release();
01687 }
01688 
01689 /// Check that a restat rule generating a header cancels compilations correctly.
01690 TEST_F(BuildTest, RestatDepfileDependency) {
01691   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
01692 "rule true\n"
01693 "  command = true\n"  // Would be "write if out-of-date" in reality.
01694 "  restat = 1\n"
01695 "build header.h: true header.in\n"
01696 "build out: cat in1\n"
01697 "  depfile = in1.d\n"));
01698 
01699   fs_.Create("header.h", "");
01700   fs_.Create("in1.d", "out: header.h");
01701   fs_.Tick();
01702   fs_.Create("header.in", "");
01703 
01704   string err;
01705   EXPECT_TRUE(builder_.AddTarget("out", &err));
01706   ASSERT_EQ("", err);
01707   EXPECT_TRUE(builder_.Build(&err));
01708   EXPECT_EQ("", err);
01709 }
01710 
01711 /// Check that a restat rule generating a header cancels compilations correctly,
01712 /// depslog case.
01713 TEST_F(BuildWithDepsLogTest, RestatDepfileDependencyDepsLog) {
01714   string err;
01715   // Note: in1 was created by the superclass SetUp().
01716   const char* manifest =
01717       "rule true\n"
01718       "  command = true\n"  // Would be "write if out-of-date" in reality.
01719       "  restat = 1\n"
01720       "build header.h: true header.in\n"
01721       "build out: cat in1\n"
01722       "  deps = gcc\n"
01723       "  depfile = in1.d\n";
01724   {
01725     State state;
01726     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
01727     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
01728 
01729     // Run the build once, everything should be ok.
01730     DepsLog deps_log;
01731     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
01732     ASSERT_EQ("", err);
01733 
01734     Builder builder(&state, config_, NULL, &deps_log, &fs_);
01735     builder.command_runner_.reset(&command_runner_);
01736     EXPECT_TRUE(builder.AddTarget("out", &err));
01737     ASSERT_EQ("", err);
01738     fs_.Create("in1.d", "out: header.h");
01739     EXPECT_TRUE(builder.Build(&err));
01740     EXPECT_EQ("", err);
01741 
01742     deps_log.Close();
01743     builder.command_runner_.release();
01744   }
01745 
01746   {
01747     State state;
01748     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
01749     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
01750 
01751     // Touch the input of the restat rule.
01752     fs_.Tick();
01753     fs_.Create("header.in", "");
01754 
01755     // Run the build again.
01756     DepsLog deps_log;
01757     ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
01758     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
01759 
01760     Builder builder(&state, config_, NULL, &deps_log, &fs_);
01761     builder.command_runner_.reset(&command_runner_);
01762     command_runner_.commands_ran_.clear();
01763     EXPECT_TRUE(builder.AddTarget("out", &err));
01764     ASSERT_EQ("", err);
01765     EXPECT_TRUE(builder.Build(&err));
01766     EXPECT_EQ("", err);
01767 
01768     // Rule "true" should have run again, but the build of "out" should have
01769     // been cancelled due to restat propagating through the depfile header.
01770     EXPECT_EQ(1u, command_runner_.commands_ran_.size());
01771 
01772     builder.command_runner_.release();
01773   }
01774 }
01775 
01776 TEST_F(BuildWithDepsLogTest, DepFileOKDepsLog) {
01777   string err;
01778   const char* manifest =
01779       "rule cc\n  command = cc $in\n  depfile = $out.d\n  deps = gcc\n"
01780       "build foo.o: cc foo.c\n";
01781 
01782   fs_.Create("foo.c", "");
01783 
01784   {
01785     State state;
01786     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
01787 
01788     // Run the build once, everything should be ok.
01789     DepsLog deps_log;
01790     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
01791     ASSERT_EQ("", err);
01792 
01793     Builder builder(&state, config_, NULL, &deps_log, &fs_);
01794     builder.command_runner_.reset(&command_runner_);
01795     EXPECT_TRUE(builder.AddTarget("foo.o", &err));
01796     ASSERT_EQ("", err);
01797     fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
01798     EXPECT_TRUE(builder.Build(&err));
01799     EXPECT_EQ("", err);
01800 
01801     deps_log.Close();
01802     builder.command_runner_.release();
01803   }
01804 
01805   {
01806     State state;
01807     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
01808 
01809     DepsLog deps_log;
01810     ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
01811     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
01812     ASSERT_EQ("", err);
01813 
01814     Builder builder(&state, config_, NULL, &deps_log, &fs_);
01815     builder.command_runner_.reset(&command_runner_);
01816 
01817     Edge* edge = state.edges_.back();
01818 
01819     state.GetNode("bar.h")->MarkDirty();  // Mark bar.h as missing.
01820     EXPECT_TRUE(builder.AddTarget("foo.o", &err));
01821     ASSERT_EQ("", err);
01822 
01823     // Expect three new edges: one generating foo.o, and two more from
01824     // loading the depfile.
01825     ASSERT_EQ(3u, state.edges_.size());
01826     // Expect our edge to now have three inputs: foo.c and two headers.
01827     ASSERT_EQ(3u, edge->inputs_.size());
01828 
01829     // Expect the command line we generate to only use the original input.
01830     ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
01831 
01832     deps_log.Close();
01833     builder.command_runner_.release();
01834   }
01835 }
01836 
01837 /// Check that a restat rule doesn't clear an edge if the depfile is missing.
01838 /// Follows from: https://github.com/martine/ninja/issues/603
01839 TEST_F(BuildTest, RestatMissingDepfile) {
01840 const char* manifest =
01841 "rule true\n"
01842 "  command = true\n"  // Would be "write if out-of-date" in reality.
01843 "  restat = 1\n"
01844 "build header.h: true header.in\n"
01845 "build out: cat header.h\n"
01846 "  depfile = out.d\n";
01847 
01848   fs_.Create("header.h", "");
01849   fs_.Tick();
01850   fs_.Create("out", "");
01851   fs_.Create("header.in", "");
01852 
01853   // Normally, only 'header.h' would be rebuilt, as
01854   // its rule doesn't touch the output and has 'restat=1' set.
01855   // But we are also missing the depfile for 'out',
01856   // which should force its command to run anyway!
01857   RebuildTarget("out", manifest);
01858   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
01859 }
01860 
01861 /// Check that a restat rule doesn't clear an edge if the deps are missing.
01862 /// https://github.com/martine/ninja/issues/603
01863 TEST_F(BuildWithDepsLogTest, RestatMissingDepfileDepslog) {
01864   string err;
01865   const char* manifest =
01866 "rule true\n"
01867 "  command = true\n"  // Would be "write if out-of-date" in reality.
01868 "  restat = 1\n"
01869 "build header.h: true header.in\n"
01870 "build out: cat header.h\n"
01871 "  deps = gcc\n"
01872 "  depfile = out.d\n";
01873 
01874   // Build once to populate ninja deps logs from out.d
01875   fs_.Create("header.in", "");
01876   fs_.Create("out.d", "out: header.h");
01877   fs_.Create("header.h", "");
01878 
01879   RebuildTarget("out", manifest, "build_log", "ninja_deps");
01880   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
01881 
01882   // Sanity: this rebuild should be NOOP
01883   RebuildTarget("out", manifest, "build_log", "ninja_deps");
01884   ASSERT_EQ(0u, command_runner_.commands_ran_.size());
01885 
01886   // Touch 'header.in', blank dependencies log (create a different one).
01887   // Building header.h triggers 'restat' outputs cleanup.
01888   // Validate that out is rebuilt netherless, as deps are missing.
01889   fs_.Tick();
01890   fs_.Create("header.in", "");
01891 
01892   // (switch to a new blank deps_log "ninja_deps2")
01893   RebuildTarget("out", manifest, "build_log", "ninja_deps2");
01894   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
01895 
01896   // Sanity: this build should be NOOP
01897   RebuildTarget("out", manifest, "build_log", "ninja_deps2");
01898   ASSERT_EQ(0u, command_runner_.commands_ran_.size());
01899 
01900   // Check that invalidating deps by target timestamp also works here
01901   // Repeat the test but touch target instead of blanking the log.
01902   fs_.Tick();
01903   fs_.Create("header.in", "");
01904   fs_.Create("out", "");
01905   RebuildTarget("out", manifest, "build_log", "ninja_deps2");
01906   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
01907 
01908   // And this build should be NOOP again
01909   RebuildTarget("out", manifest, "build_log", "ninja_deps2");
01910   ASSERT_EQ(0u, command_runner_.commands_ran_.size());
01911 }