Bug 90815 - performance tests failing consistently (hopefully final fix)
diff --git a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/content/NaySayerContentDescriber.java b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/content/NaySayerContentDescriber.java index 910d3a0..8c1569d 100644 --- a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/content/NaySayerContentDescriber.java +++ b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/content/NaySayerContentDescriber.java
@@ -10,10 +10,10 @@ *******************************************************************************/ package org.eclipse.core.tests.runtime.content; -import java.io.InputStream; +import java.io.*; import org.eclipse.core.runtime.QualifiedName; -import org.eclipse.core.runtime.content.IContentDescriber; import org.eclipse.core.runtime.content.IContentDescription; +import org.eclipse.core.runtime.content.ITextContentDescriber; /** * A content describer that always rejects its input. @@ -21,9 +21,19 @@ * for name-based content type matching should not interfere with tests * that do content-based content type matching. */ -public class NaySayerContentDescriber implements IContentDescriber { +public class NaySayerContentDescriber implements ITextContentDescriber { - public int describe(InputStream contents, IContentDescription description) { + public int describe(InputStream contents, IContentDescription description) throws IOException { + for (int i = 0;contents.read() != -1 && i < 2048; i++) { + // read some data so performance tests are more reallistic + } + return INVALID; + } + + public int describe(Reader contents, IContentDescription description) throws IOException { + for (int i = 0;contents.read() != -1 && i < 2048; i++) { + // read some data so performance tests are more reallistic + } return INVALID; }
diff --git a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/perf/ContentTypePerformanceTest.java b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/perf/ContentTypePerformanceTest.java index 22aa684..96604c7 100644 --- a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/perf/ContentTypePerformanceTest.java +++ b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/perf/ContentTypePerformanceTest.java
@@ -19,13 +19,11 @@ import org.eclipse.core.internal.content.ContentTypeBuilder; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.content.IContentType; -import org.eclipse.core.runtime.content.IContentTypeManager; +import org.eclipse.core.runtime.content.*; import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.core.tests.harness.BundleTestingHelper; import org.eclipse.core.tests.harness.PerformanceTestRunner; import org.eclipse.core.tests.runtime.*; -import org.eclipse.core.tests.runtime.content.NaySayerContentDescriber; import org.eclipse.core.tests.session.PerformanceSessionTestSuite; import org.eclipse.core.tests.session.SessionTestSuite; import org.osgi.framework.Bundle; @@ -34,20 +32,39 @@ public class ContentTypePerformanceTest extends RuntimeTest { private final static String CONTENT_TYPE_PREF_NODE = Platform.PI_RUNTIME + IPath.SEPARATOR + "content-types"; //$NON-NLS-1$ - private static final int ELEMENTS_PER_LEVEL = 2; - private static final int NUMBER_OF_LEVELS = 10; - private static final int NUMBER_OF_ELEMENTS = computeTotalTypes(NUMBER_OF_LEVELS, ELEMENTS_PER_LEVEL); - + private static final String DEFAULT_NAME = "file_" + ContentTypePerformanceTest.class.getName(); + private static final int ELEMENTS_PER_LEVEL = 4; + private static final int NUMBER_OF_LEVELS = 4; private static final String TEST_DATA_ID = "org.eclipse.core.tests.runtime.contenttype.perf.testdata"; + private static final int TOTAL_NUMBER_OF_ELEMENTS = computeTotalTypes(NUMBER_OF_LEVELS, ELEMENTS_PER_LEVEL); private static int computeTotalTypes(int levels, int elementsPerLevel) { double sum = 0; - for (int i = 1; i <= levels; i++) + for (int i = 0; i <= levels; i++) sum += Math.pow(elementsPerLevel, i); return (int) sum; } - private static String createContentType(String id, String baseTypeId, String[] fileNames, String[] fileExtensions, String describer) { + private static String createContentType(Writer writer, int number, String baseTypeId) throws IOException { + String id = "performance" + number; + String definition = generateContentType(number, id, baseTypeId, new String[] {DEFAULT_NAME}, null); + writer.write(definition); + writer.write(System.getProperty("line.separator")); + return id; + } + + public static int createContentTypes(Writer writer, String baseTypeId, int created, int numberOfLevels, int nodesPerLevel) throws IOException { + if (numberOfLevels == 0) + return 0; + int local = nodesPerLevel; + for (int i = 0; i < nodesPerLevel; i++) { + String id = createContentType(writer, created + i, baseTypeId); + local += createContentTypes(writer, id, created + local, numberOfLevels - 1, nodesPerLevel); + } + return local; + } + + private static String generateContentType(int number, String id, String baseTypeId, String[] fileNames, String[] fileExtensions) { StringBuffer result = new StringBuffer(); result.append("<content-type id=\""); result.append(id); @@ -70,32 +87,44 @@ result.append("\" "); } result.append("describer=\""); - result.append(describer); + result.append(BinarySignatureDescriber.class.getName()); + result.append(":"); + result.append(getSignatureString(number)); result.append("\"/>"); return result.toString(); } - public static int createContentTypes(Writer writer, String baseTypeId, int created, int numberOfLevels, int nodesPerLevel) throws IOException { - if (numberOfLevels == 0) - return 0; - int local = nodesPerLevel; - for (int i = 1; i < nodesPerLevel + 1; i++) { - String id = "performance" + (created + i); - String definition = createContentType(id, baseTypeId, null, baseTypeId == null ? new String[] {id} : null, NaySayerContentDescriber.class.getName()); - writer.write(definition); - writer.write(System.getProperty("line.separator")); - local += createContentTypes(writer, id, created + local, numberOfLevels - 1, nodesPerLevel); - } - return local; - } - private static String getContentTypeId(int i) { return TEST_DATA_ID + ".performance" + i; } + private static byte[] getSignature(int number) { + byte[] result = new byte[4]; + for (int i = 0; i < result.length; i++) + result[i] = (byte) ((number >> (i * 8)) & 0xFFL); + return result; + } + + private static String getSignatureString(int number) { + byte[] signature = getSignature(number); + StringBuffer result = new StringBuffer(signature.length * 3 - 1); + for (int i = 0; i < signature.length; i++) { + result.append(Integer.toHexString(0xFF & signature[i])); + result.append(' '); + } + result.deleteCharAt(result.length() - 1); + return result.toString(); + } + public static Test suite() { TestSuite suite = new TestSuite(ContentTypePerformanceTest.class.getName()); + // suite.addTest(new ContentTypePerformanceTest("testDoSetUp")); + // suite.addTest(new ContentTypePerformanceTest("testContentMatching")); + // suite.addTest(new ContentTypePerformanceTest("testContentTXTMatching")); + // suite.addTest(new ContentTypePerformanceTest("testContentXMLMatching")); + // suite.addTest(new ContentTypePerformanceTest("testDoTearDown")); + SessionTestSuite setUp = new SessionTestSuite(PI_RUNTIME_TESTS, "testDoSetUp"); setUp.addTest(new ContentTypePerformanceTest("testDoSetUp")); suite.addTest(setUp); @@ -106,7 +135,7 @@ singleRun.addTest(new ContentTypePerformanceTest("testIsKindOf")); suite.addTest(singleRun); - TestSuite loadCatalog = new PerformanceSessionTestSuite(PI_RUNTIME_TESTS, 5, "multipleSessionTests"); + TestSuite loadCatalog = new PerformanceSessionTestSuite(PI_RUNTIME_TESTS, 10, "multipleSessionTests"); loadCatalog.addTest(new ContentTypePerformanceTest("testLoadCatalog")); suite.addTest(loadCatalog); @@ -163,7 +192,8 @@ writer.write(System.getProperty("line.separator")); writer.write("<extension point=\"org.eclipse.core.runtime.contentTypes\">"); writer.write(System.getProperty("line.separator")); - createContentTypes(writer, null, 0, numberOfLevels, nodesPerLevel); + String root = createContentType(writer, 0, null); + createContentTypes(writer, root, 1, numberOfLevels, nodesPerLevel); writer.write("</extension></plugin>"); } catch (IOException e) { fail(tag + ".1.0", e); @@ -189,6 +219,22 @@ } /** + * Warms up the content type registry. + */ + private void loadChildren() { + final IContentTypeManager manager = Platform.getContentTypeManager(); + IContentType[] allTypes = manager.getAllContentTypes(); + for (int i = 0; i < allTypes.length; i++) { + String[] fileNames = allTypes[i].getFileSpecs(IContentType.IGNORE_USER_DEFINED | IContentType.FILE_NAME_SPEC); + for (int j = 0; j < fileNames.length; j++) + manager.findContentTypeFor(fileNames[j]); + String[] fileExtensions = allTypes[i].getFileSpecs(IContentType.IGNORE_USER_DEFINED | IContentType.FILE_EXTENSION_SPEC); + for (int j = 0; j < fileExtensions.length; j++) + manager.findContentTypeFor("anyname." + fileExtensions[j]); + } + } + + /** * Returns a loaded content type manager. Except for load time tests, this method should * be called outside the scope of performance monitoring. */ @@ -212,27 +258,25 @@ /** Tests how much the size of the catalog affects the performance of content type matching by content analysis */ public void testContentMatching() { - // warm up preference service loadPreferences(); // warm up content type registry final IContentTypeManager manager = loadContentTypeManager(); loadDescribers(); + loadChildren(); new PerformanceTestRunner() { protected void test() { - IContentType[] associated = null; try { - associated = manager.findContentTypesFor(getRandomContents(), null); + for (int i = 0; i < TOTAL_NUMBER_OF_ELEMENTS; i++) { + String id = getContentTypeId(i); + IContentType[] result = manager.findContentTypesFor(new ByteArrayInputStream(getSignature(i)), DEFAULT_NAME); + assertEquals("1.0." + i, 1, result.length); + assertEquals("1.1." + i, id, result[0].getId()); + } } catch (IOException e) { fail("2.0", e); } - // we know at least the text content type should be there - assertTrue("2.1", associated.length >= 1); - for (int i = 0; i < associated.length; i++) - if (associated[i].getId().equals(IContentTypeManager.CT_TEXT)) - return; - fail("2.2"); } - }.run(this, 10, 100); + }.run(this, 10, 2); } public void testDoSetUp() { @@ -259,15 +303,18 @@ loadPreferences(); // warm up content type registry final IContentTypeManager manager = loadContentTypeManager(); - final IContentType lastRoot = manager.getContentType(getContentTypeId(ELEMENTS_PER_LEVEL)); - assertNotNull("2.0", lastRoot); - final IContentType lastLeaf = manager.getContentType(getContentTypeId(NUMBER_OF_ELEMENTS)); - assertNotNull("2.1", lastLeaf); + loadChildren(); + final IContentType root = manager.getContentType(getContentTypeId(0)); + assertNotNull("2.0", root); new PerformanceTestRunner() { protected void test() { - assertTrue("3.0", lastLeaf.isKindOf(lastRoot)); + for (int i = 0; i < TOTAL_NUMBER_OF_ELEMENTS; i++) { + IContentType type = manager.getContentType(getContentTypeId(i)); + assertNotNull("3.0." + i, type); + assertTrue("3.1." + i, type.isKindOf(root)); + } } - }.run(this, 10, 100000); + }.run(this, 10, 500); } /** @@ -283,7 +330,7 @@ } }.run(this, 1, /* must run only once - the suite controls how many sessions are run */1); // sanity check to make sure we are running with good data - assertEquals("missing content types", NUMBER_OF_ELEMENTS, countTestContentTypes(Platform.getContentTypeManager().getAllContentTypes())); + assertEquals("missing content types", TOTAL_NUMBER_OF_ELEMENTS, countTestContentTypes(Platform.getContentTypeManager().getAllContentTypes())); } /** Tests how much the size of the catalog affects the performance of content type matching by name */ @@ -293,6 +340,7 @@ // warm up content type registry final IContentTypeManager manager = loadContentTypeManager(); loadDescribers(); + loadChildren(); new PerformanceTestRunner() { protected void test() { IContentType[] associated = manager.findContentTypesFor("foo.txt");