2 * Copyright 2000-2009 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package com
.intellij
.testFramework
;
18 import com
.intellij
.ide
.util
.treeView
.AbstractTreeNode
;
19 import com
.intellij
.ide
.util
.treeView
.AbstractTreeStructure
;
20 import com
.intellij
.openapi
.application
.ApplicationManager
;
21 import com
.intellij
.openapi
.fileEditor
.FileDocumentManager
;
22 import com
.intellij
.openapi
.util
.io
.FileUtil
;
23 import com
.intellij
.openapi
.util
.text
.StringUtil
;
24 import com
.intellij
.openapi
.vfs
.LocalFileSystem
;
25 import com
.intellij
.openapi
.vfs
.VfsUtil
;
26 import com
.intellij
.openapi
.vfs
.VirtualFile
;
27 import com
.intellij
.openapi
.vfs
.VirtualFileFilter
;
28 import com
.intellij
.util
.containers
.HashMap
;
29 import com
.intellij
.util
.io
.ZipUtil
;
30 import junit
.framework
.Assert
;
31 import junit
.framework
.AssertionFailedError
;
32 import org
.jetbrains
.annotations
.NotNull
;
36 import java
.io
.FilenameFilter
;
37 import java
.io
.IOException
;
39 import java
.util
.jar
.JarFile
;
41 public class IdeaTestUtil
extends PlatformTestUtil
{
44 * Measured on dual core p4 3HZ 1gig ram
46 private static final long ETALON_TIMING
= 438;
49 public static final Comparator
<AbstractTreeNode
> DEFAULT_COMPARATOR
= new Comparator
<AbstractTreeNode
>() {
50 public int compare(AbstractTreeNode o1
, AbstractTreeNode o2
) {
51 String displayText1
= o1
.getTestPresentation();
52 String displayText2
= o2
.getTestPresentation();
53 return displayText1
.compareTo(displayText2
);
57 public static final boolean COVERAGE_ENABLED_BUILD
= "true".equals(System
.getProperty("idea.coverage.enabled.build"));
58 public static final CvsVirtualFileFilter CVS_FILE_FILTER
= new CvsVirtualFileFilter();
60 private static HashMap
<String
, VirtualFile
> buildNameToFileMap(VirtualFile
[] files
, VirtualFileFilter filter
) {
61 HashMap
<String
, VirtualFile
> map
= new HashMap
<String
, VirtualFile
>();
62 for (VirtualFile file
: files
) {
63 if (filter
!= null && !filter
.accept(file
)) continue;
64 map
.put(file
.getName(), file
);
69 public static void assertDirectoriesEqual(VirtualFile dirAfter
, VirtualFile dirBefore
, VirtualFileFilter fileFilter
) throws IOException
{
70 FileDocumentManager
.getInstance().saveAllDocuments();
71 VirtualFile
[] childrenAfter
= dirAfter
.getChildren();
72 File
[] ioAfter
= new File(dirAfter
.getPath()).listFiles();
73 shallowCompare(childrenAfter
, ioAfter
);
74 VirtualFile
[] childrenBefore
= dirBefore
.getChildren();
75 File
[] ioBefore
= new File(dirBefore
.getPath()).listFiles();
76 shallowCompare(childrenBefore
, ioBefore
);
78 HashMap
<String
, VirtualFile
> mapAfter
= buildNameToFileMap(childrenAfter
, fileFilter
);
79 HashMap
<String
, VirtualFile
> mapBefore
= buildNameToFileMap(childrenBefore
, fileFilter
);
81 Set
<String
> keySetAfter
= mapAfter
.keySet();
82 Set
<String
> keySetBefore
= mapBefore
.keySet();
83 Assert
.assertEquals(keySetAfter
, keySetBefore
);
85 for (String name
: keySetAfter
) {
86 VirtualFile fileAfter
= mapAfter
.get(name
);
87 VirtualFile fileBefore
= mapBefore
.get(name
);
88 if (fileAfter
.isDirectory()) {
89 assertDirectoriesEqual(fileAfter
, fileBefore
, fileFilter
);
92 assertFilesEqual(fileAfter
, fileBefore
);
97 private static void shallowCompare(final VirtualFile
[] vfs
, final File
[] io
) {
98 List
<String
> vfsPaths
= new ArrayList
<String
>();
99 for (VirtualFile file
: vfs
) {
100 vfsPaths
.add(file
.getPath());
103 List
<String
> ioPaths
= new ArrayList
<String
>();
104 for (File file
: io
) {
105 ioPaths
.add(file
.getPath().replace(File
.separatorChar
, '/'));
108 Assert
.assertEquals(sortAndJoin(vfsPaths
), sortAndJoin(ioPaths
));
111 private static String
sortAndJoin(List
<String
> strings
) {
112 Collections
.sort(strings
);
113 StringBuilder buf
= new StringBuilder();
114 for (String string
: strings
) {
118 return buf
.toString();
121 public static void assertFilesEqual(VirtualFile fileAfter
, VirtualFile fileBefore
) throws IOException
{
122 assertJarFilesEqual(VfsUtil
.virtualToIoFile(fileAfter
), VfsUtil
.virtualToIoFile(fileBefore
));
125 public static void assertJarFilesEqual(File file1
, File file2
) throws IOException
{
126 final JarFile jarFile1
;
127 final JarFile jarFile2
;
129 jarFile1
= new JarFile(file1
);
130 jarFile2
= new JarFile(file2
);
132 catch (IOException e
) {
133 String textAfter
= String
.valueOf(FileUtil
.loadFileText(file1
));
134 String textBefore
= String
.valueOf(FileUtil
.loadFileText(file2
));
135 textAfter
= StringUtil
.convertLineSeparators(textAfter
);
136 textBefore
= StringUtil
.convertLineSeparators(textBefore
);
137 Assert
.assertEquals(file1
.getPath(), textAfter
, textBefore
);
141 final File tempDirectory1
= IdeaTestCase
.createTempDir("tmp1");
142 final File tempDirectory2
= IdeaTestCase
.createTempDir("tmp2");
143 ZipUtil
.extract(jarFile1
, tempDirectory1
, CVS_FILE_FILTER
);
144 ZipUtil
.extract(jarFile2
, tempDirectory2
, CVS_FILE_FILTER
);
147 final VirtualFile dirAfter
= LocalFileSystem
.getInstance().refreshAndFindFileByIoFile(tempDirectory1
);
148 final VirtualFile dirBefore
= LocalFileSystem
.getInstance().refreshAndFindFileByIoFile(tempDirectory2
);
149 ApplicationManager
.getApplication().runWriteAction(new Runnable() {
151 dirAfter
.refresh(false, true);
152 dirBefore
.refresh(false, true);
155 assertDirectoriesEqual(dirAfter
, dirBefore
, CVS_FILE_FILTER
);
158 public static void assertTiming(String message
, long expected
, long actual
) {
159 if (COVERAGE_ENABLED_BUILD
) return;
160 long expectedOnMyMachine
= expected
* Timings
.MACHINE_TIMING
/ ETALON_TIMING
;
161 final double acceptableChangeFactor
= 1.1;
163 // Allow 10% more in case of test machine is busy.
164 // For faster machines (expectedOnMyMachine < expected) allow nonlinear performance rating:
165 // just perform better than acceptable expected
166 if (actual
> expectedOnMyMachine
* acceptableChangeFactor
&&
167 (expectedOnMyMachine
> expected
|| actual
> expected
* acceptableChangeFactor
)) {
168 int percentage
= (int)(((float)100 * (actual
- expectedOnMyMachine
)) / expectedOnMyMachine
);
169 Assert
.fail(message
+ ". Operation took " + percentage
+ "% longer than expected. Expected on my machine: " + expectedOnMyMachine
+
170 ". Actual: " + actual
+ ". Expected on Etalon machine: " + expected
+ "; Actual on Etalon: " +
171 (actual
* ETALON_TIMING
/ Timings
.MACHINE_TIMING
));
174 int percentage
= (int)(((float)100 * (actual
- expectedOnMyMachine
)) / expectedOnMyMachine
);
175 System
.out
.println(message
+ ". Operation took " + percentage
+ "% longer than expected. Expected on my machine: " +
176 expectedOnMyMachine
+ ". Actual: " + actual
+ ". Expected on Etalon machine: " + expected
+
177 "; Actual on Etalon: " + (actual
* ETALON_TIMING
/ Timings
.MACHINE_TIMING
));
181 public static void assertTiming(String message
, long expected
, @NotNull Runnable actionToMeasure
) {
182 assertTiming(message
, expected
, 4, actionToMeasure
);
185 public static void assertTiming(String message
, long expected
, int attempts
, @NotNull Runnable actionToMeasure
) {
188 long start
= System
.currentTimeMillis();
189 actionToMeasure
.run();
190 long finish
= System
.currentTimeMillis();
192 assertTiming(message
, expected
, finish
- start
);
195 catch (AssertionFailedError e
) {
196 if (attempts
== 0) throw e
;
204 public static void main(String
[] args
) {
205 printDetectedPerformanceTimings();
208 public static void printDetectedPerformanceTimings() {
209 System
.out
.println("Etalon timing: " + ETALON_TIMING
);
210 System
.out
.println("This machine timing: " + Timings
.MACHINE_TIMING
);
213 public static class CvsVirtualFileFilter
implements VirtualFileFilter
, FilenameFilter
{
214 public boolean accept(VirtualFile file
) {
215 return !file
.isDirectory() || !"CVS".equals(file
.getName());
218 public boolean accept(File dir
, String name
) {
219 return name
.indexOf("CVS") == -1;