blob: a207e97f858c2a1933f3bd2405ab94c47be9333e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2017 IBM 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:
* IBM Corporation - initial API and implementation
* Alexander Kurtakov <akurtako@redhat.com> - Bug 459343
*******************************************************************************/
package org.eclipse.core.tests.internal.properties;
import java.util.Vector;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.core.internal.properties.IPropertyManager;
import org.eclipse.core.internal.properties.PropertyManager2;
import org.eclipse.core.internal.resources.Workspace;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.tests.internal.localstore.LocalStoreTest;
public class PropertyManagerTest extends LocalStoreTest {
public class StoredProperty {
protected QualifiedName name = null;
protected String value = null;
public StoredProperty(QualifiedName name, String value) {
super();
this.name = name;
this.value = value;
}
public QualifiedName getName() {
return name;
}
public String getStringValue() {
return value;
}
}
public static Test suite() {
// TestSuite suite = new TestSuite();
// suite.addTest(new PropertyManagerTest("testDeleteProperties"));
// return suite;
return new TestSuite(PropertyManagerTest.class);
}
public PropertyManagerTest() {
super(null);
}
public PropertyManagerTest(String name) {
super(name);
}
private void createProperties(IFile target, QualifiedName[] names, String[] values) {
for (int i = 0; i < names.length; i++) {
names[i] = new QualifiedName("org.eclipse.core.tests", "prop" + i);
values[i] = "property value" + i;
}
// create properties
for (int i = 0; i < names.length; i++) {
try {
target.setPersistentProperty(names[i], values[i]);
} catch (CoreException e) {
fail("1." + i, e);
}
}
}
private Thread[] createThreads(final IFile target, final QualifiedName[] names, final String[] values, final CoreException[] errorPointer) {
final int THREAD_COUNT = 3;
Thread[] threads = new Thread[THREAD_COUNT];
for (int j = 0; j < THREAD_COUNT; j++) {
final String id = "GetSetProperty" + j;
threads[j] = new Thread((Runnable) () -> {
try {
doGetSetProperties(target, id, names, values);
} catch (CoreException e) {
//ignore failure if the project has been deleted
if (target.exists()) {
e.printStackTrace();
errorPointer[0] = e;
return;
}
}
}, id);
threads[j].start();
}
return threads;
}
protected void doGetSetProperties(IFile target, String threadID, QualifiedName[] names, String[] values) throws CoreException {
final int N = names.length;
for (int j = 0; j < 10; j++) {
for (int i = 0; i < N; i++) {
target.getPersistentProperty(names[i]);
}
// change properties
for (int i = 0; i < N; i++) {
// values[i] = values[i] + " - changed (" + threadID + ")";
target.setPersistentProperty(names[i], values[i]);
}
// verify
for (int i = 0; i < N; i++) {
target.getPersistentProperty(names[i]);
}
}
}
private void join(Thread[] threads) {
//wait for all threads to finish
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException e) {
fail("#join", e);
}
}
}
/**
* Tests concurrent acces to the property store.
*/
public void testConcurrentAccess() {
// create common objects
final IFile target = projects[0].getFile("target");
try {
target.create(getRandomContents(), true, getMonitor());
} catch (CoreException e) {
fail("0.0", e);
}
// prepare keys and values
final int N = 50;
final QualifiedName[] names = new QualifiedName[N];
final String[] values = new String[N];
createProperties(target, names, values);
final CoreException[] errorPointer = new CoreException[1];
Thread[] threads = createThreads(target, names, values, errorPointer);
join(threads);
if (errorPointer[0] != null) {
fail("2.0", errorPointer[0]);
}
// remove trash
try {
target.delete(true, getMonitor());
} catch (CoreException e) {
fail("20.0", e);
}
}
/**
* Tests concurrent access to the property store while the project is being
* deleted.
*/
public void testConcurrentDelete() {
Thread[] threads;
final IFile target = projects[0].getFile("target");
final int REPEAT = 8;
for (int i = 0; i < REPEAT; i++) {
// create common objects
ensureExistsInWorkspace(projects[0], true);
ensureExistsInWorkspace(target, true);
// prepare keys and values
final int N = 50;
final QualifiedName[] names = new QualifiedName[N];
final String[] values = new String[N];
createProperties(target, names, values);
final CoreException[] errorPointer = new CoreException[1];
threads = createThreads(target, names, values, errorPointer);
try {
//give the threads a chance to start
Thread.sleep(10);
} catch (InterruptedException e) {
fail("1.98", e);
}
try {
//delete the project while the threads are still running
target.getProject().delete(IResource.NONE, getMonitor());
} catch (CoreException e) {
fail("1.99." + i, e);
}
join(threads);
if (errorPointer[0] != null) {
fail("2.0." + i, errorPointer[0]);
}
}
// remove trash
try {
target.delete(true, getMonitor());
} catch (CoreException e) {
fail("20.0", e);
}
}
public void testCopy() throws Throwable {
IPropertyManager manager = new PropertyManager2((Workspace) ResourcesPlugin.getWorkspace());
IProject source = projects[0];
IFolder sourceFolder = source.getFolder("myfolder");
IResource sourceFile = sourceFolder.getFile("myfile.txt");
IProject destination = projects[1];
IFolder destFolder = destination.getFolder(sourceFolder.getName());
IResource destFile = destFolder.getFile(sourceFile.getName());
QualifiedName propName = new QualifiedName("test", "prop");
String propValue = "this is the property value";
ensureExistsInWorkspace(new IResource[] {source, sourceFolder, sourceFile}, true);
/*
* persistent properties
*/
manager.setProperty(source, propName, propValue);
manager.setProperty(sourceFolder, propName, propValue);
manager.setProperty(sourceFile, propName, propValue);
assertNotNull("1.1", manager.getProperty(source, propName));
assertTrue("1.2", manager.getProperty(source, propName).equals(propValue));
assertNotNull("1.3", manager.getProperty(sourceFolder, propName));
assertTrue("1.4", manager.getProperty(sourceFolder, propName).equals(propValue));
assertNotNull("1.5", manager.getProperty(sourceFile, propName));
assertTrue("1.6", manager.getProperty(sourceFile, propName).equals(propValue));
// do the copy at the project level
manager.copy(source, destination, IResource.DEPTH_INFINITE);
assertNotNull("1.7", manager.getProperty(destination, propName));
assertTrue("1.8", manager.getProperty(destination, propName).equals(propValue));
assertNotNull("1.9", manager.getProperty(destFolder, propName));
assertTrue("1.10", manager.getProperty(destFolder, propName).equals(propValue));
assertNotNull("1.11", manager.getProperty(destFile, propName));
assertTrue("1.12", manager.getProperty(destFile, propName).equals(propValue));
// do the same thing but copy at the folder level
manager.deleteProperties(source, IResource.DEPTH_INFINITE);
manager.deleteProperties(destination, IResource.DEPTH_INFINITE);
assertNull("2.0", manager.getProperty(source, propName));
assertNull("2.1", manager.getProperty(sourceFolder, propName));
assertNull("2.2", manager.getProperty(sourceFile, propName));
assertNull("2.3", manager.getProperty(destination, propName));
assertNull("2.4", manager.getProperty(destFolder, propName));
assertNull("2.5", manager.getProperty(destFile, propName));
manager.setProperty(sourceFolder, propName, propValue);
manager.setProperty(sourceFile, propName, propValue);
assertNotNull("2.6", manager.getProperty(sourceFolder, propName));
assertTrue("2.7", manager.getProperty(sourceFolder, propName).equals(propValue));
assertNotNull("2.8", manager.getProperty(sourceFile, propName));
assertTrue("2.9", manager.getProperty(sourceFile, propName).equals(propValue));
manager.copy(sourceFolder, destFolder, IResource.DEPTH_INFINITE);
assertNotNull("2.10", manager.getProperty(destFolder, propName));
assertTrue("2.11", manager.getProperty(destFolder, propName).equals(propValue));
assertNotNull("2.12", manager.getProperty(destFile, propName));
assertTrue("2.13", manager.getProperty(destFile, propName).equals(propValue));
/* test overwrite */
String newPropValue = "change property value";
manager.setProperty(source, propName, newPropValue);
assertTrue("2.0", manager.getProperty(source, propName).equals(newPropValue));
manager.copy(source, destination, IResource.DEPTH_INFINITE);
assertTrue("2.1", manager.getProperty(destination, propName).equals(newPropValue));
}
public void testDeleteProperties() throws Throwable {
/* create common objects */
IPropertyManager manager = new PropertyManager2((Workspace) ResourcesPlugin.getWorkspace());
IFile target = projects[0].getFile("target");
ensureExistsInWorkspace(target, true);
/* server properties */
QualifiedName propName = new QualifiedName("eclipse", "prop");
String propValue = "this is the property value";
manager.setProperty(target, propName, propValue);
assertTrue("1.1", manager.getProperty(target, propName).equals(propValue));
/* delete */
manager.deleteProperties(target, IResource.DEPTH_INFINITE);
assertTrue("1.3", manager.getProperty(target, propName) == null);
//test deep deletion of project properties
IProject source = projects[0];
IFolder sourceFolder = source.getFolder("myfolder");
IResource sourceFile = sourceFolder.getFile("myfile.txt");
propName = new QualifiedName("test", "prop");
propValue = "this is the property value";
ensureExistsInWorkspace(new IResource[] {source, sourceFolder, sourceFile}, true);
/*
* persistent properties
*/
manager.setProperty(source, propName, propValue);
manager.setProperty(sourceFolder, propName, propValue);
manager.setProperty(sourceFile, propName, propValue);
assertNotNull("2.1", manager.getProperty(source, propName));
assertTrue("2.2", manager.getProperty(source, propName).equals(propValue));
assertNotNull("2.3", manager.getProperty(sourceFolder, propName));
assertTrue("2.4", manager.getProperty(sourceFolder, propName).equals(propValue));
assertNotNull("2.5", manager.getProperty(sourceFile, propName));
assertTrue("2.6", manager.getProperty(sourceFile, propName).equals(propValue));
//delete properties
manager.deleteProperties(source, IResource.DEPTH_INFINITE);
assertNull("3.1", manager.getProperty(source, propName));
assertNull("3.2", manager.getProperty(sourceFolder, propName));
assertNull("3.3", manager.getProperty(sourceFile, propName));
}
/**
* See bug 93849.
*/
public void testFileRename() {
IWorkspaceRoot root = getWorkspace().getRoot();
IProject project = root.getProject("proj");
IFolder folder = project.getFolder("folder");
IFile file1a = folder.getFile("file1");
ensureExistsInWorkspace(file1a, true);
QualifiedName key = new QualifiedName(PI_RESOURCES_TESTS, "key");
try {
file1a.setPersistentProperty(key, "value");
} catch (CoreException e) {
fail("0.5", e);
}
try {
file1a.move(new Path("file2"), true, getMonitor());
} catch (CoreException e) {
fail("0.6", e);
}
IFile file1b = folder.getFile("file1");
ensureExistsInWorkspace(file1b, true);
String value = null;
try {
value = file1b.getPersistentProperty(key);
} catch (CoreException e) {
fail("0.8", e);
}
assertNull("1.0", value);
file1a = folder.getFile("file2");
try {
value = file1a.getPersistentProperty(key);
} catch (CoreException e) {
fail("1.9", e);
}
assertEquals("2.0", "value", value);
}
/**
* See bug 93849.
*/
public void testFolderRename() {
IWorkspaceRoot root = getWorkspace().getRoot();
IProject project = root.getProject("proj");
IFolder folder1a = project.getFolder("folder1");
ensureExistsInWorkspace(folder1a, true);
QualifiedName key = new QualifiedName(PI_RESOURCES_TESTS, "key");
try {
folder1a.setPersistentProperty(key, "value");
} catch (CoreException e) {
fail("0.5", e);
}
try {
folder1a.move(new Path("folder2"), true, getMonitor());
} catch (CoreException e) {
fail("0.6", e);
}
IFolder folder1b = project.getFolder("folder1");
ensureExistsInWorkspace(folder1b, true);
String value = null;
try {
value = folder1b.getPersistentProperty(key);
} catch (CoreException e) {
fail("0.8", e);
}
assertNull("1.0", value);
folder1a = project.getFolder("folder2");
try {
value = folder1a.getPersistentProperty(key);
} catch (CoreException e) {
fail("1.9", e);
}
assertEquals("2.0", "value", value);
}
/**
* Do a stress test by adding a very large property to the store.
*/
public void testLargeProperty() {
// create common objects
IFile target = projects[0].getFile("target");
try {
target.create(getRandomContents(), true, getMonitor());
} catch (CoreException e) {
fail("0.0", e);
}
QualifiedName name = new QualifiedName("stressTest", "prop");
final int SIZE = 10000;
StringBuffer valueBuf = new StringBuffer(SIZE);
for (int i = 0; i < SIZE; i++) {
valueBuf.append("a");
}
String value = valueBuf.toString();
try {
target.setPersistentProperty(name, value);
//should fail
fail("1.0");
} catch (CoreException e) {
// expected
}
// remove trash
try {
target.delete(true, getMonitor());
} catch (CoreException e) {
fail("20.0", e);
}
}
/**
* See bug 93849.
*/
public void testProjectRename() {
IWorkspaceRoot root = getWorkspace().getRoot();
IProject project1a = root.getProject("proj1");
ensureExistsInWorkspace(project1a, true);
QualifiedName key = new QualifiedName(PI_RESOURCES_TESTS, "key");
try {
project1a.setPersistentProperty(key, "value");
} catch (CoreException e) {
fail("0.5", e);
}
try {
project1a.move(new Path("proj2"), true, getMonitor());
} catch (CoreException e) {
fail("0.6", e);
}
IProject project1b = root.getProject("proj1");
ensureExistsInWorkspace(project1b, true);
String value = null;
try {
value = project1b.getPersistentProperty(key);
} catch (CoreException e) {
fail("0.8", e);
}
assertNull("1.0", value);
project1a = root.getProject("proj2");
try {
value = project1a.getPersistentProperty(key);
} catch (CoreException e) {
fail("1.9", e);
}
assertEquals("2.0", "value", value);
}
public void testProperties() throws Throwable {
IProgressMonitor monitor = null;
// create common objects
IPropertyManager manager = new PropertyManager2((Workspace) ResourcesPlugin.getWorkspace());
IFile target = projects[0].getFile("target");
target.create(null, false, monitor);
// these are the properties that we are going to use
QualifiedName propName1 = new QualifiedName("org.eclipse.core.tests", "prop1");
QualifiedName propName2 = new QualifiedName("org.eclipse.core.tests", "prop2");
QualifiedName propName3 = new QualifiedName("org.eclipse.core.tests", "prop3");
String propValue1 = "this is the property value1";
String propValue2 = "this is the property value2";
String propValue3 = "this is the property value3";
Vector<StoredProperty> props = new Vector<>(3);
props.addElement(new StoredProperty(propName1, propValue1));
props.addElement(new StoredProperty(propName2, propValue2));
props.addElement(new StoredProperty(propName3, propValue3));
// set the properties individually and retrieve them
for (StoredProperty prop : props) {
manager.setProperty(target, prop.getName(), prop.getStringValue());
assertEquals("1.0." + prop.getName(), prop.getStringValue(), manager.getProperty(target, prop.getName()));
}
// check properties are be appropriately deleted (when set to null)
for (StoredProperty prop : props) {
manager.setProperty(target, prop.getName(), null);
assertEquals("2.0." + prop.getName(), null, manager.getProperty(target, prop.getName()));
}
assertEquals("3.0", 0, manager.getProperties(target).size());
manager.deleteProperties(target, IResource.DEPTH_INFINITE);
// remove trash
target.delete(false, monitor);
}
public void testSimpleUpdate() {
// create common objects
IFile target = projects[0].getFile("target");
try {
target.create(getRandomContents(), true, getMonitor());
} catch (CoreException e) {
fail("0.0", e);
}
// prepare keys and values
int N = 3;
QualifiedName[] names = new QualifiedName[3];
String[] values = new String[N];
for (int i = 0; i < N; i++) {
names[i] = new QualifiedName("org.eclipse.core.tests", "prop" + i);
values[i] = "property value" + i;
}
// create properties
for (int i = 0; i < N; i++) {
try {
target.setPersistentProperty(names[i], values[i]);
} catch (CoreException e) {
fail("1." + i, e);
}
}
// verify
for (int i = 0; i < N; i++) {
try {
assertTrue("2.0", target.getPersistentProperty(names[i]).equals(values[i]));
} catch (CoreException e) {
fail("3." + i, e);
}
}
for (int j = 0; j < 20; j++) {
// change properties
for (int i = 0; i < N; i++) {
try {
values[i] = values[i] + " - changed";
target.setPersistentProperty(names[i], values[i]);
} catch (CoreException e) {
fail("4." + i, e);
}
}
// verify
for (int i = 0; i < N; i++) {
try {
assertTrue("5.0", target.getPersistentProperty(names[i]).equals(values[i]));
} catch (CoreException e) {
fail("6." + i, e);
}
}
}
// remove trash
try {
target.delete(true, getMonitor());
} catch (CoreException e) {
fail("20.0", e);
}
}
}