34 virtual void SetUp() {
39 TEST_F(CleanTest, CleanAll) {
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",
"");
50 Cleaner cleaner(&state_, config_, &fs_);
52 ASSERT_EQ(0, cleaner.cleaned_files_count());
54 EXPECT_EQ(4, cleaner.cleaned_files_count());
63 fs_.files_removed_.clear();
66 EXPECT_EQ(0, cleaner.cleaned_files_count());
70 TEST_F(CleanTest, CleanAllDryRun) {
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",
"");
81 config_.dry_run =
true;
82 Cleaner cleaner(&state_, config_, &fs_);
84 ASSERT_EQ(0, cleaner.cleaned_files_count());
86 EXPECT_EQ(4, cleaner.cleaned_files_count());
95 fs_.files_removed_.clear();
98 EXPECT_EQ(4, cleaner.cleaned_files_count());
102 TEST_F(CleanTest, CleanTarget) {
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",
"");
113 Cleaner cleaner(&state_, config_, &fs_);
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());
126 fs_.files_removed_.clear();
128 ASSERT_EQ(0, cleaner.CleanTarget(
"out1"));
129 EXPECT_EQ(0, cleaner.cleaned_files_count());
130 EXPECT_EQ(0u, fs_.files_removed_.size());
133 TEST_F(CleanTest, CleanTargetDryRun) {
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",
"");
144 config_.dry_run =
true;
145 Cleaner cleaner(&state_, config_, &fs_);
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());
158 fs_.files_removed_.clear();
160 ASSERT_EQ(0, cleaner.CleanTarget(
"out1"));
161 EXPECT_EQ(2, cleaner.cleaned_files_count());
162 EXPECT_EQ(0u, fs_.files_removed_.size());
165 TEST_F(CleanTest, CleanRule) {
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",
"");
178 Cleaner cleaner(&state_, config_, &fs_);
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());
191 fs_.files_removed_.clear();
193 ASSERT_EQ(0, cleaner.CleanRule(
"cat_e"));
194 EXPECT_EQ(0, cleaner.cleaned_files_count());
195 EXPECT_EQ(0u, fs_.files_removed_.size());
198 TEST_F(CleanTest, CleanRuleDryRun) {
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",
"");
211 config_.dry_run =
true;
212 Cleaner cleaner(&state_, config_, &fs_);
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());
225 fs_.files_removed_.clear();
227 ASSERT_EQ(0, cleaner.CleanRule(
"cat_e"));
228 EXPECT_EQ(2, cleaner.cleaned_files_count());
229 EXPECT_EQ(0u, fs_.files_removed_.size());
232 TEST_F(CleanTest, CleanRuleGenerator) {
235 " command = cat $in > $out\n" 237 "build out1: cat in1\n" 238 "build out2: regen in2\n"));
239 fs_.Create(
"out1",
"");
240 fs_.Create(
"out2",
"");
242 Cleaner cleaner(&state_, config_, &fs_);
244 EXPECT_EQ(1, cleaner.cleaned_files_count());
245 EXPECT_EQ(1u, fs_.files_removed_.size());
247 fs_.Create(
"out1",
"");
250 EXPECT_EQ(2, cleaner.cleaned_files_count());
251 EXPECT_EQ(2u, fs_.files_removed_.size());
254 TEST_F(CleanTest, CleanDepFile) {
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",
"");
263 Cleaner cleaner(&state_, config_, &fs_);
265 EXPECT_EQ(2, cleaner.cleaned_files_count());
266 EXPECT_EQ(2u, fs_.files_removed_.size());
269 TEST_F(CleanTest, CleanDepFileOnCleanTarget) {
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",
"");
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());
284 TEST_F(CleanTest, CleanDepFileOnCleanRule) {
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",
"");
293 Cleaner cleaner(&state_, config_, &fs_);
295 EXPECT_EQ(2, cleaner.cleaned_files_count());
296 EXPECT_EQ(2u, fs_.files_removed_.size());
299 TEST_F(CleanTest, CleanDyndep) {
303 "build out: cat in || dd\n" 306 fs_.Create(
"in",
"");
308 "ninja_dyndep_version = 1\n" 309 "build out | out.imp: dyndep\n" 311 fs_.Create(
"out",
"");
312 fs_.Create(
"out.imp",
"");
314 Cleaner cleaner(&state_, config_, &fs_);
316 ASSERT_EQ(0, cleaner.cleaned_files_count());
318 EXPECT_EQ(2, cleaner.cleaned_files_count());
319 EXPECT_EQ(2u, fs_.files_removed_.size());
326 TEST_F(CleanTest, CleanDyndepMissing) {
329 "build out: cat in || dd\n" 332 fs_.Create(
"in",
"");
333 fs_.Create(
"out",
"");
334 fs_.Create(
"out.imp",
"");
336 Cleaner cleaner(&state_, config_, &fs_);
338 ASSERT_EQ(0, cleaner.cleaned_files_count());
340 EXPECT_EQ(1, cleaner.cleaned_files_count());
341 EXPECT_EQ(1u, fs_.files_removed_.size());
348 TEST_F(CleanTest, CleanRspFile) {
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",
"");
359 Cleaner cleaner(&state_, config_, &fs_);
361 EXPECT_EQ(2, cleaner.cleaned_files_count());
362 EXPECT_EQ(2u, fs_.files_removed_.size());
365 TEST_F(CleanTest, CleanRsp) {
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" 375 "build out2: cat_rsp in2\n" 376 " rspfile=out2.rsp\n" 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",
"");
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());
394 EXPECT_EQ(6u, fs_.files_removed_.size());
403 EXPECT_EQ(0, fs_.Stat(
"out2.rsp", &err));
406 TEST_F(CleanTest, CleanFailure) {
408 "build dir: cat src1\n"));
410 Cleaner cleaner(&state_, config_, &fs_);
414 TEST_F(CleanTest, CleanPhony) {
417 "build phony: phony t1 t2\n" 421 fs_.Create(
"phony",
"");
422 fs_.Create(
"t1",
"");
423 fs_.Create(
"t2",
"");
426 Cleaner cleaner(&state_, config_, &fs_);
428 EXPECT_EQ(2, cleaner.cleaned_files_count());
431 fs_.Create(
"t1",
"");
432 fs_.Create(
"t2",
"");
435 EXPECT_EQ(0, cleaner.CleanTarget(
"phony"));
436 EXPECT_EQ(2, cleaner.cleaned_files_count());
440 TEST_F(CleanTest, CleanDepFileAndRspFileWithSpaces) {
443 " command = cc $in > $out\n" 444 " depfile = $out.d\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" 452 fs_.Create(
"out 1",
"");
453 fs_.Create(
"out 2",
"");
454 fs_.Create(
"out 1.d",
"");
455 fs_.Create(
"out 2.rsp",
"");
457 Cleaner cleaner(&state_, config_, &fs_);
459 EXPECT_EQ(4, cleaner.cleaned_files_count());
460 EXPECT_EQ(4u, fs_.files_removed_.size());
466 EXPECT_EQ(0, fs_.Stat(
"out 2.rsp", &err));
469 struct CleanDeadTest :
public CleanTest,
public BuildLogUser{
470 virtual void SetUp() {
475 virtual void TearDown() {
478 virtual bool IsPathDead(
StringPiece)
const {
return false; }
481 TEST_F(CleanDeadTest, CleanDead) {
485 " command = cat $in > $out\n" 486 "build out1: cat in\n" 487 "build out2: cat in\n" 490 "build out2: cat in\n" 492 fs_.Create(
"in",
"");
493 fs_.Create(
"out1",
"");
494 fs_.Create(
"out2",
"");
512 Cleaner cleaner1(&state, config_, &fs_);
514 EXPECT_EQ(0, cleaner1.cleaned_files_count());
515 EXPECT_EQ(0u, fs_.files_removed_.size());
521 Cleaner cleaner2(&state_, config_, &fs_);
523 EXPECT_EQ(1, cleaner2.cleaned_files_count());
524 EXPECT_EQ(1u, fs_.files_removed_.size());
525 EXPECT_EQ(
"out1", *(fs_.files_removed_.begin()));
532 EXPECT_EQ(0, cleaner2.cleaned_files_count());
533 EXPECT_EQ(1u, fs_.files_removed_.size());
534 EXPECT_EQ(
"out1", *(fs_.files_removed_.begin()));
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...
An implementation of DiskInterface that uses an in-memory representation of disk state.
const Entries & entries() const
LoadStatus Load(const std::string &path, std::string *err)
Load the on-disk log.
void AssertParse(State *state, const char *input, ManifestParserOptions opts)
bool RecordCommand(Edge *edge, int start_time, int end_time, TimeStamp mtime=0)
StringPiece represents a slice of a string whose memory is managed externally.
Store a log of every command ran for every build.
A base test fixture that includes a State object with a builtin "cat" rule.
const char kTestFilename[]
#define ASSERT_NO_FATAL_FAILURE(a)
Options (e.g. verbosity, parallelism) passed to a build.
Global state (file status) for a single run.
LogEntry * LookupByOutput(const std::string &path)
Lookup a previously-run command by its output path.
std::vector< Edge * > edges_
All the edges of the graph.
Can answer questions about the manifest for the BuildLog.