001: /*******************************************************************************
002: * Copyright (c) 2004, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.tests.performance;
011:
012: import org.eclipse.core.resources.IProject;
013: import org.eclipse.core.resources.IWorkspace;
014: import org.eclipse.core.resources.ResourcesPlugin;
015: import org.eclipse.core.runtime.CoreException;
016: import org.eclipse.core.runtime.IProgressMonitor;
017: import org.eclipse.core.runtime.IStatus;
018: import org.eclipse.core.runtime.Status;
019: import org.eclipse.core.runtime.jobs.Job;
020: import org.eclipse.swt.widgets.Display;
021: import org.eclipse.test.performance.Dimension;
022: import org.eclipse.ui.PlatformUI;
023: import org.eclipse.ui.tests.harness.util.UITestCase;
024:
025: /**
026: * Baseclass for simple performance tests.
027: *
028: * @since 3.1
029: */
030: public abstract class BasicPerformanceTest extends UITestCase {
031:
032: public static final int NONE = 0;
033:
034: public static final int LOCAL = 1;
035:
036: public static final int GLOBAL = 2;
037:
038: private PerformanceTester tester;
039:
040: private IProject testProject;
041:
042: final private boolean tagAsGlobalSummary;
043:
044: final private boolean tagAsSummary;
045:
046: public BasicPerformanceTest(String testName) {
047: this (testName, NONE);
048: }
049:
050: /**
051: * @param testName
052: */
053: public BasicPerformanceTest(String testName, int tagging) {
054: super (testName);
055: tagAsGlobalSummary = ((tagging & GLOBAL) != 0);
056: tagAsSummary = ((tagging & LOCAL) != 0);
057: }
058:
059: /**
060: * Answers whether this test should be tagged globally.
061: *
062: * @return whether this test should be tagged globally
063: */
064: private boolean shouldGloballyTag() {
065: return tagAsGlobalSummary;
066: }
067:
068: /**
069: * Answers whether this test should be tagged locally.
070: *
071: * @return whether this test should be tagged locally
072: */
073: private boolean shouldLocallyTag() {
074: return tagAsSummary;
075: }
076:
077: /*
078: * (non-Javadoc)
079: *
080: * @see org.eclipse.ui.tests.util.UITestCase#doSetUp()
081: */
082: protected void doSetUp() throws Exception {
083: super .doSetUp();
084: tester = new PerformanceTester(this );
085: }
086:
087: /*
088: * (non-Javadoc)
089: *
090: * @see org.eclipse.ui.tests.util.UITestCase#doTearDown()
091: */
092: protected void doTearDown() throws Exception {
093: super .doTearDown();
094: tester.dispose();
095: }
096:
097: protected IProject getProject() {
098: if (testProject == null) {
099: IWorkspace workspace = ResourcesPlugin.getWorkspace();
100: testProject = workspace.getRoot().getProject(
101: UIPerformanceTestSetup.PROJECT_NAME);
102: }
103: return testProject;
104: }
105:
106: /**
107: * Asserts default properties of the measurements captured for this test
108: * case.
109: *
110: * @throws RuntimeException
111: * if the properties do not hold
112: */
113: public void assertPerformance() {
114: tester.assertPerformance();
115: }
116:
117: /**
118: * Asserts that the measurement specified by the given dimension is within a
119: * certain range with respect to some reference value. If the specified
120: * dimension isn't available, the call has no effect.
121: *
122: * @param dim
123: * the Dimension to check
124: * @param lowerPercentage
125: * a negative number indicating the percentage the measured value
126: * is allowed to be smaller than some reference value
127: * @param upperPercentage
128: * a positive number indicating the percentage the measured value
129: * is allowed to be greater than some reference value
130: * @throws RuntimeException
131: * if the properties do not hold
132: */
133: public void assertPerformanceInRelativeBand(Dimension dim,
134: int lowerPercentage, int upperPercentage) {
135: tester.assertPerformanceInRelativeBand(dim, lowerPercentage,
136: upperPercentage);
137: }
138:
139: public void commitMeasurements() {
140: tester.commitMeasurements();
141: }
142:
143: /**
144: * Called from within a test case immediately before the code to measure is
145: * run. It starts capturing of performance data. Must be followed by a call
146: * to {@link PerformanceTestCase#stopMeasuring()}before subsequent calls to
147: * this method or {@link PerformanceTestCase#commitMeasurements()}.
148: */
149: public void startMeasuring() {
150: tester.startMeasuring();
151: }
152:
153: public void stopMeasuring() {
154: tester.stopMeasuring();
155: }
156:
157: /**
158: * Mark the scenario of this test case to be included into the global
159: * performance summary. The summary shows the given dimension of the
160: * scenario and labels the scenario with the short name.
161: *
162: * @param shortName
163: * a short (shorter than 40 characters) descritive name of the
164: * scenario
165: * @param dimension
166: * the dimension to show in the summary
167: */
168: private void tagAsGlobalSummary(String shortName,
169: Dimension dimension) {
170: System.out.println("GLOBAL " + shortName);
171: tester.tagAsGlobalSummary(shortName, dimension);
172: }
173:
174: private void tagAsSummary(String shortName, Dimension dimension) {
175: System.out.println("LOCAL " + shortName);
176: tester.tagAsSummary(shortName, dimension);
177: }
178:
179: public void tagIfNecessary(String shortName, Dimension dimension) {
180: if (shouldGloballyTag()) {
181: tagAsGlobalSummary(shortName, dimension);
182: }
183: if (shouldLocallyTag()) {
184: tagAsSummary(shortName, dimension);
185: }
186: }
187:
188: public static void waitForBackgroundJobs() {
189:
190: Job backgroundJob = new Job(
191: "This is a test job which sits around being low priority until everything else finishes") {
192: protected IStatus run(IProgressMonitor monitor) {
193: return Status.OK_STATUS;
194: }
195: };
196:
197: backgroundJob.setPriority(Job.DECORATE);
198:
199: boolean hadEvents = true;
200: Display display = PlatformUI.getWorkbench().getDisplay();
201: if (display != null) {
202: while (hadEvents) {
203: hadEvents = false;
204: // Join a low priority job then spin the event loop
205: backgroundJob.schedule(0);
206: try {
207: backgroundJob.join();
208: } catch (InterruptedException e) {
209: }
210:
211: while (display.readAndDispatch()) {
212: hadEvents = true;
213: }
214: }
215: }
216: }
217:
218: /**
219: * Runs the given runnable until either 100 iterations or 4s has elapsed.
220: * Runs a minimum of 3 times.
221: *
222: * @param runnable
223: * @since 3.1
224: */
225: public static void exercise(TestRunnable runnable)
226: throws CoreException {
227: exercise(runnable, 3, 100, 4000);
228: }
229:
230: /**
231: * Exercises the given runnable until either the given number of iterations
232: * or the given amount of time has elapsed, whatever occurs first.
233: *
234: * @param runnable
235: * @param maxIterations
236: * @param maxTime
237: * @since 3.1
238: */
239: public static void exercise(TestRunnable runnable,
240: int minIterations, int maxIterations, int maxTime)
241: throws CoreException {
242: long startTime = System.currentTimeMillis();
243:
244: for (int counter = 0; counter < maxIterations; counter++) {
245:
246: try {
247: runnable.run();
248: } catch (Exception e) {
249: throw new CoreException(new Status(IStatus.ERROR,
250: UIPerformancePlugin.getDefault().getBundle()
251: .getSymbolicName(), IStatus.OK,
252: "An exception occurred", e));
253: }
254:
255: long curTime = System.currentTimeMillis();
256: if (curTime - startTime > maxTime
257: && counter >= minIterations - 1) {
258: break;
259: }
260: }
261: }
262:
263: /**
264: * Set the comment for the receiver to string. Note this is added to the
265: * output as is so you will need to add markup if you need a link.
266: *
267: * @param string
268: * The comment to write out for the test.
269: */
270: public void setDegradationComment(String string) {
271: tester.setDegradationComment(string);
272:
273: }
274:
275: }
|