diff options
author | Vasili Gulevich | 2018-01-22 07:51:21 +0000 |
---|---|---|
committer | Alexander Kurtakov | 2018-05-10 11:29:27 +0000 |
commit | fd57f9ef289f97629c92440c689b75ca3c39a2d5 (patch) | |
tree | 8fbc72b6161ce42a5450217ff352ecaab3caeaff /bundles/org.eclipse.equinox.preferences.tests/src | |
parent | 615d8cca3e8d6c38f64c2e0d29121f03a849a7eb (diff) | |
download | rt.equinox.bundles-fd57f9ef289f97629c92440c689b75ca3c39a2d5.tar.gz rt.equinox.bundles-fd57f9ef289f97629c92440c689b75ca3c39a2d5.tar.xz rt.equinox.bundles-fd57f9ef289f97629c92440c689b75ca3c39a2d5.zip |
Bug 444188: Fix concurrent access to listener collectionsI20180515-0800
EclipsePreferences is now thread-safe.
A new test bundle is created to test org.eclipse.equinox.preferences
Moving tests from
org.eclipse.core.tests.internal.preferences.EclipsePreferencesTest is
not done here.
Signed-off-by: Vasili Gulevich <vasili.gulevich@xored.com>
Signed-off-by: Michelle Stolwyk <Michelle.Stolwyk@intersystems.com>
Change-Id: Ie3f264a2b7766e574bf65ca0cba3648ce76ac458
Diffstat (limited to 'bundles/org.eclipse.equinox.preferences.tests/src')
-rw-r--r-- | bundles/org.eclipse.equinox.preferences.tests/src/org/eclipse/equinox/preferences/tests/EclipsePreferencesTest.java | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/bundles/org.eclipse.equinox.preferences.tests/src/org/eclipse/equinox/preferences/tests/EclipsePreferencesTest.java b/bundles/org.eclipse.equinox.preferences.tests/src/org/eclipse/equinox/preferences/tests/EclipsePreferencesTest.java new file mode 100644 index 000000000..accbd2dcb --- /dev/null +++ b/bundles/org.eclipse.equinox.preferences.tests/src/org/eclipse/equinox/preferences/tests/EclipsePreferencesTest.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 2018 InterSystems Corporation 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: + * InterSystems Corporation - tests for Bug 444188 + *******************************************************************************/ +package org.eclipse.equinox.preferences.tests; + +import static org.junit.Assert.assertNotNull; + +import java.util.concurrent.CountDownLatch; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.ICoreRunnable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.IEclipsePreferences.INodeChangeListener; +import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener; +import org.eclipse.core.runtime.preferences.IEclipsePreferences.NodeChangeEvent; +import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent; +import org.junit.After; +import org.junit.Test; +import org.osgi.service.prefs.BackingStoreException; +import org.osgi.service.prefs.Preferences; + +/** + * Test suite for class org.eclipse.core.internal.preferences.EclipsePreferences + * WARNING: many tests are still located in org.eclipse.core.tests.internal.preferences.EclipsePreferencesTest from eclipse.platform.runtime + */ +public class EclipsePreferencesTest { + + /** + * Concurrent access to listener collection should not lead to exceptions + * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=444188 + */ + @Test + public void testConcurrentPreferenceChangeListener() throws InterruptedException, CoreException { + final IEclipsePreferences node = createTestNode(); + final int runSize = 100000; + + executeInTwoThreads(new ICoreRunnable() { + @Override + public void run(IProgressMonitor monitor) throws CoreException { + IPreferenceChangeListener listener = new IPreferenceChangeListener() { + @Override + public void preferenceChange(PreferenceChangeEvent event) { + } + }; + for (int i = 0; i < runSize && !monitor.isCanceled(); i++) { + node.addPreferenceChangeListener(listener); // Should not throw + node.put("x", "y"); // Should not throw + node.remove("x"); // Should not throw + node.removePreferenceChangeListener(listener); // Should not throw + } + } + }); + } + + /** + * Concurrent access to listener collection should not lead to exceptions + * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=444188 + */ + @Test + public void testConcurrentNodeChangeListener() throws InterruptedException, CoreException { + final IEclipsePreferences node = createTestNode(); + final int runSize = 100000; + executeInTwoThreads(new ICoreRunnable() { + @Override + public void run(IProgressMonitor monitor) throws CoreException { + INodeChangeListener listener = new INodeChangeListener() { + + @Override + public void removed(NodeChangeEvent event) { + } + + @Override + public void added(NodeChangeEvent event) { + } + }; + for (int i = 0; i < runSize && !monitor.isCanceled(); i++) { + node.addNodeChangeListener(listener); // Should not throw + try { + node.node(Thread.currentThread().getName()).removeNode(); // Should not throw + } catch (BackingStoreException e) { + throw new CoreException(new Status(IStatus.ERROR, "org.eclipse.core.tests.runtime", 0, "", null)); + } + node.removeNodeChangeListener(listener); // Should not throw + } + } + }); + } + + private static void executeInTwoThreads(final ICoreRunnable runnable) throws InterruptedException, CoreException { + final CountDownLatch latch = new CountDownLatch(1); + Job job = Job.create("", new ICoreRunnable() { + @Override + public void run(IProgressMonitor monitor) throws CoreException { + latch.countDown(); + runnable.run(monitor); + } + }); + job.schedule(); + try { + latch.await(); + runnable.run(new NullProgressMonitor()); + } finally { + job.cancel(); + job.join(); + IStatus result = job.getResult(); + assertNotNull("Job is expected to complete", result); + if (!result.isOK()) { + throw new CoreException(result); + } + } + } + + @After + public void after() throws BackingStoreException { + getScopeRoot().removeNode(); + } + + private static String getUniqueString() { + return System.currentTimeMillis() + "-" + Math.random(); + } + + private static IEclipsePreferences createTestNode() { + return (IEclipsePreferences) getScopeRoot().node(getUniqueString()); + } + + private static IEclipsePreferences getScopeRoot() { + return (IEclipsePreferences) Platform.getPreferencesService().getRootNode().node("EclipsePreferencesTest"); + } +} |