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