diff options
Diffstat (limited to 'dsf/org.eclipse.cdt.tests.dsf')
29 files changed, 2248 insertions, 0 deletions
diff --git a/dsf/org.eclipse.cdt.tests.dsf/.classpath b/dsf/org.eclipse.cdt.tests.dsf/.classpath new file mode 100644 index 00000000000..304e86186aa --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/dsf/org.eclipse.cdt.tests.dsf/.cvsignore b/dsf/org.eclipse.cdt.tests.dsf/.cvsignore new file mode 100644 index 00000000000..ba077a4031a --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/.cvsignore @@ -0,0 +1 @@ +bin diff --git a/dsf/org.eclipse.cdt.tests.dsf/.project b/dsf/org.eclipse.cdt.tests.dsf/.project new file mode 100644 index 00000000000..1764ef4ec6f --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/.project @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.cdt.tests.dsf</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/dsf/org.eclipse.cdt.tests.dsf/.settings/org.eclipse.jdt.core.prefs b/dsf/org.eclipse.cdt.tests.dsf/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..8f1321e3841 --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,70 @@ +#Thu Sep 25 17:12:53 PDT 2008 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=warning +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.nullReference=error +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=error +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/dsf/org.eclipse.cdt.tests.dsf/.settings/org.eclipse.jdt.ui.prefs b/dsf/org.eclipse.cdt.tests.dsf/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 00000000000..28984618f01 --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,3 @@ +#Thu Oct 12 11:27:35 PDT 2006 +eclipse.preferences.version=1 +internal.default.compliance=default diff --git a/dsf/org.eclipse.cdt.tests.dsf/META-INF/MANIFEST.MF b/dsf/org.eclipse.cdt.tests.dsf/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..bbf5a59a186 --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/META-INF/MANIFEST.MF @@ -0,0 +1,17 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-Vendor: %pluginProvider +Bundle-SymbolicName: org.eclipse.cdt.tests.dsf;singleton:=true +Bundle-Version: 2.0.0.qualifier +Bundle-Activator: org.eclipse.cdt.tests.dsf.DsfTestPlugin +Bundle-Localization: plugin +Bundle-ActivationPolicy: lazy +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.debug.core, + org.eclipse.debug.ui, + org.eclipse.cdt.dsf, + org.junit4, + org.eclipse.ui, + org.eclipse.cdt.dsf.ui +Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/dsf/org.eclipse.cdt.tests.dsf/about.html b/dsf/org.eclipse.cdt.tests.dsf/about.html new file mode 100644 index 00000000000..04492dd7e1b --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/about.html @@ -0,0 +1,24 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"><head> + + +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>About</title></head><body lang="EN-US"> +<h2>About This Content</h2> + +<p>May 14, 2008</p> +<h3>License</h3> + +<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>. +For purposes of the EPL, "Program" will mean the Content.</p> + +<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p> + +</body></html>
\ No newline at end of file diff --git a/dsf/org.eclipse.cdt.tests.dsf/build.properties b/dsf/org.eclipse.cdt.tests.dsf/build.properties new file mode 100644 index 00000000000..e398e4efb7b --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/build.properties @@ -0,0 +1,7 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + about.html,\ + plugin.properties diff --git a/dsf/org.eclipse.cdt.tests.dsf/plugin.properties b/dsf/org.eclipse.cdt.tests.dsf/plugin.properties new file mode 100644 index 00000000000..309e6e2f7d7 --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/plugin.properties @@ -0,0 +1,13 @@ +############################################################################### +# Copyright (c) 2006 Wind River Systems and others. +# 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: +# Wind River Systems - initial API and implementation +############################################################################### +pluginName=Debugger Services Framework Test Plugin +providerName=Eclipse.org + diff --git a/dsf/org.eclipse.cdt.tests.dsf/plugin.xml b/dsf/org.eclipse.cdt.tests.dsf/plugin.xml new file mode 100644 index 00000000000..ba839803701 --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/plugin.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.2"?> +<plugin> + + <extension + point="org.eclipse.ui.views"> + <category + name="DSF Tests" + id="org.eclipse.cdt.tests.dsf.model"> + </category> + <view + name="Model Test View" + category="org.eclipse.cdt.tests.dsf.model" + class="org.eclipse.cdt.tests.dsf.model.ModelTestsView" + id="org.eclipse.cdt.tests.dsf.model.ModelTestView"> + </view> + </extension> +</plugin> diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/DsfTestPlugin.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/DsfTestPlugin.java new file mode 100644 index 00000000000..742f1dda5cf --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/DsfTestPlugin.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class DsfTestPlugin extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.eclipse.cdt.tests.dsf"; //$NON-NLS-1$ + + // The shared instance + private static DsfTestPlugin fgPlugin; + private static BundleContext fgBundleContext; + + /** + * The constructor + */ + public DsfTestPlugin() { + fgPlugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext context) throws Exception { + fgBundleContext = context; + super.start(context); + } + + /* + * (non-Javadoc) + * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception { + super.stop(context); + fgBundleContext = null; + fgPlugin = null; + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static DsfTestPlugin getDefault() { + return fgPlugin; + } + + public static BundleContext getBundleContext() { + return fgBundleContext; + } + +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/TestDsfExecutor.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/TestDsfExecutor.java new file mode 100644 index 00000000000..3abea7202ae --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/TestDsfExecutor.java @@ -0,0 +1,50 @@ +package org.eclipse.cdt.tests.dsf; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import org.eclipse.cdt.dsf.concurrent.DefaultDsfExecutor; + +/** + * DsfExecutor for use with unit tests. It records the exceptions that were + * thrown in the executor thread so that they can be re-thrown by the test. + * + */ +public class TestDsfExecutor extends DefaultDsfExecutor { + private List<Throwable> fExceptions = Collections.synchronizedList(new ArrayList<Throwable>()); + + @Override + protected void afterExecute(Runnable r, Throwable t) { + super.afterExecute(r, t); + if (r instanceof Future<?>) { + Future<?> future = (Future<?>)r; + try { + if (future.isDone()) { + future.get(); + } + future.get(); + } catch (InterruptedException e) { // Ignore + } catch (CancellationException e) { // Ignore also + } catch (ExecutionException e) { + if (e.getCause() != null) { + fExceptions.add(e.getCause()); + } + } + } + } + + public boolean exceptionsCaught() { + return fExceptions.size() != 0; + } + + public Throwable[] getExceptions() { + synchronized (fExceptions) { + return fExceptions.toArray(new Throwable[fExceptions.size()]); + } + } + +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/ValueHolder.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/ValueHolder.java new file mode 100644 index 00000000000..fb3945e25fd --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/ValueHolder.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf; + +/** + * Utility class to hold a value retrieved in a runnable. + * Usage in a test is as follows: + * <pre> + * final ValueHolder<Integer> value = new ValueHolder<Integer>(); + * fExecutor.execute(new Runnable() { + * public void run() { + * value.fValue = 1; + * } + * }); + * Assert.assertTrue(value.fValue == 1); + * </pre> + */ +public class ValueHolder<V> { + public V fValue; +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/concurrent/DsfQueryTests.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/concurrent/DsfQueryTests.java new file mode 100644 index 00000000000..6c78e535019 --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/concurrent/DsfQueryTests.java @@ -0,0 +1,216 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.concurrent; + +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import junit.framework.Assert; + +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.DsfRunnable; +import org.eclipse.cdt.dsf.concurrent.Query; +import org.eclipse.cdt.tests.dsf.DsfTestPlugin; +import org.eclipse.cdt.tests.dsf.TestDsfExecutor; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Tests that exercise the Query object. + */ +public class DsfQueryTests { + TestDsfExecutor fExecutor; + + @Before + public void startServices() throws ExecutionException, InterruptedException { + fExecutor = new TestDsfExecutor(); + } + + @After + public void shutdownServices() throws ExecutionException, InterruptedException { + fExecutor.submit(new DsfRunnable() { public void run() { + fExecutor.shutdown(); + }}).get(); + if (fExecutor.exceptionsCaught()) { + Throwable[] exceptions = fExecutor.getExceptions(); + throw new ExecutionException(exceptions[0]); + } + fExecutor = null; + } + + @Test + public void simpleGetTest() throws InterruptedException, ExecutionException { + Query<Integer> q = new Query<Integer>() { + @Override + protected void execute(DataRequestMonitor<Integer> rm) { + rm.setData(1); + rm.done(); + } + }; + // Check initial state + Assert.assertTrue(!q.isDone()); + Assert.assertTrue(!q.isCancelled()); + + fExecutor.execute(q); + Assert.assertEquals(1, (int)q.get()); + + // Check final state + Assert.assertTrue(q.isDone()); + Assert.assertTrue(!q.isCancelled()); + + } + + @Test + public void getWithMultipleDispatchesTest() throws InterruptedException, ExecutionException { + Query<Integer> q = new Query<Integer>() { + @Override + protected void execute(final DataRequestMonitor<Integer> rm) { + fExecutor.execute(new DsfRunnable() { + public void run() { + rm.setData(1); + rm.done(); + } + @Override + public String toString() { return super.toString() + "\n getWithMultipleDispatchesTest() second runnable"; } //$NON-NLS-1$ + }); + } + @Override + public String toString() { return super.toString() + "\n getWithMultipleDispatchesTest() first runnable (query)"; } //$NON-NLS-1$ + }; + fExecutor.execute(q); + Assert.assertEquals(1, (int)q.get()); + } + + @Test (expected = ExecutionException.class) + public void exceptionOnGetTest() throws InterruptedException, ExecutionException { + Query<Integer> q = new Query<Integer>() { + @Override + protected void execute(final DataRequestMonitor<Integer> rm) { + rm.setStatus(new Status(IStatus.ERROR, DsfTestPlugin.PLUGIN_ID, -1, "", null)); //$NON-NLS-1$ + rm.done(); + } + }; + + fExecutor.execute(q); + + try { + q.get(); + } finally { + Assert.assertTrue(q.isDone()); + Assert.assertTrue(!q.isCancelled()); + } + } + + @Test + public void cancelWhileWaitingTest() throws InterruptedException, ExecutionException { + final Query<Integer> q = new Query<Integer>() { + @Override + protected void execute(final DataRequestMonitor<Integer> rm) { + // Call done with a delay of 1 second, to avoid stalling the tests. + fExecutor.schedule( + new DsfRunnable() { + public void run() { rm.done(); } + }, + 1, TimeUnit.SECONDS); + } + }; + + fExecutor.execute(q); + + // Note: no point in checking isDone() and isCancelled() here, because + // the value could change on timing. + + // This does not really guarantee that the cancel will be called after + // the call to Fugure.get(), but the 1ms delay in call to schedule should + // help. + new Job("DsfQueryTests cancel job") { @Override public IStatus run(IProgressMonitor monitor) { //$NON-NLS-1$ + q.cancel(false); + return Status.OK_STATUS; + }}.schedule(1); + + try { + q.get(); + } catch (CancellationException e) { + return; // Success + } finally { + Assert.assertTrue(q.isDone()); + Assert.assertTrue(q.isCancelled()); + } + Assert.assertTrue("CancellationException should have been thrown", false); //$NON-NLS-1$ + } + + @Test + public void cancelBeforeWaitingTest() throws InterruptedException, ExecutionException { + final Query<Integer> q = new Query<Integer>() { + @Override protected void execute(final DataRequestMonitor<Integer> rm) { + Assert.fail("Query was cancelled, it should not be called."); //$NON-NLS-1$ + rm.done(); + } + }; + + // Cancel before invoking the query. + q.cancel(false); + + Assert.assertTrue(q.isDone()); + Assert.assertTrue(q.isCancelled()); + + // Start the query. + fExecutor.execute(q); + + // Block to retrieve data + try { + q.get(); + } catch (CancellationException e) { + return; // Success + } finally { + Assert.assertTrue(q.isDone()); + Assert.assertTrue(q.isCancelled()); + } + Assert.assertTrue("CancellationException should have been thrown", false); //$NON-NLS-1$ + } + + @Test + public void getTimeoutTest() throws InterruptedException, ExecutionException { + final Query<Integer> q = new Query<Integer>() { + @Override + protected void execute(final DataRequestMonitor<Integer> rm) { + // Call done with a delay of 1 second, to avoid stalling the tests. + fExecutor.schedule( + new DsfRunnable() { + public void run() { rm.done(); } + }, + 1, TimeUnit.SECONDS); + } + }; + + fExecutor.execute(q); + + // Note: no point in checking isDone() and isCancelled() here, because + // the value could change on timing. + + try { + q.get(1, TimeUnit.MILLISECONDS); + } catch (TimeoutException e) { + return; // Success + } finally { + Assert.assertFalse("Query should not be done yet, it should have timed out first.", q.isDone()); //$NON-NLS-1$ + } + Assert.assertTrue("TimeoutException should have been thrown", false); //$NON-NLS-1$ + } + +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/concurrent/DsfSequenceProgressTests.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/concurrent/DsfSequenceProgressTests.java new file mode 100644 index 00000000000..fb55ecf1985 --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/concurrent/DsfSequenceProgressTests.java @@ -0,0 +1,271 @@ +/******************************************************************************* + * Copyright (c) 2008 Nokia and others. + * 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: + * Nokia - initial implementation. Oct. 2008 + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.concurrent; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ExecutionException; + +import junit.framework.Assert; +import junit.framework.AssertionFailedError; + +import org.eclipse.cdt.dsf.concurrent.DsfRunnable; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.concurrent.Sequence; +import org.eclipse.cdt.tests.dsf.TestDsfExecutor; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.swt.widgets.Display; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Test whether a step in a sequence can control the progress monitor. + */ +public class DsfSequenceProgressTests { + private List<Throwable> fExceptions = Collections.synchronizedList(new ArrayList<Throwable>()); + TestDsfExecutor fExecutor; + + @Before + public void startExecutor() throws ExecutionException, InterruptedException { + fExecutor = new TestDsfExecutor(); + } + + @After + public void shutdownExecutor() throws ExecutionException, InterruptedException { + fExecutor.submit(new DsfRunnable() { public void run() { + fExecutor.shutdown(); + }}).get(); + if (fExecutor.exceptionsCaught()) { + Throwable[] exceptions = fExecutor.getExceptions(); + throw new ExecutionException(exceptions[0]); + } + fExecutor = null; + } + + // Create a counter for tracking number of steps performed and steps + // rolled back. + class IntegerHolder { int fInteger; } + final IntegerHolder stepCounter = new IntegerHolder(); + final IntegerHolder rollBackCounter = new IntegerHolder(); + + class SleepStep extends Sequence.Step { + + @Override + public int getTicks() { + return 6; + } + + @Override public void execute(RequestMonitor requestMonitor) { + stepCounter.fInteger++; + + sleep(getTicks(), requestMonitor, null); + + requestMonitor.done(); + } + + @Override public void rollBack(RequestMonitor requestMonitor) { + rollBackCounter.fInteger++; + + sleep(1, null, null); + + requestMonitor.done(); + } + + } + + class SleepStepWithProgress extends Sequence.StepWithProgress { + + @Override + public int getTicks() { + return 6; + } + + private final static int SUB_TICKS = 3; + + @Override + public void execute(RequestMonitor rm, IProgressMonitor pm) { + stepCounter.fInteger++; + + + // step has its own sub-progress ticks which take the total ticks + // of this step and divides them into subticks + pm.beginTask(getTaskName() + ": ", SUB_TICKS); + sleep(SUB_TICKS, rm, pm); + + rm.done(); + pm.done(); + } + + @Override + public void rollBack(RequestMonitor rm) { + rollBackCounter.fInteger++; + + sleep(2, null, null); + rm.done(); + } + + } + + @Test + /** + * It's better to run this as a manual interactive test. Run this as a JUnit + * plugin test.<br> + * <br> + * In the test workbench, watch the progress bar in the Progress View.<br> + * <br> + * During execution of a StepWithProgress, you should see the progress bar + * is growing and you can have more responsive cancel.<br> + * <br> + * Meanwhile, during execution of a step without progress, you should see + * that progress bar does not grow and cancel does not work until end of the + * step.<br> + * <br> + * Also watch that when you cancel the progress bar during the execution of + * the sequence, you should see that "Rollback.." appears in the progress bar + * label.<br> + */ + public void sequenceProgressTest() throws InterruptedException, ExecutionException { + + final Sequence.Step[] steps = new Sequence.Step[] { + + new SleepStepWithProgress() { + @Override + public String getTaskName() { + return "StepWithProgress #1"; + }}, + + new SleepStepWithProgress() { + @Override + public String getTaskName() { + return "StepWithProgress #2"; + }}, + + new SleepStep() { + @Override + public String getTaskName() { + return "Step #3"; + }}, + + new SleepStep() { + @Override + public String getTaskName() { + return "Step #4"; + }}, + }; + + + fExceptions.clear(); + + Job myJob = new Job("Run test sequence") { + + @Override + protected IStatus run(IProgressMonitor monitor) { + // Create and start. + Sequence sequence = new Sequence(fExecutor, monitor, "Run my sequence", "Rollback my sequence") { + @Override public Step[] getSteps() { return steps; } + }; + fExecutor.execute(sequence); + + // Block and wait for sequence to complete. + try { + sequence.get(); + } catch (InterruptedException e) { + // ignore here. + } catch (ExecutionException e) { + // Expected exception, ignore here. + } finally { + try { + System.out.println("StepCounter: " + stepCounter.fInteger); + System.out.println("RollBackCounter: " + rollBackCounter.fInteger); + + if (sequence.isCancelled()) + Assert.assertTrue( + "Wrong number of steps were rolled back after cancellation.", + stepCounter.fInteger == rollBackCounter.fInteger); + else { + Assert.assertTrue( + "Wrong number of steps executed.", + stepCounter.fInteger == steps.length); + Assert.assertTrue( + "Some steps are mistakenly rolled back", + rollBackCounter.fInteger == 0); + } + + // Check state from Future interface + Assert.assertTrue(sequence.isDone()); + } catch (AssertionFailedError e) { + fExceptions.add(e); + } + } + return null; + }}; + + myJob.schedule(); + + // Wait for the job to finish + waitForJob(myJob); + + // now throw any assertion errors. + if (fExceptions.size() > 0) + throw (AssertionFailedError)fExceptions.get(0); + + } + + private static void sleep(int seconds, RequestMonitor rm, IProgressMonitor pm) { + try { + for (int i = 0; i < seconds; i++) { + if (pm != null) + pm.subTask("subStep - " + (i+1)); + + Thread.sleep(1000); + + if (pm != null) { + pm.worked(1); + + if (pm.isCanceled()) { + return; + } + } + + if (rm != null && rm.isCanceled()) { + return; + } + } + + } catch (InterruptedException e) { + // ignore + } + } + + // Wait for a job to finish without possible blocking of UI thread. + // + private static void waitForJob(Job job) { + Display display = Display.getCurrent(); + while (true) { + IStatus status = job.getResult(); + if (status != null) + break; + if (display != null) { + while (display.readAndDispatch()) ; + } + try { + Thread.sleep(50); + } catch (InterruptedException e) { + job.cancel(); + break; + } + } + } +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/concurrent/DsfSequenceTests.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/concurrent/DsfSequenceTests.java new file mode 100644 index 00000000000..51e8569376a --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/concurrent/DsfSequenceTests.java @@ -0,0 +1,315 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.concurrent; + +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +import junit.framework.Assert; + +import org.eclipse.cdt.dsf.concurrent.DsfRunnable; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.concurrent.Sequence; +import org.eclipse.cdt.tests.dsf.DsfTestPlugin; +import org.eclipse.cdt.tests.dsf.TestDsfExecutor; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Status; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Tests that exercise the Sequence object. + */ +public class DsfSequenceTests { + TestDsfExecutor fExecutor; + + @Before + public void startExecutor() throws ExecutionException, InterruptedException { + fExecutor = new TestDsfExecutor(); + } + + @After + public void shutdownExecutor() throws ExecutionException, InterruptedException { + fExecutor.submit(new DsfRunnable() { public void run() { + fExecutor.shutdown(); + }}).get(); + if (fExecutor.exceptionsCaught()) { + Throwable[] exceptions = fExecutor.getExceptions(); + throw new ExecutionException(exceptions[0]); + } + fExecutor = null; + } + + @Test + public void simpleTest() throws InterruptedException, ExecutionException { + // Create a counter for tracking number of steps performed. + class IntegerHolder { int fInteger; } + final IntegerHolder stepCounter = new IntegerHolder(); + + // Create the steps of the sequence + final Sequence.Step[] steps = new Sequence.Step[] { + new Sequence.Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + stepCounter.fInteger++; + requestMonitor.done(); + } + }, + new Sequence.Step() { + @Override + public void execute(RequestMonitor requestMonitor) { + stepCounter.fInteger++; + requestMonitor.done(); + } + } + }; + + // Create, start, and wait for the sequence. + Sequence sequence = new Sequence(fExecutor) { + @Override public Step[] getSteps() { return steps; } + }; + Assert.assertTrue(!sequence.isDone()); + Assert.assertTrue(!sequence.isCancelled()); + + fExecutor.execute(sequence); + sequence.get(); + + // Check the count + Assert.assertTrue(stepCounter.fInteger == 2); + + // Check post conditions + Assert.assertTrue(sequence.isDone()); + Assert.assertTrue(!sequence.isCancelled()); + } + + @Test (expected = ExecutionException.class) + public void rollbackTest() throws InterruptedException, ExecutionException { + // Create a counter for tracking number of steps performed and steps + // rolled back. + class IntegerHolder { int fInteger; } + final IntegerHolder stepCounter = new IntegerHolder(); + final IntegerHolder rollBackCounter = new IntegerHolder(); + + // Create the steps of the sequence + final Sequence.Step[] steps = new Sequence.Step[] { + new Sequence.Step() { + @Override public void execute(RequestMonitor requestMonitor) { + stepCounter.fInteger++; + requestMonitor.done(); + } + @Override public void rollBack(RequestMonitor requestMonitor) { + rollBackCounter.fInteger++; + requestMonitor.done(); + } + }, + new Sequence.Step() { + @Override public void execute(RequestMonitor requestMonitor) { + stepCounter.fInteger++; + requestMonitor.setStatus(new Status(IStatus.ERROR, DsfTestPlugin.PLUGIN_ID, -1, "", null)); //$NON-NLS-1$ + requestMonitor.done(); + } + @Override public void rollBack(RequestMonitor requestMonitor) { + rollBackCounter.fInteger++; + requestMonitor.done(); + } + } + }; + + // Create and start. + Sequence sequence = new Sequence(fExecutor) { + @Override public Step[] getSteps() { return steps; } + }; + fExecutor.execute(sequence); + + // Block and wait for sequence to bomplete. + try { + sequence.get(); + } finally { + // Both steps should be performed + Assert.assertTrue(stepCounter.fInteger == 2); + // Only one step is rolled back, the first one. + Assert.assertTrue(rollBackCounter.fInteger == 1); + + // Check state from Future interface + Assert.assertTrue(sequence.isDone()); + Assert.assertTrue(!sequence.isCancelled()); + } + Assert.assertTrue("Exception should have been thrown", false); //$NON-NLS-1$ + } + + /** + * The goal of this test it to check that if an exception is thrown within + * the Step.execute(), the step will return from the Future.get() method. + */ + @Test (expected = ExecutionException.class) + public void exceptionTest() throws InterruptedException, ExecutionException { + final Sequence.Step[] steps = new Sequence.Step[] { + new Sequence.Step() { + @Override public void execute(RequestMonitor requestMonitor) { + throw new Error("Exception part of unit test."); //$NON-NLS-1$ + } + } + }; + + // Create and start. + Sequence sequence = new Sequence(fExecutor) { + @Override public Step[] getSteps() { return steps; } + }; + fExecutor.execute(sequence); + + // Block and wait for sequence to bomplete. + try { + sequence.get(); + } finally { + // Check state from Future interface + Assert.assertTrue(sequence.isDone()); + Assert.assertTrue(!sequence.isCancelled()); + } + Assert.assertTrue("Exception should have been thrown", false); //$NON-NLS-1$ + } + + + @Test (expected = CancellationException.class) + public void cancelBeforeWaitingTest() throws InterruptedException, ExecutionException { + // Create the sequence + final Sequence.Step[] steps = new Sequence.Step[] { + new Sequence.Step() { + @Override public void execute(RequestMonitor requestMonitor) { + Assert.assertTrue("Sequence was cancelled, it should not be called.", false); //$NON-NLS-1$ + } + } + }; + Sequence sequence = new Sequence(fExecutor) { + @Override public Step[] getSteps() { return steps; } + }; + + // Cancel before invoking the sequence. + sequence.cancel(false); + + Assert.assertTrue(!sequence.isDone()); + Assert.assertTrue(sequence.isCancelled()); + + // Start the sequence + fExecutor.execute(sequence); + + // Block and wait for sequence to bomplete. + try { + sequence.get(); + } finally { + Assert.assertTrue(sequence.isDone()); + Assert.assertTrue(sequence.isCancelled()); + } + Assert.assertTrue("CancellationException should have been thrown", false); //$NON-NLS-1$ + } + + + @Test (expected = CancellationException.class) + public void cancelFromStepTest() throws InterruptedException, ExecutionException { + // Create a counter for tracking number of steps performed and steps + // rolled back. + class IntegerHolder { int fInteger; } + final IntegerHolder stepCounter = new IntegerHolder(); + final IntegerHolder rollBackCounter = new IntegerHolder(); + + // Create the steps of the sequence + final Sequence.Step[] steps = new Sequence.Step[] { + new Sequence.Step() { + @Override public void execute(RequestMonitor requestMonitor) { + stepCounter.fInteger++; + requestMonitor.done(); + } + @Override public void rollBack(RequestMonitor requestMonitor) { + rollBackCounter.fInteger++; + requestMonitor.done(); + } + }, + new Sequence.Step() { + @Override public void execute(RequestMonitor requestMonitor) { + stepCounter.fInteger++; + + // Perform the cancel! + getSequence().cancel(false); + + requestMonitor.done(); + } + @Override public void rollBack(RequestMonitor requestMonitor) { + rollBackCounter.fInteger++; + requestMonitor.done(); + } + } + }; + + // Create and start sequence with a delay. Delay so that we call get() before + // cancel is called. + final Sequence sequence = new Sequence(fExecutor) { + @Override public Step[] getSteps() { return steps; } + }; + fExecutor.schedule(sequence, 1, TimeUnit.MILLISECONDS); + + // Block to retrieve data + try { + sequence.get(); + } finally { + // Both steps should be performed + Assert.assertTrue(stepCounter.fInteger == 2); + // Both roll-backs should be performed since cancel does not take effect until + // after the step is completed. + Assert.assertTrue(rollBackCounter.fInteger == 2); + + Assert.assertTrue(sequence.isDone()); + Assert.assertTrue(sequence.isCancelled()); + } + Assert.assertTrue("CancellationException should have been thrown", false); //$NON-NLS-1$ + } + + @Test (expected = CancellationException.class) + public void cancelBeforeWithProgressManagerTest() throws InterruptedException, ExecutionException { + // Create the sequence + final Sequence.Step[] steps = new Sequence.Step[] { + new Sequence.Step() { + @Override public void execute(RequestMonitor requestMonitor) { + Assert.assertTrue("Sequence was cancelled, it should not be called.", false); //$NON-NLS-1$ + } + } + }; + + // Create the progress monitor that we will cancel. + IProgressMonitor pm = new NullProgressMonitor(); + + // Create the seqeunce with our steps. + Sequence sequence = new Sequence(fExecutor, pm, "", "") { //$NON-NLS-1$ //$NON-NLS-2$ + @Override public Step[] getSteps() { return steps; } + }; + + // Cancel the progress monitor before invoking the sequence. Note + // that the state of the sequence doesn't change yet, because the + // sequence does not check the progress monitor until it is executed. + pm.setCanceled(true); + + // Start the sequence + fExecutor.execute(sequence); + + // Block and wait for sequence to bomplete. Exception is thrown, + // which is expected. + try { + sequence.get(); + } finally { + Assert.assertTrue(sequence.isDone()); + Assert.assertTrue(sequence.isCancelled()); + } + } + + +}
\ No newline at end of file diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/dm/DMContextsTest.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/dm/DMContextsTest.java new file mode 100644 index 00000000000..86f33078888 --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/dm/DMContextsTest.java @@ -0,0 +1,185 @@ +/******************************************************************************* + * Copyright (c) 2007 Ericsson and others. + * 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: + * Ericsson - Initial Implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.dm; + +import static org.junit.Assert.assertTrue; + +import java.util.concurrent.ExecutionException; + +import org.eclipse.cdt.dsf.concurrent.DsfRunnable; +import org.eclipse.cdt.dsf.datamodel.AbstractDMContext; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.tests.dsf.TestDsfExecutor; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + + + +public class DMContextsTest { + + TestDsfExecutor fExecutor; + DsfSession fSession; + + @Before public void startExecutor() throws ExecutionException, InterruptedException { + fExecutor = new TestDsfExecutor(); + fExecutor.submit(new DsfRunnable() { public void run() { + fSession = DsfSession.startSession(fExecutor, "DMContextsTest"); //$NON-NLS-1$ + }}).get(); + + // Build a hierarchy of contexts to run the tests. Note that this hierarchy + // is not valid in the DSF model, but that is ok for these tests. + // Let's build the following: + // + // SecondType4 + // | + // FirstType3 SecondType7 + // | | + // ThirdType2 ThirdType6 + // | / | + // FirstType1 ThirdType5 + // | / + // FirstType0 + c[7] = new SecondType(new IDMContext[0], 7); + c[6] = new ThirdType(new IDMContext[]{c[7]}, 6); + c[5] = new ThirdType(new IDMContext[]{c[6]}, 5); + c[4] = new SecondType(new IDMContext[0], 4); + c[3] = new FirstType(new IDMContext[]{c[4]}, 3); + c[2] = new ThirdType(new IDMContext[]{c[3]}, 2); + c[1] = new FirstType(new IDMContext[]{c[2],c[6]}, 1); + c[0] = new FirstType(new IDMContext[]{c[1],c[5]}, 0); + } + + @After public void shutdownExecutor() throws ExecutionException, InterruptedException { + DsfSession.endSession(fSession); + fSession = null; + + fExecutor.submit(new DsfRunnable() { public void run() { + fExecutor.shutdown(); + }}).get(); + if (fExecutor.exceptionsCaught()) { + Throwable[] exceptions = fExecutor.getExceptions(); + throw new ExecutionException(exceptions[0]); + } + fExecutor = null; + } + + + BaseContextType c[] = new BaseContextType[8]; + + + private class BaseContextType extends AbstractDMContext { + final int fId; + + public BaseContextType(IDMContext[] parents, int id) { + super(fSession.getId(), parents); + fId = id; + } + + @Override + public String toString() { return baseToString() + ".[" + fId + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ + + @Override + public boolean equals(Object obj) { + return super.baseEquals(obj) && ((BaseContextType)obj).fId == fId; + } + + @Override + public int hashCode() { return super.baseHashCode() ^ fId; } + } + + private class FirstType extends BaseContextType { + public FirstType(IDMContext[] parents, int id) { + super(parents, id); + } + } + + private class SecondType extends BaseContextType { + public SecondType(IDMContext[] parents, int id) { + super(parents, id); + } + } + + private class ThirdType extends BaseContextType { + public ThirdType(IDMContext[] parents, int id) { + super(parents, id); + } + } + + private interface UnknownType extends IDMContext {} + + /** + * Test that we get the closest ancestor in terms of depth. + */ + @Test + public void testClosestAncestor() throws Throwable { + BaseContextType ancestor = DMContexts.getAncestorOfType(c[0], FirstType.class); + assertTrue("Got unexpected null ancestor", ancestor != null); + assertTrue("Got ancestor " + ancestor.fId + " intead of 1", ancestor.fId == 0); + + ancestor = DMContexts.getAncestorOfType(c[0], SecondType.class); + assertTrue("Got unexpected null ancestor", ancestor != null); + assertTrue("Got ancestor " + ancestor.fId + " intead of 8", ancestor.fId == 7); + + ancestor = DMContexts.getAncestorOfType(c[0], ThirdType.class); + assertTrue("Got unexpected null ancestor", ancestor != null); + assertTrue("Got ancestor " + ancestor.fId + " intead of 6", ancestor.fId == 5); + + ancestor = DMContexts.getAncestorOfType(c[1], SecondType.class); + assertTrue("Got unexpected null ancestor", ancestor != null); + assertTrue("Got ancestor " + ancestor.fId + " intead of 8", ancestor.fId == 7); + + ancestor = DMContexts.getAncestorOfType(c[1], ThirdType.class); + assertTrue("Got unexpected null ancestor", ancestor != null); + assertTrue("Got ancestor " + ancestor.fId + " intead of 3", ancestor.fId == 2); + + ancestor = DMContexts.getAncestorOfType(c[5], FirstType.class); + assertTrue("Got unexpected non-null ancestor", ancestor == null); + } + + /** + * Test that we get all the ancestors in order of closest in terms of depth. + */ + @Test + public void testAllClosestAncestors() throws Throwable { + + checkAncestors(c[0], BaseContextType.class, new int[]{0,1,5,2,6,3,7,4}); + checkAncestors(c[0], FirstType.class, new int[]{0,1,3}); + checkAncestors(c[0], SecondType.class, new int[]{7,4}); + checkAncestors(c[0], ThirdType.class, new int[]{5,2,6}); + + UnknownType[] exprAncestors = DMContexts.getAllAncestorsOfType(c[0], UnknownType.class); + assertTrue("Got unexpected non-null ancestor list", exprAncestors == null); + } + + private <V extends IDMContext> void checkAncestors(BaseContextType ctx, Class<V> type, int[] expected) { + BaseContextType[] ancestors = (BaseContextType[])DMContexts.getAllAncestorsOfType(ctx, type); + assertTrue("Got unexpected null ancestor", ancestors != null); + + String ancestorsStr = "", expectedStr = ""; + for (int k=0;k<ancestors.length;k++) { + ancestorsStr += ancestors[k].fId + ","; + } + for (int j=0;j<expected.length;j++) { + expectedStr += expected[j] + ","; + } + + assertTrue("Got " + ancestorsStr + " instead of " + expectedStr, ancestors.length == expected.length); + for (int i=0;i<expected.length;i++) { + if (ancestors[i].fId != expected[i]) { + assertTrue("Got " + ancestorsStr + " instead of " + expectedStr, false); + } + } + } + +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/AbstractService.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/AbstractService.java new file mode 100644 index 00000000000..2aa8af6699b --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/AbstractService.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.events; + +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.concurrent.ThreadSafe; +import org.eclipse.cdt.dsf.service.AbstractDsfService; +import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.tests.dsf.DsfTestPlugin; +import org.osgi.framework.BundleContext; + +/** + * Test service class used to test event behavior. It has three types of events + * and three methods to receive the events. + * + */ +abstract public class AbstractService extends AbstractDsfService +{ + AbstractService(DsfSession session) { + super(session); + } + + @Override protected BundleContext getBundleContext() { + return DsfTestPlugin.getBundleContext(); + } + + @Override public void initialize(final RequestMonitor requestMonitor) { + super.initialize( + new RequestMonitor(getExecutor(), requestMonitor) { + @Override + public void handleSuccess() { + doInitialize(requestMonitor); + } + }); + } + + private void doInitialize(RequestMonitor requestMonitor) { + getSession().addServiceEventListener(this, null); + requestMonitor.done(); + } + + @Override public void shutdown(RequestMonitor requestMonitor) { + getSession().removeServiceEventListener(this); + super.shutdown(requestMonitor); + } + + /////////////////////////////////////////////////////////////////////////// + // Test API + /** Records the number in the event 1 object when this service received the event. */ + int fEvent1RecipientNumber; + + /** Records the number in the event 2 object when this service received the event. */ + int fEvent2RecipientNumber; + + /** Records the number in the event 3 object when this service received the event. */ + int fEvent3RecipientNumber; + + /** Simple event class 1 */ + public class Event1 { + // 1-based counter for the recipient of the event. + int fRecipientNumberCounter = 1; + } + + /** Simple event class 2. Note it doesn't have any relation to event 1 */ + public class Event2 { + int fRecipientNumberCounter = 1; + } + + /** Simple event class 3. Note it does sub-class event 1 */ + public class Event3 extends Event1 {} + + @ThreadSafe + public void dispatchEvent1() { + getSession().dispatchEvent(new Event1(), getProperties()); + } + + @ThreadSafe + public void dispatchEvent2() { + getSession().dispatchEvent(new Event2(), getProperties()); + } + + @ThreadSafe + public void dispatchEvent3() { + getSession().dispatchEvent(new Event3(), getProperties()); + } + + /** Handles event 1 (and event 3 which derives from event 1) */ + @DsfServiceEventHandler public void eventDispatched(Event1 e) { + fEvent1RecipientNumber = e.fRecipientNumberCounter++; + } + + /** Handles event 2 only */ + @DsfServiceEventHandler public void eventDispatched(Event2 e) { + fEvent2RecipientNumber = e.fRecipientNumberCounter++; + } + + /** Handles event 3 only */ + @DsfServiceEventHandler public void eventDispatched(Event3 e) { + fEvent3RecipientNumber = e.fRecipientNumberCounter++; + } +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/Event1.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/Event1.java new file mode 100644 index 00000000000..9ac2e055b40 --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/Event1.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.events; + + +public class Event1 { + +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/Event2.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/Event2.java new file mode 100644 index 00000000000..1cc5cb11afa --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/Event2.java @@ -0,0 +1,15 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.events; + +public class Event2 extends Event1 { + +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/EventTest.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/EventTest.java new file mode 100644 index 00000000000..2f4963c17a4 --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/EventTest.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.events; + +import java.util.concurrent.ExecutionException; + +import org.eclipse.cdt.dsf.concurrent.DsfRunnable; +import org.eclipse.cdt.dsf.service.DsfServicesTracker; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.tests.dsf.DsfTestPlugin; +import org.eclipse.cdt.tests.dsf.TestDsfExecutor; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class EventTest { + + DsfSession fSession; + TestDsfExecutor fExecutor; + DsfServicesTracker fTracker; + Service1 fService1; + Service2 fService2; + Service3 fService3; + + @Before public void startServices() throws ExecutionException, InterruptedException { + fExecutor = new TestDsfExecutor(); + + fExecutor.submit(new DsfRunnable() { public void run() { + fSession = DsfSession.startSession(fExecutor, "org.eclipse.cdt.tests.dsf"); //$NON-NLS-1$ + }}).get(); + + StartupSequence startupSeq = new StartupSequence(fSession); + fExecutor.execute(startupSeq); + startupSeq.get(); + + fExecutor.submit(new DsfRunnable() { public void run() { + fTracker = new DsfServicesTracker(DsfTestPlugin.getBundleContext(), fSession.getId()); + fService1 = fTracker.getService(Service1.class); + fService2 = fTracker.getService(Service2.class); + fService3 = fTracker.getService(Service3.class); + }}).get(); + Assert.assertNotNull(fService1); + Assert.assertNotNull(fService2); + Assert.assertNotNull(fService3); + } + + @After public void shutdownServices() throws ExecutionException, InterruptedException { + ShutdownSequence shutdownSeq = new ShutdownSequence(fSession); + fExecutor.execute(shutdownSeq); + shutdownSeq.get(); + + fExecutor.submit(new DsfRunnable() { public void run() { + fService1 = null; + fService2 = null; + fService3 = null; + fTracker.dispose(); + fTracker = null; + DsfSession.endSession(fSession); + fSession = null; + fExecutor.shutdown(); + }}).get(); + + if (fExecutor.exceptionsCaught()) { + Throwable[] exceptions = fExecutor.getExceptions(); + throw new ExecutionException(exceptions[0]); + } + fExecutor = null; + } + + /** + * Test only the startup and shutdown sequences. + */ + @Test public void startStopTest() { + } + + /** + * Tests dispatching event 1. The goal of the test is to make sure that + * recipients are called in the correct order. + */ + @Test public void event1Test() throws ExecutionException, InterruptedException { + fService1.dispatchEvent1(); + fExecutor.submit(new DsfRunnable() { public void run() { + Assert.assertTrue(1 == fService1.fEvent1RecipientNumber); + Assert.assertTrue(2 == fService2.fEvent1RecipientNumber); + Assert.assertTrue(3 == fService3.fEvent1RecipientNumber); + Assert.assertTrue(0 == fService1.fEvent2RecipientNumber); + Assert.assertTrue(0 == fService2.fEvent2RecipientNumber); + Assert.assertTrue(0 == fService3.fEvent2RecipientNumber); + Assert.assertTrue(0 == fService1.fEvent3RecipientNumber); + Assert.assertTrue(0 == fService2.fEvent3RecipientNumber); + Assert.assertTrue(0 == fService3.fEvent3RecipientNumber); + }}).get(); + } + + /** + * Tests dispatching event 2. The goal of the test is to make sure that + * recipients are called in the correct order, and that the other events + * are not registered. + */ + @Test public void event2Test() throws ExecutionException, InterruptedException { + fService1.dispatchEvent2(); + fExecutor.submit(new DsfRunnable() { public void run() { + Assert.assertTrue(0 == fService1.fEvent1RecipientNumber); + Assert.assertTrue(0 == fService2.fEvent1RecipientNumber); + Assert.assertTrue(0 == fService3.fEvent1RecipientNumber); + Assert.assertTrue(1 == fService1.fEvent2RecipientNumber); + Assert.assertTrue(2 == fService2.fEvent2RecipientNumber); + Assert.assertTrue(3 == fService3.fEvent2RecipientNumber); + Assert.assertTrue(0 == fService1.fEvent3RecipientNumber); + Assert.assertTrue(0 == fService2.fEvent3RecipientNumber); + Assert.assertTrue(0 == fService3.fEvent3RecipientNumber); + }}).get(); + } + + /** + * Tests dispatching event 2. The goal of the test is to make sure that + * both event 2 and even 3 recipients are called for this event. + * <br> + * Note: When a single listener object has more than one method that that + * matches the event, both methods will be called. But there is currently + * no guaranteed order in which they should be called. + */ + @Test public void event3Test() throws ExecutionException, InterruptedException { + fService1.dispatchEvent3(); + fExecutor.submit(new DsfRunnable() { public void run() { + Assert.assertTrue(1 == fService1.fEvent1RecipientNumber || 2 == fService1.fEvent1RecipientNumber); + Assert.assertTrue(3 == fService2.fEvent1RecipientNumber || 4 == fService2.fEvent1RecipientNumber); + Assert.assertTrue(5 == fService3.fEvent1RecipientNumber || 6 == fService3.fEvent1RecipientNumber); + Assert.assertTrue(0 == fService1.fEvent2RecipientNumber); + Assert.assertTrue(0 == fService2.fEvent2RecipientNumber); + Assert.assertTrue(0 == fService3.fEvent2RecipientNumber); + Assert.assertTrue(1 == fService1.fEvent3RecipientNumber || 2 == fService1.fEvent3RecipientNumber); + Assert.assertTrue(3 == fService2.fEvent3RecipientNumber || 4 == fService2.fEvent3RecipientNumber); + Assert.assertTrue(5 == fService3.fEvent3RecipientNumber || 6 == fService3.fEvent3RecipientNumber); + }}).get(); + } + +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/Service1.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/Service1.java new file mode 100644 index 00000000000..89ab8c771b8 --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/Service1.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.events; + +import java.util.Hashtable; + +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.service.DsfSession; + +public class Service1 extends AbstractService { + Service1(DsfSession session) { + super(session); + } + + @Override public void initialize(final RequestMonitor requestMonitor) { + super.initialize( + new RequestMonitor(getExecutor(), requestMonitor) { + @Override + public void handleSuccess() { + doInitialize(requestMonitor); + } + }); + } + + private void doInitialize(RequestMonitor requestMonitor) { + register(new String[]{Service1.class.getName()}, new Hashtable<String,String>()); + requestMonitor.done(); + } + + @Override public void shutdown(RequestMonitor requestMonitor) { + unregister(); + super.shutdown(requestMonitor); + } +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/Service2.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/Service2.java new file mode 100644 index 00000000000..bb70dc51186 --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/Service2.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.events; + +import java.util.Hashtable; + +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.service.DsfSession; + +public class Service2 extends AbstractService { + Service2(DsfSession session) { + super(session); + } + + @Override public void initialize(final RequestMonitor requestMonitor) { + super.initialize( + new RequestMonitor(getExecutor(), requestMonitor) { + @Override + public void handleSuccess() { + doInitialize(requestMonitor); + } + }); + } + + private void doInitialize(RequestMonitor requestMonitor) { + getServicesTracker().getService(Service1.class); + register(new String[]{Service2.class.getName()}, new Hashtable<String,String>()); + requestMonitor.done(); + } + + @Override public void shutdown(RequestMonitor requestMonitor) { + unregister(); + super.shutdown(requestMonitor); + } +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/Service3.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/Service3.java new file mode 100644 index 00000000000..c16057e288c --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/Service3.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.events; + +import java.util.Hashtable; + +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.tests.dsf.DsfTestPlugin; +import org.osgi.framework.BundleContext; + +public class Service3 extends AbstractService { + Service3(DsfSession session) { + super(session); + } + + @Override protected BundleContext getBundleContext() { + return DsfTestPlugin.getBundleContext(); + } + + @Override public void initialize(final RequestMonitor requestMonitor) { + super.initialize( + new RequestMonitor(getExecutor(), requestMonitor) { + @Override + public void handleSuccess() { + doInitialize(requestMonitor); + } + }); + } + + private void doInitialize(RequestMonitor requestMonitor) { + getServicesTracker().getService(Service1.class); + getServicesTracker().getService(Service2.class); + register(new String[]{Service3.class.getName()}, new Hashtable<String,String>()); + requestMonitor.done(); + } + + @Override public void shutdown(RequestMonitor requestMonitor) { + unregister(); + super.shutdown(requestMonitor); + } +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/ShutdownSequence.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/ShutdownSequence.java new file mode 100644 index 00000000000..06f05dc329d --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/ShutdownSequence.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.events; + +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.concurrent.Sequence; +import org.eclipse.cdt.dsf.service.DsfServicesTracker; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.dsf.service.IDsfService; +import org.eclipse.cdt.tests.dsf.DsfTestPlugin; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +class ShutdownSequence extends Sequence { + + DsfSession fSession; + DsfServicesTracker fTracker; + + ShutdownSequence(DsfSession session) { + super(session.getExecutor()); + fSession = session; + } + + @Override + public Step[] getSteps() { return fSteps; } + + final Step[] fSteps = new Step[] { + new Step() { + @Override public void execute(RequestMonitor requestMonitor) { + fTracker = new DsfServicesTracker(DsfTestPlugin.getBundleContext(), fSession.getId()); + requestMonitor.done(); + } + + @Override public void rollBack(RequestMonitor requestMonitor) { + fTracker.dispose(); + fTracker = null; + requestMonitor.done(); + } + }, + new Step() { @Override public void execute(RequestMonitor requestMonitor) { + shutdownService(Service3.class, requestMonitor); + }}, + new Step() { @Override public void execute(RequestMonitor requestMonitor) { + shutdownService(Service2.class, requestMonitor); + }}, + new Step() { @Override public void execute(RequestMonitor requestMonitor) { + shutdownService(Service1.class, requestMonitor); + }}, + new Step() { @Override public void execute(RequestMonitor requestMonitor) { + fTracker.dispose(); + fTracker = null; + requestMonitor.done(); + }} + }; + + private void shutdownService(Class<? extends IDsfService> clazz, RequestMonitor requestMonitor) { + IDsfService service = fTracker.getService(clazz); + if (service != null) { + service.shutdown(requestMonitor); + } + else { + requestMonitor.setStatus(new Status(IStatus.ERROR, DsfTestPlugin.PLUGIN_ID, -1, "Service '" + clazz.getName() + "' not found.", null)); //$NON-NLS-1$//$NON-NLS-2$ + requestMonitor.done(); + } + } + +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/StartupSequence.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/StartupSequence.java new file mode 100644 index 00000000000..408755c448b --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/events/StartupSequence.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.events; + +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.concurrent.Sequence; +import org.eclipse.cdt.dsf.service.DsfSession; + +class StartupSequence extends Sequence { + DsfSession fSession; + + StartupSequence(DsfSession session) { + super(session.getExecutor()); + fSession = session; + } + + @Override + public Step[] getSteps() { return fSteps; } + + final Step[] fSteps = new Step[] { + new Step() { @Override public void execute(RequestMonitor requestMonitor) { + new Service1(fSession).initialize(requestMonitor); + }}, + new Step() { @Override public void execute(RequestMonitor requestMonitor) { + new Service2(fSession).initialize(requestMonitor); + }}, + new Step() { @Override public void execute(RequestMonitor requestMonitor) { + new Service3(fSession).initialize(requestMonitor); + }} + }; +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/service/MultiInstanceTestService.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/service/MultiInstanceTestService.java new file mode 100644 index 00000000000..283aae2e8ee --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/service/MultiInstanceTestService.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.service; + +import java.util.Hashtable; + +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.service.AbstractDsfService; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.tests.dsf.DsfTestPlugin; +import org.osgi.framework.BundleContext; + +public class MultiInstanceTestService extends AbstractDsfService { + + public static String PROP_INSTANCE_ID = "org.eclipse.cdt.dsf.tests.service.MultiInstanceTestService.id"; //$NON-NLS-1$ + String fInstanceId; + + public MultiInstanceTestService(DsfSession session, String instanceId) { + super(session); + fInstanceId = instanceId; + } + + @Override + protected BundleContext getBundleContext() { + return DsfTestPlugin.getBundleContext(); + } + + @Override + public void initialize(final RequestMonitor requestMonitor) { + super.initialize( + new RequestMonitor(getExecutor(), requestMonitor) { + @Override + public void handleSuccess() { + doInitialize(requestMonitor); + } + }); + } + + private void doInitialize(RequestMonitor requestMonitor) { + Hashtable<String,String> properties = new Hashtable<String,String>(); + properties.put(PROP_INSTANCE_ID, fInstanceId); + register(new String[]{MultiInstanceTestService.class.getName()}, properties); + requestMonitor.done(); + } + + @Override + public void shutdown(RequestMonitor requestMonitor) { + unregister(); + super.shutdown(requestMonitor); + } +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/service/ServiceTests.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/service/ServiceTests.java new file mode 100644 index 00000000000..9f6b830908b --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/service/ServiceTests.java @@ -0,0 +1,277 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.service; + +import java.lang.reflect.Constructor; +import java.util.concurrent.ExecutionException; + +import org.eclipse.cdt.dsf.concurrent.DsfRunnable; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.concurrent.Sequence; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.dsf.service.IDsfService; +import org.eclipse.cdt.tests.dsf.DsfTestPlugin; +import org.eclipse.cdt.tests.dsf.TestDsfExecutor; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; + +public class ServiceTests { + TestDsfExecutor fExecutor; + + @Before public void startExecutor() throws ExecutionException, InterruptedException { + fExecutor = new TestDsfExecutor(); + } + + @After public void shutdownExecutor() throws ExecutionException, InterruptedException { + fExecutor.submit(new DsfRunnable() { public void run() { + fExecutor.shutdown(); + }}).get(); + if (fExecutor.exceptionsCaught()) { + Throwable[] exceptions = fExecutor.getExceptions(); + throw new ExecutionException(exceptions[0]); + } + fExecutor = null; + } + + private class CreateSessionStep extends Sequence.Step { + private DsfSession fSession; + @Override public void execute(RequestMonitor requestMonitor) { + fSession = DsfSession.startSession(fExecutor, "org.eclipse.cdt.dsf.tests"); //$NON-NLS-1$ + requestMonitor.done(); + } + + DsfSession getSession() { return fSession; } + } + + private class ShutdownSessionStep extends Sequence.Step { + private CreateSessionStep fCreateSessionStep; + + ShutdownSessionStep(CreateSessionStep createSessionStep) { + fCreateSessionStep = createSessionStep; + } + + @Override + public void execute(RequestMonitor requestMonitor) { + DsfSession.endSession(fCreateSessionStep.getSession()); + requestMonitor.done(); + } + } + + private class InitializeServiceStep extends Sequence.Step { + CreateSessionStep fCreateSessionStep; + Class<? extends IDsfService> fServiceClass; + IDsfService fService; + + InitializeServiceStep(CreateSessionStep createSessionStep, Class<? extends IDsfService> serviceClass) { + fCreateSessionStep = createSessionStep; + fServiceClass = serviceClass; + } + IDsfService getService() { return fService; } + + @Override + public void execute(RequestMonitor requestMonitor) { + try { + Constructor<? extends IDsfService> c = fServiceClass.getConstructor(new Class[] {DsfSession.class}); + fService = c.newInstance(new Object[] {fCreateSessionStep.getSession()}); + } catch (Exception e) { + Assert.fail("Unexpected exception"); //$NON-NLS-1$ + } + fService.initialize(requestMonitor); + } + } + + private class InitializeMultiInstanceServiceStep extends InitializeServiceStep { + String fServiceId; + + InitializeMultiInstanceServiceStep(CreateSessionStep createSessionStep, Class<? extends IDsfService> serviceClass, String serviceId) { + super(createSessionStep, serviceClass); + fServiceId = serviceId; + } + @Override + IDsfService getService() { return fService; } + + @Override + public void execute(RequestMonitor requestMonitor) { + try { + Constructor<? extends IDsfService> c = + fServiceClass.getConstructor(new Class[] {DsfSession.class, String.class}); + fService = c.newInstance(new Object[] {fCreateSessionStep.getSession(), fServiceId}); + } catch (Exception e) { + Assert.fail("Unexpected exception"); //$NON-NLS-1$ + } + fService.initialize(requestMonitor); + } + } + + private class ShutdownServiceStep extends Sequence.Step { + InitializeServiceStep fInitializeServiceStep; + ShutdownServiceStep(InitializeServiceStep initStep) { + fInitializeServiceStep = initStep; + } + + @Override + public void execute(RequestMonitor requestMonitor) { + fInitializeServiceStep.getService().shutdown(requestMonitor); + } + } + + + abstract private class TestRetrievingReferenceStep extends Sequence.Step { + String fClass; + boolean fShouldSucceed; + + TestRetrievingReferenceStep(Class<?> clazz, boolean shouldSucceed) { + fClass = clazz.getName(); + fShouldSucceed = shouldSucceed; + } + + abstract String getFilter(); + + @Override + public void execute(RequestMonitor requestMonitor) { + ServiceReference[] refs = null; + try { + refs = DsfTestPlugin.getBundleContext().getServiceReferences(fClass, getFilter()); + } catch (InvalidSyntaxException e) { + Assert.fail("Unexpected exception"); //$NON-NLS-1$ + } + if (fShouldSucceed) { + Assert.assertTrue(refs != null); + Assert.assertTrue(refs.length == 1); + IDsfService service = (IDsfService)DsfTestPlugin.getBundleContext().getService(refs[0]); + Assert.assertTrue(service != null); + DsfTestPlugin.getBundleContext().ungetService(refs[0]); + } else { + Assert.assertTrue(refs == null); + } + requestMonitor.done(); + } + } + + private class TestRetrievingSimpleServiceReferenceStep extends TestRetrievingReferenceStep { + CreateSessionStep fCreateSessionStep; + TestRetrievingSimpleServiceReferenceStep(Class<?> clazz, boolean shouldSucceed, CreateSessionStep createSessionStep) { + super(clazz, shouldSucceed); + fCreateSessionStep = createSessionStep; + } + @Override + String getFilter() { + return "(" + IDsfService.PROP_SESSION_ID + "=" + fCreateSessionStep.getSession().getId() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + } + + private class TestRetrievingMultiSessionServiceReferenceStep extends TestRetrievingSimpleServiceReferenceStep { + String fServiceId; + TestRetrievingMultiSessionServiceReferenceStep(Class<?> clazz, boolean shouldSucceed, CreateSessionStep createSessionStep, + String serviceId) { + super(clazz, shouldSucceed, createSessionStep); + fServiceId = serviceId; + } + @Override + String getFilter() { + return "(&" + //$NON-NLS-1$ + "(" + IDsfService.PROP_SESSION_ID + "=" + fCreateSessionStep.getSession().getId() + ")" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + "(" + MultiInstanceTestService.PROP_INSTANCE_ID + "=" + fServiceId + ")" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + ")"; //$NON-NLS-1$ + } + } + + @Test + public void singleServiceTest() throws InterruptedException, ExecutionException { + Sequence seq = new Sequence(fExecutor) { + CreateSessionStep fSessionStep; + InitializeServiceStep fServiceStep; + + @Override + public Step[] getSteps() { return fSteps; } + + final private Step[] fSteps = new Step[] + { + fSessionStep = new CreateSessionStep(), + fServiceStep = new InitializeServiceStep(fSessionStep, SimpleTestService.class), + new TestRetrievingSimpleServiceReferenceStep(SimpleTestService.class, true, fSessionStep), + new ShutdownServiceStep(fServiceStep), + new TestRetrievingSimpleServiceReferenceStep(SimpleTestService.class, false, fSessionStep), + new ShutdownSessionStep(fSessionStep) + }; + }; + fExecutor.execute(seq); + seq.get(); + } + + /** + * Creates two sessions and starts a single service within each session. + * Then it tests retrieving the reference to the service. + */ + @Test + public void singleServiceMultiSessionTest() throws InterruptedException, ExecutionException { + Sequence seq = new Sequence(fExecutor) { + CreateSessionStep fSession1Step; + CreateSessionStep fSession2Step; + InitializeServiceStep fSession1ServiceStep; + InitializeServiceStep fSession2ServiceStep; + + @Override + public Step[] getSteps() { return fSteps; } + + final private Step[] fSteps = new Step[] + { + fSession1Step = new CreateSessionStep(), + fSession2Step = new CreateSessionStep(), + fSession1ServiceStep = new InitializeServiceStep(fSession1Step, SimpleTestService.class), + fSession2ServiceStep = new InitializeServiceStep(fSession2Step, SimpleTestService.class), + new TestRetrievingSimpleServiceReferenceStep(SimpleTestService.class, true, fSession1Step), + new TestRetrievingSimpleServiceReferenceStep(SimpleTestService.class, true, fSession2Step), + new ShutdownServiceStep(fSession1ServiceStep), + new ShutdownServiceStep(fSession2ServiceStep), + new TestRetrievingSimpleServiceReferenceStep(SimpleTestService.class, false, fSession1Step), + new TestRetrievingSimpleServiceReferenceStep(SimpleTestService.class, false, fSession2Step), + new ShutdownSessionStep(fSession1Step), + new ShutdownSessionStep(fSession2Step) + }; + }; + fExecutor.execute(seq); + seq.get(); + } + + @Test + public void multiServiceServiceTest() throws InterruptedException, ExecutionException { + Sequence seq = new Sequence(fExecutor) { + CreateSessionStep fSessionStep; + InitializeServiceStep fService1Step; + InitializeServiceStep fService2Step; + + @Override + public Step[] getSteps() { return fSteps; } + + final private Step[] fSteps = new Step[] + { + fSessionStep = new CreateSessionStep(), + fService1Step = new InitializeMultiInstanceServiceStep(fSessionStep, MultiInstanceTestService.class, "1"), //$NON-NLS-1$ + fService2Step = new InitializeMultiInstanceServiceStep(fSessionStep, MultiInstanceTestService.class, "2"), //$NON-NLS-1$ + new TestRetrievingMultiSessionServiceReferenceStep(MultiInstanceTestService.class, true, fSessionStep, "1"), //$NON-NLS-1$ + new TestRetrievingMultiSessionServiceReferenceStep(MultiInstanceTestService.class, true, fSessionStep, "2"), //$NON-NLS-1$ + new ShutdownServiceStep(fService1Step), + new ShutdownServiceStep(fService2Step), + new TestRetrievingMultiSessionServiceReferenceStep(MultiInstanceTestService.class, false, fSessionStep, "1"), //$NON-NLS-1$ + new TestRetrievingMultiSessionServiceReferenceStep(MultiInstanceTestService.class, false, fSessionStep, "2"), //$NON-NLS-1$ + new ShutdownSessionStep(fSessionStep) + }; + }; + fExecutor.execute(seq); + seq.get(); + } + +} diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/service/SimpleTestService.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/service/SimpleTestService.java new file mode 100644 index 00000000000..83737c13967 --- /dev/null +++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/service/SimpleTestService.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems and others. + * 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.tests.dsf.service; + +import java.util.Hashtable; + +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.service.AbstractDsfService; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.tests.dsf.DsfTestPlugin; +import org.osgi.framework.BundleContext; + +public class SimpleTestService extends AbstractDsfService { + + public SimpleTestService(DsfSession session) { + super(session); + } + + @Override + protected BundleContext getBundleContext() { + return DsfTestPlugin.getBundleContext(); + } + + @Override + public void initialize(final RequestMonitor requestMonitor) { + super.initialize( + new RequestMonitor(getExecutor(), requestMonitor) { + @Override + public void handleSuccess() { + doInitialize(requestMonitor); + } + }); + } + + private void doInitialize(RequestMonitor requestMonitor) { + register(new String[]{SimpleTestService.class.getName()}, new Hashtable<String,String>()); + requestMonitor.done(); + } + + @Override + public void shutdown(RequestMonitor requestMonitor) { + unregister(); + super.shutdown(requestMonitor); + } +} |