| /******************************************************************************* |
| * 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); |
| } |
| } |
| |
| } |