Imported Upstream version 1.7.1
[platform/upstream/ninja.git] / src / clean_test.cc
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
20 struct CleanTest : public StateTestWithBuiltinRules {
21   VirtualFileSystem fs_;
22   BuildConfig config_;
23   virtual void SetUp() {
24     config_.verbosity = BuildConfig::QUIET;
25   }
26 };
27
28 TEST_F(CleanTest, CleanAll) {
29   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
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) {
60   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
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) {
92   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
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) {
123   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
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) {
155   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
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) {
188   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
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) {
222   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
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) {
244   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
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) {
259   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
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) {
274   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
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) {
289   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
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) {
306   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
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) {
347   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
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;
356   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
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) {
381   ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
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 }