09e9a71eac0363cb9a2271bf70cf5575254b6a9f
[idea/community.git] / jps / jps-builders / testSrc / org / jetbrains / ether / IncrementalTestCase.java
1 /*
2  * Copyright 2000-2012 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.jetbrains.ether;
17
18 import com.intellij.openapi.diagnostic.Logger;
19 import com.intellij.openapi.util.SystemInfo;
20 import com.intellij.openapi.util.io.FileUtil;
21 import junit.framework.TestCase;
22 import junitx.framework.FileAssert;
23 import org.apache.log4j.Level;
24 import org.apache.log4j.PropertyConfigurator;
25 import org.jetbrains.annotations.NonNls;
26 import org.jetbrains.annotations.Nullable;
27 import org.jetbrains.jps.Project;
28 import org.jetbrains.jps.api.CanceledStatus;
29 import org.jetbrains.jps.idea.IdeaProjectLoader;
30 import org.jetbrains.jps.incremental.AllProjectScope;
31 import org.jetbrains.jps.incremental.BuilderRegistry;
32 import org.jetbrains.jps.incremental.FSState;
33 import org.jetbrains.jps.incremental.IncProjectBuilder;
34 import org.jetbrains.jps.incremental.storage.BuildDataManager;
35 import org.jetbrains.jps.incremental.storage.ProjectTimestamps;
36 import org.jetbrains.jps.server.ProjectDescriptor;
37
38 import java.io.*;
39 import java.util.Properties;
40
41 /**
42  * Created by IntelliJ IDEA.
43  * User: db
44  * Date: 26.07.11
45  * Time: 0:34
46  * To change this template use File | Settings | File Templates.
47  */
48 public abstract class IncrementalTestCase extends TestCase {
49   private static class RootStripper {
50     private String root;
51
52     void setRoot(final String root) {
53       this.root = root;
54     }
55
56     String strip(final String s){
57       if (s.startsWith(root)) {
58         return s.substring(root.length());
59       }
60       
61       return s;
62     }
63   } 
64
65   static {
66     Logger.setFactory(new Logger.Factory() {
67           @Override
68           public Logger getLoggerInstance(String category) {
69             final org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(category);
70
71             final boolean affectedLogger = category.equals("#org.jetbrains.jps.incremental.java.JavaBuilder") ||
72                                            category.equals("#org.jetbrains.jps.incremental.IncProjectBuilder");
73
74             return new Logger() {
75               @Override
76               public boolean isDebugEnabled() {
77                 return affectedLogger;
78               }
79
80               @Override
81               public void debug(@NonNls String message) {
82               }
83
84               @Override
85               public void debug(@Nullable Throwable t) {
86               }
87
88               @Override
89               public void debug(@NonNls String message, @Nullable Throwable t) {
90               }
91
92               @Override
93               public void error(@NonNls String message, @Nullable Throwable t, @NonNls String... details) {
94               }
95
96               @Override
97               public void info(@NonNls String message) {
98                 if (affectedLogger) {
99                   logger.info(stripper.strip(message));
100                 }
101               }
102
103               @Override
104               public void info(@NonNls String message, @Nullable Throwable t) {
105               }
106
107               @Override
108               public void warn(@NonNls String message, @Nullable Throwable t) {
109               }
110
111               @Override
112               public void setLevel(Level level) {
113               }
114             };
115           }
116         });
117   }
118
119   private static RootStripper stripper = new RootStripper();
120   
121   private final String groupName;
122   private final String tempDir = System.getProperty("java.io.tmpdir");
123
124   private String baseDir;
125   private String workDir;
126
127   protected IncrementalTestCase(final String name) throws Exception {
128     super(name);
129     groupName = name;
130   }
131
132   @Override
133   protected void setUp() throws Exception {
134     super.setUp();
135
136     baseDir = "jps/testData" + File.separator + "incremental" + File.separator;
137
138     for (int i = 0; ; i++) {
139       final File tmp = new File(tempDir + File.separator + "__temp__" + i);
140       if (tmp.mkdir()) {
141         workDir = tmp.getPath() + File.separator;
142         break;
143       }
144     }
145
146     FileUtil.copyDir(new File(getBaseDir()), new File(getWorkDir()));
147   }
148
149   @Override
150   protected void tearDown() throws Exception {
151     super.tearDown();
152     delete(new File(workDir));
153   }
154
155   private String getDir(final String prefix) {
156     final String name = getName();
157
158     assert (name.startsWith("test"));
159
160     final String result = Character.toLowerCase(name.charAt("test".length())) + name.substring("test".length() + 1);
161
162     return prefix + groupName + File.separator + result;
163   }
164
165   private String getBaseDir() {
166     return getDir(baseDir);
167   }
168
169   private String getWorkDir() {
170     return getDir(workDir);
171   }
172
173   private static void delete(final File file) throws Exception {
174     if (file.isDirectory()) {
175       final File[] files = file.listFiles();
176
177       if (files != null) {
178         for (File f : files) {
179           delete(f);
180         }
181       }
182     }
183
184     if (!file.delete()) throw new IOException("could not delete file or directory " + file.getPath());
185   }
186   private static void copy(final File input, final File output) throws Exception {
187     if (input.isDirectory()) {
188       if (output.mkdirs()) {
189         final File[] files = input.listFiles();
190
191         if (files != null) {
192           for (File f : files) {
193             copy(f, new File(output.getPath() + File.separator + f.getName()));
194           }
195         }
196       }
197       else {
198         throw new IOException("unable to create directory " + output.getPath());
199       }
200     }
201     else if (input.isFile()) {
202       final FileReader in = new FileReader(input);
203       final FileWriter out = new FileWriter(output);
204
205       try {
206         int c;
207         while ((c = in.read()) != -1) out.write(c);
208       }
209       finally {
210         in.close();
211         out.close();
212       }
213     }
214   }
215
216   private void modify() throws Exception {
217     final File dir = new File(getBaseDir());
218     final File[] files = dir.listFiles(new FileFilter() {
219       public boolean accept(final File pathname) {
220         final String name = pathname.getName();
221
222         return name.endsWith(".java.new") || name.endsWith(".java.remove");
223       }
224     });
225
226     for (File input : files) {
227       final String name = input.getName();
228
229       final boolean copy = name.endsWith(".java.new");
230       final String postfix = name.substring(0, name.length() - (copy ? ".new" : ".remove").length());
231       final int pathSep = postfix.indexOf("$");
232       final String basename = pathSep == -1 ? postfix : postfix.substring(pathSep + 1);
233       final String path =
234         getWorkDir() + File.separator + (pathSep == -1 ? "src" : postfix.substring(0, pathSep).replace('-', File.separatorChar));
235       final File output = new File(path + File.separator + basename);
236
237       if (copy) {
238         copy(input, output);
239       }
240       else {
241         output.delete();
242       }
243     }
244   }
245
246   private void initLoggers() {
247     final Properties properties = new Properties();
248
249     properties.setProperty("log4j.rootCategory", "INFO, A1");
250     properties.setProperty("log4j.appender.A1", "org.apache.log4j.FileAppender");
251     properties.setProperty("log4j.appender.A1.file", getWorkDir() + ".log");
252     properties.setProperty("log4j.appender.A1.layout", "org.apache.log4j.PatternLayout");
253     properties.setProperty("log4j.appender.A1.layout.ConversionPattern", "%m%n");
254
255     PropertyConfigurator.configure(properties);
256   }
257
258   public void doTest() throws Exception {
259     stripper.setRoot(getWorkDir() + File.separator);
260     
261     initLoggers();
262
263     final String projectPath = getWorkDir() + File.separator + ".idea";
264     final Project project = new Project();
265
266     IdeaProjectLoader.loadFromPath(project, projectPath, "");
267
268     final ProjectDescriptor projectDescriptor =
269       new ProjectDescriptor(projectPath, project, new FSState(true), new ProjectTimestamps(projectPath),
270                             new BuildDataManager(projectPath, true));
271     final IncProjectBuilder builder = new IncProjectBuilder(projectDescriptor, BuilderRegistry.getInstance(), CanceledStatus.NULL);
272
273     builder.build(new AllProjectScope(project, true), false, true);
274
275     if (SystemInfo.isUnix) {
276       Thread.sleep(1000);
277     }
278
279     modify();
280
281     builder.build(new AllProjectScope(project, false), true, false);
282
283     projectDescriptor.release();
284
285     FileAssert.assertEquals(new File(getBaseDir() + ".log"), new File(getWorkDir() + ".log"));
286   }
287 }