Ninja
clean_test.cc
Go to the documentation of this file.
1 // Copyright 2011 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "clean.h"
16 #include "build.h"
17 
18 #include "util.h"
19 #include "test.h"
20 
21 #ifndef _WIN32
22 #include <unistd.h>
23 #endif
24 
25 using namespace std;
26 
27 namespace {
28 
29 const char kTestFilename[] = "CleanTest-tempfile";
30 
31 struct CleanTest : public StateTestWithBuiltinRules {
33  BuildConfig config_;
34  virtual void SetUp() {
35  config_.verbosity = BuildConfig::QUIET;
36  }
37 };
38 
39 TEST_F(CleanTest, CleanAll) {
40  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
41 "build in1: cat src1\n"
42 "build out1: cat in1\n"
43 "build in2: cat src2\n"
44 "build out2: cat in2\n"));
45  fs_.Create("in1", "");
46  fs_.Create("out1", "");
47  fs_.Create("in2", "");
48  fs_.Create("out2", "");
49 
50  Cleaner cleaner(&state_, config_, &fs_);
51 
52  ASSERT_EQ(0, cleaner.cleaned_files_count());
53  EXPECT_EQ(0, cleaner.CleanAll());
54  EXPECT_EQ(4, cleaner.cleaned_files_count());
55  EXPECT_EQ(4u, fs_.files_removed_.size());
56 
57  // Check they are removed.
58  string err;
59  EXPECT_EQ(0, fs_.Stat("in1", &err));
60  EXPECT_EQ(0, fs_.Stat("out1", &err));
61  EXPECT_EQ(0, fs_.Stat("in2", &err));
62  EXPECT_EQ(0, fs_.Stat("out2", &err));
63  fs_.files_removed_.clear();
64 
65  EXPECT_EQ(0, cleaner.CleanAll());
66  EXPECT_EQ(0, cleaner.cleaned_files_count());
67  EXPECT_EQ(0u, fs_.files_removed_.size());
68 }
69 
70 TEST_F(CleanTest, CleanAllDryRun) {
71  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
72 "build in1: cat src1\n"
73 "build out1: cat in1\n"
74 "build in2: cat src2\n"
75 "build out2: cat in2\n"));
76  fs_.Create("in1", "");
77  fs_.Create("out1", "");
78  fs_.Create("in2", "");
79  fs_.Create("out2", "");
80 
81  config_.dry_run = true;
82  Cleaner cleaner(&state_, config_, &fs_);
83 
84  ASSERT_EQ(0, cleaner.cleaned_files_count());
85  EXPECT_EQ(0, cleaner.CleanAll());
86  EXPECT_EQ(4, cleaner.cleaned_files_count());
87  EXPECT_EQ(0u, fs_.files_removed_.size());
88 
89  // Check they are not removed.
90  string err;
91  EXPECT_LT(0, fs_.Stat("in1", &err));
92  EXPECT_LT(0, fs_.Stat("out1", &err));
93  EXPECT_LT(0, fs_.Stat("in2", &err));
94  EXPECT_LT(0, fs_.Stat("out2", &err));
95  fs_.files_removed_.clear();
96 
97  EXPECT_EQ(0, cleaner.CleanAll());
98  EXPECT_EQ(4, cleaner.cleaned_files_count());
99  EXPECT_EQ(0u, fs_.files_removed_.size());
100 }
101 
102 TEST_F(CleanTest, CleanTarget) {
103  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
104 "build in1: cat src1\n"
105 "build out1: cat in1\n"
106 "build in2: cat src2\n"
107 "build out2: cat in2\n"));
108  fs_.Create("in1", "");
109  fs_.Create("out1", "");
110  fs_.Create("in2", "");
111  fs_.Create("out2", "");
112 
113  Cleaner cleaner(&state_, config_, &fs_);
114 
115  ASSERT_EQ(0, cleaner.cleaned_files_count());
116  ASSERT_EQ(0, cleaner.CleanTarget("out1"));
117  EXPECT_EQ(2, cleaner.cleaned_files_count());
118  EXPECT_EQ(2u, fs_.files_removed_.size());
119 
120  // Check they are removed.
121  string err;
122  EXPECT_EQ(0, fs_.Stat("in1", &err));
123  EXPECT_EQ(0, fs_.Stat("out1", &err));
124  EXPECT_LT(0, fs_.Stat("in2", &err));
125  EXPECT_LT(0, fs_.Stat("out2", &err));
126  fs_.files_removed_.clear();
127 
128  ASSERT_EQ(0, cleaner.CleanTarget("out1"));
129  EXPECT_EQ(0, cleaner.cleaned_files_count());
130  EXPECT_EQ(0u, fs_.files_removed_.size());
131 }
132 
133 TEST_F(CleanTest, CleanTargetDryRun) {
134  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
135 "build in1: cat src1\n"
136 "build out1: cat in1\n"
137 "build in2: cat src2\n"
138 "build out2: cat in2\n"));
139  fs_.Create("in1", "");
140  fs_.Create("out1", "");
141  fs_.Create("in2", "");
142  fs_.Create("out2", "");
143 
144  config_.dry_run = true;
145  Cleaner cleaner(&state_, config_, &fs_);
146 
147  ASSERT_EQ(0, cleaner.cleaned_files_count());
148  ASSERT_EQ(0, cleaner.CleanTarget("out1"));
149  EXPECT_EQ(2, cleaner.cleaned_files_count());
150  EXPECT_EQ(0u, fs_.files_removed_.size());
151 
152  // Check they are not removed.
153  string err;
154  EXPECT_LT(0, fs_.Stat("in1", &err));
155  EXPECT_LT(0, fs_.Stat("out1", &err));
156  EXPECT_LT(0, fs_.Stat("in2", &err));
157  EXPECT_LT(0, fs_.Stat("out2", &err));
158  fs_.files_removed_.clear();
159 
160  ASSERT_EQ(0, cleaner.CleanTarget("out1"));
161  EXPECT_EQ(2, cleaner.cleaned_files_count());
162  EXPECT_EQ(0u, fs_.files_removed_.size());
163 }
164 
165 TEST_F(CleanTest, CleanRule) {
166  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
167 "rule cat_e\n"
168 " command = cat -e $in > $out\n"
169 "build in1: cat_e src1\n"
170 "build out1: cat in1\n"
171 "build in2: cat_e src2\n"
172 "build out2: cat in2\n"));
173  fs_.Create("in1", "");
174  fs_.Create("out1", "");
175  fs_.Create("in2", "");
176  fs_.Create("out2", "");
177 
178  Cleaner cleaner(&state_, config_, &fs_);
179 
180  ASSERT_EQ(0, cleaner.cleaned_files_count());
181  ASSERT_EQ(0, cleaner.CleanRule("cat_e"));
182  EXPECT_EQ(2, cleaner.cleaned_files_count());
183  EXPECT_EQ(2u, fs_.files_removed_.size());
184 
185  // Check they are removed.
186  string err;
187  EXPECT_EQ(0, fs_.Stat("in1", &err));
188  EXPECT_LT(0, fs_.Stat("out1", &err));
189  EXPECT_EQ(0, fs_.Stat("in2", &err));
190  EXPECT_LT(0, fs_.Stat("out2", &err));
191  fs_.files_removed_.clear();
192 
193  ASSERT_EQ(0, cleaner.CleanRule("cat_e"));
194  EXPECT_EQ(0, cleaner.cleaned_files_count());
195  EXPECT_EQ(0u, fs_.files_removed_.size());
196 }
197 
198 TEST_F(CleanTest, CleanRuleDryRun) {
199  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
200 "rule cat_e\n"
201 " command = cat -e $in > $out\n"
202 "build in1: cat_e src1\n"
203 "build out1: cat in1\n"
204 "build in2: cat_e src2\n"
205 "build out2: cat in2\n"));
206  fs_.Create("in1", "");
207  fs_.Create("out1", "");
208  fs_.Create("in2", "");
209  fs_.Create("out2", "");
210 
211  config_.dry_run = true;
212  Cleaner cleaner(&state_, config_, &fs_);
213 
214  ASSERT_EQ(0, cleaner.cleaned_files_count());
215  ASSERT_EQ(0, cleaner.CleanRule("cat_e"));
216  EXPECT_EQ(2, cleaner.cleaned_files_count());
217  EXPECT_EQ(0u, fs_.files_removed_.size());
218 
219  // Check they are not removed.
220  string err;
221  EXPECT_LT(0, fs_.Stat("in1", &err));
222  EXPECT_LT(0, fs_.Stat("out1", &err));
223  EXPECT_LT(0, fs_.Stat("in2", &err));
224  EXPECT_LT(0, fs_.Stat("out2", &err));
225  fs_.files_removed_.clear();
226 
227  ASSERT_EQ(0, cleaner.CleanRule("cat_e"));
228  EXPECT_EQ(2, cleaner.cleaned_files_count());
229  EXPECT_EQ(0u, fs_.files_removed_.size());
230 }
231 
232 TEST_F(CleanTest, CleanRuleGenerator) {
233  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
234 "rule regen\n"
235 " command = cat $in > $out\n"
236 " generator = 1\n"
237 "build out1: cat in1\n"
238 "build out2: regen in2\n"));
239  fs_.Create("out1", "");
240  fs_.Create("out2", "");
241 
242  Cleaner cleaner(&state_, config_, &fs_);
243  EXPECT_EQ(0, cleaner.CleanAll());
244  EXPECT_EQ(1, cleaner.cleaned_files_count());
245  EXPECT_EQ(1u, fs_.files_removed_.size());
246 
247  fs_.Create("out1", "");
248 
249  EXPECT_EQ(0, cleaner.CleanAll(/*generator=*/true));
250  EXPECT_EQ(2, cleaner.cleaned_files_count());
251  EXPECT_EQ(2u, fs_.files_removed_.size());
252 }
253 
254 TEST_F(CleanTest, CleanDepFile) {
255  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
256 "rule cc\n"
257 " command = cc $in > $out\n"
258 " depfile = $out.d\n"
259 "build out1: cc in1\n"));
260  fs_.Create("out1", "");
261  fs_.Create("out1.d", "");
262 
263  Cleaner cleaner(&state_, config_, &fs_);
264  EXPECT_EQ(0, cleaner.CleanAll());
265  EXPECT_EQ(2, cleaner.cleaned_files_count());
266  EXPECT_EQ(2u, fs_.files_removed_.size());
267 }
268 
269 TEST_F(CleanTest, CleanDepFileOnCleanTarget) {
270  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
271 "rule cc\n"
272 " command = cc $in > $out\n"
273 " depfile = $out.d\n"
274 "build out1: cc in1\n"));
275  fs_.Create("out1", "");
276  fs_.Create("out1.d", "");
277 
278  Cleaner cleaner(&state_, config_, &fs_);
279  EXPECT_EQ(0, cleaner.CleanTarget("out1"));
280  EXPECT_EQ(2, cleaner.cleaned_files_count());
281  EXPECT_EQ(2u, fs_.files_removed_.size());
282 }
283 
284 TEST_F(CleanTest, CleanDepFileOnCleanRule) {
285  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
286 "rule cc\n"
287 " command = cc $in > $out\n"
288 " depfile = $out.d\n"
289 "build out1: cc in1\n"));
290  fs_.Create("out1", "");
291  fs_.Create("out1.d", "");
292 
293  Cleaner cleaner(&state_, config_, &fs_);
294  EXPECT_EQ(0, cleaner.CleanRule("cc"));
295  EXPECT_EQ(2, cleaner.cleaned_files_count());
296  EXPECT_EQ(2u, fs_.files_removed_.size());
297 }
298 
299 TEST_F(CleanTest, CleanDyndep) {
300  // Verify that a dyndep file can be loaded to discover a new output
301  // to be cleaned.
302  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
303 "build out: cat in || dd\n"
304 " dyndep = dd\n"
305  ));
306  fs_.Create("in", "");
307  fs_.Create("dd",
308 "ninja_dyndep_version = 1\n"
309 "build out | out.imp: dyndep\n"
310 );
311  fs_.Create("out", "");
312  fs_.Create("out.imp", "");
313 
314  Cleaner cleaner(&state_, config_, &fs_);
315 
316  ASSERT_EQ(0, cleaner.cleaned_files_count());
317  EXPECT_EQ(0, cleaner.CleanAll());
318  EXPECT_EQ(2, cleaner.cleaned_files_count());
319  EXPECT_EQ(2u, fs_.files_removed_.size());
320 
321  string err;
322  EXPECT_EQ(0, fs_.Stat("out", &err));
323  EXPECT_EQ(0, fs_.Stat("out.imp", &err));
324 }
325 
326 TEST_F(CleanTest, CleanDyndepMissing) {
327  // Verify that a missing dyndep file is tolerated.
328  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
329 "build out: cat in || dd\n"
330 " dyndep = dd\n"
331  ));
332  fs_.Create("in", "");
333  fs_.Create("out", "");
334  fs_.Create("out.imp", "");
335 
336  Cleaner cleaner(&state_, config_, &fs_);
337 
338  ASSERT_EQ(0, cleaner.cleaned_files_count());
339  EXPECT_EQ(0, cleaner.CleanAll());
340  EXPECT_EQ(1, cleaner.cleaned_files_count());
341  EXPECT_EQ(1u, fs_.files_removed_.size());
342 
343  string err;
344  EXPECT_EQ(0, fs_.Stat("out", &err));
345  EXPECT_EQ(1, fs_.Stat("out.imp", &err));
346 }
347 
348 TEST_F(CleanTest, CleanRspFile) {
349  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
350 "rule cc\n"
351 " command = cc $in > $out\n"
352 " rspfile = $rspfile\n"
353 " rspfile_content=$in\n"
354 "build out1: cc in1\n"
355 " rspfile = cc1.rsp\n"));
356  fs_.Create("out1", "");
357  fs_.Create("cc1.rsp", "");
358 
359  Cleaner cleaner(&state_, config_, &fs_);
360  EXPECT_EQ(0, cleaner.CleanAll());
361  EXPECT_EQ(2, cleaner.cleaned_files_count());
362  EXPECT_EQ(2u, fs_.files_removed_.size());
363 }
364 
365 TEST_F(CleanTest, CleanRsp) {
366  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
367 "rule cat_rsp \n"
368 " command = cat $rspfile > $out\n"
369 " rspfile = $rspfile\n"
370 " rspfile_content = $in\n"
371 "build in1: cat src1\n"
372 "build out1: cat in1\n"
373 "build in2: cat_rsp src2\n"
374 " rspfile=in2.rsp\n"
375 "build out2: cat_rsp in2\n"
376 " rspfile=out2.rsp\n"
377 ));
378  fs_.Create("in1", "");
379  fs_.Create("out1", "");
380  fs_.Create("in2.rsp", "");
381  fs_.Create("out2.rsp", "");
382  fs_.Create("in2", "");
383  fs_.Create("out2", "");
384 
385  Cleaner cleaner(&state_, config_, &fs_);
386  ASSERT_EQ(0, cleaner.cleaned_files_count());
387  ASSERT_EQ(0, cleaner.CleanTarget("out1"));
388  EXPECT_EQ(2, cleaner.cleaned_files_count());
389  ASSERT_EQ(0, cleaner.CleanTarget("in2"));
390  EXPECT_EQ(2, cleaner.cleaned_files_count());
391  ASSERT_EQ(0, cleaner.CleanRule("cat_rsp"));
392  EXPECT_EQ(2, cleaner.cleaned_files_count());
393 
394  EXPECT_EQ(6u, fs_.files_removed_.size());
395 
396  // Check they are removed.
397  string err;
398  EXPECT_EQ(0, fs_.Stat("in1", &err));
399  EXPECT_EQ(0, fs_.Stat("out1", &err));
400  EXPECT_EQ(0, fs_.Stat("in2", &err));
401  EXPECT_EQ(0, fs_.Stat("out2", &err));
402  EXPECT_EQ(0, fs_.Stat("in2.rsp", &err));
403  EXPECT_EQ(0, fs_.Stat("out2.rsp", &err));
404 }
405 
406 TEST_F(CleanTest, CleanFailure) {
407  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
408  "build dir: cat src1\n"));
409  fs_.MakeDir("dir");
410  Cleaner cleaner(&state_, config_, &fs_);
411  EXPECT_NE(0, cleaner.CleanAll());
412 }
413 
414 TEST_F(CleanTest, CleanPhony) {
415  string err;
416  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
417 "build phony: phony t1 t2\n"
418 "build t1: cat\n"
419 "build t2: cat\n"));
420 
421  fs_.Create("phony", "");
422  fs_.Create("t1", "");
423  fs_.Create("t2", "");
424 
425  // Check that CleanAll does not remove "phony".
426  Cleaner cleaner(&state_, config_, &fs_);
427  EXPECT_EQ(0, cleaner.CleanAll());
428  EXPECT_EQ(2, cleaner.cleaned_files_count());
429  EXPECT_LT(0, fs_.Stat("phony", &err));
430 
431  fs_.Create("t1", "");
432  fs_.Create("t2", "");
433 
434  // Check that CleanTarget does not remove "phony".
435  EXPECT_EQ(0, cleaner.CleanTarget("phony"));
436  EXPECT_EQ(2, cleaner.cleaned_files_count());
437  EXPECT_LT(0, fs_.Stat("phony", &err));
438 }
439 
440 TEST_F(CleanTest, CleanDepFileAndRspFileWithSpaces) {
441  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
442 "rule cc_dep\n"
443 " command = cc $in > $out\n"
444 " depfile = $out.d\n"
445 "rule cc_rsp\n"
446 " command = cc $in > $out\n"
447 " rspfile = $out.rsp\n"
448 " rspfile_content = $in\n"
449 "build out$ 1: cc_dep in$ 1\n"
450 "build out$ 2: cc_rsp in$ 1\n"
451 ));
452  fs_.Create("out 1", "");
453  fs_.Create("out 2", "");
454  fs_.Create("out 1.d", "");
455  fs_.Create("out 2.rsp", "");
456 
457  Cleaner cleaner(&state_, config_, &fs_);
458  EXPECT_EQ(0, cleaner.CleanAll());
459  EXPECT_EQ(4, cleaner.cleaned_files_count());
460  EXPECT_EQ(4u, fs_.files_removed_.size());
461 
462  string err;
463  EXPECT_EQ(0, fs_.Stat("out 1", &err));
464  EXPECT_EQ(0, fs_.Stat("out 2", &err));
465  EXPECT_EQ(0, fs_.Stat("out 1.d", &err));
466  EXPECT_EQ(0, fs_.Stat("out 2.rsp", &err));
467 }
468 
469 struct CleanDeadTest : public CleanTest, public BuildLogUser{
470  virtual void SetUp() {
471  // In case a crashing test left a stale file behind.
473  CleanTest::SetUp();
474  }
475  virtual void TearDown() {
477  }
478  virtual bool IsPathDead(StringPiece) const { return false; }
479 };
480 
481 TEST_F(CleanDeadTest, CleanDead) {
482  State state;
483  ASSERT_NO_FATAL_FAILURE(AssertParse(&state,
484 "rule cat\n"
485 " command = cat $in > $out\n"
486 "build out1: cat in\n"
487 "build out2: cat in\n"
488 ));
489  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
490 "build out2: cat in\n"
491 ));
492  fs_.Create("in", "");
493  fs_.Create("out1", "");
494  fs_.Create("out2", "");
495 
496  BuildLog log1;
497  string err;
498  EXPECT_TRUE(log1.OpenForWrite(kTestFilename, *this, &err));
499  ASSERT_EQ("", err);
500  log1.RecordCommand(state.edges_[0], 15, 18);
501  log1.RecordCommand(state.edges_[1], 20, 25);
502  log1.Close();
503 
504  BuildLog log2;
505  EXPECT_TRUE(log2.Load(kTestFilename, &err));
506  ASSERT_EQ("", err);
507  ASSERT_EQ(2u, log2.entries().size());
508  ASSERT_TRUE(log2.LookupByOutput("out1"));
509  ASSERT_TRUE(log2.LookupByOutput("out2"));
510 
511  // First use the manifest that describe how to build out1.
512  Cleaner cleaner1(&state, config_, &fs_);
513  EXPECT_EQ(0, cleaner1.CleanDead(log2.entries()));
514  EXPECT_EQ(0, cleaner1.cleaned_files_count());
515  EXPECT_EQ(0u, fs_.files_removed_.size());
516  EXPECT_NE(0, fs_.Stat("in", &err));
517  EXPECT_NE(0, fs_.Stat("out1", &err));
518  EXPECT_NE(0, fs_.Stat("out2", &err));
519 
520  // Then use the manifest that does not build out1 anymore.
521  Cleaner cleaner2(&state_, config_, &fs_);
522  EXPECT_EQ(0, cleaner2.CleanDead(log2.entries()));
523  EXPECT_EQ(1, cleaner2.cleaned_files_count());
524  EXPECT_EQ(1u, fs_.files_removed_.size());
525  EXPECT_EQ("out1", *(fs_.files_removed_.begin()));
526  EXPECT_NE(0, fs_.Stat("in", &err));
527  EXPECT_EQ(0, fs_.Stat("out1", &err));
528  EXPECT_NE(0, fs_.Stat("out2", &err));
529 
530  // Nothing to do now.
531  EXPECT_EQ(0, cleaner2.CleanDead(log2.entries()));
532  EXPECT_EQ(0, cleaner2.cleaned_files_count());
533  EXPECT_EQ(1u, fs_.files_removed_.size());
534  EXPECT_EQ("out1", *(fs_.files_removed_.begin()));
535  EXPECT_NE(0, fs_.Stat("in", &err));
536  EXPECT_EQ(0, fs_.Stat("out1", &err));
537  EXPECT_NE(0, fs_.Stat("out2", &err));
538  log2.Close();
539 }
540 
541 TEST_F(CleanDeadTest, CleanDeadPreservesInputs) {
542  State state;
543  ASSERT_NO_FATAL_FAILURE(AssertParse(&state,
544 "rule cat\n"
545 " command = cat $in > $out\n"
546 "build out1: cat in\n"
547 "build out2: cat in\n"
548 ));
549  // This manifest does not build out1 anymore, but makes
550  // it an implicit input. CleanDead should detect this
551  // and preserve it.
552  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
553 "build out2: cat in | out1\n"
554 ));
555  fs_.Create("in", "");
556  fs_.Create("out1", "");
557  fs_.Create("out2", "");
558 
559  BuildLog log1;
560  string err;
561  EXPECT_TRUE(log1.OpenForWrite(kTestFilename, *this, &err));
562  ASSERT_EQ("", err);
563  log1.RecordCommand(state.edges_[0], 15, 18);
564  log1.RecordCommand(state.edges_[1], 20, 25);
565  log1.Close();
566 
567  BuildLog log2;
568  EXPECT_TRUE(log2.Load(kTestFilename, &err));
569  ASSERT_EQ("", err);
570  ASSERT_EQ(2u, log2.entries().size());
571  ASSERT_TRUE(log2.LookupByOutput("out1"));
572  ASSERT_TRUE(log2.LookupByOutput("out2"));
573 
574  // First use the manifest that describe how to build out1.
575  Cleaner cleaner1(&state, config_, &fs_);
576  EXPECT_EQ(0, cleaner1.CleanDead(log2.entries()));
577  EXPECT_EQ(0, cleaner1.cleaned_files_count());
578  EXPECT_EQ(0u, fs_.files_removed_.size());
579  EXPECT_NE(0, fs_.Stat("in", &err));
580  EXPECT_NE(0, fs_.Stat("out1", &err));
581  EXPECT_NE(0, fs_.Stat("out2", &err));
582 
583  // Then use the manifest that does not build out1 anymore.
584  Cleaner cleaner2(&state_, config_, &fs_);
585  EXPECT_EQ(0, cleaner2.CleanDead(log2.entries()));
586  EXPECT_EQ(0, cleaner2.cleaned_files_count());
587  EXPECT_EQ(0u, fs_.files_removed_.size());
588  EXPECT_NE(0, fs_.Stat("in", &err));
589  EXPECT_NE(0, fs_.Stat("out1", &err));
590  EXPECT_NE(0, fs_.Stat("out2", &err));
591 
592  // Nothing to do now.
593  EXPECT_EQ(0, cleaner2.CleanDead(log2.entries()));
594  EXPECT_EQ(0, cleaner2.cleaned_files_count());
595  EXPECT_EQ(0u, fs_.files_removed_.size());
596  EXPECT_NE(0, fs_.Stat("in", &err));
597  EXPECT_NE(0, fs_.Stat("out1", &err));
598  EXPECT_NE(0, fs_.Stat("out2", &err));
599  log2.Close();
600 }
601 } // anonymous namespace
const char kTestFilename[]
TEST_F(PlanTest, Basic)
Definition: build_test.cc:67
Definition: hash_map.h:26
Options (e.g. verbosity, parallelism) passed to a build.
Definition: build.h:176
Verbosity verbosity
Definition: build.h:185
Can answer questions about the manifest for the BuildLog.
Definition: build_log.h:32
Store a log of every command ran for every build.
Definition: build_log.h:45
LogEntry * LookupByOutput(const std::string &path)
Lookup a previously-run command by its output path.
Definition: build_log.cc:327
void Close()
Definition: build_log.cc:125
LoadStatus Load(const std::string &path, std::string *err)
Load the on-disk log.
Definition: build_log.cc:208
const Entries & entries() const
Definition: build_log.h:96
bool OpenForWrite(const std::string &path, const BuildLogUser &user, std::string *err)
Prepares writing to the log file without actually opening it - that will happen when/if it's needed.
Definition: build_log.cc:77
bool RecordCommand(Edge *edge, int start_time, int end_time, TimeStamp mtime=0)
Definition: build_log.cc:90
Definition: clean.h:30
A base test fixture that includes a State object with a builtin "cat" rule.
Definition: test.h:30
Global state (file status) for a single run.
Definition: state.h:95
std::vector< Edge * > edges_
All the edges of the graph.
Definition: state.h:138
StringPiece represents a slice of a string whose memory is managed externally.
Definition: string_piece.h:25
An implementation of DiskInterface that uses an in-memory representation of disk state.
Definition: test.h:51
void AssertParse(State *state, const char *input, ManifestParserOptions opts)
Definition: test.cc:100
int platformAwareUnlink(const char *filename)
Definition: util.cc:1025