This commit was manufactured by cvs2svn to create branch 'perf_213'.
Cherrypick from master 2004-11-25 21:54:01 UTC John Arthorne <johna> 'Refactored performance tests':
tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/CoreTest.java
tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/FileSystemHelper.java
tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/PerformanceTestRunner.javadiff --git a/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/CoreTest.java b/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/CoreTest.java
new file mode 100644
index 0000000..c92004a
--- /dev/null
+++ b/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/CoreTest.java
@@ -0,0 +1,253 @@
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.core.tests.harness;
+
+import java.io.*;
+import junit.framework.TestCase;
+import org.eclipse.core.internal.utils.UniversalUniqueIdentifier;
+import org.eclipse.core.runtime.*;
+
+/**
+ * @since 3.1
+ */
+public class CoreTest extends TestCase {
+
+ // plug-in identified for the core.tests.harness plug-in.
+ public static final String PI_HARNESS = "org.eclipse.core.tests.harness";
+
+ /** counter for generating unique random filesystem locations */
+ protected static int nextLocationCounter = 0;
+
+ public CoreTest() {
+ super();
+ }
+
+ public CoreTest(String name) {
+ super(name);
+ }
+
+ public static void log(String pluginID, IStatus status) {
+ Platform.getLog(Platform.getBundle(pluginID)).log(status);
+ }
+
+ public static void log(String pluginID, Throwable e) {
+ log(pluginID, new Status(IStatus.ERROR, pluginID, IStatus.ERROR, "Error", e)); //$NON-NLS-1$
+ }
+
+ public static void debug(String message) {
+ String id = "org.eclipse.core.tests.harness/debug";
+ String option = Platform.getDebugOption(id);
+ if (Boolean.TRUE.toString().equalsIgnoreCase(option))
+ System.out.println(message);
+ }
+
+ public String getUniqueString() {
+ return new UniversalUniqueIdentifier().toString();
+ }
+
+ /**
+ * Fails the test due to the given throwable.
+ */
+ public static void fail(String message, Throwable e) {
+ // If the exception is a CoreException with a multistatus
+ // then print out the multistatus so we can see all the info.
+ if (e instanceof CoreException) {
+ IStatus status = ((CoreException) e).getStatus();
+ if (status.getChildren().length > 0)
+ write(status, 0);
+ } else
+ e.printStackTrace();
+ fail(message + ": " + e);
+ }
+
+ private static void write(IStatus status, int indent) {
+ PrintStream output = System.out;
+ indent(output, indent);
+ output.println("Severity: " + status.getSeverity());
+
+ indent(output, indent);
+ output.println("Plugin ID: " + status.getPlugin());
+
+ indent(output, indent);
+ output.println("Code: " + status.getCode());
+
+ indent(output, indent);
+ output.println("Message: " + status.getMessage());
+
+ if (status.isMultiStatus()) {
+ IStatus[] children = status.getChildren();
+ for (int i = 0; i < children.length; i++)
+ write(children[i], indent + 1);
+ }
+ }
+
+ private static void indent(OutputStream output, int indent) {
+ for (int i = 0; i < indent; i++)
+ try {
+ output.write("\t".getBytes());
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+
+ public IPath getTempDir() {
+ return FileSystemHelper.getTempDir();
+ }
+
+ /**
+ * Returns a unique location on disk. It is guaranteed that no file currently
+ * exists at that location. The returned location will be unique with respect
+ * to all other locations generated by this method in the current session.
+ * If the caller creates a folder or file at this location, they are responsible for
+ * deleting it when finished.
+ */
+ public IPath getRandomLocation() {
+ return FileSystemHelper.getRandomLocation(getTempDir());
+ }
+
+ /**
+ * Return String with some random text to use
+ * as contents for a file resource.
+ */
+ public String getRandomString() {
+ switch ((int) Math.round(Math.random() * 10)) {
+ case 0 :
+ return "este e' o meu conteudo (portuguese)";
+ case 1 :
+ return "ho ho ho";
+ case 2 :
+ return "I'll be back";
+ case 3 :
+ return "don't worry, be happy";
+ case 4 :
+ return "there is no imagination for more sentences";
+ case 5 :
+ return "customize yours";
+ case 6 :
+ return "foo";
+ case 7 :
+ return "bar";
+ case 8 :
+ return "foobar";
+ case 9 :
+ return "case 9";
+ default :
+ return "these are my contents";
+ }
+ }
+
+ /**
+ * Return an input stream with some random text to use
+ * as contents for a file resource.
+ */
+ public InputStream getRandomContents() {
+ return new ByteArrayInputStream(getRandomString().getBytes());
+ }
+
+ public IProgressMonitor getMonitor() {
+ return new FussyProgressMonitor();
+ }
+
+ /**
+ * Copy the data from the input stream to the output stream.
+ * Do not close either of the streams.
+ */
+ public void transferDataWithoutClose(InputStream input, OutputStream output) {
+ try {
+ int c = 0;
+ while ((c = input.read()) != -1)
+ output.write(c);
+ } catch (IOException e) {
+ e.printStackTrace();
+ assertTrue(e.toString(), false);
+ }
+ }
+
+ /**
+ * Copy the data from the input stream to the output stream.
+ * Close both streams when finished.
+ */
+ public void transferData(InputStream input, OutputStream output) {
+ try {
+ try {
+ int c = 0;
+ while ((c = input.read()) != -1)
+ output.write(c);
+ } finally {
+ input.close();
+ output.close();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ assertTrue(e.toString(), false);
+ }
+ }
+
+ /**
+ * Return an input stream with some the specified text to use
+ * as contents for a file resource.
+ */
+ public InputStream getContents(String text) {
+ return new ByteArrayInputStream(text.getBytes());
+ }
+
+ public InputStream getContents(java.io.File target, String errorCode) {
+ try {
+ return new FileInputStream(target);
+ } catch (IOException e) {
+ fail(errorCode, e);
+ }
+ return null; // never happens
+ }
+
+ protected void ensureDoesNotExistInFileSystem(java.io.File file) {
+ FileSystemHelper.clear(file);
+ }
+
+ protected void assertEquals(String message, Object[] expected, Object[] actual, boolean orderImportant) {
+ // if the order in the array must match exactly, then call the other method
+ if (orderImportant) {
+ assertEquals(message, expected, actual);
+ return;
+ }
+ // otherwise use this method and check that the arrays are equal in any order
+ if (expected == null && actual == null)
+ return;
+ if (expected == actual)
+ return;
+ if (expected == null || actual == null)
+ assertTrue(message + ".1", false);
+ if (expected.length != actual.length)
+ assertTrue(message + ".2", false);
+ boolean[] found = new boolean[expected.length];
+ for (int i = 0; i < expected.length; i++) {
+ for (int j = 0; j < expected.length; j++) {
+ if (!found[j] && expected[i].equals(actual[j]))
+ found[j] = true;
+ }
+ }
+ for (int i = 0; i < found.length; i++)
+ if (!found[i])
+ assertTrue(message + ".3." + i, false);
+ }
+
+ protected void assertEquals(String message, Object[] expected, Object[] actual) {
+ if (expected == null && actual == null)
+ return;
+ if (expected == null || actual == null)
+ fail(message);
+ if (expected.length != actual.length)
+ fail(message);
+ for (int i = 0; i < expected.length; i++)
+ assertEquals(message, expected[i], actual[i]);
+ }
+
+}
diff --git a/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/FileSystemHelper.java b/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/FileSystemHelper.java
new file mode 100644
index 0000000..fd7d6f7
--- /dev/null
+++ b/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/FileSystemHelper.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.core.tests.harness;
+
+import org.eclipse.core.runtime.*;
+
+/**
+ * Home for file system-related utility methods.
+ */
+public class FileSystemHelper {
+ /** counter for generating unique random filesystem locations */
+ protected static int nextLocationCounter = 0;
+ private static final long MASK = 0x00000000FFFFFFFFL;
+
+ /*
+ * Return the root directory for the temp dir.
+ */
+ public static IPath getTempDir() {
+ return new Path(System.getProperty("java.io.tmpdir"));
+ }
+
+ /**
+ * Returns a unique location on disk. It is guaranteed that no file currently
+ * exists at that location. The returned location will be unique with respect
+ * to all other locations generated by this method in the current session.
+ * If the caller creates a folder or file at this location, they are responsible for
+ * deleting it when finished.
+ */
+ public static IPath getRandomLocation(IPath parent) {
+ IPath path = computeRandomLocation(parent);
+ while (path.toFile().exists()) {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ path = computeRandomLocation(parent);
+ }
+ return path;
+ }
+
+ public static IPath computeRandomLocation(IPath parent) {
+ long segment = (((long) ++nextLocationCounter) << 32) | (System.currentTimeMillis() & MASK);
+ return parent.append(Long.toString(segment));
+ }
+
+ public static void clear(java.io.File file) {
+ if (!file.exists())
+ return;
+ if (file.isDirectory()) {
+ String[] files = file.list();
+ if (files != null) // be careful since file.list() can return null
+ for (int i = 0; i < files.length; ++i)
+ clear(new java.io.File(file, files[i]));
+ }
+ if (!file.delete()) {
+ String message = "ensureDoesNotExistInFileSystem(File) could not delete: " + file.getPath();
+ CoreTest.log(CoreTest.PI_HARNESS, new Status(IStatus.WARNING, CoreTest.PI_HARNESS, IStatus.OK, message, null));
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/PerformanceTestRunner.java b/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/PerformanceTestRunner.java
new file mode 100644
index 0000000..a90b57f
--- /dev/null
+++ b/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/PerformanceTestRunner.java
@@ -0,0 +1,66 @@
+/**********************************************************************
+ * Copyright (c) 2004 IBM Corporation and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Common Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.core.tests.harness;
+
+import junit.framework.TestCase;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.test.performance.Performance;
+import org.eclipse.test.performance.PerformanceMeter;
+
+/**
+ * Helper class for executing a performance test. Takes care of starting, stopping,
+ * and commiting performance timers.
+ */
+public abstract class PerformanceTestRunner {
+
+ /**
+ * Implemented by subclasses to perform the work to be measured.
+ */
+ protected abstract void test();
+
+ /**
+ * Executes the performance test the given number of times. Use the outer time
+ * to execute the test several times in order to obtain a normalized average. Use
+ * the inner loop for very fast tests that would otherwise be difficult to measure
+ * due to Java's poor timer granularity. The inner loop is not needed for long
+ * tests that typically take more than a second to execute.
+ *
+ * @param testCase The test that is running (used to obtain an appropriate meter)
+ * @param outer The number of repetitions of the test.
+ * @param inner The number of repetitions within the performance timer.
+ */
+ public final void run(TestCase testCase, int outer, int inner) {
+ Performance perf = Performance.getDefault();
+ PerformanceMeter meter = perf.createPerformanceMeter(perf.getDefaultScenarioId(testCase));
+ try {
+ for (int i = 0; i < outer; i++) {
+ setUp();
+ meter.start();
+ for (int j = 0; j < inner; j++)
+ test();
+ meter.stop();
+ tearDown();
+ }
+ meter.commit();
+ perf.assertPerformance(meter);
+ } catch (CoreException e) {
+ CoreTest.fail("Failed performance test", e);
+ } finally {
+ meter.dispose();
+ }
+ }
+ protected void setUp() throws CoreException{
+ // subclasses to override
+ }
+
+ protected void tearDown() throws CoreException {
+ // subclasses to override
+ }
+}
\ No newline at end of file