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