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   // Mark a path dirty.
00439   void Dirty(const string& path);
00440 
00441   BuildConfig MakeConfig() {
00442     BuildConfig config;
00443     config.verbosity = BuildConfig::QUIET;
00444     return config;
00445   }
00446 
00447   BuildConfig config_;
00448   FakeCommandRunner command_runner_;
00449   VirtualFileSystem fs_;
00450   Builder builder_;
00451 
00452   BuildStatus status_;
00453 };
00454 
00455 bool FakeCommandRunner::CanRunMore() {
00456   // Only run one at a time.
00457   return last_command_ == NULL;
00458 }
00459 
00460 bool FakeCommandRunner::StartCommand(Edge* edge) {
00461   assert(!last_command_);
00462   commands_ran_.push_back(edge->EvaluateCommand());
00463   if (edge->rule().name() == "cat"  ||
00464       edge->rule().name() == "cat_rsp" ||
00465       edge->rule().name() == "cc" ||
00466       edge->rule().name() == "touch" ||
00467       edge->rule().name() == "touch-interrupt") {
00468     for (vector<Node*>::iterator out = edge->outputs_.begin();
00469          out != edge->outputs_.end(); ++out) {
00470       fs_->Create((*out)->path(), "");
00471     }
00472   } else if (edge->rule().name() == "true" ||
00473              edge->rule().name() == "fail" ||
00474              edge->rule().name() == "interrupt") {
00475     // Don't do anything.
00476   } else {
00477     printf("unknown command\n");
00478     return false;
00479   }
00480 
00481   last_command_ = edge;
00482   return true;
00483 }
00484 
00485 bool FakeCommandRunner::WaitForCommand(Result* result) {
00486   if (!last_command_)
00487     return false;
00488 
00489   Edge* edge = last_command_;
00490   result->edge = edge;
00491 
00492   if (edge->rule().name() == "interrupt" ||
00493       edge->rule().name() == "touch-interrupt") {
00494     result->status = ExitInterrupted;
00495     return true;
00496   }
00497 
00498   if (edge->rule().name() == "fail")
00499     result->status = ExitFailure;
00500   else
00501     result->status = ExitSuccess;
00502   last_command_ = NULL;
00503   return true;
00504 }
00505 
00506 vector<Edge*> FakeCommandRunner::GetActiveEdges() {
00507   vector<Edge*> edges;
00508   if (last_command_)
00509     edges.push_back(last_command_);
00510   return edges;
00511 }
00512 
00513 void FakeCommandRunner::Abort() {
00514   last_command_ = NULL;
00515 }
00516 
00517 void BuildTest::Dirty(const string& path) {
00518   Node* node = GetNode(path);
00519   node->MarkDirty();
00520 
00521   // If it's an input file, mark that we've already stat()ed it and
00522   // it's missing.
00523   if (!node->in_edge())
00524     node->MarkMissing();
00525 }
00526 
00527 TEST_F(BuildTest, NoWork) {
00528   string err;
00529   EXPECT_TRUE(builder_.AlreadyUpToDate());
00530 }
00531 
00532 TEST_F(BuildTest, OneStep) {
00533   // Given a dirty target with one ready input,
00534   // we should rebuild the target.
00535   Dirty("cat1");
00536   string err;
00537   EXPECT_TRUE(builder_.AddTarget("cat1", &err));
00538   ASSERT_EQ("", err);
00539   EXPECT_TRUE(builder_.Build(&err));
00540   ASSERT_EQ("", err);
00541 
00542   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
00543   EXPECT_EQ("cat in1 > cat1", command_runner_.commands_ran_[0]);
00544 }
00545 
00546 TEST_F(BuildTest, OneStep2) {
00547   // Given a target with one dirty input,
00548   // we should rebuild the target.
00549   Dirty("cat1");
00550   string err;
00551   EXPECT_TRUE(builder_.AddTarget("cat1", &err));
00552   ASSERT_EQ("", err);
00553   EXPECT_TRUE(builder_.Build(&err));
00554   EXPECT_EQ("", err);
00555 
00556   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
00557   EXPECT_EQ("cat in1 > cat1", command_runner_.commands_ran_[0]);
00558 }
00559 
00560 TEST_F(BuildTest, TwoStep) {
00561   string err;
00562   EXPECT_TRUE(builder_.AddTarget("cat12", &err));
00563   ASSERT_EQ("", err);
00564   EXPECT_TRUE(builder_.Build(&err));
00565   EXPECT_EQ("", err);
00566   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
00567   // Depending on how the pointers work out, we could've ran
00568   // the first two commands in either order.
00569   EXPECT_TRUE((command_runner_.commands_ran_[0] == "cat in1 > cat1" &&
00570                command_runner_.commands_ran_[1] == "cat in1 in2 > cat2") ||
00571               (command_runner_.commands_ran_[1] == "cat in1 > cat1" &&
00572                command_runner_.commands_ran_[0] == "cat in1 in2 > cat2"));
00573 
00574   EXPECT_EQ("cat cat1 cat2 > cat12", command_runner_.commands_ran_[2]);
00575 
00576   fs_.Tick();
00577 
00578   // Modifying in2 requires rebuilding one intermediate file
00579   // and the final file.
00580   fs_.Create("in2", "");
00581   state_.Reset();
00582   EXPECT_TRUE(builder_.AddTarget("cat12", &err));
00583   ASSERT_EQ("", err);
00584   EXPECT_TRUE(builder_.Build(&err));
00585   ASSERT_EQ("", err);
00586   ASSERT_EQ(5u, command_runner_.commands_ran_.size());
00587   EXPECT_EQ("cat in1 in2 > cat2", command_runner_.commands_ran_[3]);
00588   EXPECT_EQ("cat cat1 cat2 > cat12", command_runner_.commands_ran_[4]);
00589 }
00590 
00591 TEST_F(BuildTest, TwoOutputs) {
00592   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00593 "rule touch\n"
00594 "  command = touch $out\n"
00595 "build out1 out2: touch in.txt\n"));
00596 
00597   fs_.Create("in.txt", "");
00598 
00599   string err;
00600   EXPECT_TRUE(builder_.AddTarget("out1", &err));
00601   ASSERT_EQ("", err);
00602   EXPECT_TRUE(builder_.Build(&err));
00603   EXPECT_EQ("", err);
00604   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
00605   EXPECT_EQ("touch out1 out2", command_runner_.commands_ran_[0]);
00606 }
00607 
00608 // Test case from
00609 //   https://github.com/martine/ninja/issues/148
00610 TEST_F(BuildTest, MultiOutIn) {
00611   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00612 "rule touch\n"
00613 "  command = touch $out\n"
00614 "build in1 otherfile: touch in\n"
00615 "build out: touch in | in1\n"));
00616 
00617   fs_.Create("in", "");
00618   fs_.Tick();
00619   fs_.Create("in1", "");
00620 
00621   string err;
00622   EXPECT_TRUE(builder_.AddTarget("out", &err));
00623   ASSERT_EQ("", err);
00624   EXPECT_TRUE(builder_.Build(&err));
00625   EXPECT_EQ("", err);
00626 }
00627 
00628 TEST_F(BuildTest, Chain) {
00629   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00630 "build c2: cat c1\n"
00631 "build c3: cat c2\n"
00632 "build c4: cat c3\n"
00633 "build c5: cat c4\n"));
00634 
00635   fs_.Create("c1", "");
00636 
00637   string err;
00638   EXPECT_TRUE(builder_.AddTarget("c5", &err));
00639   ASSERT_EQ("", err);
00640   EXPECT_TRUE(builder_.Build(&err));
00641   EXPECT_EQ("", err);
00642   ASSERT_EQ(4u, command_runner_.commands_ran_.size());
00643 
00644   err.clear();
00645   command_runner_.commands_ran_.clear();
00646   state_.Reset();
00647   EXPECT_TRUE(builder_.AddTarget("c5", &err));
00648   ASSERT_EQ("", err);
00649   EXPECT_TRUE(builder_.AlreadyUpToDate());
00650 
00651   fs_.Tick();
00652 
00653   fs_.Create("c3", "");
00654   err.clear();
00655   command_runner_.commands_ran_.clear();
00656   state_.Reset();
00657   EXPECT_TRUE(builder_.AddTarget("c5", &err));
00658   ASSERT_EQ("", err);
00659   EXPECT_FALSE(builder_.AlreadyUpToDate());
00660   EXPECT_TRUE(builder_.Build(&err));
00661   ASSERT_EQ(2u, command_runner_.commands_ran_.size());  // 3->4, 4->5
00662 }
00663 
00664 TEST_F(BuildTest, MissingInput) {
00665   // Input is referenced by build file, but no rule for it.
00666   string err;
00667   Dirty("in1");
00668   EXPECT_FALSE(builder_.AddTarget("cat1", &err));
00669   EXPECT_EQ("'in1', needed by 'cat1', missing and no known rule to make it",
00670             err);
00671 }
00672 
00673 TEST_F(BuildTest, MissingTarget) {
00674   // Target is not referenced by build file.
00675   string err;
00676   EXPECT_FALSE(builder_.AddTarget("meow", &err));
00677   EXPECT_EQ("unknown target: 'meow'", err);
00678 }
00679 
00680 TEST_F(BuildTest, MakeDirs) {
00681   string err;
00682 
00683 #ifdef _WIN32
00684   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00685                                       "build subdir\\dir2\\file: cat in1\n"));
00686   EXPECT_TRUE(builder_.AddTarget("subdir\\dir2\\file", &err));
00687 #else
00688   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00689                                       "build subdir/dir2/file: cat in1\n"));
00690   EXPECT_TRUE(builder_.AddTarget("subdir/dir2/file", &err));
00691 #endif
00692 
00693   EXPECT_EQ("", err);
00694   EXPECT_TRUE(builder_.Build(&err));
00695   ASSERT_EQ("", err);
00696   ASSERT_EQ(2u, fs_.directories_made_.size());
00697   EXPECT_EQ("subdir", fs_.directories_made_[0]);
00698 #ifdef _WIN32
00699   EXPECT_EQ("subdir\\dir2", fs_.directories_made_[1]);
00700 #else
00701   EXPECT_EQ("subdir/dir2", fs_.directories_made_[1]);
00702 #endif
00703 }
00704 
00705 TEST_F(BuildTest, DepFileMissing) {
00706   string err;
00707   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00708 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
00709 "build foo.o: cc foo.c\n"));
00710   fs_.Create("foo.c", "");
00711 
00712   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00713   ASSERT_EQ("", err);
00714   ASSERT_EQ(1u, fs_.files_read_.size());
00715   EXPECT_EQ("foo.o.d", fs_.files_read_[0]);
00716 }
00717 
00718 TEST_F(BuildTest, DepFileOK) {
00719   string err;
00720   int orig_edges = state_.edges_.size();
00721   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00722 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
00723 "build foo.o: cc foo.c\n"));
00724   Edge* edge = state_.edges_.back();
00725 
00726   fs_.Create("foo.c", "");
00727   GetNode("bar.h")->MarkDirty();  // Mark bar.h as missing.
00728   fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
00729   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00730   ASSERT_EQ("", err);
00731   ASSERT_EQ(1u, fs_.files_read_.size());
00732   EXPECT_EQ("foo.o.d", fs_.files_read_[0]);
00733 
00734   // Expect three new edges: one generating foo.o, and two more from
00735   // loading the depfile.
00736   ASSERT_EQ(orig_edges + 3, (int)state_.edges_.size());
00737   // Expect our edge to now have three inputs: foo.c and two headers.
00738   ASSERT_EQ(3u, edge->inputs_.size());
00739 
00740   // Expect the command line we generate to only use the original input.
00741   ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
00742 }
00743 
00744 TEST_F(BuildTest, DepFileParseError) {
00745   string err;
00746   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00747 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
00748 "build foo.o: cc foo.c\n"));
00749   fs_.Create("foo.c", "");
00750   fs_.Create("foo.o.d", "randomtext\n");
00751   EXPECT_FALSE(builder_.AddTarget("foo.o", &err));
00752   EXPECT_EQ("expected depfile 'foo.o.d' to mention 'foo.o', got 'randomtext'",
00753             err);
00754 }
00755 
00756 TEST_F(BuildTest, OrderOnlyDeps) {
00757   string err;
00758   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00759 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
00760 "build foo.o: cc foo.c || otherfile\n"));
00761   Edge* edge = state_.edges_.back();
00762 
00763   fs_.Create("foo.c", "");
00764   fs_.Create("otherfile", "");
00765   fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
00766   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00767   ASSERT_EQ("", err);
00768 
00769   // One explicit, two implicit, one order only.
00770   ASSERT_EQ(4u, edge->inputs_.size());
00771   EXPECT_EQ(2, edge->implicit_deps_);
00772   EXPECT_EQ(1, edge->order_only_deps_);
00773   // Verify the inputs are in the order we expect
00774   // (explicit then implicit then orderonly).
00775   EXPECT_EQ("foo.c", edge->inputs_[0]->path());
00776   EXPECT_EQ("blah.h", edge->inputs_[1]->path());
00777   EXPECT_EQ("bar.h", edge->inputs_[2]->path());
00778   EXPECT_EQ("otherfile", edge->inputs_[3]->path());
00779 
00780   // Expect the command line we generate to only use the original input.
00781   ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
00782 
00783   // explicit dep dirty, expect a rebuild.
00784   EXPECT_TRUE(builder_.Build(&err));
00785   ASSERT_EQ("", err);
00786   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
00787 
00788   fs_.Tick();
00789 
00790   // Recreate the depfile, as it should have been deleted by the build.
00791   fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
00792 
00793   // implicit dep dirty, expect a rebuild.
00794   fs_.Create("blah.h", "");
00795   fs_.Create("bar.h", "");
00796   command_runner_.commands_ran_.clear();
00797   state_.Reset();
00798   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00799   EXPECT_TRUE(builder_.Build(&err));
00800   ASSERT_EQ("", err);
00801   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
00802 
00803   fs_.Tick();
00804 
00805   // Recreate the depfile, as it should have been deleted by the build.
00806   fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
00807 
00808   // order only dep dirty, no rebuild.
00809   fs_.Create("otherfile", "");
00810   command_runner_.commands_ran_.clear();
00811   state_.Reset();
00812   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00813   EXPECT_EQ("", err);
00814   EXPECT_TRUE(builder_.AlreadyUpToDate());
00815 
00816   // implicit dep missing, expect rebuild.
00817   fs_.RemoveFile("bar.h");
00818   command_runner_.commands_ran_.clear();
00819   state_.Reset();
00820   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00821   EXPECT_TRUE(builder_.Build(&err));
00822   ASSERT_EQ("", err);
00823   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
00824 }
00825 
00826 TEST_F(BuildTest, RebuildOrderOnlyDeps) {
00827   string err;
00828   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00829 "rule cc\n  command = cc $in\n"
00830 "rule true\n  command = true\n"
00831 "build oo.h: cc oo.h.in\n"
00832 "build foo.o: cc foo.c || oo.h\n"));
00833 
00834   fs_.Create("foo.c", "");
00835   fs_.Create("oo.h.in", "");
00836 
00837   // foo.o and order-only dep dirty, build both.
00838   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00839   EXPECT_TRUE(builder_.Build(&err));
00840   ASSERT_EQ("", err);
00841   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
00842 
00843   // all clean, no rebuild.
00844   command_runner_.commands_ran_.clear();
00845   state_.Reset();
00846   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00847   EXPECT_EQ("", err);
00848   EXPECT_TRUE(builder_.AlreadyUpToDate());
00849 
00850   // order-only dep missing, build it only.
00851   fs_.RemoveFile("oo.h");
00852   command_runner_.commands_ran_.clear();
00853   state_.Reset();
00854   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00855   EXPECT_TRUE(builder_.Build(&err));
00856   ASSERT_EQ("", err);
00857   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
00858   ASSERT_EQ("cc oo.h.in", command_runner_.commands_ran_[0]);
00859 
00860   fs_.Tick();
00861 
00862   // order-only dep dirty, build it only.
00863   fs_.Create("oo.h.in", "");
00864   command_runner_.commands_ran_.clear();
00865   state_.Reset();
00866   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00867   EXPECT_TRUE(builder_.Build(&err));
00868   ASSERT_EQ("", err);
00869   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
00870   ASSERT_EQ("cc oo.h.in", command_runner_.commands_ran_[0]);
00871 }
00872 
00873 TEST_F(BuildTest, Phony) {
00874   string err;
00875   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00876 "build out: cat bar.cc\n"
00877 "build all: phony out\n"));
00878   fs_.Create("bar.cc", "");
00879 
00880   EXPECT_TRUE(builder_.AddTarget("all", &err));
00881   ASSERT_EQ("", err);
00882 
00883   // Only one command to run, because phony runs no command.
00884   EXPECT_FALSE(builder_.AlreadyUpToDate());
00885   EXPECT_TRUE(builder_.Build(&err));
00886   ASSERT_EQ("", err);
00887   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
00888 }
00889 
00890 TEST_F(BuildTest, PhonyNoWork) {
00891   string err;
00892   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00893 "build out: cat bar.cc\n"
00894 "build all: phony out\n"));
00895   fs_.Create("bar.cc", "");
00896   fs_.Create("out", "");
00897 
00898   EXPECT_TRUE(builder_.AddTarget("all", &err));
00899   ASSERT_EQ("", err);
00900   EXPECT_TRUE(builder_.AlreadyUpToDate());
00901 }
00902 
00903 TEST_F(BuildTest, Fail) {
00904   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00905 "rule fail\n"
00906 "  command = fail\n"
00907 "build out1: fail\n"));
00908 
00909   string err;
00910   EXPECT_TRUE(builder_.AddTarget("out1", &err));
00911   ASSERT_EQ("", err);
00912 
00913   EXPECT_FALSE(builder_.Build(&err));
00914   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
00915   ASSERT_EQ("subcommand failed", err);
00916 }
00917 
00918 TEST_F(BuildTest, SwallowFailures) {
00919   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00920 "rule fail\n"
00921 "  command = fail\n"
00922 "build out1: fail\n"
00923 "build out2: fail\n"
00924 "build out3: fail\n"
00925 "build all: phony out1 out2 out3\n"));
00926 
00927   // Swallow two failures, die on the third.
00928   config_.failures_allowed = 3;
00929 
00930   string err;
00931   EXPECT_TRUE(builder_.AddTarget("all", &err));
00932   ASSERT_EQ("", err);
00933 
00934   EXPECT_FALSE(builder_.Build(&err));
00935   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
00936   ASSERT_EQ("subcommands failed", err);
00937 }
00938 
00939 TEST_F(BuildTest, SwallowFailuresLimit) {
00940   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00941 "rule fail\n"
00942 "  command = fail\n"
00943 "build out1: fail\n"
00944 "build out2: fail\n"
00945 "build out3: fail\n"
00946 "build final: cat out1 out2 out3\n"));
00947 
00948   // Swallow ten failures; we should stop before building final.
00949   config_.failures_allowed = 11;
00950 
00951   string err;
00952   EXPECT_TRUE(builder_.AddTarget("final", &err));
00953   ASSERT_EQ("", err);
00954 
00955   EXPECT_FALSE(builder_.Build(&err));
00956   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
00957   ASSERT_EQ("cannot make progress due to previous errors", err);
00958 }
00959 
00960 struct BuildWithLogTest : public BuildTest {
00961   BuildWithLogTest() {
00962     builder_.SetBuildLog(&build_log_);
00963   }
00964 
00965   BuildLog build_log_;
00966 };
00967 
00968 TEST_F(BuildWithLogTest, NotInLogButOnDisk) {
00969   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00970 "rule cc\n"
00971 "  command = cc\n"
00972 "build out1: cc in\n"));
00973 
00974   // Create input/output that would be considered up to date when
00975   // not considering the command line hash.
00976   fs_.Create("in", "");
00977   fs_.Create("out1", "");
00978   string err;
00979 
00980   // Because it's not in the log, it should not be up-to-date until
00981   // we build again.
00982   EXPECT_TRUE(builder_.AddTarget("out1", &err));
00983   EXPECT_FALSE(builder_.AlreadyUpToDate());
00984 
00985   command_runner_.commands_ran_.clear();
00986   state_.Reset();
00987 
00988   EXPECT_TRUE(builder_.AddTarget("out1", &err));
00989   EXPECT_TRUE(builder_.Build(&err));
00990   EXPECT_TRUE(builder_.AlreadyUpToDate());
00991 }
00992 
00993 TEST_F(BuildWithLogTest, RestatTest) {
00994   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00995 "rule true\n"
00996 "  command = true\n"
00997 "  restat = 1\n"
00998 "rule cc\n"
00999 "  command = cc\n"
01000 "  restat = 1\n"
01001 "build out1: cc in\n"
01002 "build out2: true out1\n"
01003 "build out3: cat out2\n"));
01004 
01005   fs_.Create("out1", "");
01006   fs_.Create("out2", "");
01007   fs_.Create("out3", "");
01008 
01009   fs_.Tick();
01010 
01011   fs_.Create("in", "");
01012 
01013   // Do a pre-build so that there's commands in the log for the outputs,
01014   // otherwise, the lack of an entry in the build log will cause out3 to rebuild
01015   // regardless of restat.
01016   string err;
01017   EXPECT_TRUE(builder_.AddTarget("out3", &err));
01018   ASSERT_EQ("", err);
01019   EXPECT_TRUE(builder_.Build(&err));
01020   ASSERT_EQ("", err);
01021   command_runner_.commands_ran_.clear();
01022   state_.Reset();
01023 
01024   fs_.Tick();
01025 
01026   fs_.Create("in", "");
01027   // "cc" touches out1, so we should build out2.  But because "true" does not
01028   // touch out2, we should cancel the build of out3.
01029   EXPECT_TRUE(builder_.AddTarget("out3", &err));
01030   ASSERT_EQ("", err);
01031   EXPECT_TRUE(builder_.Build(&err));
01032   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
01033 
01034   // If we run again, it should be a no-op, because the build log has recorded
01035   // that we've already built out2 with an input timestamp of 2 (from out1).
01036   command_runner_.commands_ran_.clear();
01037   state_.Reset();
01038   EXPECT_TRUE(builder_.AddTarget("out3", &err));
01039   ASSERT_EQ("", err);
01040   EXPECT_TRUE(builder_.AlreadyUpToDate());
01041 
01042   fs_.Tick();
01043 
01044   fs_.Create("in", "");
01045 
01046   // The build log entry should not, however, prevent us from rebuilding out2
01047   // if out1 changes.
01048   command_runner_.commands_ran_.clear();
01049   state_.Reset();
01050   EXPECT_TRUE(builder_.AddTarget("out3", &err));
01051   ASSERT_EQ("", err);
01052   EXPECT_TRUE(builder_.Build(&err));
01053   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
01054 }
01055 
01056 TEST_F(BuildWithLogTest, RestatMissingFile) {
01057   // If a restat rule doesn't create its output, and the output didn't
01058   // exist before the rule was run, consider that behavior equivalent
01059   // to a rule that doesn't modify its existent output file.
01060 
01061   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
01062 "rule true\n"
01063 "  command = true\n"
01064 "  restat = 1\n"
01065 "rule cc\n"
01066 "  command = cc\n"
01067 "build out1: true in\n"
01068 "build out2: cc out1\n"));
01069 
01070   fs_.Create("in", "");
01071   fs_.Create("out2", "");
01072 
01073   // Do a pre-build so that there's commands in the log for the outputs,
01074   // otherwise, the lack of an entry in the build log will cause out2 to rebuild
01075   // regardless of restat.
01076   string err;
01077   EXPECT_TRUE(builder_.AddTarget("out2", &err));
01078   ASSERT_EQ("", err);
01079   EXPECT_TRUE(builder_.Build(&err));
01080   ASSERT_EQ("", err);
01081   command_runner_.commands_ran_.clear();
01082   state_.Reset();
01083 
01084   fs_.Tick();
01085   fs_.Create("in", "");
01086   fs_.Create("out2", "");
01087 
01088   // Run a build, expect only the first command to run.
01089   // It doesn't touch its output (due to being the "true" command), so
01090   // we shouldn't run the dependent build.
01091   EXPECT_TRUE(builder_.AddTarget("out2", &err));
01092   ASSERT_EQ("", err);
01093   EXPECT_TRUE(builder_.Build(&err));
01094   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
01095 }
01096 
01097 // Test scenario, in which an input file is removed, but output isn't changed
01098 // https://github.com/martine/ninja/issues/295
01099 TEST_F(BuildWithLogTest, RestatMissingInput) {
01100   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
01101     "rule true\n"
01102     "  command = true\n"
01103     "  depfile = $out.d\n"
01104     "  restat = 1\n"
01105     "rule cc\n"
01106     "  command = cc\n"
01107     "build out1: true in\n"
01108     "build out2: cc out1\n"));
01109 
01110   // Create all necessary files
01111   fs_.Create("in", "");
01112 
01113   // The implicit dependencies and the depfile itself
01114   // are newer than the output
01115   TimeStamp restat_mtime = fs_.Tick();
01116   fs_.Create("out1.d", "out1: will.be.deleted restat.file\n");
01117   fs_.Create("will.be.deleted", "");
01118   fs_.Create("restat.file", "");
01119 
01120   // Run the build, out1 and out2 get built
01121   string err;
01122   EXPECT_TRUE(builder_.AddTarget("out2", &err));
01123   ASSERT_EQ("", err);
01124   EXPECT_TRUE(builder_.Build(&err));
01125   ASSERT_EQ(2u, command_runner_.commands_ran_.size());
01126 
01127   // See that an entry in the logfile is created, capturing
01128   // the right mtime
01129   BuildLog::LogEntry * log_entry = build_log_.LookupByOutput("out1");
01130   ASSERT_TRUE(NULL != log_entry);
01131   ASSERT_EQ(restat_mtime, log_entry->restat_mtime);
01132 
01133   // Now remove a file, referenced from depfile, so that target becomes
01134   // dirty, but the output does not change
01135   fs_.RemoveFile("will.be.deleted");
01136 
01137   // Trigger the build again - only out1 gets built
01138   command_runner_.commands_ran_.clear();
01139   state_.Reset();
01140   EXPECT_TRUE(builder_.AddTarget("out2", &err));
01141   ASSERT_EQ("", err);
01142   EXPECT_TRUE(builder_.Build(&err));
01143   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
01144 
01145   // Check that the logfile entry remains correctly set
01146   log_entry = build_log_.LookupByOutput("out1");
01147   ASSERT_TRUE(NULL != log_entry);
01148   ASSERT_EQ(restat_mtime, log_entry->restat_mtime);
01149 }
01150 
01151 struct BuildDryRun : public BuildWithLogTest {
01152   BuildDryRun() {
01153     config_.dry_run = true;
01154   }
01155 };
01156 
01157 TEST_F(BuildDryRun, AllCommandsShown) {
01158   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
01159 "rule true\n"
01160 "  command = true\n"
01161 "  restat = 1\n"
01162 "rule cc\n"
01163 "  command = cc\n"
01164 "  restat = 1\n"
01165 "build out1: cc in\n"
01166 "build out2: true out1\n"
01167 "build out3: cat out2\n"));
01168 
01169   fs_.Create("out1", "");
01170   fs_.Create("out2", "");
01171   fs_.Create("out3", "");
01172 
01173   fs_.Tick();
01174 
01175   fs_.Create("in", "");
01176 
01177   // "cc" touches out1, so we should build out2.  But because "true" does not
01178   // touch out2, we should cancel the build of out3.
01179   string err;
01180   EXPECT_TRUE(builder_.AddTarget("out3", &err));
01181   ASSERT_EQ("", err);
01182   EXPECT_TRUE(builder_.Build(&err));
01183   ASSERT_EQ(3u, command_runner_.commands_ran_.size());
01184 }
01185 
01186 // Test that RSP files are created when & where appropriate and deleted after
01187 // successful execution.
01188 TEST_F(BuildTest, RspFileSuccess)
01189 {
01190   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
01191     "rule cat_rsp\n"
01192     "  command = cat $rspfile > $out\n"
01193     "  rspfile = $rspfile\n"
01194     "  rspfile_content = $long_command\n"
01195     "build out1: cat in\n"
01196     "build out2: cat_rsp in\n"
01197     "  rspfile = out2.rsp\n"
01198     "  long_command = Some very long command\n"));
01199 
01200   fs_.Create("out1", "");
01201   fs_.Create("out2", "");
01202   fs_.Create("out3", "");
01203 
01204   fs_.Tick();
01205 
01206   fs_.Create("in", "");
01207 
01208   string err;
01209   EXPECT_TRUE(builder_.AddTarget("out1", &err));
01210   ASSERT_EQ("", err);
01211   EXPECT_TRUE(builder_.AddTarget("out2", &err));
01212   ASSERT_EQ("", err);
01213 
01214   size_t files_created = fs_.files_created_.size();
01215   size_t files_removed = fs_.files_removed_.size();
01216 
01217   EXPECT_TRUE(builder_.Build(&err));
01218   ASSERT_EQ(2u, command_runner_.commands_ran_.size()); // cat + cat_rsp
01219 
01220   // The RSP file was created
01221   ASSERT_EQ(files_created + 1, fs_.files_created_.size());
01222   ASSERT_EQ(1u, fs_.files_created_.count("out2.rsp"));
01223 
01224   // The RSP file was removed
01225   ASSERT_EQ(files_removed + 1, fs_.files_removed_.size());
01226   ASSERT_EQ(1u, fs_.files_removed_.count("out2.rsp"));
01227 }
01228 
01229 // Test that RSP file is created but not removed for commands, which fail
01230 TEST_F(BuildTest, RspFileFailure) {
01231   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
01232     "rule fail\n"
01233     "  command = fail\n"
01234     "  rspfile = $rspfile\n"
01235     "  rspfile_content = $long_command\n"
01236     "build out: fail in\n"
01237     "  rspfile = out.rsp\n"
01238     "  long_command = Another very long command\n"));
01239 
01240   fs_.Create("out", "");
01241   fs_.Tick();
01242   fs_.Create("in", "");
01243 
01244   string err;
01245   EXPECT_TRUE(builder_.AddTarget("out", &err));
01246   ASSERT_EQ("", err);
01247 
01248   size_t files_created = fs_.files_created_.size();
01249   size_t files_removed = fs_.files_removed_.size();
01250 
01251   EXPECT_FALSE(builder_.Build(&err));
01252   ASSERT_EQ("subcommand failed", err);
01253   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
01254 
01255   // The RSP file was created
01256   ASSERT_EQ(files_created + 1, fs_.files_created_.size());
01257   ASSERT_EQ(1u, fs_.files_created_.count("out.rsp"));
01258 
01259   // The RSP file was NOT removed
01260   ASSERT_EQ(files_removed, fs_.files_removed_.size());
01261   ASSERT_EQ(0u, fs_.files_removed_.count("out.rsp"));
01262 
01263   // The RSP file contains what it should
01264   ASSERT_EQ("Another very long command", fs_.files_["out.rsp"].contents);
01265 }
01266 
01267 // Test that contens of the RSP file behaves like a regular part of
01268 // command line, i.e. triggers a rebuild if changed
01269 TEST_F(BuildWithLogTest, RspFileCmdLineChange) {
01270   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
01271     "rule cat_rsp\n"
01272     "  command = cat $rspfile > $out\n"
01273     "  rspfile = $rspfile\n"
01274     "  rspfile_content = $long_command\n"
01275     "build out: cat_rsp in\n"
01276     "  rspfile = out.rsp\n"
01277     "  long_command = Original very long command\n"));
01278 
01279   fs_.Create("out", "");
01280   fs_.Tick();
01281   fs_.Create("in", "");
01282 
01283   string err;
01284   EXPECT_TRUE(builder_.AddTarget("out", &err));
01285   ASSERT_EQ("", err);
01286 
01287   // 1. Build for the 1st time (-> populate log)
01288   EXPECT_TRUE(builder_.Build(&err));
01289   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
01290 
01291   // 2. Build again (no change)
01292   command_runner_.commands_ran_.clear();
01293   state_.Reset();
01294   EXPECT_TRUE(builder_.AddTarget("out", &err));
01295   EXPECT_EQ("", err);
01296   ASSERT_TRUE(builder_.AlreadyUpToDate());
01297 
01298   // 3. Alter the entry in the logfile
01299   // (to simulate a change in the command line between 2 builds)
01300   BuildLog::LogEntry * log_entry = build_log_.LookupByOutput("out");
01301   ASSERT_TRUE(NULL != log_entry);
01302   ASSERT_NO_FATAL_FAILURE(AssertHash(
01303         "cat out.rsp > out;rspfile=Original very long command",
01304         log_entry->command_hash));
01305   log_entry->command_hash++;  // Change the command hash to something else.
01306   // Now expect the target to be rebuilt
01307   command_runner_.commands_ran_.clear();
01308   state_.Reset();
01309   EXPECT_TRUE(builder_.AddTarget("out", &err));
01310   EXPECT_EQ("", err);
01311   EXPECT_TRUE(builder_.Build(&err));
01312   EXPECT_EQ(1u, command_runner_.commands_ran_.size());
01313 }
01314 
01315 TEST_F(BuildTest, InterruptCleanup) {
01316   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
01317 "rule interrupt\n"
01318 "  command = interrupt\n"
01319 "rule touch-interrupt\n"
01320 "  command = touch-interrupt\n"
01321 "build out1: interrupt in1\n"
01322 "build out2: touch-interrupt in2\n"));
01323 
01324   fs_.Create("out1", "");
01325   fs_.Create("out2", "");
01326   fs_.Tick();
01327   fs_.Create("in1", "");
01328   fs_.Create("in2", "");
01329 
01330   // An untouched output of an interrupted command should be retained.
01331   string err;
01332   EXPECT_TRUE(builder_.AddTarget("out1", &err));
01333   EXPECT_EQ("", err);
01334   EXPECT_FALSE(builder_.Build(&err));
01335   EXPECT_EQ("interrupted by user", err);
01336   builder_.Cleanup();
01337   EXPECT_GT(fs_.Stat("out1"), 0);
01338   err = "";
01339 
01340   // A touched output of an interrupted command should be deleted.
01341   EXPECT_TRUE(builder_.AddTarget("out2", &err));
01342   EXPECT_EQ("", err);
01343   EXPECT_FALSE(builder_.Build(&err));
01344   EXPECT_EQ("interrupted by user", err);
01345   builder_.Cleanup();
01346   EXPECT_EQ(0, fs_.Stat("out2"));
01347 }
01348 
01349 TEST_F(BuildTest, PhonyWithNoInputs) {
01350   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
01351 "build nonexistent: phony\n"
01352 "build out1: cat || nonexistent\n"
01353 "build out2: cat nonexistent\n"));
01354   fs_.Create("out1", "");
01355   fs_.Create("out2", "");
01356 
01357   // out1 should be up to date even though its input is dirty, because its
01358   // order-only dependency has nothing to do.
01359   string err;
01360   EXPECT_TRUE(builder_.AddTarget("out1", &err));
01361   ASSERT_EQ("", err);
01362   EXPECT_TRUE(builder_.AlreadyUpToDate());
01363 
01364   // out2 should still be out of date though, because its input is dirty.
01365   err.clear();
01366   command_runner_.commands_ran_.clear();
01367   state_.Reset();
01368   EXPECT_TRUE(builder_.AddTarget("out2", &err));
01369   ASSERT_EQ("", err);
01370   EXPECT_TRUE(builder_.Build(&err));
01371   EXPECT_EQ("", err);
01372   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
01373 }
01374 
01375 TEST_F(BuildTest, DepsGccWithEmptyDepfileErrorsOut) {
01376   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
01377 "rule cc\n"
01378 "  command = cc\n"
01379 "  deps = gcc\n"
01380 "build out: cc\n"));
01381   Dirty("out");
01382 
01383   string err;
01384   EXPECT_TRUE(builder_.AddTarget("out", &err));
01385   ASSERT_EQ("", err);
01386   EXPECT_FALSE(builder_.AlreadyUpToDate());
01387 
01388   EXPECT_FALSE(builder_.Build(&err));
01389   ASSERT_EQ("subcommand failed", err);
01390   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
01391 }
01392 
01393 TEST_F(BuildTest, StatusFormatReplacePlaceholder) {
01394   EXPECT_EQ("[%/s0/t0/r0/u0/f0]",
01395             status_.FormatProgressStatus("[%%/s%s/t%t/r%r/u%u/f%f]"));
01396 }
01397 
01398 TEST_F(BuildTest, FailedDepsParse) {
01399   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
01400 "build bad_deps.o: cat in1\n"
01401 "  deps = gcc\n"
01402 "  depfile = in1.d\n"));
01403 
01404   string err;
01405   EXPECT_TRUE(builder_.AddTarget("bad_deps.o", &err));
01406   ASSERT_EQ("", err);
01407 
01408   // These deps will fail to parse, as they should only have one
01409   // path to the left of the colon.
01410   fs_.Create("in1.d", "AAA BBB");
01411 
01412   EXPECT_FALSE(builder_.Build(&err));
01413   EXPECT_EQ("subcommand failed", err);
01414 }
01415 
01416 /// Tests of builds involving deps logs necessarily must span
01417 /// multiple builds.  We reuse methods on BuildTest but not the
01418 /// builder_ it sets up, because we want pristine objects for
01419 /// each build.
01420 struct BuildWithDepsLogTest : public BuildTest {
01421   BuildWithDepsLogTest() {}
01422 
01423   virtual void SetUp() {
01424     BuildTest::SetUp();
01425 
01426     temp_dir_.CreateAndEnter("BuildWithDepsLogTest");
01427   }
01428 
01429   virtual void TearDown() {
01430     temp_dir_.Cleanup();
01431   }
01432 
01433   ScopedTempDir temp_dir_;
01434 
01435   /// Shadow parent class builder_ so we don't accidentally use it.
01436   void* builder_;
01437 };
01438 
01439 /// Run a straightforwad build where the deps log is used.
01440 TEST_F(BuildWithDepsLogTest, Straightforward) {
01441   string err;
01442   // Note: in1 was created by the superclass SetUp().
01443   const char* manifest =
01444       "build out: cat in1\n"
01445       "  deps = gcc\n"
01446       "  depfile = in1.d\n";
01447   {
01448     State state;
01449     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
01450     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
01451 
01452     // Run the build once, everything should be ok.
01453     DepsLog deps_log;
01454     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
01455     ASSERT_EQ("", err);
01456 
01457     Builder builder(&state, config_, NULL, &deps_log, &fs_);
01458     builder.command_runner_.reset(&command_runner_);
01459     EXPECT_TRUE(builder.AddTarget("out", &err));
01460     ASSERT_EQ("", err);
01461     fs_.Create("in1.d", "out: in2");
01462     EXPECT_TRUE(builder.Build(&err));
01463     EXPECT_EQ("", err);
01464 
01465     // The deps file should have been removed.
01466     EXPECT_EQ(0, fs_.Stat("in1.d"));
01467     // Recreate it for the next step.
01468     fs_.Create("in1.d", "out: in2");
01469     deps_log.Close();
01470     builder.command_runner_.release();
01471   }
01472 
01473   {
01474     State state;
01475     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
01476     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
01477 
01478     // Touch the file only mentioned in the deps.
01479     fs_.Tick();
01480     fs_.Create("in2", "");
01481 
01482     // Run the build again.
01483     DepsLog deps_log;
01484     ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
01485     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
01486 
01487     Builder builder(&state, config_, NULL, &deps_log, &fs_);
01488     builder.command_runner_.reset(&command_runner_);
01489     command_runner_.commands_ran_.clear();
01490     EXPECT_TRUE(builder.AddTarget("out", &err));
01491     ASSERT_EQ("", err);
01492     EXPECT_TRUE(builder.Build(&err));
01493     EXPECT_EQ("", err);
01494 
01495     // We should have rebuilt the output due to in2 being
01496     // out of date.
01497     EXPECT_EQ(1u, command_runner_.commands_ran_.size());
01498 
01499     builder.command_runner_.release();
01500   }
01501 }
01502 
01503 /// Verify that obsolete dependency info causes a rebuild.
01504 /// 1) Run a successful build where everything has time t, record deps.
01505 /// 2) Move input/output to time t+1 -- despite files in alignment,
01506 ///    should still need to rebuild due to deps at older time.
01507 TEST_F(BuildWithDepsLogTest, ObsoleteDeps) {
01508   string err;
01509   // Note: in1 was created by the superclass SetUp().
01510   const char* manifest =
01511       "build out: cat in1\n"
01512       "  deps = gcc\n"
01513       "  depfile = in1.d\n";
01514   {
01515     // Run an ordinary build that gathers dependencies.
01516     fs_.Create("in1", "");
01517     fs_.Create("in1.d", "out: ");
01518 
01519     State state;
01520     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
01521     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
01522 
01523     // Run the build once, everything should be ok.
01524     DepsLog deps_log;
01525     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
01526     ASSERT_EQ("", err);
01527 
01528     Builder builder(&state, config_, NULL, &deps_log, &fs_);
01529     builder.command_runner_.reset(&command_runner_);
01530     EXPECT_TRUE(builder.AddTarget("out", &err));
01531     ASSERT_EQ("", err);
01532     EXPECT_TRUE(builder.Build(&err));
01533     EXPECT_EQ("", err);
01534 
01535     deps_log.Close();
01536     builder.command_runner_.release();
01537   }
01538 
01539   // Push all files one tick forward so that only the deps are out
01540   // of date.
01541   fs_.Tick();
01542   fs_.Create("in1", "");
01543   fs_.Create("out", "");
01544 
01545   // The deps file should have been removed, so no need to timestamp it.
01546   EXPECT_EQ(0, fs_.Stat("in1.d"));
01547 
01548   {
01549     State state;
01550     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
01551     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
01552 
01553     DepsLog deps_log;
01554     ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
01555     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
01556 
01557     Builder builder(&state, config_, NULL, &deps_log, &fs_);
01558     builder.command_runner_.reset(&command_runner_);
01559     command_runner_.commands_ran_.clear();
01560     EXPECT_TRUE(builder.AddTarget("out", &err));
01561     ASSERT_EQ("", err);
01562 
01563     // Recreate the deps file here because the build expects them to exist.
01564     fs_.Create("in1.d", "out: ");
01565 
01566     EXPECT_TRUE(builder.Build(&err));
01567     EXPECT_EQ("", err);
01568 
01569     // We should have rebuilt the output due to the deps being
01570     // out of date.
01571     EXPECT_EQ(1u, command_runner_.commands_ran_.size());
01572 
01573     builder.command_runner_.release();
01574   }
01575 }
01576 
01577 TEST_F(BuildWithDepsLogTest, DepsIgnoredInDryRun) {
01578   const char* manifest =
01579       "build out: cat in1\n"
01580       "  deps = gcc\n"
01581       "  depfile = in1.d\n";
01582 
01583   fs_.Create("out", "");
01584   fs_.Tick();
01585   fs_.Create("in1", "");
01586 
01587   State state;
01588   ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
01589   ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
01590 
01591   // The deps log is NULL in dry runs.
01592   config_.dry_run = true;
01593   Builder builder(&state, config_, NULL, NULL, &fs_);
01594   builder.command_runner_.reset(&command_runner_);
01595   command_runner_.commands_ran_.clear();
01596 
01597   string err;
01598   EXPECT_TRUE(builder.AddTarget("out", &err));
01599   ASSERT_EQ("", err);
01600   EXPECT_TRUE(builder.Build(&err));
01601   ASSERT_EQ(1u, command_runner_.commands_ran_.size());
01602 
01603   builder.command_runner_.release();
01604 }
01605 
01606 /// Check that a restat rule generating a header cancels compilations correctly.
01607 TEST_F(BuildWithDepsLogTest, RestatDepfileDependency) {
01608   string err;
01609   // Note: in1 was created by the superclass SetUp().
01610   const char* manifest =
01611       "rule true\n"
01612       "  command = true\n"  // Would be "write if out-of-date" in reality.
01613       "  restat = 1\n"
01614       "build header.h: true header.in\n"
01615       "build out: cat in1\n"
01616       "  deps = gcc\n"
01617       "  depfile = in1.d\n";
01618   {
01619     State state;
01620     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
01621     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
01622 
01623     // Run the build once, everything should be ok.
01624     DepsLog deps_log;
01625     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
01626     ASSERT_EQ("", err);
01627 
01628     Builder builder(&state, config_, NULL, &deps_log, &fs_);
01629     builder.command_runner_.reset(&command_runner_);
01630     EXPECT_TRUE(builder.AddTarget("out", &err));
01631     ASSERT_EQ("", err);
01632     fs_.Create("in1.d", "out: header.h");
01633     EXPECT_TRUE(builder.Build(&err));
01634     EXPECT_EQ("", err);
01635 
01636     deps_log.Close();
01637     builder.command_runner_.release();
01638   }
01639 
01640   {
01641     State state;
01642     ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
01643     ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
01644 
01645     // Touch the input of the restat rule.
01646     fs_.Tick();
01647     fs_.Create("header.in", "");
01648 
01649     // Run the build again.
01650     DepsLog deps_log;
01651     ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
01652     ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
01653 
01654     Builder builder(&state, config_, NULL, &deps_log, &fs_);
01655     builder.command_runner_.reset(&command_runner_);
01656     command_runner_.commands_ran_.clear();
01657     EXPECT_TRUE(builder.AddTarget("out", &err));
01658     ASSERT_EQ("", err);
01659     EXPECT_TRUE(builder.Build(&err));
01660     EXPECT_EQ("", err);
01661 
01662     // Rule "true" should have run again, but the build of "out" should have
01663     // been cancelled due to restat propagating through the depfile header.
01664     EXPECT_EQ(1u, command_runner_.commands_ran_.size());
01665 
01666     builder.command_runner_.release();
01667   }
01668 }