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 "graph.h"
00019 #include "test.h"
00020 
00021 /// Fixture for tests involving Plan.
00022 // Though Plan doesn't use State, it's useful to have one around
00023 // to create Nodes and Edges.
00024 struct PlanTest : public StateTestWithBuiltinRules {
00025   Plan plan_;
00026 };
00027 
00028 TEST_F(PlanTest, Basic) {
00029   AssertParse(&state_,
00030 "build out: cat mid\n"
00031 "build mid: cat in\n");
00032   GetNode("mid")->dirty_ = true;
00033   GetNode("out")->dirty_ = true;
00034   string err;
00035   EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
00036   ASSERT_EQ("", err);
00037   ASSERT_TRUE(plan_.more_to_do());
00038 
00039   Edge* edge = plan_.FindWork();
00040   ASSERT_TRUE(edge);
00041   ASSERT_EQ("in",  edge->inputs_[0]->file_->path_);
00042   ASSERT_EQ("mid", edge->outputs_[0]->file_->path_);
00043 
00044   ASSERT_FALSE(plan_.FindWork());
00045 
00046   plan_.EdgeFinished(edge);
00047 
00048   edge = plan_.FindWork();
00049   ASSERT_TRUE(edge);
00050   ASSERT_EQ("mid", edge->inputs_[0]->file_->path_);
00051   ASSERT_EQ("out", edge->outputs_[0]->file_->path_);
00052 
00053   plan_.EdgeFinished(edge);
00054 
00055   ASSERT_FALSE(plan_.more_to_do());
00056   edge = plan_.FindWork();
00057   ASSERT_EQ(0, edge);
00058 }
00059 
00060 // Test that two outputs from one rule can be handled as inputs to the next.
00061 TEST_F(PlanTest, DoubleOutputDirect) {
00062   AssertParse(&state_,
00063 "build out: cat mid1 mid2\n"
00064 "build mid1 mid2: cat in\n");
00065   GetNode("mid1")->dirty_ = true;
00066   GetNode("mid2")->dirty_ = true;
00067   GetNode("out")->dirty_ = true;
00068 
00069   string err;
00070   EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
00071   ASSERT_EQ("", err);
00072   ASSERT_TRUE(plan_.more_to_do());
00073 
00074   Edge* edge;
00075   edge = plan_.FindWork();
00076   ASSERT_TRUE(edge);  // cat in
00077   plan_.EdgeFinished(edge);
00078 
00079   edge = plan_.FindWork();
00080   ASSERT_TRUE(edge);  // cat mid1 mid2
00081   plan_.EdgeFinished(edge);
00082 
00083   edge = plan_.FindWork();
00084   ASSERT_FALSE(edge);  // done
00085 }
00086 
00087 // Test that two outputs from one rule can eventually be routed to another.
00088 TEST_F(PlanTest, DoubleOutputIndirect) {
00089   AssertParse(&state_,
00090 "build out: cat b1 b2\n"
00091 "build b1: cat a1\n"
00092 "build b2: cat a2\n"
00093 "build a1 a2: cat in\n");
00094   GetNode("a1")->dirty_ = true;
00095   GetNode("a2")->dirty_ = true;
00096   GetNode("b1")->dirty_ = true;
00097   GetNode("b2")->dirty_ = true;
00098   GetNode("out")->dirty_ = true;
00099   string err;
00100   EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
00101   ASSERT_EQ("", err);
00102   ASSERT_TRUE(plan_.more_to_do());
00103 
00104   Edge* edge;
00105   edge = plan_.FindWork();
00106   ASSERT_TRUE(edge);  // cat in
00107   plan_.EdgeFinished(edge);
00108 
00109   edge = plan_.FindWork();
00110   ASSERT_TRUE(edge);  // cat a1
00111   plan_.EdgeFinished(edge);
00112 
00113   edge = plan_.FindWork();
00114   ASSERT_TRUE(edge);  // cat a2
00115   plan_.EdgeFinished(edge);
00116 
00117   edge = plan_.FindWork();
00118   ASSERT_TRUE(edge);  // cat b1 b2
00119   plan_.EdgeFinished(edge);
00120 
00121   edge = plan_.FindWork();
00122   ASSERT_FALSE(edge);  // done
00123 }
00124 
00125 // Test that two edges from one output can both execute.
00126 TEST_F(PlanTest, DoubleDependent) {
00127   AssertParse(&state_,
00128 "build out: cat a1 a2\n"
00129 "build a1: cat mid\n"
00130 "build a2: cat mid\n"
00131 "build mid: cat in\n");
00132   GetNode("mid")->dirty_ = true;
00133   GetNode("a1")->dirty_ = true;
00134   GetNode("a2")->dirty_ = true;
00135   GetNode("out")->dirty_ = true;
00136 
00137   string err;
00138   EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
00139   ASSERT_EQ("", err);
00140   ASSERT_TRUE(plan_.more_to_do());
00141 
00142   Edge* edge;
00143   edge = plan_.FindWork();
00144   ASSERT_TRUE(edge);  // cat in
00145   plan_.EdgeFinished(edge);
00146 
00147   edge = plan_.FindWork();
00148   ASSERT_TRUE(edge);  // cat mid
00149   plan_.EdgeFinished(edge);
00150 
00151   edge = plan_.FindWork();
00152   ASSERT_TRUE(edge);  // cat mid
00153   plan_.EdgeFinished(edge);
00154 
00155   edge = plan_.FindWork();
00156   ASSERT_TRUE(edge);  // cat a1 a2
00157   plan_.EdgeFinished(edge);
00158 
00159   edge = plan_.FindWork();
00160   ASSERT_FALSE(edge);  // done
00161 }
00162 
00163 TEST_F(PlanTest, DependencyCycle) {
00164   AssertParse(&state_,
00165 "build out: cat mid\n"
00166 "build mid: cat in\n"
00167 "build in: cat pre\n"
00168 "build pre: cat out\n");
00169   GetNode("out")->dirty_ = true;
00170   GetNode("mid")->dirty_ = true;
00171   GetNode("in")->dirty_ = true;
00172   GetNode("pre")->dirty_ = true;
00173 
00174   string err;
00175   EXPECT_FALSE(plan_.AddTarget(GetNode("out"), &err));
00176   ASSERT_EQ("dependency cycle: out -> mid -> in -> pre -> out", err);
00177 }
00178 
00179 struct BuildTest : public StateTestWithBuiltinRules,
00180                    public CommandRunner {
00181   BuildTest() : config_(MakeConfig()), builder_(&state_, config_), now_(1),
00182                 last_command_(NULL) {
00183     builder_.disk_interface_ = &fs_;
00184     builder_.command_runner_ = this;
00185     AssertParse(&state_,
00186 "build cat1: cat in1\n"
00187 "build cat2: cat in1 in2\n"
00188 "build cat12: cat cat1 cat2\n");
00189 
00190     fs_.Create("in1", now_, "");
00191     fs_.Create("in2", now_, "");
00192   }
00193 
00194   // Mark a path dirty.
00195   void Dirty(const string& path);
00196 
00197   // CommandRunner impl
00198   virtual bool CanRunMore();
00199   virtual bool StartCommand(Edge* edge);
00200   virtual Edge* WaitForCommand(bool* success, string* output);
00201 
00202   BuildConfig MakeConfig() {
00203     BuildConfig config;
00204     config.verbosity = BuildConfig::QUIET;
00205     return config;
00206   }
00207 
00208   BuildConfig config_;
00209   Builder builder_;
00210   int now_;
00211 
00212   VirtualFileSystem fs_;
00213 
00214   vector<string> commands_ran_;
00215   Edge* last_command_;
00216 };
00217 
00218 void BuildTest::Dirty(const string& path) {
00219   Node* node = GetNode(path);
00220   node->dirty_ = true;
00221 
00222   // If it's an input file, mark that we've already stat()ed it and
00223   // it's missing.
00224   if (!node->in_edge_)
00225     node->file_->mtime_ = 0;
00226 }
00227 
00228 bool BuildTest::CanRunMore() {
00229   // Only run one at a time.
00230   return last_command_ == NULL;
00231 }
00232 
00233 bool BuildTest::StartCommand(Edge* edge) {
00234   assert(!last_command_);
00235   commands_ran_.push_back(edge->EvaluateCommand());
00236   if (edge->rule_->name_ == "cat" || edge->rule_->name_ == "cc" ||
00237         edge->rule_->name_ == "touch") {
00238     for (vector<Node*>::iterator out = edge->outputs_.begin();
00239          out != edge->outputs_.end(); ++out) {
00240       fs_.Create((*out)->file_->path_, now_, "");
00241     }
00242   } else if (edge->rule_->name_ == "true" ||
00243              edge->rule_->name_ == "fail") {
00244     // Don't do anything.
00245   } else {
00246     printf("unknown command\n");
00247     return false;
00248   }
00249 
00250   last_command_ = edge;
00251   return true;
00252 }
00253 
00254 Edge* BuildTest::WaitForCommand(bool* success, string* output) {
00255   if (Edge* edge = last_command_) {
00256     if (edge->rule_->name_ == "fail")
00257       *success = false;
00258     else
00259       *success = true;
00260     last_command_ = NULL;
00261     return edge;
00262   }
00263   return NULL;
00264 }
00265 
00266 TEST_F(BuildTest, NoWork) {
00267   string err;
00268   EXPECT_TRUE(builder_.AlreadyUpToDate());
00269 }
00270 
00271 TEST_F(BuildTest, OneStep) {
00272   // Given a dirty target with one ready input,
00273   // we should rebuild the target.
00274   Dirty("cat1");
00275   string err;
00276   EXPECT_TRUE(builder_.AddTarget("cat1", &err));
00277   ASSERT_EQ("", err);
00278   EXPECT_TRUE(builder_.Build(&err));
00279   ASSERT_EQ("", err);
00280 
00281   ASSERT_EQ(1u, commands_ran_.size());
00282   EXPECT_EQ("cat in1 > cat1", commands_ran_[0]);
00283 }
00284 
00285 TEST_F(BuildTest, OneStep2) {
00286   // Given a target with one dirty input,
00287   // we should rebuild the target.
00288   Dirty("cat1");
00289   string err;
00290   EXPECT_TRUE(builder_.AddTarget("cat1", &err));
00291   ASSERT_EQ("", err);
00292   EXPECT_TRUE(builder_.Build(&err));
00293   EXPECT_EQ("", err);
00294 
00295   ASSERT_EQ(1u, commands_ran_.size());
00296   EXPECT_EQ("cat in1 > cat1", commands_ran_[0]);
00297 }
00298 
00299 TEST_F(BuildTest, TwoStep) {
00300   string err;
00301   EXPECT_TRUE(builder_.AddTarget("cat12", &err));
00302   ASSERT_EQ("", err);
00303   EXPECT_TRUE(builder_.Build(&err));
00304   EXPECT_EQ("", err);
00305   ASSERT_EQ(3u, commands_ran_.size());
00306   // Depending on how the pointers work out, we could've ran
00307   // the first two commands in either order.
00308   EXPECT_TRUE((commands_ran_[0] == "cat in1 > cat1" &&
00309                commands_ran_[1] == "cat in1 in2 > cat2") ||
00310               (commands_ran_[1] == "cat in1 > cat1" &&
00311                commands_ran_[0] == "cat in1 in2 > cat2"));
00312 
00313   EXPECT_EQ("cat cat1 cat2 > cat12", commands_ran_[2]);
00314 
00315   now_++;
00316 
00317   // Modifying in2 requires rebuilding one intermediate file
00318   // and the final file.
00319   fs_.Create("in2", now_, "");
00320   state_.Reset();
00321   EXPECT_TRUE(builder_.AddTarget("cat12", &err));
00322   ASSERT_EQ("", err);
00323   EXPECT_TRUE(builder_.Build(&err));
00324   ASSERT_EQ("", err);
00325   ASSERT_EQ(5u, commands_ran_.size());
00326   EXPECT_EQ("cat in1 in2 > cat2", commands_ran_[3]);
00327   EXPECT_EQ("cat cat1 cat2 > cat12", commands_ran_[4]);
00328 }
00329 
00330 TEST_F(BuildTest, TwoOutputs) {
00331   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00332 "rule touch\n"
00333 "  command = touch $out\n"
00334 "build out1 out2: touch in.txt\n"));
00335 
00336   fs_.Create("in.txt", now_, "");
00337 
00338   string err;
00339   EXPECT_TRUE(builder_.AddTarget("out1", &err));
00340   ASSERT_EQ("", err);
00341   EXPECT_TRUE(builder_.Build(&err));
00342   EXPECT_EQ("", err);
00343   ASSERT_EQ(1u, commands_ran_.size());
00344   EXPECT_EQ("touch out1 out2", commands_ran_[0]);
00345 }
00346 
00347 TEST_F(BuildTest, Chain) {
00348   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00349 "build c2: cat c1\n"
00350 "build c3: cat c2\n"
00351 "build c4: cat c3\n"
00352 "build c5: cat c4\n"));
00353 
00354   fs_.Create("c1", now_, "");
00355 
00356   string err;
00357   EXPECT_TRUE(builder_.AddTarget("c5", &err));
00358   ASSERT_EQ("", err);
00359   EXPECT_TRUE(builder_.Build(&err));
00360   EXPECT_EQ("", err);
00361   ASSERT_EQ(4u, commands_ran_.size());
00362 
00363   err.clear();
00364   commands_ran_.clear();
00365   state_.Reset();
00366   EXPECT_TRUE(builder_.AddTarget("c5", &err));
00367   ASSERT_EQ("", err);
00368   EXPECT_TRUE(builder_.AlreadyUpToDate());
00369 
00370   now_++;
00371 
00372   fs_.Create("c3", now_, "");
00373   err.clear();
00374   commands_ran_.clear();
00375   state_.Reset();
00376   EXPECT_TRUE(builder_.AddTarget("c5", &err));
00377   ASSERT_EQ("", err);
00378   EXPECT_FALSE(builder_.AlreadyUpToDate());
00379   EXPECT_TRUE(builder_.Build(&err));
00380   ASSERT_EQ(2u, commands_ran_.size());  // 3->4, 4->5
00381 }
00382 
00383 TEST_F(BuildTest, MissingInput) {
00384   // Input is referenced by build file, but no rule for it.
00385   string err;
00386   Dirty("in1");
00387   EXPECT_FALSE(builder_.AddTarget("cat1", &err));
00388   EXPECT_EQ("'in1', needed by 'cat1', missing and no known rule to make it",
00389             err);
00390 }
00391 
00392 TEST_F(BuildTest, MissingTarget) {
00393   // Target is not referenced by build file.
00394   string err;
00395   EXPECT_FALSE(builder_.AddTarget("meow", &err));
00396   EXPECT_EQ("unknown target: 'meow'", err);
00397 }
00398 
00399 TEST_F(BuildTest, MakeDirs) {
00400   string err;
00401 
00402 #ifdef WIN32
00403   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_, "build subdir\\dir2\\file: cat in1\n"));
00404   EXPECT_TRUE(builder_.AddTarget("subdir\\dir2\\file", &err));
00405 #else
00406   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_, "build subdir/dir2/file: cat in1\n"));
00407   EXPECT_TRUE(builder_.AddTarget("subdir/dir2/file", &err));
00408 #endif
00409 
00410   EXPECT_EQ("", err);
00411   now_ = 0;  // Make all stat()s return file not found.
00412   EXPECT_TRUE(builder_.Build(&err));
00413   ASSERT_EQ("", err);
00414   ASSERT_EQ(2u, fs_.directories_made_.size());
00415   EXPECT_EQ("subdir", fs_.directories_made_[0]);
00416 #ifdef WIN32
00417   EXPECT_EQ("subdir\\dir2", fs_.directories_made_[1]);
00418 #else
00419   EXPECT_EQ("subdir/dir2", fs_.directories_made_[1]);
00420 #endif
00421 }
00422 
00423 TEST_F(BuildTest, DepFileMissing) {
00424   string err;
00425   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00426 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
00427 "build foo.o: cc foo.c\n"));
00428   fs_.Create("foo.c", now_, "");
00429 
00430   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00431   ASSERT_EQ("", err);
00432   ASSERT_EQ(1u, fs_.files_read_.size());
00433   EXPECT_EQ("foo.o.d", fs_.files_read_[0]);
00434 }
00435 
00436 TEST_F(BuildTest, DepFileOK) {
00437   string err;
00438   int orig_edges = state_.edges_.size();
00439   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00440 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
00441 "build foo.o: cc foo.c\n"));
00442   Edge* edge = state_.edges_.back();
00443 
00444   fs_.Create("foo.c", now_, "");
00445   GetNode("bar.h")->dirty_ = true;  // Mark bar.h as missing.
00446   fs_.Create("foo.o.d", now_, "foo.o: blah.h bar.h\n");
00447   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00448   ASSERT_EQ("", err);
00449   ASSERT_EQ(1u, fs_.files_read_.size());
00450   EXPECT_EQ("foo.o.d", fs_.files_read_[0]);
00451 
00452   // Expect three new edges: one generating foo.o, and two more from
00453   // loading the depfile.
00454   ASSERT_EQ(orig_edges + 3, (int)state_.edges_.size());
00455   // Expect our edge to now have three inputs: foo.c and two headers.
00456   ASSERT_EQ(3u, edge->inputs_.size());
00457 
00458   // Expect the command line we generate to only use the original input.
00459   ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
00460 }
00461 
00462 TEST_F(BuildTest, DepFileParseError) {
00463   string err;
00464   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00465 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
00466 "build foo.o: cc foo.c\n"));
00467   fs_.Create("foo.c", now_, "");
00468   fs_.Create("foo.o.d", now_, "foo.o blah.h bar.h\n");
00469   EXPECT_FALSE(builder_.AddTarget("foo.o", &err));
00470   EXPECT_EQ("foo.o.d: line 1, col 7: expected ':', got 'blah.h'", err);
00471 }
00472 
00473 TEST_F(BuildTest, OrderOnlyDeps) {
00474   string err;
00475   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00476 "rule cc\n  command = cc $in\n  depfile = $out.d\n"
00477 "build foo.o: cc foo.c || otherfile\n"));
00478   Edge* edge = state_.edges_.back();
00479 
00480   fs_.Create("foo.c", now_, "");
00481   fs_.Create("otherfile", now_, "");
00482   fs_.Create("foo.o.d", now_, "foo.o: blah.h bar.h\n");
00483   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00484   ASSERT_EQ("", err);
00485 
00486   // One explicit, two implicit, one order only.
00487   ASSERT_EQ(4u, edge->inputs_.size());
00488   EXPECT_EQ(2, edge->implicit_deps_);
00489   EXPECT_EQ(1, edge->order_only_deps_);
00490   // Verify the inputs are in the order we expect
00491   // (explicit then implicit then orderonly).
00492   EXPECT_EQ("foo.c", edge->inputs_[0]->file_->path_);
00493   EXPECT_EQ("blah.h", edge->inputs_[1]->file_->path_);
00494   EXPECT_EQ("bar.h", edge->inputs_[2]->file_->path_);
00495   EXPECT_EQ("otherfile", edge->inputs_[3]->file_->path_);
00496 
00497   // Expect the command line we generate to only use the original input.
00498   ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
00499 
00500   // explicit dep dirty, expect a rebuild.
00501   EXPECT_TRUE(builder_.Build(&err));
00502   ASSERT_EQ("", err);
00503   ASSERT_EQ(1u, commands_ran_.size());
00504 
00505   now_++;
00506 
00507   // implicit dep dirty, expect a rebuild.
00508   fs_.Create("blah.h", now_, "");
00509   fs_.Create("bar.h", now_, "");
00510   commands_ran_.clear();
00511   state_.Reset();
00512   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00513   EXPECT_TRUE(builder_.Build(&err));
00514   ASSERT_EQ("", err);
00515   ASSERT_EQ(1u, commands_ran_.size());
00516 
00517   now_++;
00518 
00519   // order only dep dirty, no rebuild.
00520   fs_.Create("otherfile", now_, "");
00521   commands_ran_.clear();
00522   state_.Reset();
00523   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00524   EXPECT_EQ("", err);
00525   EXPECT_TRUE(builder_.AlreadyUpToDate());
00526 
00527   // implicit dep missing, expect rebuild.
00528   fs_.RemoveFile("bar.h");
00529   commands_ran_.clear();
00530   state_.Reset();
00531   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00532   EXPECT_TRUE(builder_.Build(&err));
00533   ASSERT_EQ("", err);
00534   ASSERT_EQ(1u, commands_ran_.size());
00535 }
00536 
00537 TEST_F(BuildTest, RebuildOrderOnlyDeps) {
00538   string err;
00539   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00540 "rule cc\n  command = cc $in\n"
00541 "rule true\n  command = true\n"
00542 "build oo.h: cc oo.h.in\n"
00543 "build foo.o: cc foo.c || oo.h\n"));
00544 
00545   fs_.Create("foo.c", now_, "");
00546   fs_.Create("oo.h.in", now_, "");
00547 
00548   // foo.o and order-only dep dirty, build both.
00549   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00550   EXPECT_TRUE(builder_.Build(&err));
00551   ASSERT_EQ("", err);
00552   ASSERT_EQ(2u, commands_ran_.size());
00553 
00554   // all clean, no rebuild.
00555   commands_ran_.clear();
00556   state_.Reset();
00557   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00558   EXPECT_EQ("", err);
00559   EXPECT_TRUE(builder_.AlreadyUpToDate());
00560 
00561   // order-only dep missing, build it only.
00562   fs_.RemoveFile("oo.h");
00563   commands_ran_.clear();
00564   state_.Reset();
00565   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00566   EXPECT_TRUE(builder_.Build(&err));
00567   ASSERT_EQ("", err);
00568   ASSERT_EQ(1u, commands_ran_.size());
00569   ASSERT_EQ("cc oo.h.in", commands_ran_[0]);
00570 
00571   now_++;
00572 
00573   // order-only dep dirty, build it only.
00574   fs_.Create("oo.h.in", now_, "");
00575   commands_ran_.clear();
00576   state_.Reset();
00577   EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
00578   EXPECT_TRUE(builder_.Build(&err));
00579   ASSERT_EQ("", err);
00580   ASSERT_EQ(1u, commands_ran_.size());
00581   ASSERT_EQ("cc oo.h.in", commands_ran_[0]);
00582 }
00583 
00584 TEST_F(BuildTest, Phony) {
00585   string err;
00586   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00587 "build out: cat bar.cc\n"
00588 "build all: phony out\n"));
00589   fs_.Create("bar.cc", now_, "");
00590 
00591   EXPECT_TRUE(builder_.AddTarget("all", &err));
00592   ASSERT_EQ("", err);
00593 
00594   // Only one command to run, because phony runs no command.
00595   EXPECT_FALSE(builder_.AlreadyUpToDate());
00596   EXPECT_TRUE(builder_.Build(&err));
00597   ASSERT_EQ("", err);
00598   ASSERT_EQ(1u, commands_ran_.size());
00599 }
00600 
00601 TEST_F(BuildTest, PhonyNoWork) {
00602   string err;
00603   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00604 "build out: cat bar.cc\n"
00605 "build all: phony out\n"));
00606   fs_.Create("bar.cc", now_, "");
00607   fs_.Create("out", now_, "");
00608 
00609   EXPECT_TRUE(builder_.AddTarget("all", &err));
00610   ASSERT_EQ("", err);
00611   EXPECT_TRUE(builder_.AlreadyUpToDate());
00612 }
00613 
00614 TEST_F(BuildTest, Fail) {
00615   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00616 "rule fail\n"
00617 "  command = fail\n"
00618 "build out1: fail\n"));
00619 
00620   string err;
00621   EXPECT_TRUE(builder_.AddTarget("out1", &err));
00622   ASSERT_EQ("", err);
00623 
00624   EXPECT_FALSE(builder_.Build(&err));
00625   ASSERT_EQ(1u, commands_ran_.size());
00626   ASSERT_EQ("subcommand failed", err);
00627 }
00628 
00629 TEST_F(BuildTest, SwallowFailures) {
00630   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00631 "rule fail\n"
00632 "  command = fail\n"
00633 "build out1: fail\n"
00634 "build out2: fail\n"
00635 "build out3: fail\n"
00636 "build all: phony out1 out2 out3\n"));
00637 
00638   // Swallow two failures, die on the third.
00639   config_.swallow_failures = 2;
00640 
00641   string err;
00642   EXPECT_TRUE(builder_.AddTarget("all", &err));
00643   ASSERT_EQ("", err);
00644 
00645   EXPECT_FALSE(builder_.Build(&err));
00646   ASSERT_EQ(3u, commands_ran_.size());
00647   ASSERT_EQ("subcommands failed", err);
00648 }
00649 
00650 TEST_F(BuildTest, SwallowFailuresLimit) {
00651   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00652 "rule fail\n"
00653 "  command = fail\n"
00654 "build out1: fail\n"
00655 "build out2: fail\n"
00656 "build out3: fail\n"
00657 "build final: cat out1 out2 out3\n"));
00658 
00659   // Swallow ten failures; we should stop before building final.
00660   config_.swallow_failures = 10;
00661 
00662   string err;
00663   EXPECT_TRUE(builder_.AddTarget("final", &err));
00664   ASSERT_EQ("", err);
00665 
00666   EXPECT_FALSE(builder_.Build(&err));
00667   ASSERT_EQ(3u, commands_ran_.size());
00668   ASSERT_EQ("cannot make progress due to previous errors", err);
00669 }
00670 
00671 struct BuildWithLogTest : public BuildTest {
00672   BuildWithLogTest() {
00673     state_.build_log_ = builder_.log_ = &build_log_;
00674   }
00675 
00676   BuildLog build_log_;
00677 };
00678 
00679 TEST_F(BuildWithLogTest, RestatTest) {
00680   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
00681 "rule true\n"
00682 "  command = true\n"
00683 "  restat = 1\n"
00684 "rule cc\n"
00685 "  command = cc\n"
00686 "  restat = 1\n"
00687 "build out1: cc in\n"
00688 "build out2: true out1\n"
00689 "build out3: cat out2\n"));
00690 
00691   fs_.Create("out1", now_, "");
00692   fs_.Create("out2", now_, "");
00693   fs_.Create("out3", now_, "");
00694 
00695   now_++;
00696 
00697   fs_.Create("in", now_, "");
00698 
00699   // "cc" touches out1, so we should build out2.  But because "true" does not
00700   // touch out2, we should cancel the build of out3.
00701   string err;
00702   EXPECT_TRUE(builder_.AddTarget("out3", &err));
00703   ASSERT_EQ("", err);
00704   EXPECT_TRUE(builder_.Build(&err));
00705   ASSERT_EQ(2u, commands_ran_.size());
00706 
00707   // If we run again, it should be a no-op, because the build log has recorded
00708   // that we've already built out2 with an input timestamp of 2 (from out1).
00709   commands_ran_.clear();
00710   state_.Reset();
00711   EXPECT_TRUE(builder_.AddTarget("out3", &err));
00712   ASSERT_EQ("", err);
00713   EXPECT_TRUE(builder_.AlreadyUpToDate());
00714 
00715   now_++;
00716 
00717   fs_.Create("in", now_, "");
00718 
00719   // The build log entry should not, however, prevent us from rebuilding out2
00720   // if out1 changes.
00721   commands_ran_.clear();
00722   state_.Reset();
00723   EXPECT_TRUE(builder_.AddTarget("out3", &err));
00724   ASSERT_EQ("", err);
00725   EXPECT_TRUE(builder_.Build(&err));
00726   ASSERT_EQ(2u, commands_ran_.size());
00727 }