blob: 1089e976d7490293c9c0c272404b1906f7b50a1b [file] [log] [blame]
/*******************************************************************************
* 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;
/**
* 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");
}
}