/******************************************************************************* * Copyright (c) 2000, 2012 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 *******************************************************************************/ package org.eclipse.core.tests.resources.regression; import java.io.IOException; import java.io.InputStream; import junit.framework.Test; import junit.framework.TestSuite; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.internal.resources.Resource; import org.eclipse.core.resources.*; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.Platform; import org.eclipse.core.tests.resources.ResourceTest; /** * When moving a resource "x" from parent "a" to parent "b", if "x" or any of * its children can't be deleted, both "a" and "b" become out-of-sync and resource info is lost. */ public class Bug_032076 extends ResourceTest { public Bug_032076() { super(""); } public Bug_032076(String name) { super(name); } public static Test suite() { return new TestSuite(Bug_032076.class); } public void testFileBugOnWindows() { if (!isWindows()) { return; } InputStream input = null; IProject project = null; try { IWorkspace workspace = getWorkspace(); project = workspace.getRoot().getProject(getUniqueString()); IFolder sourceParent = project.getFolder("source_parent"); IFolder destinationParent = project.getFolder("destination_parent"); // this file will be made irremovable IFile sourceFile = sourceParent.getFile("file1.txt"); IFile destinationFile = destinationParent.getFile(sourceFile.getName()); ensureExistsInWorkspace(new IResource[] {sourceFile, destinationParent}, true); // add a marker to a file to ensure the move operation is not losing anything String attributeKey = getRandomString(); String attributeValue = getRandomString(); long markerId = -1; try { IMarker bookmark = null; bookmark = sourceFile.createMarker(IMarker.BOOKMARK); bookmark.setAttribute(attributeKey, attributeValue); markerId = bookmark.getId(); } catch (CoreException e) { fail("0.1", e); } // opens the file so it cannot be removed on Windows try { input = sourceFile.getContents(); } catch (CoreException ce) { fail("1.0"); } try { sourceFile.move(destinationFile.getFullPath(), IResource.FORCE, getMonitor()); fail("2.0"); } catch (CoreException ce) { // success } // the source parent is in sync assertTrue("3.0", sourceParent.isSynchronized(IResource.DEPTH_INFINITE)); // the target parent is in sync assertTrue("3.1", destinationParent.isSynchronized(IResource.DEPTH_INFINITE)); // file has been copied to destination assertTrue("3.4", destinationFile.exists()); // ensure marker info has not been lost try { IMarker marker = destinationFile.findMarker(markerId); assertNotNull("3.6", marker); assertEquals("3.7", attributeValue, marker.getAttribute(attributeKey)); } catch (CoreException e) { fail("3.8", e); } // non-removable file has been moved (but not in file system - they are out-of-sync) assertTrue("4.1", sourceFile.exists()); assertTrue("4.2", sourceFile.isSynchronized(IResource.DEPTH_ZERO)); // refresh the source parent try { sourceParent.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); } catch (CoreException e) { fail("4.4"); } // file is still found in source tree assertTrue("4.7", sourceFile.exists()); } finally { try { if (input != null) { input.close(); } } catch (IOException e) { fail("5.0", e); } finally { if (project != null) { ensureDoesNotExistInFileSystem(project); } } } } public void testFolderBugOnWindows() { if (!isWindows()) { return; } InputStream input = null; IProject project = null; try { IWorkspace workspace = getWorkspace(); project = workspace.getRoot().getProject(getUniqueString()); IFolder sourceParent = project.getFolder("source_parent"); IFolder destinationParent = project.getFolder("destination_parent"); IFolder folder = sourceParent.getFolder("folder"); IFolder destinationFolder = destinationParent.getFolder(folder.getName()); // this file will be made un-removable IFile file1 = folder.getFile("file1.txt"); // but not this one IFile file2 = folder.getFile("file2.txt"); ensureExistsInWorkspace(new IResource[] {file1, file2, destinationParent}, true); // add a marker to a file to ensure the move operation is not losing anything String attributeKey = getRandomString(); String attributeValue = getRandomString(); long markerId = -1; try { IMarker bookmark = null; bookmark = file1.createMarker(IMarker.BOOKMARK); bookmark.setAttribute(attributeKey, attributeValue); markerId = bookmark.getId(); } catch (CoreException e) { fail("0.1", e); } // opens a file so it (and its parent) cannot be removed on Windows try { input = file1.getContents(); } catch (CoreException ce) { fail("1.0", ce); } try { folder.move(destinationFolder.getFullPath(), IResource.FORCE, getMonitor()); fail("2.0"); } catch (CoreException ce) { // success } // the source parent is in sync assertTrue("3.0", sourceParent.isSynchronized(IResource.DEPTH_INFINITE)); // the target parent is in-sync assertTrue("3.1", destinationParent.isSynchronized(IResource.DEPTH_INFINITE)); // resources have been copied to destination assertTrue("3.3", destinationFolder.exists()); assertTrue("3.4", destinationFolder.getFile(file1.getName()).exists()); assertTrue("3.5", destinationFolder.getFile(file2.getName()).exists()); // ensure marker info has not been lost try { IMarker marker = destinationFolder.getFile(file1.getName()).findMarker(markerId); assertNotNull("3.6", marker); assertEquals("3.7", attributeValue, marker.getAttribute(attributeKey)); } catch (CoreException e) { fail("3.8", e); } // non-removable resources still exist in source assertTrue("4.1", folder.exists()); assertTrue("4.2", file1.exists()); //this file should be successfully moved assertTrue("4.3", !file2.exists()); // refresh the source parent try { sourceParent.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); } catch (CoreException e) { fail("4.4"); } // non-removable resources still in source tree assertTrue("4.6", folder.exists()); assertTrue("4.7", file1.exists()); assertTrue("4.8", !file2.exists()); } finally { try { if (input != null) { input.close(); } } catch (IOException e) { fail("5.0", e); } finally { if (project != null) { ensureDoesNotExistInFileSystem(project); } } } } public void testProjectBugOnWindows() { if (!isWindows()) { return; } IProject sourceProject = null; IProject destinationProject = null; InputStream input = null; try { IWorkspace workspace = getWorkspace(); sourceProject = workspace.getRoot().getProject(getUniqueString() + ".source"); destinationProject = workspace.getRoot().getProject(getUniqueString() + ".dest"); // this file will be made un-removable IFile file1 = sourceProject.getFile("file1.txt"); // but not this one IFile file2 = sourceProject.getFile("file2.txt"); ensureExistsInWorkspace(new IResource[] {file1, file2}, true); // add a marker to a file to ensure the move operation is not losing anything String attributeKey = getRandomString(); String attributeValue = getRandomString(); long markerId = -1; try { IMarker bookmark = null; bookmark = file1.createMarker(IMarker.BOOKMARK); bookmark.setAttribute(attributeKey, attributeValue); markerId = bookmark.getId(); } catch (CoreException e) { fail("0.1", e); } // opens a file so it (and its parent) cannot be removed on Windows try { input = file1.getContents(); } catch (CoreException ce) { fail("1.0", ce); } try { sourceProject.move(destinationProject.getFullPath(), IResource.FORCE, getMonitor()); fail("2.0"); } catch (CoreException ce) { // success } // the source does not exist assertTrue("3.0", !sourceProject.exists()); assertTrue("3.1", sourceProject.isSynchronized(IResource.DEPTH_INFINITE)); // the target exists and is in sync assertTrue("3.2", destinationProject.exists()); assertTrue("3.3", destinationProject.isSynchronized(IResource.DEPTH_INFINITE)); // resources have been copied to destination assertTrue("3.4", destinationProject.getFile(file1.getProjectRelativePath()).exists()); assertTrue("3.5", destinationProject.getFile(file2.getProjectRelativePath()).exists()); // ensure marker info has not been lost try { IMarker marker = destinationProject.getFile(file1.getProjectRelativePath()).findMarker(markerId); assertNotNull("3.6", marker); assertEquals("3.7", attributeValue, marker.getAttribute(attributeKey)); } catch (CoreException e) { fail("3.8", e); } assertTrue("5.0", workspace.getRoot().isSynchronized(IResource.DEPTH_INFINITE)); } finally { try { if (input != null) { input.close(); } } catch (IOException e) { fail("6.0", e); } finally { if (sourceProject != null) { ensureDoesNotExistInFileSystem(sourceProject); } if (destinationProject != null) { ensureDoesNotExistInFileSystem(destinationProject); } } } } /** * TODO: This test is currently failing and needs further investigation (bug 203078) */ public void _testFileBugOnLinux() { if (!(Platform.getOS().equals(Platform.OS_LINUX) && isReadOnlySupported())) { return; } IFileStore roFolderStore = null; IProject project = null; try { IWorkspace workspace = getWorkspace(); project = workspace.getRoot().getProject(getUniqueString()); IFolder sourceParent = project.getFolder("source_parent"); IFolder roFolder = sourceParent.getFolder("sub-folder"); IFolder destinationParent = project.getFolder("destination_parent"); // this file will be made un-removable IFile sourceFile = roFolder.getFile("file.txt"); IFile destinationFile = destinationParent.getFile("file.txt"); ensureExistsInWorkspace(new IResource[] {sourceFile, destinationParent}, true); roFolderStore = ((Resource) roFolder).getStore(); // add a marker to a file to ensure the move operation is not losing anything String attributeKey = getRandomString(); String attributeValue = getRandomString(); long markerId = -1; try { IMarker bookmark = null; bookmark = sourceFile.createMarker(IMarker.BOOKMARK); bookmark.setAttribute(attributeKey, attributeValue); markerId = bookmark.getId(); } catch (CoreException e) { fail("0.1", e); } // mark sub-folder as read-only so its immediate children cannot be removed on Linux setReadOnly(roFolder, true); try { sourceFile.move(destinationFile.getFullPath(), IResource.FORCE, getMonitor()); fail("2.0"); } catch (CoreException ce) { // success } // the source parent is out-of-sync assertTrue("3.0", !sourceParent.isSynchronized(IResource.DEPTH_INFINITE)); // the target parent is in-sync assertTrue("3.1", destinationParent.isSynchronized(IResource.DEPTH_INFINITE)); // file has been copied to destination assertTrue("3.4", destinationFile.exists()); // ensure marker info has not been lost try { IMarker marker = destinationFile.findMarker(markerId); assertNotNull("3.6", marker); assertEquals("3.7", attributeValue, marker.getAttribute(attributeKey)); } catch (CoreException e) { fail("3.8", e); } // non-removable file has been moved (but not in file system - they are out-of-sync) assertTrue("4.1", !sourceFile.exists()); // refresh the source parent try { sourceParent.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); } catch (CoreException e) { fail("4.4"); } // non-removable file now reappear in the resource tree assertTrue("4.7", sourceFile.exists()); } finally { if (roFolderStore != null) { setReadOnly(roFolderStore, false); } if (project != null) { ensureDoesNotExistInFileSystem(project); } } } /** * TODO: This test is currently failing and needs further investigation (bug 203078) */ public void _testFolderBugOnLinux() { if (!(Platform.getOS().equals(Platform.OS_LINUX) && isReadOnlySupported())) { return; } IFileStore roFolderLocation = null, destinationROFolderLocation = null; IProject project = null; try { IWorkspace workspace = getWorkspace(); project = workspace.getRoot().getProject(getUniqueString()); IFolder sourceParent = project.getFolder("source_parent"); IFolder roFolder = sourceParent.getFolder("sub-folder"); IFolder folder = roFolder.getFolder("folder"); IFile file1 = roFolder.getFile("file1.txt"); IFile file2 = folder.getFile("file2.txt"); IFolder destinationParent = project.getFolder("destination_parent"); IFolder destinationROFolder = destinationParent.getFolder(roFolder.getName()); ensureExistsInWorkspace(new IResource[] {file1, file2, destinationParent}, true); roFolderLocation = ((Resource) roFolder).getStore(); destinationROFolderLocation = ((Resource) destinationROFolder).getStore(); // add a marker to a file to ensure the move operation is not losing anything String attributeKey = getRandomString(); String attributeValue = getRandomString(); long markerId = -1; try { IMarker bookmark = null; bookmark = file1.createMarker(IMarker.BOOKMARK); bookmark.setAttribute(attributeKey, attributeValue); markerId = bookmark.getId(); } catch (CoreException e) { fail("0.1", e); } // mark sub-folder as read-only so its immediate children cannot be removed on Linux setReadOnly(roFolder, true); try { roFolder.move(destinationParent.getFullPath().append(roFolder.getName()), IResource.FORCE, getMonitor()); fail("2.0"); } catch (CoreException ce) { // success } // the source parent is out-of-sync assertTrue("3.0", !sourceParent.isSynchronized(IResource.DEPTH_INFINITE)); // the target parent is in-sync assertTrue("3.1", destinationParent.isSynchronized(IResource.DEPTH_INFINITE)); // resources have been copied to destination IFolder destinationFolder = destinationROFolder.getFolder(folder.getName()); IFile destinationFile1 = destinationROFolder.getFile(file1.getName()); IFile destinationFile2 = destinationFolder.getFile(file2.getName()); assertTrue("3.2", destinationROFolder.exists()); assertTrue("3.4", destinationFolder.exists()); assertTrue("3.5", destinationFile1.exists()); assertTrue("3.6", destinationFile2.exists()); // ensure marker info has not been lost try { IMarker marker = destinationROFolder.getFile(file1.getName()).findMarker(markerId); assertNotNull("3.7", marker); assertEquals("3.8", attributeValue, marker.getAttribute(attributeKey)); } catch (CoreException e) { fail("3.9", e); } // non-removable resources have been moved (but not in file system - they are out-of-sync) assertTrue("4.0", !roFolder.exists()); assertTrue("4.1", !folder.exists()); assertTrue("4.2", !file1.exists()); assertTrue("4.3", !file2.exists()); // refresh the source parent try { sourceParent.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); } catch (CoreException e) { fail("4.4"); } // non-removed resources now reappear in the resource tree assertTrue("4.5", roFolder.exists()); assertTrue("4.6", folder.exists()); assertTrue("4.7", file1.exists()); assertTrue("4.8", !file2.exists()); } finally { if (roFolderLocation != null) { setReadOnly(roFolderLocation, false); } if (destinationROFolderLocation != null) { setReadOnly(destinationROFolderLocation, false); } if (project != null) { ensureDoesNotExistInFileSystem(project); } } } /** * TODO: This test is currently failing and needs further investigation (bug 203078) */ public void _testProjectBugOnLinux() { if (!(Platform.getOS().equals(Platform.OS_LINUX) && isReadOnlySupported())) { return; } IWorkspace workspace = getWorkspace(); IProject sourceProject = workspace.getRoot().getProject(getUniqueString() + ".source"); IProject destinationProject = null; IFileStore projectParentStore = getTempStore(); IFileStore projectStore = projectParentStore.getChild(sourceProject.getName()); try { IProjectDescription sourceDescription = workspace.newProjectDescription(sourceProject.getName()); sourceDescription.setLocationURI(projectStore.toURI()); destinationProject = workspace.getRoot().getProject(getUniqueString() + ".dest"); IProjectDescription destinationDescription = workspace.newProjectDescription(destinationProject.getName()); // create and open the source project at a non-default location try { sourceProject.create(sourceDescription, getMonitor()); } catch (CoreException e) { fail("0.1", e); } try { sourceProject.open(getMonitor()); } catch (CoreException e) { fail("0.2", e); } IFile file1 = sourceProject.getFile("file1.txt"); ensureExistsInWorkspace(new IResource[] {file1}, true); // add a marker to a file to ensure the move operation is not losing anything String attributeKey = getRandomString(); String attributeValue = getRandomString(); long markerId = -1; try { IMarker bookmark = null; bookmark = file1.createMarker(IMarker.BOOKMARK); bookmark.setAttribute(attributeKey, attributeValue); markerId = bookmark.getId(); } catch (CoreException e) { fail("0.5", e); } // mark sub-folder as read-only so its immediate children cannot be removed on Linux setReadOnly(projectParentStore, true); try { sourceProject.move(destinationDescription, IResource.FORCE, getMonitor()); fail("2.0"); } catch (CoreException ce) { // success } // the source does not exist assertTrue("3.0", !sourceProject.exists()); // the target exists and is in sync assertTrue("3.1", destinationProject.exists()); assertTrue("3.2", destinationProject.isSynchronized(IResource.DEPTH_INFINITE)); // resources have been copied to destination assertTrue("3.4", destinationProject.getFile(file1.getProjectRelativePath()).exists()); // ensure marker info has not been lost try { IMarker marker = destinationProject.getFile(file1.getProjectRelativePath()).findMarker(markerId); assertNotNull("3.6", marker); assertEquals("3.7", attributeValue, marker.getAttribute(attributeKey)); } catch (CoreException e) { fail("3.8", e); } // project's content area still exists in file system assertTrue("4.0", projectStore.fetchInfo().exists()); assertTrue("5.0", workspace.getRoot().isSynchronized(IResource.DEPTH_INFINITE)); } finally { setReadOnly(projectParentStore, false); ensureDoesNotExistInFileSystem(sourceProject); if (destinationProject != null) { ensureDoesNotExistInFileSystem(destinationProject); } } } }