Added
Link Here
|
1 |
/******************************************************************************* |
2 |
* Copyright (c) 2000, 2005 IBM Corporation and others. |
3 |
* All rights reserved. This program and the accompanying materials |
4 |
* are made available under the terms of the Eclipse Public License v1.0 |
5 |
* which accompanies this distribution, and is available at |
6 |
* http://www.eclipse.org/legal/epl-v10.html |
7 |
* |
8 |
* Contributors: |
9 |
* IBM Corporation - initial API and implementation |
10 |
*******************************************************************************/ |
11 |
package org.eclipse.jdt.core.tests.performance; |
12 |
|
13 |
import java.io.ByteArrayInputStream; |
14 |
import java.io.PrintStream; |
15 |
import java.util.ArrayList; |
16 |
import java.util.HashMap; |
17 |
import java.util.Map; |
18 |
|
19 |
import junit.framework.*; |
20 |
|
21 |
import org.eclipse.core.resources.IContainer; |
22 |
import org.eclipse.core.resources.IFile; |
23 |
import org.eclipse.core.resources.IFolder; |
24 |
import org.eclipse.core.resources.IProject; |
25 |
import org.eclipse.core.resources.IWorkspace; |
26 |
import org.eclipse.core.resources.IWorkspaceRoot; |
27 |
import org.eclipse.core.resources.IWorkspaceRunnable; |
28 |
import org.eclipse.core.resources.ResourcesPlugin; |
29 |
import org.eclipse.core.runtime.*; |
30 |
import org.eclipse.jdt.core.*; |
31 |
import org.eclipse.jdt.core.search.*; |
32 |
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; |
33 |
import org.eclipse.jdt.internal.core.IJavaElementRequestor; |
34 |
import org.eclipse.jdt.internal.core.JavaElement; |
35 |
import org.eclipse.jdt.internal.core.JavaProject; |
36 |
import org.eclipse.jdt.internal.core.NameLookup; |
37 |
|
38 |
/** |
39 |
*/ |
40 |
public class FullSourceWorkspaceModelTests extends FullSourceWorkspaceTests implements IJavaSearchConstants { |
41 |
|
42 |
// Tests counters |
43 |
private static int TESTS_COUNT = 0; |
44 |
private final static int ITERATIONS_COUNT = 200; |
45 |
private final static int LINUX_FOLDERS_COUNT = 200; |
46 |
private final static int FOLDERS_COUNT = 100; |
47 |
private final static int LINUX_PACKAGES_COUNT = 200; |
48 |
private final static int PACKAGES_COUNT = 20; |
49 |
|
50 |
// Log file streams |
51 |
private static PrintStream[] LOG_STREAMS = new PrintStream[LOG_TYPES.length]; |
52 |
|
53 |
// Search variables |
54 |
IJavaSearchScope scope; |
55 |
protected JavaSearchResultCollector resultCollector; |
56 |
|
57 |
// Type path |
58 |
static IPath BIG_PROJECT_TYPE_PATH; |
59 |
|
60 |
/** |
61 |
* @param name |
62 |
*/ |
63 |
public FullSourceWorkspaceModelTests(String name) { |
64 |
super(name); |
65 |
} |
66 |
|
67 |
static { |
68 |
// org.eclipse.jdt.internal.core.NameLookup.VERBOSE = true; |
69 |
// TESTS_NAMES = new String[] { "testPerfSeekPackageFragments" }; |
70 |
} |
71 |
public static Test suite() { |
72 |
Test suite = buildSuite(testClass()); |
73 |
TESTS_COUNT = suite.countTestCases(); |
74 |
createPrintStream(testClass().getName(), LOG_STREAMS, TESTS_COUNT, null); |
75 |
return suite; |
76 |
} |
77 |
|
78 |
private static Class testClass() { |
79 |
return FullSourceWorkspaceModelTests.class; |
80 |
} |
81 |
|
82 |
protected void setUp() throws Exception { |
83 |
super.setUp(); |
84 |
this.resultCollector = new JavaSearchResultCollector(); |
85 |
this.scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { JDT_CORE_PROJECT }); |
86 |
if (BIG_PROJECT == null) { |
87 |
setUpBigProject(); |
88 |
} |
89 |
} |
90 |
private void setUpBigProject() throws CoreException { |
91 |
try { |
92 |
IWorkspace workspace = ResourcesPlugin.getWorkspace(); |
93 |
IWorkspaceRoot workspaceRoot = workspace.getRoot(); |
94 |
long start = System.currentTimeMillis(); |
95 |
boolean linux = "linux".equals(System.getProperty("osgi.os", "?")); |
96 |
// setup projects with several source folders and several packages per source folder |
97 |
final int rootLength = linux ? LINUX_FOLDERS_COUNT : FOLDERS_COUNT; |
98 |
final String[] sourceFolders = new String[rootLength]; |
99 |
for (int i = 0; i < rootLength; i++) { |
100 |
sourceFolders[i] = "src" + i; |
101 |
} |
102 |
String path = workspaceRoot.getLocation().toString() + "/BigProject/src"; |
103 |
int packLength = linux ? LINUX_PACKAGES_COUNT : PACKAGES_COUNT; |
104 |
for (int i = 0; i < rootLength; i++) { |
105 |
for (int j = 0; j < packLength; j++) { |
106 |
new java.io.File(path + i + "/org/eclipse/jdt/core/tests" + i + "/performance" + j).mkdirs(); |
107 |
} |
108 |
} |
109 |
ENV.addProject(BIG_PROJECT_NAME); |
110 |
BIG_PROJECT = (JavaProject) createJavaProject("BigProject", sourceFolders, "bin", "1.4"); |
111 |
if (DEBUG) { |
112 |
System.out.println("Time to create big project = "+(System.currentTimeMillis()-start)); |
113 |
} |
114 |
BIG_PROJECT_TYPE_PATH = new Path("/BigProject/src" + (rootLength-1) + "/org/eclipse/jdt/core/tests" + (rootLength-1) + "/performance" + (packLength-1) + "/TestBigProject.java"); |
115 |
IFile file = workspaceRoot.getFile(BIG_PROJECT_TYPE_PATH); |
116 |
String content = "package org.eclipse.jdt.core.tests" + (rootLength-1) + ".performance" + (packLength-1) + ";\n" + |
117 |
"public class TestBigProject {}\n"; |
118 |
file.create(new ByteArrayInputStream(content.getBytes()), true, null); |
119 |
} finally { |
120 |
// do not delete project |
121 |
} |
122 |
|
123 |
} |
124 |
/* (non-Javadoc) |
125 |
* @see junit.framework.TestCase#tearDown() |
126 |
*/ |
127 |
protected void tearDown() throws Exception { |
128 |
|
129 |
// End of execution => one test less |
130 |
TESTS_COUNT--; |
131 |
|
132 |
// Log perf result |
133 |
if (LOG_DIR != null) { |
134 |
logPerfResult(LOG_STREAMS, TESTS_COUNT); |
135 |
} |
136 |
|
137 |
// Print statistics |
138 |
if (TESTS_COUNT == 0) { |
139 |
// System.out.println("-------------------------------------"); |
140 |
// System.out.println("Search performance test statistics:"); |
141 |
// NumberFormat intFormat = NumberFormat.getIntegerInstance(); |
142 |
// System.out.println(" - "+intFormat.format(REFERENCES[0])+" type references found."); |
143 |
// System.out.println(" - "+intFormat.format(REFERENCES[1])+" field references found."); |
144 |
// System.out.println(" - "+intFormat.format(REFERENCES[2])+" method references found."); |
145 |
// System.out.println(" - "+intFormat.format(REFERENCES[3])+" constructor references found."); |
146 |
// System.out.println(" - "+intFormat.format(ALL_TYPES_NAMES)+" all types names."); |
147 |
// System.out.println("-------------------------------------\n"); |
148 |
} |
149 |
super.tearDown(); |
150 |
} |
151 |
/** |
152 |
* Simple search result collector: only count matches. |
153 |
*/ |
154 |
class JavaSearchResultCollector extends SearchRequestor { |
155 |
int count = 0; |
156 |
public void acceptSearchMatch(SearchMatch match) throws CoreException { |
157 |
this.count++; |
158 |
} |
159 |
} |
160 |
|
161 |
protected void search(String patternString, int searchFor, int limitTo) throws CoreException { |
162 |
int matchMode = patternString.indexOf('*') != -1 || patternString.indexOf('?') != -1 |
163 |
? SearchPattern.R_PATTERN_MATCH |
164 |
: SearchPattern.R_EXACT_MATCH; |
165 |
SearchPattern pattern = SearchPattern.createPattern( |
166 |
patternString, |
167 |
searchFor, |
168 |
limitTo, |
169 |
matchMode | SearchPattern.R_CASE_SENSITIVE); |
170 |
new SearchEngine().search( |
171 |
pattern, |
172 |
new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}, |
173 |
this.scope, |
174 |
this.resultCollector, |
175 |
null); |
176 |
} |
177 |
|
178 |
/** |
179 |
* @see org.eclipse.jdt.core.tests.model.AbstractJavaModelTests#assertElementEquals(String, String, IJavaElement) |
180 |
*/ |
181 |
protected void assertElementEquals(String message, String expected, IJavaElement element) { |
182 |
String actual = element == null ? "<null>" : ((JavaElement) element).toStringWithAncestors(false/*don't show key*/); |
183 |
if (!expected.equals(actual)) { |
184 |
System.out.println(getName()+" actual result is:"); |
185 |
System.out.println(actual + ','); |
186 |
} |
187 |
assertEquals(message, expected, actual); |
188 |
} |
189 |
/** |
190 |
* @see org.eclipse.jdt.core.tests.model.AbstractJavaModelTests#assertElementsEqual(String, String, IJavaElement[]) |
191 |
*/ |
192 |
protected void assertElementsEqual(String message, String expected, IJavaElement[] elements) { |
193 |
assertElementsEqual(message, expected, elements, false/*don't show key*/); |
194 |
} |
195 |
/** |
196 |
* @see org.eclipse.jdt.core.tests.model.AbstractJavaModelTests#assertElementsEqual(String, String, IJavaElement[], boolean) |
197 |
*/ |
198 |
protected void assertElementsEqual(String message, String expected, IJavaElement[] elements, boolean showResolvedInfo) { |
199 |
StringBuffer buffer = new StringBuffer(); |
200 |
if (elements != null) { |
201 |
for (int i = 0, length = elements.length; i < length; i++){ |
202 |
JavaElement element = (JavaElement)elements[i]; |
203 |
if (element == null) { |
204 |
buffer.append("<null>"); |
205 |
} else { |
206 |
buffer.append(element.toStringWithAncestors(showResolvedInfo)); |
207 |
} |
208 |
if (i != length-1) buffer.append("\n"); |
209 |
} |
210 |
} else { |
211 |
buffer.append("<null>"); |
212 |
} |
213 |
String actual = buffer.toString(); |
214 |
if (!expected.equals(actual)) { |
215 |
System.out.println(getName()+" actual result is:"); |
216 |
System.out.println(actual + ','); |
217 |
} |
218 |
assertEquals(message, expected, actual); |
219 |
} |
220 |
|
221 |
/** |
222 |
* Clean last category table cache |
223 |
* @param type Tells whether previous search was a type search or not |
224 |
*/ |
225 |
protected void cleanCategoryTableCache(boolean type) throws CoreException { |
226 |
long time = System.currentTimeMillis(); |
227 |
if (type) { |
228 |
search("foo", FIELD, DECLARATIONS); |
229 |
} else { |
230 |
search("Foo", TYPE, DECLARATIONS); |
231 |
} |
232 |
// if (DEBUG) System.out.println("Time to clean category table cache: "+(System.currentTimeMillis()-time)); |
233 |
} |
234 |
|
235 |
/** |
236 |
* @see org.eclipse.jdt.core.tests.model.AbstractJavaModelTests#createJavaProject(String, String[], String[], String[][], String[][], String[], String[][], String[][], boolean[], String, String[], String[][], String[][], String) |
237 |
*/ |
238 |
protected IJavaProject createJavaProject(final String projectName, final String[] sourceFolders, final String projectOutput, final String compliance) throws CoreException { |
239 |
final IJavaProject[] result = new IJavaProject[1]; |
240 |
IWorkspaceRunnable create = new IWorkspaceRunnable() { |
241 |
public void run(IProgressMonitor monitor) throws CoreException { |
242 |
|
243 |
// create classpath entries |
244 |
IProject project = ENV.getProject(projectName); |
245 |
IPath projectPath = project.getFullPath(); |
246 |
int sourceLength = sourceFolders == null ? 0 : sourceFolders.length; |
247 |
IClasspathEntry[] entries = new IClasspathEntry[sourceLength]; |
248 |
for (int i= 0; i < sourceLength; i++) { |
249 |
IPath sourcePath = new Path(sourceFolders[i]); |
250 |
int segmentCount = sourcePath.segmentCount(); |
251 |
if (segmentCount > 0) { |
252 |
// create folder and its parents |
253 |
IContainer container = project; |
254 |
for (int j = 0; j < segmentCount; j++) { |
255 |
IFolder folder = container.getFolder(new Path(sourcePath.segment(j))); |
256 |
if (!folder.exists()) { |
257 |
folder.create(true, true, null); |
258 |
} |
259 |
container = folder; |
260 |
} |
261 |
} |
262 |
// create source entry |
263 |
entries[i] = |
264 |
JavaCore.newSourceEntry( |
265 |
projectPath.append(sourcePath), |
266 |
new IPath[0], |
267 |
new IPath[0], |
268 |
null |
269 |
); |
270 |
} |
271 |
|
272 |
// create project's output folder |
273 |
IPath outputPath = new Path(projectOutput); |
274 |
if (outputPath.segmentCount() > 0) { |
275 |
IFolder output = project.getFolder(outputPath); |
276 |
if (!output.exists()) { |
277 |
output.create(true, true, null); |
278 |
} |
279 |
} |
280 |
|
281 |
// set classpath and output location |
282 |
IJavaProject javaProject = ENV.getJavaProject(projectName); |
283 |
javaProject.setRawClasspath(entries, projectPath.append(outputPath), null); |
284 |
|
285 |
// set compliance level options |
286 |
if ("1.5".equals(compliance)) { |
287 |
Map options = new HashMap(); |
288 |
options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5); |
289 |
options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5); |
290 |
options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5); |
291 |
javaProject.setOptions(options); |
292 |
} |
293 |
|
294 |
result[0] = javaProject; |
295 |
} |
296 |
}; |
297 |
ResourcesPlugin.getWorkspace().run(create, null); |
298 |
return result[0]; |
299 |
} |
300 |
private NameLookup getNameLookup(JavaProject project) throws JavaModelException { |
301 |
return project.newNameLookup((WorkingCopyOwner)null); |
302 |
} |
303 |
|
304 |
/** |
305 |
* Performance tests for model: Find Unknown type. |
306 |
* |
307 |
* First wait that already started indexing jobs end before perform test. |
308 |
* Perform one search before measure performance for warm-up. |
309 |
*/ |
310 |
public void testProjectFindType() throws CoreException { |
311 |
tagAsSummary("Model>Find Type", true); // put in fingerprint |
312 |
|
313 |
// Wait for indexing end |
314 |
waitUntilIndexesReady(); |
315 |
|
316 |
// Warm up |
317 |
String fullQualifiedName = BIG_PROJECT_TYPE_PATH.removeFileExtension().removeFirstSegments(2).toString(); |
318 |
fullQualifiedName = fullQualifiedName.replace('/', '.'); |
319 |
IType type = BIG_PROJECT.findType(fullQualifiedName); |
320 |
assertNotNull("We should find "+BIG_PROJECT_NAME+" type!", type); |
321 |
|
322 |
// Clean memory |
323 |
runGc(); |
324 |
|
325 |
// Measures |
326 |
int iterations = 30; |
327 |
for (int i=0; i<MEASURES_COUNT; i++) { |
328 |
cleanCategoryTableCache(true); |
329 |
startMeasuring(); |
330 |
for (int n=0; n<iterations; n++) { |
331 |
type = BIG_PROJECT.findType(fullQualifiedName); |
332 |
} |
333 |
stopMeasuring(); |
334 |
assertNotNull("We should find "+BIG_PROJECT_NAME+" type!", type); |
335 |
} |
336 |
|
337 |
// Commit |
338 |
commitMeasurements(); |
339 |
assertPerformance(); |
340 |
} |
341 |
|
342 |
/** |
343 |
* Performance tests for model: Find Unknown type. |
344 |
* |
345 |
* First wait that already started indexing jobs end before perform test. |
346 |
* Perform one search before measure performance for warm-up. |
347 |
*/ |
348 |
public void testProjectFindUnknownType() throws CoreException { |
349 |
tagAsSummary("Model>Find Unknown Type", true); // put in fingerprint |
350 |
|
351 |
// Wait for indexing end |
352 |
waitUntilIndexesReady(); |
353 |
|
354 |
// Warm up20 |
355 |
IType type = BIG_PROJECT.findType("org.eclipse.jdt.core.tests10.performance10.Unknown"); |
356 |
assertNull("We should not find an unknown type!", type); |
357 |
|
358 |
// Clean memory |
359 |
runGc(); |
360 |
|
361 |
// Measures |
362 |
int iterations = 10; |
363 |
for (int i=0; i<MEASURES_COUNT; i++) { |
364 |
cleanCategoryTableCache(true); |
365 |
startMeasuring(); |
366 |
for (int n=0; n<iterations; n++) { |
367 |
type = BIG_PROJECT.findType("org.eclipse.jdt.core.tests10.performance10.Unknown"); |
368 |
} |
369 |
stopMeasuring(); |
370 |
assertNull("We should not find an unknown type!", type); |
371 |
} |
372 |
|
373 |
// Commit |
374 |
commitMeasurements(); |
375 |
assertPerformance(); |
376 |
} |
377 |
|
378 |
/* |
379 |
* Performance test for looking up package fragments |
380 |
* (see bug 72683 Slow code assist in Display view) |
381 |
*/ |
382 |
public void testPerfSeekPackageFragments() throws CoreException { |
383 |
assertNotNull("We should have the 'BigProject' in workspace!", BIG_PROJECT); |
384 |
class PackageRequestor implements IJavaElementRequestor { |
385 |
ArrayList pkgs = new ArrayList(); |
386 |
public void acceptField(IField field) {} |
387 |
public void acceptInitializer(IInitializer initializer) {} |
388 |
public void acceptMemberType(IType type) {} |
389 |
public void acceptMethod(IMethod method) {} |
390 |
public void acceptPackageFragment(IPackageFragment packageFragment) { |
391 |
if (pkgs != null) |
392 |
pkgs.add(packageFragment); |
393 |
} |
394 |
public void acceptType(IType type) {} |
395 |
public boolean isCanceled() { |
396 |
return false; |
397 |
} |
398 |
} |
399 |
|
400 |
// first pass: ensure all class are loaded, and ensure that the test works as expected |
401 |
PackageRequestor requestor = new PackageRequestor(); |
402 |
getNameLookup(BIG_PROJECT).seekPackageFragments("org.eclipse.jdt.core.tests78.performance5", false/*not partial match*/, requestor); |
403 |
int size = requestor.pkgs.size(); |
404 |
IJavaElement[] result = new IJavaElement[size]; |
405 |
requestor.pkgs.toArray(result); |
406 |
assertElementsEqual( |
407 |
"Unexpected packages", |
408 |
"org.eclipse.jdt.core.tests78.performance5 [in src78 [in "+BIG_PROJECT_NAME+"]]", |
409 |
result |
410 |
); |
411 |
|
412 |
// measure performance |
413 |
requestor.pkgs = null; |
414 |
for (int i = 0; i < MEASURES_COUNT; i++) { |
415 |
int iterations = 30; |
416 |
startMeasuring(); |
417 |
for (int j = 0; j < iterations; j++) { |
418 |
getNameLookup(BIG_PROJECT).seekPackageFragments("org.eclipse.jdt.core.tests" + j + "0.performance" + j, false/*not partial match*/, requestor); |
419 |
} |
420 |
stopMeasuring(); |
421 |
} |
422 |
commitMeasurements(); |
423 |
assertPerformance(); |
424 |
} |
425 |
} |