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 "test.h"
19 
23  virtual void SetUp() {
25  }
26 };
27 
28 TEST_F(CleanTest, CleanAll) {
30 "build in1: cat src1\n"
31 "build out1: cat in1\n"
32 "build in2: cat src2\n"
33 "build out2: cat in2\n"));
34  fs_.Create("in1", "");
35  fs_.Create("out1", "");
36  fs_.Create("in2", "");
37  fs_.Create("out2", "");
38 
39  Cleaner cleaner(&state_, config_, &fs_);
40 
41  ASSERT_EQ(0, cleaner.cleaned_files_count());
42  EXPECT_EQ(0, cleaner.CleanAll());
43  EXPECT_EQ(4, cleaner.cleaned_files_count());
44  EXPECT_EQ(4u, fs_.files_removed_.size());
45 
46  // Check they are removed.
47  string err;
48  EXPECT_EQ(0, fs_.Stat("in1", &err));
49  EXPECT_EQ(0, fs_.Stat("out1", &err));
50  EXPECT_EQ(0, fs_.Stat("in2", &err));
51  EXPECT_EQ(0, fs_.Stat("out2", &err));
52  fs_.files_removed_.clear();
53 
54  EXPECT_EQ(0, cleaner.CleanAll());
55  EXPECT_EQ(0, cleaner.cleaned_files_count());
56  EXPECT_EQ(0u, fs_.files_removed_.size());
57 }
58 
59 TEST_F(CleanTest, CleanAllDryRun) {
61 "build in1: cat src1\n"
62 "build out1: cat in1\n"
63 "build in2: cat src2\n"
64 "build out2: cat in2\n"));
65  fs_.Create("in1", "");
66  fs_.Create("out1", "");
67  fs_.Create("in2", "");
68  fs_.Create("out2", "");
69 
70  config_.dry_run = true;
71  Cleaner cleaner(&state_, config_, &fs_);
72 
73  ASSERT_EQ(0, cleaner.cleaned_files_count());
74  EXPECT_EQ(0, cleaner.CleanAll());
75  EXPECT_EQ(4, cleaner.cleaned_files_count());
76  EXPECT_EQ(0u, fs_.files_removed_.size());
77 
78  // Check they are not removed.
79  string err;
80  EXPECT_LT(0, fs_.Stat("in1", &err));
81  EXPECT_LT(0, fs_.Stat("out1", &err));
82  EXPECT_LT(0, fs_.Stat("in2", &err));
83  EXPECT_LT(0, fs_.Stat("out2", &err));
84  fs_.files_removed_.clear();
85 
86  EXPECT_EQ(0, cleaner.CleanAll());
87  EXPECT_EQ(4, cleaner.cleaned_files_count());
88  EXPECT_EQ(0u, fs_.files_removed_.size());
89 }
90 
91 TEST_F(CleanTest, CleanTarget) {
93 "build in1: cat src1\n"
94 "build out1: cat in1\n"
95 "build in2: cat src2\n"
96 "build out2: cat in2\n"));
97  fs_.Create("in1", "");
98  fs_.Create("out1", "");
99  fs_.Create("in2", "");
100  fs_.Create("out2", "");
101 
102  Cleaner cleaner(&state_, config_, &fs_);
103 
104  ASSERT_EQ(0, cleaner.cleaned_files_count());
105  ASSERT_EQ(0, cleaner.CleanTarget("out1"));
106  EXPECT_EQ(2, cleaner.cleaned_files_count());
107  EXPECT_EQ(2u, fs_.files_removed_.size());
108 
109  // Check they are removed.
110  string err;
111  EXPECT_EQ(0, fs_.Stat("in1", &err));
112  EXPECT_EQ(0, fs_.Stat("out1", &err));
113  EXPECT_LT(0, fs_.Stat("in2", &err));
114  EXPECT_LT(0, fs_.Stat("out2", &err));
115  fs_.files_removed_.clear();
116 
117  ASSERT_EQ(0, cleaner.CleanTarget("out1"));
118  EXPECT_EQ(0, cleaner.cleaned_files_count());
119  EXPECT_EQ(0u, fs_.files_removed_.size());
120 }
121 
122 TEST_F(CleanTest, CleanTargetDryRun) {
124 "build in1: cat src1\n"
125 "build out1: cat in1\n"
126 "build in2: cat src2\n"
127 "build out2: cat in2\n"));
128  fs_.Create("in1", "");
129  fs_.Create("out1", "");
130  fs_.Create("in2", "");
131  fs_.Create("out2", "");
132 
133  config_.dry_run = true;
134  Cleaner cleaner(&state_, config_, &fs_);
135 
136  ASSERT_EQ(0, cleaner.cleaned_files_count());
137  ASSERT_EQ(0, cleaner.CleanTarget("out1"));
138  EXPECT_EQ(2, cleaner.cleaned_files_count());
139  EXPECT_EQ(0u, fs_.files_removed_.size());
140 
141  // Check they are not removed.
142  string err;
143  EXPECT_LT(0, fs_.Stat("in1", &err));
144  EXPECT_LT(0, fs_.Stat("out1", &err));
145  EXPECT_LT(0, fs_.Stat("in2", &err));
146  EXPECT_LT(0, fs_.Stat("out2", &err));
147  fs_.files_removed_.clear();
148 
149  ASSERT_EQ(0, cleaner.CleanTarget("out1"));
150  EXPECT_EQ(2, cleaner.cleaned_files_count());
151  EXPECT_EQ(0u, fs_.files_removed_.size());
152 }
153 
154 TEST_F(CleanTest, CleanRule) {
156 "rule cat_e\n"
157 " command = cat -e $in > $out\n"
158 "build in1: cat_e src1\n"
159 "build out1: cat in1\n"
160 "build in2: cat_e src2\n"
161 "build out2: cat in2\n"));
162  fs_.Create("in1", "");
163  fs_.Create("out1", "");
164  fs_.Create("in2", "");
165  fs_.Create("out2", "");
166 
167  Cleaner cleaner(&state_, config_, &fs_);
168 
169  ASSERT_EQ(0, cleaner.cleaned_files_count());
170  ASSERT_EQ(0, cleaner.CleanRule("cat_e"));
171  EXPECT_EQ(2, cleaner.cleaned_files_count());
172  EXPECT_EQ(2u, fs_.files_removed_.size());
173 
174  // Check they are removed.
175  string err;
176  EXPECT_EQ(0, fs_.Stat("in1", &err));
177  EXPECT_LT(0, fs_.Stat("out1", &err));
178  EXPECT_EQ(0, fs_.Stat("in2", &err));
179  EXPECT_LT(0, fs_.Stat("out2", &err));
180  fs_.files_removed_.clear();
181 
182  ASSERT_EQ(0, cleaner.CleanRule("cat_e"));
183  EXPECT_EQ(0, cleaner.cleaned_files_count());
184  EXPECT_EQ(0u, fs_.files_removed_.size());
185 }
186 
187 TEST_F(CleanTest, CleanRuleDryRun) {
189 "rule cat_e\n"
190 " command = cat -e $in > $out\n"
191 "build in1: cat_e src1\n"
192 "build out1: cat in1\n"
193 "build in2: cat_e src2\n"
194 "build out2: cat in2\n"));
195  fs_.Create("in1", "");
196  fs_.Create("out1", "");
197  fs_.Create("in2", "");
198  fs_.Create("out2", "");
199 
200  config_.dry_run = true;
201  Cleaner cleaner(&state_, config_, &fs_);
202 
203  ASSERT_EQ(0, cleaner.cleaned_files_count());
204  ASSERT_EQ(0, cleaner.CleanRule("cat_e"));
205  EXPECT_EQ(2, cleaner.cleaned_files_count());
206  EXPECT_EQ(0u, fs_.files_removed_.size());
207 
208  // Check they are not removed.
209  string err;
210  EXPECT_LT(0, fs_.Stat("in1", &err));
211  EXPECT_LT(0, fs_.Stat("out1", &err));
212  EXPECT_LT(0, fs_.Stat("in2", &err));
213  EXPECT_LT(0, fs_.Stat("out2", &err));
214  fs_.files_removed_.clear();
215 
216  ASSERT_EQ(0, cleaner.CleanRule("cat_e"));
217  EXPECT_EQ(2, cleaner.cleaned_files_count());
218  EXPECT_EQ(0u, fs_.files_removed_.size());
219 }
220 
221 TEST_F(CleanTest, CleanRuleGenerator) {
223 "rule regen\n"
224 " command = cat $in > $out\n"
225 " generator = 1\n"
226 "build out1: cat in1\n"
227 "build out2: regen in2\n"));
228  fs_.Create("out1", "");
229  fs_.Create("out2", "");
230 
231  Cleaner cleaner(&state_, config_, &fs_);
232  EXPECT_EQ(0, cleaner.CleanAll());
233  EXPECT_EQ(1, cleaner.cleaned_files_count());
234  EXPECT_EQ(1u, fs_.files_removed_.size());
235 
236  fs_.Create("out1", "");
237 
238  EXPECT_EQ(0, cleaner.CleanAll(/*generator=*/true));
239  EXPECT_EQ(2, cleaner.cleaned_files_count());
240  EXPECT_EQ(2u, fs_.files_removed_.size());
241 }
242 
243 TEST_F(CleanTest, CleanDepFile) {
245 "rule cc\n"
246 " command = cc $in > $out\n"
247 " depfile = $out.d\n"
248 "build out1: cc in1\n"));
249  fs_.Create("out1", "");
250  fs_.Create("out1.d", "");
251 
252  Cleaner cleaner(&state_, config_, &fs_);
253  EXPECT_EQ(0, cleaner.CleanAll());
254  EXPECT_EQ(2, cleaner.cleaned_files_count());
255  EXPECT_EQ(2u, fs_.files_removed_.size());
256 }
257 
258 TEST_F(CleanTest, CleanDepFileOnCleanTarget) {
260 "rule cc\n"
261 " command = cc $in > $out\n"
262 " depfile = $out.d\n"
263 "build out1: cc in1\n"));
264  fs_.Create("out1", "");
265  fs_.Create("out1.d", "");
266 
267  Cleaner cleaner(&state_, config_, &fs_);
268  EXPECT_EQ(0, cleaner.CleanTarget("out1"));
269  EXPECT_EQ(2, cleaner.cleaned_files_count());
270  EXPECT_EQ(2u, fs_.files_removed_.size());
271 }
272 
273 TEST_F(CleanTest, CleanDepFileOnCleanRule) {
275 "rule cc\n"
276 " command = cc $in > $out\n"
277 " depfile = $out.d\n"
278 "build out1: cc in1\n"));
279  fs_.Create("out1", "");
280  fs_.Create("out1.d", "");
281 
282  Cleaner cleaner(&state_, config_, &fs_);
283  EXPECT_EQ(0, cleaner.CleanRule("cc"));
284  EXPECT_EQ(2, cleaner.cleaned_files_count());
285  EXPECT_EQ(2u, fs_.files_removed_.size());
286 }
287 
288 TEST_F(CleanTest, CleanRspFile) {
290 "rule cc\n"
291 " command = cc $in > $out\n"
292 " rspfile = $rspfile\n"
293 " rspfile_content=$in\n"
294 "build out1: cc in1\n"
295 " rspfile = cc1.rsp\n"));
296  fs_.Create("out1", "");
297  fs_.Create("cc1.rsp", "");
298 
299  Cleaner cleaner(&state_, config_, &fs_);
300  EXPECT_EQ(0, cleaner.CleanAll());
301  EXPECT_EQ(2, cleaner.cleaned_files_count());
302  EXPECT_EQ(2u, fs_.files_removed_.size());
303 }
304 
305 TEST_F(CleanTest, CleanRsp) {
307 "rule cat_rsp \n"
308 " command = cat $rspfile > $out\n"
309 " rspfile = $rspfile\n"
310 " rspfile_content = $in\n"
311 "build in1: cat src1\n"
312 "build out1: cat in1\n"
313 "build in2: cat_rsp src2\n"
314 " rspfile=in2.rsp\n"
315 "build out2: cat_rsp in2\n"
316 " rspfile=out2.rsp\n"
317 ));
318  fs_.Create("in1", "");
319  fs_.Create("out1", "");
320  fs_.Create("in2.rsp", "");
321  fs_.Create("out2.rsp", "");
322  fs_.Create("in2", "");
323  fs_.Create("out2", "");
324 
325  Cleaner cleaner(&state_, config_, &fs_);
326  ASSERT_EQ(0, cleaner.cleaned_files_count());
327  ASSERT_EQ(0, cleaner.CleanTarget("out1"));
328  EXPECT_EQ(2, cleaner.cleaned_files_count());
329  ASSERT_EQ(0, cleaner.CleanTarget("in2"));
330  EXPECT_EQ(2, cleaner.cleaned_files_count());
331  ASSERT_EQ(0, cleaner.CleanRule("cat_rsp"));
332  EXPECT_EQ(2, cleaner.cleaned_files_count());
333 
334  EXPECT_EQ(6u, fs_.files_removed_.size());
335 
336  // Check they are removed.
337  string err;
338  EXPECT_EQ(0, fs_.Stat("in1", &err));
339  EXPECT_EQ(0, fs_.Stat("out1", &err));
340  EXPECT_EQ(0, fs_.Stat("in2", &err));
341  EXPECT_EQ(0, fs_.Stat("out2", &err));
342  EXPECT_EQ(0, fs_.Stat("in2.rsp", &err));
343  EXPECT_EQ(0, fs_.Stat("out2.rsp", &err));
344 }
345 
346 TEST_F(CleanTest, CleanFailure) {
348  "build dir: cat src1\n"));
349  fs_.MakeDir("dir");
350  Cleaner cleaner(&state_, config_, &fs_);
351  EXPECT_NE(0, cleaner.CleanAll());
352 }
353 
354 TEST_F(CleanTest, CleanPhony) {
355  string err;
357 "build phony: phony t1 t2\n"
358 "build t1: cat\n"
359 "build t2: cat\n"));
360 
361  fs_.Create("phony", "");
362  fs_.Create("t1", "");
363  fs_.Create("t2", "");
364 
365  // Check that CleanAll does not remove "phony".
366  Cleaner cleaner(&state_, config_, &fs_);
367  EXPECT_EQ(0, cleaner.CleanAll());
368  EXPECT_EQ(2, cleaner.cleaned_files_count());
369  EXPECT_LT(0, fs_.Stat("phony", &err));
370 
371  fs_.Create("t1", "");
372  fs_.Create("t2", "");
373 
374  // Check that CleanTarget does not remove "phony".
375  EXPECT_EQ(0, cleaner.CleanTarget("phony"));
376  EXPECT_EQ(2, cleaner.cleaned_files_count());
377  EXPECT_LT(0, fs_.Stat("phony", &err));
378 }
379 
380 TEST_F(CleanTest, CleanDepFileAndRspFileWithSpaces) {
382 "rule cc_dep\n"
383 " command = cc $in > $out\n"
384 " depfile = $out.d\n"
385 "rule cc_rsp\n"
386 " command = cc $in > $out\n"
387 " rspfile = $out.rsp\n"
388 " rspfile_content = $in\n"
389 "build out$ 1: cc_dep in$ 1\n"
390 "build out$ 2: cc_rsp in$ 1\n"
391 ));
392  fs_.Create("out 1", "");
393  fs_.Create("out 2", "");
394  fs_.Create("out 1.d", "");
395  fs_.Create("out 2.rsp", "");
396 
397  Cleaner cleaner(&state_, config_, &fs_);
398  EXPECT_EQ(0, cleaner.CleanAll());
399  EXPECT_EQ(4, cleaner.cleaned_files_count());
400  EXPECT_EQ(4u, fs_.files_removed_.size());
401 
402  string err;
403  EXPECT_EQ(0, fs_.Stat("out 1", &err));
404  EXPECT_EQ(0, fs_.Stat("out 2", &err));
405  EXPECT_EQ(0, fs_.Stat("out 1.d", &err));
406  EXPECT_EQ(0, fs_.Stat("out 2.rsp", &err));
407 }
An implementation of DiskInterface that uses an in-memory representation of disk state.
Definition: test.h:134
Verbosity verbosity
Definition: build.h:148
void AssertParse(State *state, const char *input, ManifestParserOptions opts)
Definition: test.cc:98
BuildConfig config_
Definition: clean_test.cc:22
A base test fixture that includes a State object with a builtin "cat" rule.
Definition: test.h:113
int CleanAll(bool generator=false)
Clean all built files, except for files created by generator rules.
Definition: clean.cc:113
int CleanRule(const Rule *rule)
Clean all the file built with the given rule rule.
Definition: clean.cc:221
#define EXPECT_EQ(a, b)
Definition: test.h:64
int cleaned_files_count() const
Definition: clean.h:66
VirtualFileSystem fs_
Definition: clean_test.cc:21
#define ASSERT_EQ(a, b)
Definition: test.h:81
TEST_F(CleanTest, CleanAll)
Definition: clean_test.cc:28
#define EXPECT_LT(a, b)
Definition: test.h:70
#define ASSERT_NO_FATAL_FAILURE(a)
Definition: test.h:97
Options (e.g. verbosity, parallelism) passed to a build.
Definition: build.h:139
virtual void SetUp()
Definition: clean_test.cc:23
#define EXPECT_NE(a, b)
Definition: test.h:66
Definition: clean.h:30
int CleanTarget(Node *target)
Clean the given target and all the file built for it.
Definition: clean.cc:156