From 2ca62aba70c29fab8bf006b40e00ac3b233ea131 Mon Sep 17 00:00:00 2001 From: Uwe Stieber Date: Thu, 14 Dec 2006 09:04:06 +0000 Subject: [PATCH] [166117] add infra-structure for common test data location management and log collection on failure --- .../META-INF/MANIFEST.MF | 3 +- .../org.eclipse.rse.tests/plugin.properties | 7 +- rse/tests/org.eclipse.rse.tests/plugin.xml | 13 + .../rse/tests/RSECombinedTestSuite.java | 10 +- .../org/eclipse/rse/tests/RSETestsPlugin.java | 78 ++- .../rse/tests/RSETestsResources.properties | 16 +- .../core/IRSECoreTestCaseProperties.java | 10 +- .../core/IRSETestLogCollectorDelegate.java | 24 + .../org/eclipse/rse/tests/core/IRSEViews.java | 46 ++ .../rse/tests/core/RSECoreTestCase.java | 537 +++++++++++++++++- .../tests/core/RSEWaitAndDispatchUtil.java | 127 +++++ .../connection/RSEBaseConnectionTestCase.java | 3 +- .../connection/RSEConnectionTestCase.java | 1 - .../connection/RSEConnectionTestSuite.java | 11 +- .../RSEDefaultTestLogCollectorDelegate.java | 152 +++++ .../RSEInternalFrameworkTestCase.java | 160 ++++++ .../RSEInternalFrameworkTestSuite.java | 12 +- .../internal/RSETestsPluginTestCase.java | 22 +- .../persistence/RSEPersistenceTestSuite.java | 11 +- .../teamConfig/RSE Combined Test Suite.launch | 36 ++ 20 files changed, 1235 insertions(+), 44 deletions(-) create mode 100644 rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/IRSETestLogCollectorDelegate.java create mode 100644 rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/IRSEViews.java create mode 100644 rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/RSEWaitAndDispatchUtil.java create mode 100644 rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/internal/RSEDefaultTestLogCollectorDelegate.java create mode 100644 rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/internal/RSEInternalFrameworkTestCase.java create mode 100644 rse/tests/org.eclipse.rse.tests/teamConfig/RSE Combined Test Suite.launch diff --git a/rse/tests/org.eclipse.rse.tests/META-INF/MANIFEST.MF b/rse/tests/org.eclipse.rse.tests/META-INF/MANIFEST.MF index 51e2fc1373c..55bb5a0e0c2 100644 --- a/rse/tests/org.eclipse.rse.tests/META-INF/MANIFEST.MF +++ b/rse/tests/org.eclipse.rse.tests/META-INF/MANIFEST.MF @@ -13,6 +13,7 @@ Require-Bundle: org.junit, org.eclipse.rse.core, org.eclipse.rse.ui, org.eclipse.rse.subsystems.files.core, - org.eclipse.rse.subsystems.shells.core + org.eclipse.rse.subsystems.shells.core, + org.eclipse.rse.tests.framework Eclipse-LazyStart: true Bundle-RequiredExecutionEnvironment: J2SE-1.4 diff --git a/rse/tests/org.eclipse.rse.tests/plugin.properties b/rse/tests/org.eclipse.rse.tests/plugin.properties index 22adf0a4705..4391e9c20b6 100644 --- a/rse/tests/org.eclipse.rse.tests/plugin.properties +++ b/rse/tests/org.eclipse.rse.tests/plugin.properties @@ -6,9 +6,12 @@ # http://www.eclipse.org/legal/epl-v10.html # # Contributors: -# IBM Corporation - initial API and implementation -# Martin Oberhuber (Wind River) - fix ant build for "assert", make consistent +# IBM Corporation - initial API and implementation +# Martin Oberhuber (Wind River) - fix ant build for "assert", make consistent ############################################################################### +# +# Externalized MANIFEST.MF and plugin.xml strings +# pluginName=RSE Core Tests providerName=Eclipse.org diff --git a/rse/tests/org.eclipse.rse.tests/plugin.xml b/rse/tests/org.eclipse.rse.tests/plugin.xml index 4d8a6316736..78a7bfcb361 100644 --- a/rse/tests/org.eclipse.rse.tests/plugin.xml +++ b/rse/tests/org.eclipse.rse.tests/plugin.xml @@ -1,4 +1,17 @@ + + + + + + + + + + + + + diff --git a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/RSECombinedTestSuite.java b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/RSECombinedTestSuite.java index 15789c32131..d2e199487bf 100644 --- a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/RSECombinedTestSuite.java +++ b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/RSECombinedTestSuite.java @@ -13,6 +13,7 @@ import junit.framework.Test; import junit.framework.TestSuite; import org.eclipse.rse.tests.core.connection.RSEConnectionTestSuite; +import org.eclipse.rse.tests.framework.DelegatingTestSuiteHolder; import org.eclipse.rse.tests.internal.RSEInternalFrameworkTestSuite; import org.eclipse.rse.tests.persistence.RSEPersistenceTestSuite; @@ -20,7 +21,7 @@ import org.eclipse.rse.tests.persistence.RSEPersistenceTestSuite; * Main class bundling all single specialized test suites into a * overall complete one. */ -public class RSECombinedTestSuite { +public class RSECombinedTestSuite extends DelegatingTestSuiteHolder { /** * Standard Java application main method. Allows to launch the test @@ -53,4 +54,11 @@ public class RSECombinedTestSuite { return suite; } + + /* (non-Javadoc) + * @see org.eclipse.rse.tests.framework.AbstractTestSuiteHolder#getTestSuite() + */ + public TestSuite getTestSuite() { + return (TestSuite)RSECombinedTestSuite.suite(); + } } diff --git a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/RSETestsPlugin.java b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/RSETestsPlugin.java index d000d74619e..fab0e12725c 100644 --- a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/RSETestsPlugin.java +++ b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/RSETestsPlugin.java @@ -12,10 +12,15 @@ package org.eclipse.rse.tests; import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; import java.util.MissingResourceException; import java.util.ResourceBundle; +import org.eclipse.rse.tests.core.IRSETestLogCollectorDelegate; +import org.eclipse.rse.tests.internal.RSEDefaultTestLogCollectorDelegate; import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; /** * Main plugin class for the RSE JUnit tests framework. This @@ -28,6 +33,12 @@ public class RSETestsPlugin extends AbstractUIPlugin { // The resource bundle associated with this plugin. private ResourceBundle resourceBundle; + // Test log collector delegates storage. + private final List logCollectorDelegates = new ArrayList(); + + // Default test log collector delegate + private final IRSETestLogCollectorDelegate defaultLogCollectorDelegate = new RSEDefaultTestLogCollectorDelegate(); + /** * Constructor. */ @@ -116,11 +127,27 @@ public class RSETestsPlugin extends AbstractUIPlugin { assert arguments != null; String resourceString = getResourceString(key); if (!resourceString.startsWith("!")) { //$NON-NLS-1$ - MessageFormat.format(resourceString, arguments); + return MessageFormat.format(resourceString, arguments); } return resourceString; } + /* (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + addDelegate(defaultLogCollectorDelegate); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + removeDelegate(defaultLogCollectorDelegate); + super.stop(context); + } + /** * Checks if the test case given through the specified key is enabled for * execution. A test case is considered enabled if either
@@ -136,15 +163,52 @@ public class RSETestsPlugin extends AbstractUIPlugin { */ public static boolean isTestCaseEnabled(String testId) { assert testId != null; + // Test first for the system property (explicit -D option). String value = System.getProperty(testId); -// if (value != null) return Boolean.parseBoolean(value); - if (value != null) return value.equals("true"); //$NON-NLS-1$ - + if (value != null) return Boolean.getBoolean(value); + // If the system property is not set, check for the key in the resource bundle value = getResourceString(testId); -// if (value != null && !value.startsWith("!")) return Boolean.parseBoolean(value); //$NON-NLS-1$ - if (value != null && !value.startsWith("!")) return value.equals("true"); //$NON-NLS-1$ //$NON-NLS-2$ - return false; + if (value != null && !value.startsWith("!")) return Boolean.valueOf(value).booleanValue(); //$NON-NLS-1$ + + // the test is considered enabled as well if not otherwise explicitly overriden + return true; + } + + /** + * Add the specified test collector delegate to the list. If the specified + * delegate had been already added to the list before, the method will return + * without re-adding the test collector delegate again. + * + * @param delegate The test collector delegate to add. Must be not null. + */ + public synchronized void addDelegate(IRSETestLogCollectorDelegate delegate) { + assert delegate != null; + if (delegate != null && !logCollectorDelegates.contains(delegate)) { + logCollectorDelegates.add(delegate); + } + } + + /** + * Removes the specified test collector delegate from the list. If the specified + * delegate had not been added to the list before, the method will return immediatelly. + * + * @param delegate The test collector delegate to remove. Must be not null. + */ + public synchronized void removeDelegate(IRSETestLogCollectorDelegate delegate) { + assert delegate != null; + if (delegate != null) { + logCollectorDelegates.remove(delegate); + } + } + + /** + * Returns the currently list of known test log collector delegates. + * + * @return The currently known list of test collector delegates. + */ + public synchronized IRSETestLogCollectorDelegate[] getTestLogCollectorDelegates() { + return (IRSETestLogCollectorDelegate[])logCollectorDelegates.toArray(new IRSETestLogCollectorDelegate[logCollectorDelegates.size()]); } } diff --git a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/RSETestsResources.properties b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/RSETestsResources.properties index 908b8b7e599..69e7d2876b4 100644 --- a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/RSETestsResources.properties +++ b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/RSETestsResources.properties @@ -14,11 +14,23 @@ # Each test case can be disabled individually here. # +RSETestsPluginTestCase.testPluginResourceBundle=true + +RSEInternalFrameworkTestCase.testCoreTestPropertiesHandling=true +RSEInternalFrameworkTestCase.testWaitAndDispatch=true +RSEInternalFrameworkTestCase.testTestDataLocationManagement=true + RSEConnectionTestCase.testConnect=true RSEConnectionTestCase.testResolveFilterString=true RSEPersistenceTest.testHostCreation=true RSEPersistenceTest.testHostDeletion=true -RSEConnectionTestCase.testConnect=true -RSEConnectionTestCase.testResolveFilterString=true +# +# The following section contains externalized string for the single classes +# + +RSETestsPluginTestCase.dontRemove.testNeverEnabledThis=false +RSETestsPluginTestCase.dontRemove.testResolveString=testResolveString +RSETestsPluginTestCase.dontRemove.testResolveStringOneParameter=testResolveString, param={0} +RSETestsPluginTestCase.dontRemove.testResolveStringMultiParameter=testResolveString, param={0}, param={1} diff --git a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/IRSECoreTestCaseProperties.java b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/IRSECoreTestCaseProperties.java index a223beabe81..4116eaa7007 100644 --- a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/IRSECoreTestCaseProperties.java +++ b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/IRSECoreTestCaseProperties.java @@ -20,7 +20,7 @@ public interface IRSECoreTestCaseProperties { * expanded before the test case is starting. The original view maximized * state will be restored after the test case finished. *

- * Default value is true. + * Default value is false. */ public static final String PROP_MAXIMIZE_REMOTE_SYSTEMS_VIEW = PROP_BASE_KEY + ".maximizeRemoteSystemsView"; //$NON-NLS-1$ @@ -40,4 +40,12 @@ public interface IRSECoreTestCaseProperties { * Default value is false. */ public static final String PROP_FORCE_BACKGROUND_EXECUTION = PROP_BASE_KEY + ".forceBackgroundExecution"; //$NON-NLS-1$ + + /** + * Boolean property controling if the printed test start, stop and delay information + * includes the time consumed from calling setUp and tearDown. + *

+ * Default value is false. + */ + public static final String PROP_PERFORMANCE_TIMING_INCLUDE_SETUP_TEARDOWN = PROP_BASE_KEY + ".timingsIncludeSetupAndTearDown"; //$NON-NLS-1$ } diff --git a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/IRSETestLogCollectorDelegate.java b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/IRSETestLogCollectorDelegate.java new file mode 100644 index 00000000000..def9993d6a2 --- /dev/null +++ b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/IRSETestLogCollectorDelegate.java @@ -0,0 +1,24 @@ +/* ******************************************************************************* + * Copyright (c) 2006 IBM Corporation. All rights reserved. + * This program and the accompanying materials are made available under the terms + * of the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Uwe Stieber (Wind River) - initial contribution. + * *******************************************************************************/ +package org.eclipse.rse.tests.core; + +import org.eclipse.core.runtime.IPath; + +/** + * Test log collector delegate interface contract. The test + * collector delegates will be called from the RSECoreTestCase + * in case the last test which had been run failed. + */ +public interface IRSETestLogCollectorDelegate { + + public IPath[] getAbsoluteLogFileLocations(); + + public void dispose(); +} diff --git a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/IRSEViews.java b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/IRSEViews.java new file mode 100644 index 00000000000..9c39384d4be --- /dev/null +++ b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/IRSEViews.java @@ -0,0 +1,46 @@ +/* ******************************************************************************* + * Copyright (c) 2006 IBM Corporation. All rights reserved. + * This program and the accompanying materials are made available under the terms + * of the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Uwe Stieber (Wind River) - initial contribution. + * *******************************************************************************/ +package org.eclipse.rse.tests.core; + +/** + * Defines the several unique shared RSE view ids. + */ +public interface IRSEViews { + + /** + * The unique remote systems view id. + */ + public final String RSE_REMOTE_SYSTEMS_VIEW_ID = "org.eclipse.rse.ui.view.systemView"; //$NON-NLS-1$ + + /** + * The unique remote team view id. + */ + public final String RSE_TEAM_VIEW_ID = "org.eclipse.rse.ui.view.teamView"; //$NON-NLS-1$ + + /** + * The unique remote system details view id. + */ + public final String RSE_REMOTE_SYSTEMS_DETAILS_VIEW_ID = "org.eclipse.rse.ui.view.systemTableView"; //$NON-NLS-1$ + + /** + * The unique remote search view id. + */ + public final String RSE_REMOTE_SEARCH_VIEW_ID = "org.eclipse.rse.ui.view.SystemSearchView"; //$NON-NLS-1$ + + /** + * The unique remote scratchpad view id. + */ + public final String RSE_REMOTE_SCRATCHPAD_VIEW_ID = "org.eclipse.rse.ui.view.scratchpad.SystemScratchpadViewPart"; //$NON-NLS-1$ + + /** + * The unique remote monitor view id. + */ + public final String RSE_REMOTE_MONITOR_VIEW_ID = "org.eclipse.rse.ui.view.monitorView"; //$NON-NLS-1$ +} diff --git a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/RSECoreTestCase.java b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/RSECoreTestCase.java index 07bfa22076f..48dcd17bb22 100644 --- a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/RSECoreTestCase.java +++ b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/RSECoreTestCase.java @@ -9,26 +9,58 @@ * *******************************************************************************/ package org.eclipse.rse.tests.core; +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URL; +import java.text.DateFormat; +import java.util.Date; +import java.util.HashSet; +import java.util.Locale; import java.util.Properties; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; +import junit.framework.AssertionFailedError; +import junit.framework.Test; import junit.framework.TestCase; +import junit.framework.TestListener; import junit.framework.TestResult; import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.rse.tests.RSETestsPlugin; -import org.eclipse.swt.widgets.Display; +import org.eclipse.rse.tests.core.RSEWaitAndDispatchUtil.IInterruptCondition; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IViewReference; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.WorkbenchException; +import org.osgi.framework.Bundle; /** * Core RSE test case infra structure implementation. */ public class RSECoreTestCase extends TestCase { + // Test properties storage. private final Properties properties = new Properties(); + // Internal. Used to remember view zoom state changes. + private boolean rseSystemsViewZoomStateChanged = false; + /** * Constructor. */ @@ -56,9 +88,10 @@ public class RSECoreTestCase extends TestCase { * test properties or to add additional ones. */ protected void initializeProperties() { - setProperty(IRSECoreTestCaseProperties.PROP_MAXIMIZE_REMOTE_SYSTEMS_VIEW, true); + setProperty(IRSECoreTestCaseProperties.PROP_MAXIMIZE_REMOTE_SYSTEMS_VIEW, false); setProperty(IRSECoreTestCaseProperties.PROP_SWITCH_TO_PERSPECTIVE, "org.eclipse.rse.ui.view.SystemPerspective"); //$NON-NLS-1$ setProperty(IRSECoreTestCaseProperties.PROP_FORCE_BACKGROUND_EXECUTION, false); + setProperty(IRSECoreTestCaseProperties.PROP_PERFORMANCE_TIMING_INCLUDE_SETUP_TEARDOWN, false); } /** @@ -92,10 +125,12 @@ public class RSECoreTestCase extends TestCase { */ protected final void setProperty(String key, String value) { assert key != null; - if (value != null) { - properties.setProperty(key, value); - } else { - properties.remove(key); + if (key != null) { + if (value != null) { + properties.setProperty(key, value); + } else { + properties.remove(key); + } } } @@ -119,6 +154,17 @@ public class RSECoreTestCase extends TestCase { } } + /** + * Returns the configured string value of the specified property. + * + * @param key The property key. Must be not null. + * @return The property value or null if the specified property does not exist. + */ + protected final String getProperty(String key) { + assert key != null; + return properties.getProperty(key, null); + } + // ***** Test case life cycle management and support methods ***** private final static QualifiedName BACKGROUND_TEST_EXECUTION_FINISHED = new QualifiedName(RSETestsPlugin.getDefault().getBundle().getSymbolicName(), "background_test_execution_finished"); //$NON-NLS-1$ @@ -146,7 +192,9 @@ public class RSECoreTestCase extends TestCase { monitor.beginTask("Running test " + RSECoreTestCase.this.getName() + " ...", IProgressMonitor.UNKNOWN); //$NON-NLS-1$ //$NON-NLS-2$ // Execute the test now. + result.addListener(TEST_LISTENER); RSECoreTestCase.super.run(result); + result.removeListener(TEST_LISTENER); monitor.done(); @@ -157,6 +205,33 @@ public class RSECoreTestCase extends TestCase { } } + private final static class RSEBackgroundTestExecutionJobWaiter implements IInterruptCondition { + private final Job job; + + /** + * Constructor. + * + * @param job The job to wait for the execution to finish. Must be not null. + */ + public RSEBackgroundTestExecutionJobWaiter(Job job) { + assert job != null; + this.job = job; + } + + /* (non-Javadoc) + * @see org.eclipse.rse.tests.core.RSEWaitAndDispatchUtil.IInterruptCondition#isTrue() + */ + public boolean isTrue() { + // Interrupt the wait method if the job signaled that it has finished. + return ((Boolean)job.getProperty(BACKGROUND_TEST_EXECUTION_FINISHED)).booleanValue(); + } + + /* (non-Javadoc) + * @see org.eclipse.rse.tests.core.RSEWaitAndDispatchUtil.IInterruptCondition#dispose() + */ + public void dispose() { /* nothing to dispose here */ } + } + /* (non-Javadoc) * @see junit.framework.TestCase#run(junit.framework.TestResult) */ @@ -164,36 +239,450 @@ public class RSECoreTestCase extends TestCase { if (isProperty(IRSECoreTestCaseProperties.PROP_FORCE_BACKGROUND_EXECUTION, false)) { // do not force test execution into background, just call super.run(result) // from with the current thread. + result.addListener(TEST_LISTENER); super.run(result); + result.removeListener(TEST_LISTENER); } else { // Create the background job - final Job job = new RSEBackgroundTestExecutionJob(result); + Job job = new RSEBackgroundTestExecutionJob(result); // Initialize the BACKGROUND_EXECUTION_TEST_RESULT property job.setProperty(BACKGROUND_TEST_EXECUTION_FINISHED, Boolean.FALSE); // schedule the job to run immediatelly job.schedule(); // wait till the job finished executing - Boolean isFinished = (Boolean)job.getProperty(BACKGROUND_TEST_EXECUTION_FINISHED); - Display display = Display.findDisplay(Thread.currentThread()); - if (display != null) { - // The current thread is a display thread. The display event queue - // must be not blocked as otherwise asynchronous events are blocked too!!!!! - while (!Boolean.TRUE.equals(isFinished)) { - if (!display.readAndDispatch()) display.sleep(); - isFinished = (Boolean)job.getProperty(BACKGROUND_TEST_EXECUTION_FINISHED); - } - } else { - // The current thread is not a display thread. The thread can be put asleep - // for while till the test result is retried to poll. - while (!Boolean.TRUE.equals(isFinished)) { - try { Thread.sleep(500); } catch (InterruptedException e) { /* ignored on purpose */ } - isFinished = (Boolean)job.getProperty(BACKGROUND_TEST_EXECUTION_FINISHED); - } - } + RSEWaitAndDispatchUtil.waitAndDispatch(0, new RSEBackgroundTestExecutionJobWaiter(job)); } } + /* (non-Javadoc) + * @see junit.framework.TestCase#runBare() + */ + public void runBare() throws Throwable { + // If PROP_PERFORMANCE_TIMING_INCLUDE_SETUP_TEARDOWN is set to true, + // print the timing information including the tests setUp and tearDown methods. + if (isProperty(IRSECoreTestCaseProperties.PROP_PERFORMANCE_TIMING_INCLUDE_SETUP_TEARDOWN, true)) { + // Print timing information here + long start = printTestStartInformation(getName()); + try { + super.runBare(); + } finally { + printTestEndInformation(getName(), start); + } + } else { + // Do no print timing information + super.runBare(); + } + } + + /* (non-Javadoc) + * @see junit.framework.TestCase#runTest() + */ + protected void runTest() throws Throwable { + // If PROP_PERFORMANCE_TIMING_INCLUDE_SETUP_TEARDOWN is set to false (default), + // print the timing information only the test method itself. + if (isProperty(IRSECoreTestCaseProperties.PROP_PERFORMANCE_TIMING_INCLUDE_SETUP_TEARDOWN, false)) { + // Print timing information here and run the test. + long start = printTestStartInformation(getName()); + try { + super.runTest(); + } finally { + printTestEndInformation(getName(), start); + } + } else { + // Do no print timing information, just run the test + super.runTest(); + } + } + + // Local date format presenting long date and time format. + private final DateFormat DATE_FORMAT = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.getDefault()); + + /** + * Print the start date and time of the specified test to stdout. + * + * @param name The name of the starting test. Must be not null! + * @return The start time of the test in milliseconds. + */ + protected long printTestStartInformation(String name) { + assert name != null; + long startTime = System.currentTimeMillis(); + if (name != null) { + System.out.println("\n=== " + name + " started at: " + DATE_FORMAT.format(new Date(startTime))); //$NON-NLS-1$ //$NON-NLS-2$ + } + return startTime; + } + /** + * Print the end date and time as well as the delay of the specified test to stdout. + * + * @param name The name of the finished test. Must be not null! + * @param startTime The start time of the test in milliseconds. + */ + protected void printTestEndInformation(String name, long startTime) { + assert name != null; + long endTime = System.currentTimeMillis(); + if (name != null) { + long duration = endTime - startTime; + System.out.println("=== " + name + " finished at: " + DATE_FORMAT.format(new Date(endTime)) + " (duration: " + duration + " ms)"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + } + /* (non-Javadoc) + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + + String perspectiveId = getProperty(IRSECoreTestCaseProperties.PROP_SWITCH_TO_PERSPECTIVE); + assertNotNull("Invalid null-value for test case perspective id!", perspectiveId); //$NON-NLS-1$ + + // in case the test case is launched within a new workspace, the eclipse intro + // view is hiding everything else. Find the intro page and hide it. + hideView("org.eclipse.ui.internal.introview", perspectiveId); //$NON-NLS-1$ + + // toggle the Remote Systems View zoom state. + rseSystemsViewZoomStateChanged = false; + IViewPart part = showView(IRSEViews.RSE_REMOTE_SYSTEMS_VIEW_ID, perspectiveId); + assertNotNull("RSE Remote System View is not available!", part); //$NON-NLS-1$ + // Unfortunately, for the zooming, we needs the view reference and not the view part :-( + IViewReference reference = findView(IRSEViews.RSE_REMOTE_SYSTEMS_VIEW_ID, perspectiveId); + assertNotNull("Failed to lookup view reference for RSE Remote Systems View!", reference); //$NON-NLS-1$ + if (reference.getPage().getPartState(reference) != IWorkbenchPage.STATE_MAXIMIZED + && isProperty(IRSECoreTestCaseProperties.PROP_MAXIMIZE_REMOTE_SYSTEMS_VIEW, true)) { + reference.getPage().toggleZoom(reference); + rseSystemsViewZoomStateChanged = true; + } else if (reference.getPage().getPartState(reference) == IWorkbenchPage.STATE_MAXIMIZED + && isProperty(IRSECoreTestCaseProperties.PROP_MAXIMIZE_REMOTE_SYSTEMS_VIEW, false)) { + reference.getPage().toggleZoom(reference); + rseSystemsViewZoomStateChanged = true; + } + + // Give the UI a chance to repaint if the view zoom state changed + if (rseSystemsViewZoomStateChanged) RSEWaitAndDispatchUtil.waitAndDispatch(1000); + } + + /* (non-Javadoc) + * @see junit.framework.TestCase#tearDown() + */ + protected void tearDown() throws Exception { + // restore the original view zoom state + if (rseSystemsViewZoomStateChanged) { + String perspectiveId = getProperty(IRSECoreTestCaseProperties.PROP_SWITCH_TO_PERSPECTIVE); + assertNotNull("Invalid null-value for test case perspective id!", perspectiveId); //$NON-NLS-1$ + + IViewReference reference = findView(IRSEViews.RSE_REMOTE_SYSTEMS_VIEW_ID, perspectiveId); + assertNotNull("Failed to lookup view reference for RSE Remote Systems View!", reference); //$NON-NLS-1$ + if (reference.getPage().getPartState(reference) == IWorkbenchPage.STATE_MAXIMIZED + && isProperty(IRSECoreTestCaseProperties.PROP_MAXIMIZE_REMOTE_SYSTEMS_VIEW, true)) { + reference.getPage().toggleZoom(reference); + } else if (reference.getPage().getPartState(reference) != IWorkbenchPage.STATE_MAXIMIZED + && isProperty(IRSECoreTestCaseProperties.PROP_MAXIMIZE_REMOTE_SYSTEMS_VIEW, false)) { + reference.getPage().toggleZoom(reference); + } + rseSystemsViewZoomStateChanged = false; + } + + super.tearDown(); + } + + // ***** View and perspective management and support methods ***** + + /** + * Finds the view reference for the view identified by the specified id. + * + * @param viewId The unique view id. Must be not null. + * @param prespectiveId The unique perspective id within the view should be searched. Must be not null. + * @return The view reference instance to the view or null if not available. + * @throws WorkbenchException If the specified perspective could not be shown. + */ + protected final IViewReference findView(String viewId, String perspectiveId) throws WorkbenchException { + assert viewId != null && perspectiveId != null; + if (viewId == null || perspectiveId == null) return null; + + // First of all, we have to lookup the currently active workbench + // of the currently active workbench window. + IWorkbench workbench = PlatformUI.getWorkbench(); + assertNotNull("Failed to query current workbench instance!", workbench); //$NON-NLS-1$ + // and the corresponding currently active workbench window. + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + assertNotNull("Failed to query currently active workbench window!", window); //$NON-NLS-1$ + + // Now we have to switch to the specified perspecitve + workbench.showPerspective(perspectiveId, window); + + // From the active workbench window, we need the active workbench page + IWorkbenchPage page = window.getActivePage(); + assertNotNull("Failed to query currently active workbench page!", page); //$NON-NLS-1$ + + return page.findViewReference(viewId); + } + + /** + * Shows and activate the view identified by the specified id. + * + * @param viewId The unique view id. Must be not null. + * @param prespectiveId The unique perspective id within the view should be activated. Must be not null. + * @return The view part instance to the view or null if it cannot be shown. + * @throws WorkbenchException If the specified perspective could not be shown. + */ + protected final IViewPart showView(String viewId, String perspectiveId) throws WorkbenchException { + assert viewId != null && perspectiveId != null; + if (viewId == null || perspectiveId == null) return null; + + // First of all, we have to lookup the currently active workbench + // of the currently active workbench window. + IWorkbench workbench = PlatformUI.getWorkbench(); + assertNotNull("Failed to query current workbench instance!", workbench); //$NON-NLS-1$ + // and the corresponding currently active workbench window. + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + assertNotNull("Failed to query currently active workbench window!", window); //$NON-NLS-1$ + + // Now we have to switch to the specified perspecitve + workbench.showPerspective(perspectiveId, window); + + // From the active workbench window, we need the active workbench page + IWorkbenchPage page = window.getActivePage(); + assertNotNull("Failed to query currently active workbench page!", page); //$NON-NLS-1$ + + return page.showView(viewId); + } + + /** + * Hides the view identified by the specified id. + * + * @param viewId The unique view id. Must be not null. + * @param prespectiveId The unique perspective id the view should be hidden from. Must be not null. + * @throws WorkbenchException If the specified perspective could not be shown. + */ + protected final void hideView(String viewId, String perspectiveId) throws WorkbenchException { + assert viewId != null && perspectiveId != null; + if (viewId == null || perspectiveId == null) return; + + IViewReference viewReference = findView(viewId, perspectiveId); + if (viewReference != null) { + // at this point we can safely asume that we can access the active page directly + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().hideView(viewReference); + // give the UI a chance to execute the hideView and repaint + RSEWaitAndDispatchUtil.waitAndDispatch(1000); + } + } + + // ***** Test data management and support methods ***** + + /** + * Returns the absolute test data location path calculated out of the known + * test data location root (org.eclipse.rse.tests plugin location + sub + * directory 'test.data'), the specified relative path (relative to the + * test data location root) and the current execution host operating system + * string (if requested). The method will test the resulting location + * to be:
+ *


+ * If the calculated test data location does not pass these conditions, the + * method will return null. + * + * @param relativePath A path relative to the test data location root path. Must be not nullTrue if to append the current execution host operating system string, false otherwise. + * + * @return The root path to the test data location or null if the test data location does cannot be read or is not a directory. + */ + protected final IPath getTestDataLocation(String relativePath, boolean appendHostOS) { + assert relativePath != null; + IPath root = null; + + if (relativePath != null) { + Bundle bundle = RSETestsPlugin.getDefault().getBundle(); + if (bundle != null) { + // build up the complete relative path + IPath relative = new Path ("test.data").append(relativePath); //$NON-NLS-1$ + if (appendHostOS) relative = relative.append(Platform.getOS()); + + URL url = FileLocator.find(bundle, relative, null); + if (url != null) { + try { + // Resolve the URL to an absolute path + root = new Path(FileLocator.resolve(url).getFile()); + // test the resulting path element to be accessible + if (!root.toFile().isDirectory() || !root.toFile().canRead()) { + root = null; + } + } catch (IOException e) { /* ignored on purpose */ } + } + } + } + + return root; + } + + // ***** Test failures log collector management and support methods ***** + + private final TestListener TEST_LISTENER = new RSETestFailureListener(); + + /** + * Listens to the test executions and collect the test log files + * through the known list of test log collector delegates in a test + * had an error or failed. + */ + private class RSETestFailureListener implements TestListener { + + /* (non-Javadoc) + * @see junit.framework.TestListener#startTest(junit.framework.Test) + */ + public void startTest(Test test) { + } + + /* (non-Javadoc) + * @see junit.framework.TestListener#addError(junit.framework.Test, java.lang.Throwable) + */ + public synchronized void addError(Test test, Throwable error) { + if (test != null && error != null) { + // Log the error to the error log. + IStatus status = new Status(IStatus.ERROR, + RSETestsPlugin.getDefault().getBundle().getSymbolicName(), + "RSE JUnit test case '" + test + "' failed with error. Possible cause: " + error.getLocalizedMessage(), //$NON-NLS-1$ //$NON-NLS-2$ + error + ); + RSETestsPlugin.getDefault().getLog().log(status); + + // Collect the log files if at least one test log collector is known + collectTestLogs(test); + } + } + + /* (non-Javadoc) + * @see junit.framework.TestListener#addFailure(junit.framework.Test, junit.framework.AssertionFailedError) + */ + public synchronized void addFailure(Test test, AssertionFailedError failure) { + if (test != null && failure != null) { + // Log the failure to the error log. + IStatus status = new Status(IStatus.ERROR, + RSETestsPlugin.getDefault().getBundle().getSymbolicName(), + "RSE JUnit test case '" + test + "' failed. Failure: " + failure.getLocalizedMessage(), //$NON-NLS-1$ //$NON-NLS-2$ + failure + ); + RSETestsPlugin.getDefault().getLog().log(status); + + // Collect the log files if at least one test log collector is known + collectTestLogs(test); + } + } + + /* (non-Javadoc) + * @see junit.framework.TestListener#endTest(junit.framework.Test) + */ + public void endTest(Test test) { + } + } + + /** + * Collect the test logs for the failed test. + * + * @param test The failed test. Must be not null. + */ + protected synchronized void collectTestLogs(Test test) { + if (test != null) { + // get a snapshot of the currently known test log collector delegates + IRSETestLogCollectorDelegate[] delegates = RSETestsPlugin.getDefault().getTestLogCollectorDelegates(); + if (delegates.length > 0) { + // Write the logs to the test plugins state location. Check if older archives with the same + // name already exist and delete them. + IPath stateLocation = RSETestsPlugin.getDefault().getStateLocation(); + if (stateLocation != null && stateLocation.toFile().isDirectory()) { + // Build up the archives name + String archiveName = "RSEUnittestFailureLogs_" + test + ".zip"; //$NON-NLS-1$ //$NON-NLS-2$ + IPath archivePath = stateLocation.append(archiveName); + // Delete the target file if it exist. + if (archivePath.toFile().exists()) archivePath.toFile().delete(); + + // Now the file should not exist anymore --> open the new ZIP archive + ZipOutputStream stream = null; + try { + if (archivePath.toFile().createNewFile()) { + stream = new ZipOutputStream(new FileOutputStream(archivePath.toFile())); + stream.setLevel(9); + + // cache the names of the entries added to the ZIP stream. + // They needs to be unique! + Set nameCache = new HashSet(); + + // call each test log collector delegate for the absolute file names + // and add each of the returned files to the ZIP archive. + for (int i = 0; i < delegates.length; i++) { + IRSETestLogCollectorDelegate delegate = delegates[i]; + // get the list of log files to collect from the delegate + IPath[] locations = delegate.getAbsoluteLogFileLocations(); + if (locations != null && locations.length > 0) { + for (int j = 0; j < locations.length; j++) { + IPath location = locations[j]; + // The location is expected to be absolute, the file + // must be a file and it must be readable. + if (location != null && location.isAbsolute() + && location.toFile().isFile() && location.toFile().canRead()) { + File file = location.toFile(); + String entryName = file.getName(); + if (nameCache.contains(entryName)) { + // unify the name by prepending the directory elements in + // front of the name till it is unique. + IPath unifier = location.removeLastSegments(1); + entryName = unifier.lastSegment() + "_" + entryName; //$NON-NLS-1$ + while (nameCache.contains(entryName) && !unifier.isEmpty()) { + unifier = location.removeLastSegments(1); + entryName = unifier.lastSegment() + "_" + entryName; //$NON-NLS-1$ + } + + // if the name is still not unique, append a count to it + long count = 0; + // force to make a copy of the current name + String base = new String(entryName.getBytes()); + while (nameCache.contains(entryName)) { + entryName = base + " (" + count + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + count++; + } + } else { + nameCache.add(entryName); + } + + ZipEntry zipEntry = new ZipEntry(entryName); + zipEntry.setTime(file.lastModified()); + stream.putNextEntry(zipEntry); + + // Read the file bytewise and write it bytewise to the ZIP + BufferedInputStream fileStream = null; + try { + fileStream = new BufferedInputStream(new FileInputStream(file)); + int character = fileStream.read(); + while (character >= 0) { + stream.write(character); + character = fileStream.read(); + } + } catch (IOException e) { + if (Platform.inDebugMode()) e.printStackTrace(); + } finally { + // Explicitly catch the possible IOException of the close() call here. + // This keep the loop going, otherwise we would drop out of all. + try { if (fileStream != null) fileStream.close(); } catch (IOException e) { if (Platform.inDebugMode()) e.printStackTrace(); } + stream.closeEntry(); + } + } + } + } + + // If done with the current test log collector delegate, signal the delegate to dispose himself. + // This gives the delegate the chance to remove any possibly created temporary file. + delegate.dispose(); + } + } + } catch(IOException e) { + /* ignored on purpose */ + } finally { + // always close the stream if open + try { if (stream != null) stream.close(); } catch (IOException e) { if (Platform.inDebugMode()) e.printStackTrace(); } + } + } + } + } + } } diff --git a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/RSEWaitAndDispatchUtil.java b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/RSEWaitAndDispatchUtil.java new file mode 100644 index 00000000000..4912a556b3c --- /dev/null +++ b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/RSEWaitAndDispatchUtil.java @@ -0,0 +1,127 @@ +/* ******************************************************************************* + * Copyright (c) 2006 IBM Corporation. All rights reserved. + * This program and the accompanying materials are made available under the terms + * of the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Uwe Stieber (Wind River) - initial contribution. + * *******************************************************************************/ +package org.eclipse.rse.tests.core; + +import org.eclipse.swt.widgets.Display; + +/** + * RSE unit test framework helper class providing common functionality + * to hold the current thread from execution time out and/or condition + * based. + *

+ * Note: The class cannot be instanciated as all provided methods + * are declared static! + */ +public final class RSEWaitAndDispatchUtil { + + /** + * Private constructor. + */ + private RSEWaitAndDispatchUtil() {} + + /** + * Blocks the calling thread from execution till the specified + * time out has exceeded. If the calling thread is an display thread, + * the display event dispatching will be kept going during this time. + * The method will return immediatelly if any time out less or equal + * to 0 is specified. + * + * @param timeout The time to wait till the method return in milli seconds. Must be larger than 0. + */ + public static void waitAndDispatch(long timeout) { + assert timeout > 0; + if (timeout > 0) { + long start = System.currentTimeMillis(); + Display display = Display.findDisplay(Thread.currentThread()); + if (display != null) { + // ok, we are running within a display thread --> keep the + // display event dispatching running. + long current = System.currentTimeMillis(); + while ((current - start) < timeout) { + if (!display.readAndDispatch()) display.sleep(); + current = System.currentTimeMillis(); + } + } else { + // we are not running within a display thread --> we can + // just block the thread here + try { Thread.sleep(timeout); } catch (InterruptedException e) { /* ignored on purpose */ } + } + } + } + + /** + * Public interface used to interrupt waiting for a condition to + * come true and/or a timeout occurs. + */ + public interface IInterruptCondition { + /** + * Test if the interrupt condition is true. + * + * @return true if the condition is fulfilled and the wait method should return, false otherwise. + */ + public boolean isTrue(); + + /** + * Dispose the interrupt condition. Cleanup whatever necessary. + * This method will be called only once just before the wait + * method returns. + */ + public void dispose(); + } + + /** + * Blocks the calling thread from execution till the specified + * time out has exceeded or the specified interrupt condition is true. + * If the calling thread is an display thread, the display event dispatching will + * be kept going during this time. The method will return immediatelly if any time + * out less than 0 is specified or the interrupt condition is true from + * the beginning. If a time out of 0 is specified, the method will be wait indefinite + * amount of time till the interrupt condition ever becomes true. + * + * @param timeout The time to wait till the method return in milli seconds. Must be larger or equals than 0. + * @param condition The interrupt condition to test. Must be not null. + */ + public static boolean waitAndDispatch(long timeout, IInterruptCondition condition) { + assert timeout >= 0 && condition != null; + + boolean isTimedOut= false; + if (timeout >= 0 && condition != null) { + long start = System.currentTimeMillis(); + Display display = Display.findDisplay(Thread.currentThread()); + if (display != null) { + // ok, we are running within a display thread --> keep the + // display event dispatching running. + long current = System.currentTimeMillis(); + while (timeout == 0 || (current - start) < timeout) { + if (condition.isTrue()) break; + if (!display.readAndDispatch()) display.sleep(); + current = System.currentTimeMillis(); + } + isTimedOut = (current - start) >= timeout && timeout > 0; + } else { + // ok, we are not running within a display thread --> we can + // just block the thread here + long current = System.currentTimeMillis(); + while (timeout == 0 || (current - start) < timeout) { + if (condition.isTrue()) break; + try { Thread.sleep(50); } catch (InterruptedException e) { /* ignored on purpose */ } + current = System.currentTimeMillis(); + } + isTimedOut = (current - start) >= timeout && timeout > 0; + } + } + + // Signal the interrupt condition that we are done here + // and it can cleanup whatever necessary. + condition.dispose(); + + return isTimedOut; + } +} diff --git a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/connection/RSEBaseConnectionTestCase.java b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/connection/RSEBaseConnectionTestCase.java index 6d403513e33..0b0b99d6382 100644 --- a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/connection/RSEBaseConnectionTestCase.java +++ b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/connection/RSEBaseConnectionTestCase.java @@ -103,6 +103,7 @@ public class RSEBaseConnectionTestCase extends RSECoreTestCase { if (profile == null) { profile = RSEConnectionTestUtil.createProfile(profileName); } + assertNotNull("Failed to find and create profile!", profile); //$NON-NLS-1$ String hostName = getHostName(); assertNotSame("need to change the host name in SystemConnectionInfo.properties", "unknown", hostName); //$NON-NLS-1$ //$NON-NLS-2$ host = RSEConnectionTestUtil.findHost(profileName, hostName); @@ -228,4 +229,4 @@ public class RSEBaseConnectionTestCase extends RSECoreTestCase { return getString(DEFAULT_PASSWORD); } -} +} \ No newline at end of file diff --git a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/connection/RSEConnectionTestCase.java b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/connection/RSEConnectionTestCase.java index 0a5f61b76a9..a4b6265d9f3 100644 --- a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/connection/RSEConnectionTestCase.java +++ b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/connection/RSEConnectionTestCase.java @@ -40,7 +40,6 @@ public class RSEConnectionTestCase extends RSEBaseConnectionTestCase { subsystem.connect(); assertTrue("Subsystem not connected", subsystem.isConnected()); //$NON-NLS-1$ subsystem.disconnect(); - Thread.sleep(5000); // disconnect runs as a separate job, give it some time to disconnect assertFalse(subsystem.isConnected()); } diff --git a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/connection/RSEConnectionTestSuite.java b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/connection/RSEConnectionTestSuite.java index c3854665ade..5cdda3ebd06 100644 --- a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/connection/RSEConnectionTestSuite.java +++ b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/connection/RSEConnectionTestSuite.java @@ -12,10 +12,12 @@ package org.eclipse.rse.tests.core.connection; import junit.framework.Test; import junit.framework.TestSuite; +import org.eclipse.rse.tests.framework.DelegatingTestSuiteHolder; + /** * Main class bundling all RSE connection test cases. */ -public class RSEConnectionTestSuite { +public class RSEConnectionTestSuite extends DelegatingTestSuiteHolder { /** * Standard Java application main method. Allows to launch the test @@ -45,4 +47,11 @@ public class RSEConnectionTestSuite { return suite; } + + /* (non-Javadoc) + * @see org.eclipse.rse.tests.framework.AbstractTestSuiteHolder#getTestSuite() + */ + public TestSuite getTestSuite() { + return (TestSuite)RSEConnectionTestSuite.suite(); + } } diff --git a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/internal/RSEDefaultTestLogCollectorDelegate.java b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/internal/RSEDefaultTestLogCollectorDelegate.java new file mode 100644 index 00000000000..2adc009de59 --- /dev/null +++ b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/internal/RSEDefaultTestLogCollectorDelegate.java @@ -0,0 +1,152 @@ +/* ******************************************************************************* + * Copyright (c) 2006 IBM Corporation. All rights reserved. + * This program and the accompanying materials are made available under the terms + * of the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Uwe Stieber (Wind River) - initial contribution. + * *******************************************************************************/ +package org.eclipse.rse.tests.internal; + +import java.io.BufferedOutputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.text.DateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Properties; + +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.rse.tests.core.IRSETestLogCollectorDelegate; + +/** + * Default implementation of a test log collector delegate. Collects the + * main log files like the Eclipse platforms .log and other default information. + */ +public class RSEDefaultTestLogCollectorDelegate implements IRSETestLogCollectorDelegate { + private final List locationsToDispose = new ArrayList(); + + /* (non-Javadoc) + * @see org.eclipse.rse.tests.core.IRSETestLogCollectorDelegate#dispose() + */ + public synchronized void dispose() { + if (!locationsToDispose.isEmpty()) { + Iterator iterator = locationsToDispose.iterator(); + while (iterator.hasNext()) { + Object element = iterator.next(); + if (element instanceof IPath) { + IPath path = (IPath)element; + if (path.toFile().exists()) path.toFile().delete(); + } + } + } + locationsToDispose.clear(); + } + + /* (non-Javadoc) + * @see org.eclipse.rse.tests.core.IRSETestLogCollectorDelegate#getAbsoluteLogFileLocations() + */ + public synchronized IPath[] getAbsoluteLogFileLocations() { + List locations = new ArrayList(); + locationsToDispose.clear(); + + internalCollectEclipsePlatformLog(locations); + internalCollectJavaSystemProperties(locations); + + return (IPath[])locations.toArray(new IPath[locations.size()]); + } + + /** + * Lookup the Eclipse platform log (System property osgi.logfile or + * /.metadata/.log). + * + * @param locations The list of collected log file locations to add the found location to. Must be not null. + */ + private void internalCollectEclipsePlatformLog(final List locations) { + assert locations != null; + + // Try the OSGi framework system property first. + String osgi_logfile = System.getProperty("osgi.logfile", null); //$NON-NLS-1$ + IPath osgi_logfile_path = osgi_logfile != null ? new Path(osgi_logfile) : null; + if (osgi_logfile_path == null || !osgi_logfile_path.toFile().canRead()) { + // If we cannot get the log file via OSGi, fallback to the well known Eclipse + // platform log location. + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + IPath platformLog = root.getLocation().append(".metadata").append(".log"); //$NON-NLS-1$ //$NON-NLS-2$ + if (platformLog.toFile().canRead()) locations.add(platformLog); + } else { + // Directly use the log file path as given from the OSGi framework + locations.add(osgi_logfile_path); + } + } + + /** + * Dumps the current values of all set Java system properties into + * a temporary file. + * + * @param locations The list of collected log file locations to add the temp file location to. Must be not null. + */ + private void internalCollectJavaSystemProperties(final List locations) { + // Dump the Java system properties into a temporary file. + String tmpdir = System.getProperty("java.io.tmpdir"); //$NON-NLS-1$ + if (tmpdir != null) { + IPath tmpdirPath = new Path(tmpdir); + if (tmpdirPath.toFile().canWrite() && tmpdirPath.toFile().isDirectory()) { + tmpdirPath = tmpdirPath.append("java_system_properties.txt"); //$NON-NLS-1$ + if (tmpdirPath.toFile().exists()) tmpdirPath.toFile().delete(); + + BufferedOutputStream stream = null; + try { + if (tmpdirPath.toFile().createNewFile()) { + // remember that we created a temporaryvfile (which will be deleted within the dispose() method). + locationsToDispose.add(tmpdirPath); + + StringBuffer buffer = new StringBuffer(); + buffer.append("#\n"); //$NON-NLS-1$ + buffer.append("# Generated at " + DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.getDefault()).format(new Date(System.currentTimeMillis())) + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + buffer.append("#\n\n"); //$NON-NLS-1$ + + Properties properties = System.getProperties(); + + // For a better overview within the resulting file, we sort + // the property keys first. + Enumeration names = properties.propertyNames(); + List propertyKeys = new ArrayList(); + while (names.hasMoreElements()) { + propertyKeys.add(names.nextElement()); + } + Collections.sort(propertyKeys); + + Iterator iterator = propertyKeys.iterator(); + while (iterator.hasNext()) { + String propertyKey = (String)iterator.next(); + String propertyValue = properties.getProperty(propertyKey, ""); //$NON-NLS-1$ + buffer.append(propertyKey + "=" + propertyValue + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + stream = new BufferedOutputStream(new FileOutputStream(tmpdirPath.toFile())); + stream.write(buffer.toString().getBytes()); + + // If we reach this point, we can add the temporary created file + // to the returned locations. + locations.add(tmpdirPath); + } + } catch (IOException e) { + if (Platform.inDebugMode()) e.printStackTrace(); + } finally { + try { if (stream != null) stream.close(); } catch (IOException e) { if (Platform.inDebugMode()) e.printStackTrace(); } + } + } + } + } +} diff --git a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/internal/RSEInternalFrameworkTestCase.java b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/internal/RSEInternalFrameworkTestCase.java new file mode 100644 index 00000000000..80c0b891c5e --- /dev/null +++ b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/internal/RSEInternalFrameworkTestCase.java @@ -0,0 +1,160 @@ +/* ******************************************************************************* + * Copyright (c) 2006 IBM Corporation. All rights reserved. + * This program and the accompanying materials are made available under the terms + * of the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Uwe Stieber (Wind River) - initial contribution. + * *******************************************************************************/ +package org.eclipse.rse.tests.internal; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.rse.tests.RSETestsPlugin; +import org.eclipse.rse.tests.core.IRSECoreTestCaseProperties; +import org.eclipse.rse.tests.core.RSECoreTestCase; +import org.eclipse.rse.tests.core.RSEWaitAndDispatchUtil; +import org.eclipse.rse.tests.core.RSEWaitAndDispatchUtil.IInterruptCondition; +import org.eclipse.ui.PlatformUI; + +/** + * Tests the very core RSE test framework functionality. + */ +public class RSEInternalFrameworkTestCase extends RSECoreTestCase { + + /** + * Test the properties managment and support methods of the + * RSECoreTestCase implementation. + */ + public void testCoreTestPropertiesHandling() { + if (!RSETestsPlugin.isTestCaseEnabled("RSEInternalFrameworkTestCase.testCoreTestPropertiesHandling")) return; //$NON-NLS-1$ + + // test for our defaults + assertTrue("Unexpected default for property PROP_MAXIMIZE_REMOTE_SYSTEMS_VIEW!", isProperty(IRSECoreTestCaseProperties.PROP_MAXIMIZE_REMOTE_SYSTEMS_VIEW, false)); //$NON-NLS-1$ + assertEquals("Unexpected default for property PROP_SWITCH_TO_PERSPECTIVE!", "org.eclipse.rse.ui.view.SystemPerspective", getProperty(IRSECoreTestCaseProperties.PROP_SWITCH_TO_PERSPECTIVE)); //$NON-NLS-1$ //$NON-NLS-2$ + assertTrue("Unexpected default for property PROP_FORCE_BACKGROUND_EXECUTION!", isProperty(IRSECoreTestCaseProperties.PROP_FORCE_BACKGROUND_EXECUTION, false)); //$NON-NLS-1$ + assertTrue("Unexpected default for property PROP_PERFORMANCE_TIMING_INCLUDE_SETUP_TEARDOWN!", isProperty(IRSECoreTestCaseProperties.PROP_PERFORMANCE_TIMING_INCLUDE_SETUP_TEARDOWN, false)); //$NON-NLS-1$ + + // test the specific methods with simulated data + setProperty("testBooleanProperty", true); //$NON-NLS-1$ + assertTrue("Unexpected stored value for testBooleanProperty!", isProperty("testBooleanProperty", true)); //$NON-NLS-1$ //$NON-NLS-2$ + setProperty("testBooleanProperty", false); //$NON-NLS-1$ + assertTrue("Unexpected stored value for testBooleanProperty!", isProperty("testBooleanProperty", false)); //$NON-NLS-1$ //$NON-NLS-2$ + setProperty("testBooleanProperty", null); //$NON-NLS-1$ + assertNull("testBooleanProperty not removed!", getProperty("testBooleanProperty")); //$NON-NLS-1$ //$NON-NLS-2$ + + setProperty("testStringProperty", "stringPropertyValue"); //$NON-NLS-1$ //$NON-NLS-2$ + assertTrue("Unexpected stored value for testStringProperty!", isProperty("testStringProperty", "stringPropertyValue")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + setProperty("testStringProperty", "0123456789"); //$NON-NLS-1$ //$NON-NLS-2$ + assertTrue("Unexpected stored value for testStringProperty!", isProperty("testStringProperty", "0123456789")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + setProperty("testStringProperty", null); //$NON-NLS-1$ + assertNull("testStringProperty not removed!", getProperty("testStringProperty")); //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * Test waiter interrupt condition implementation. + */ + private static class TestWaiter implements IInterruptCondition { + private final List params; + public TestWaiter(List params) { + assert params != null; + this.params = params; + } + public boolean isTrue() { return params.size() > 0; } + public void dispose() { params.clear(); } + } + + private static class TestJob extends Job { + private final List params; + public TestJob(List params) { + super("Test Job"); //$NON-NLS-1$ + assert params != null; + this.params = params; + } + + protected IStatus run(IProgressMonitor monitor) { + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + public void run() { + params.add(Boolean.TRUE); + } + }); + return Status.OK_STATUS; + } + } + + /** + * Test the RSEWaitAndDispatchUtil wait methods. + */ + public void testWaitAndDispatch() { + if (!RSETestsPlugin.isTestCaseEnabled("RSEInternalFrameworkTestCase.testWaitAndDispatch")) return; //$NON-NLS-1$ + + // the simple wait and dispatch is time out based + long start = System.currentTimeMillis(); + RSEWaitAndDispatchUtil.waitAndDispatch(2500); + long end = System.currentTimeMillis(); + assertTrue("Failed to wait a given timeout!", (end - start) >= 2500); //$NON-NLS-1$ + + // the more complex wait and dispatch method has to stop + // on a given condition. + final List params = new ArrayList(); + + // the trick here is to make the condition true only if a + // runnable passed through the display thread. That should + // give us the asurance that the display event dispatching + // is kept running. + Job job = new TestJob(params); + job.setUser(false); + job.setSystem(true); + job.setPriority(Job.SHORT); + job.setRule(ResourcesPlugin.getWorkspace().getRoot()); + job.schedule(3000); + + boolean timeout = RSEWaitAndDispatchUtil.waitAndDispatch(10000, new TestWaiter(params)); + assertFalse("Interrupt condition failed to stop wait method!", timeout); //$NON-NLS-1$ + assertEquals("Interrupt condition failed to dispose!", 0, params.size()); //$NON-NLS-1$ + } + + /** + * Test accessing the test data location. + */ + public void testTestDataLocationManagement() { + if (!RSETestsPlugin.isTestCaseEnabled("RSEInternalFrameworkTestCase.testTestDataLocationManagement")) return; //$NON-NLS-1$ + + // get the pure test data location root path. + IPath root = getTestDataLocation("", false); //$NON-NLS-1$ + assertNotNull("Failed to query test data location root!", root); //$NON-NLS-1$ + assertTrue("Test data root location " + root.toOSString() + " is not a directory!", root.toFile().isDirectory()); //$NON-NLS-1$ //$NON-NLS-2$ + assertTrue("Test data root location " + root.toOSString() + " cannot be read!", root.toFile().canRead()); //$NON-NLS-1$ //$NON-NLS-2$ + + // get a test data location path under the root + String relative = "unittest_" + System.currentTimeMillis(); //$NON-NLS-1$ + // as the directories should not exist yet, a call to getTestDataLocation must return null + IPath path = getTestDataLocation(relative, false); + assertNull("Test data location exist but should not!", path); //$NON-NLS-1$ + + // go and create the path now (including the OS) + String os = Platform.getOS(); + assertNotNull("Failed to query current execution host operating system string!", os); //$NON-NLS-1$ + path = root.append(relative + "/" + os); //$NON-NLS-1$ + assertTrue("Failed to create test data location directories. Permission problem?", path.toFile().mkdirs()); //$NON-NLS-1$ + + // Now, the re-query must be successful. + IPath path2 = getTestDataLocation(relative, false); + assertNotNull("Test data location " + root.append(relative).toOSString() + " seems not to exist!", path2); //$NON-NLS-1$ //$NON-NLS-2$ + path2 = getTestDataLocation(relative, true); + assertNotNull("Test data location " + path.toOSString() + " seems not to exist!", path2); //$NON-NLS-1$ //$NON-NLS-2$ + + // Delete the created pathes again + assertTrue("Failed to delete test data location " + path.toOSString() + "!", path.toFile().delete()); //$NON-NLS-1$ //$NON-NLS-2$ + assertTrue("Failed to delete test data location " + root.append(relative).toOSString() + "!", root.append(relative).toFile().delete()); //$NON-NLS-1$ //$NON-NLS-2$ + } +} diff --git a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/internal/RSEInternalFrameworkTestSuite.java b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/internal/RSEInternalFrameworkTestSuite.java index 5a1f5352ab4..b6d272a0986 100644 --- a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/internal/RSEInternalFrameworkTestSuite.java +++ b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/internal/RSEInternalFrameworkTestSuite.java @@ -12,11 +12,13 @@ package org.eclipse.rse.tests.internal; import junit.framework.Test; import junit.framework.TestSuite; +import org.eclipse.rse.tests.framework.DelegatingTestSuiteHolder; + /** * Main class bundling all internal test case asuring the consistent * functionality of the test framework itself. */ -public class RSEInternalFrameworkTestSuite { +public class RSEInternalFrameworkTestSuite extends DelegatingTestSuiteHolder { /** * Standard Java application main method. Allows to launch the test @@ -43,7 +45,15 @@ public class RSEInternalFrameworkTestSuite { TestSuite suite = new TestSuite("RSE Internal Framework Test Suite"); //$NON-NLS-1$ // add the single test suites to the overall one here. suite.addTestSuite(RSETestsPluginTestCase.class); + suite.addTestSuite(RSEInternalFrameworkTestCase.class); return suite; } + + /* (non-Javadoc) + * @see org.eclipse.rse.tests.framework.AbstractTestSuiteHolder#getTestSuite() + */ + public TestSuite getTestSuite() { + return (TestSuite)RSEInternalFrameworkTestSuite.suite(); + } } diff --git a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/internal/RSETestsPluginTestCase.java b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/internal/RSETestsPluginTestCase.java index e9518b961ce..8491001ae8e 100644 --- a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/internal/RSETestsPluginTestCase.java +++ b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/internal/RSETestsPluginTestCase.java @@ -5,7 +5,7 @@ * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Uwe Stieber (Wind River) - initial contribution. + * Uwe Stieber (Wind River) - initial contribution. * *******************************************************************************/ package org.eclipse.rse.tests.internal; @@ -28,5 +28,25 @@ public class RSETestsPluginTestCase extends RSECoreTestCase { ResourceBundle bundle = RSETestsPlugin.getDefault().getResourceBundle(); assertNotNull("No resource bundle associated with RSETestsPlugin!", bundle); //$NON-NLS-1$ + + // our own test id must be true here, otherwise we wouldn't had + // reached this point anyway. + assertTrue("Unexpected return value false!", RSETestsPlugin.isTestCaseEnabled("RSETestsPluginTestCase.testPluginResourceBundle")); //$NON-NLS-1$ //$NON-NLS-2$ + + // a test id not listed within the resources file must be always true + assertTrue("Unexpected return value false!", RSETestsPlugin.isTestCaseEnabled("RSETestsPluginTestCase.testNeverAddThisToTheResourceBundle")); //$NON-NLS-1$ //$NON-NLS-2$ + + // this test id should be never enabled + assertFalse("Unexpected return value true!", RSETestsPlugin.isTestCaseEnabled("RSETestsPluginTestCase.dontRemove.testNeverEnabledThis")); //$NON-NLS-1$ //$NON-NLS-2$ + + // Test the different getResourceString methods. + String expected = "testResolveString"; //$NON-NLS-1$ + assertEquals("Unexpected return value!", expected, RSETestsPlugin.getResourceString("RSETestsPluginTestCase.dontRemove.testResolveString")); //$NON-NLS-1$ //$NON-NLS-2$ + + expected = "testResolveString, param=value"; //$NON-NLS-1$ + assertEquals("Unexpected return value!", expected, RSETestsPlugin.getResourceString("RSETestsPluginTestCase.dontRemove.testResolveStringOneParameter", "value")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + expected = "testResolveString, param=value1, param=value2"; //$NON-NLS-1$ + assertEquals("Unexpected return value!", expected, RSETestsPlugin.getResourceString("RSETestsPluginTestCase.dontRemove.testResolveStringMultiParameter", new Object[] { "value1", "value2" })); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ } } diff --git a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/persistence/RSEPersistenceTestSuite.java b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/persistence/RSEPersistenceTestSuite.java index 27f4b1469d6..b65338efede 100644 --- a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/persistence/RSEPersistenceTestSuite.java +++ b/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/persistence/RSEPersistenceTestSuite.java @@ -3,10 +3,12 @@ package org.eclipse.rse.tests.persistence; import junit.framework.Test; import junit.framework.TestSuite; +import org.eclipse.rse.tests.framework.DelegatingTestSuiteHolder; + /** * Main class bundling all RSE connection test cases. */ -public class RSEPersistenceTestSuite { +public class RSEPersistenceTestSuite extends DelegatingTestSuiteHolder { /** * Standard Java application main method. Allows to launch the test @@ -36,4 +38,11 @@ public class RSEPersistenceTestSuite { return suite; } + + /* (non-Javadoc) + * @see org.eclipse.rse.tests.framework.AbstractTestSuiteHolder#getTestSuite() + */ + public TestSuite getTestSuite() { + return (TestSuite)RSEPersistenceTestSuite.suite(); + } } diff --git a/rse/tests/org.eclipse.rse.tests/teamConfig/RSE Combined Test Suite.launch b/rse/tests/org.eclipse.rse.tests/teamConfig/RSE Combined Test Suite.launch new file mode 100644 index 00000000000..9c73fdd44b8 --- /dev/null +++ b/rse/tests/org.eclipse.rse.tests/teamConfig/RSE Combined Test Suite.launch @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +