/******************************************************************************* * 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 *******************************************************************************/ package org.eclipse.core.tests.internal.localstore; import junit.framework.Test; import junit.framework.TestSuite; import org.eclipse.core.internal.resources.*; import org.eclipse.core.resources.*; import org.eclipse.core.runtime.*; /** * Tests the move operation. */ public class MoveTest extends LocalStoreTest { public MoveTest() { super(); } public MoveTest(String name) { super(name); } @Override public String[] defineHierarchy() { return new String[] {"/", "/file1", "/file2", "/folder1/", "/folder1/file3", "/folder1/file4", "/folder2/", "/folder2/file5", "/folder2/file6", "/folder1/folder3/", "/folder1/folder3/file7", "/folder1/folder3/file8"}; } public static Test suite() { TestSuite suite = new TestSuite(MoveTest.class.getName()); suite.addTest(new MoveTest("testRenameProjects")); suite.addTest(new MoveTest("testRenameFolder")); suite.addTest(new MoveTest("testRenameFile")); suite.addTest(new MoveTest("testMoveFolderBetweenProjects")); suite.addTest(new MoveTest("testMoveFileBetweenProjects")); suite.addTest(new MoveTest("testMoveFolderAcrossVolumes")); suite.addTest(new MoveTest("testMoveFileAcrossVolumes")); suite.addTest(new MoveTest("testMoveHierarchy")); suite.addTest(new MoveTest("testMoveHierarchyBetweenProjects")); suite.addTest(new MoveTest("testMoveResource")); return suite; } /** * This test has Windows as the target OS. Drives C: and D: should be available. */ public void testMoveFileAcrossVolumes() { if (!isWindows()) { return; } /* look for the adequate environment */ String[] devices = findAvailableDevices(); if (devices[0] == null || devices[1] == null) { return; } // create common objects String location = getUniqueString(); IProject source = getWorkspace().getRoot().getProject(location + "1"); IProject destination = getWorkspace().getRoot().getProject(location + "2"); try { source.create(getMonitor()); source.open(getMonitor()); IProjectDescription description = getWorkspace().newProjectDescription(destination.getName()); description.setLocation(new Path(devices[1] + location)); destination.create(description, getMonitor()); destination.open(getMonitor()); } catch (CoreException e) { fail("0.0", e); } String fileName = "fileToBeMoved.txt"; IFile file = source.getFile(fileName); try { file.create(getRandomContents(), true, getMonitor()); } catch (CoreException e) { fail("1.0", e); } // add some properties to file (persistent and session) QualifiedName[] propNames = new QualifiedName[numberOfProperties]; String[] propValues = new String[numberOfProperties]; try { for (int j = 0; j < numberOfProperties; j++) { propNames[j] = new QualifiedName("test", "prop" + j); propValues[j] = "value" + j; file.setPersistentProperty(propNames[j], propValues[j]); file.setSessionProperty(propNames[j], propValues[j]); } } catch (CoreException e) { fail("2.0", e); } // move file IPath dest = destination.getFile(fileName).getFullPath(); try { file.move(dest, true, getMonitor()); } catch (CoreException e) { fail("3.0", e); } // assert file was moved IFile newFile = destination.getFile(fileName); assertDoesNotExistInWorkspace("4.1", file); assertDoesNotExistInFileSystem("4.2", file); assertExistsInWorkspace("4.3", newFile); assertExistsInFileSystem("4.4", newFile); // assert properties still exist (server, local and session) try { for (int j = 0; j < numberOfProperties; j++) { String persistentValue = newFile.getPersistentProperty(propNames[j]); Object sessionValue = newFile.getSessionProperty(propNames[j]); assertEquals("5.1", persistentValue, propValues[j]); assertEquals("5.2", sessionValue, propValues[j]); } } catch (CoreException e) { fail("5.3", e); } // remove garbage try { source.delete(true, true, getMonitor()); destination.delete(true, true, getMonitor()); } catch (CoreException e) { fail("20.0", e); } } /** * Move one file from one project to another. */ public void testMoveFileBetweenProjects() throws Exception { // create common objects IProject[] projects = getWorkspace().getRoot().getProjects(); // get file instance String fileName = "newFile.txt"; IFile file = projects[0].getFile(fileName); ensureExistsInWorkspace(file, true); // add some properties to file (persistent and session) QualifiedName[] propNames = new QualifiedName[numberOfProperties]; String[] propValues = new String[numberOfProperties]; for (int j = 0; j < numberOfProperties; j++) { propNames[j] = new QualifiedName("test", "prop" + j); propValues[j] = "value" + j; file.setPersistentProperty(propNames[j], propValues[j]); file.setSessionProperty(propNames[j], propValues[j]); } // move file IPath destination = projects[1].getFile(fileName).getFullPath(); file.move(destination, true, null); // get new file instance IFile newFile = projects[1].getFile(fileName); // assert file was renamed assertDoesNotExistInWorkspace(file); assertDoesNotExistInFileSystem(file); assertExistsInWorkspace(newFile); assertExistsInFileSystem(newFile); // assert properties still exist (server, local and session) for (int j = 0; j < numberOfProperties; j++) { String persistentValue = newFile.getPersistentProperty(propNames[j]); Object sessionValue = newFile.getSessionProperty(propNames[j]); assertTrue("persistent property value is not the same", propValues[j].equals(persistentValue)); assertTrue("session property value is not the same", propValues[j].equals(sessionValue)); } } /** * This test has Windows as the target OS. Drives C: and D: should be available. */ public void testMoveFolderAcrossVolumes() { if (!isWindows()) { return; } /* look for the adequate environment */ String[] devices = findAvailableDevices(); if (devices[0] == null || devices[1] == null) { return; } // create common objects String location = getUniqueString(); IProject source = getWorkspace().getRoot().getProject(location + "1"); IProject destination = getWorkspace().getRoot().getProject(location + "2"); try { source.create(getMonitor()); source.open(getMonitor()); IProjectDescription description = getWorkspace().newProjectDescription(destination.getName()); description.setLocation(new Path(devices[1] + location)); destination.create(description, getMonitor()); destination.open(getMonitor()); } catch (CoreException e) { fail("0.0", e); } // get folder instance String folderName = "folderToBeMoved"; IFolder folder = source.getFolder(folderName); try { folder.create(true, true, getMonitor()); } catch (CoreException e) { fail("1.0", e); } // add some properties to file (persistent and session) QualifiedName[] propNames = new QualifiedName[numberOfProperties]; String[] propValues = new String[numberOfProperties]; try { for (int j = 0; j < numberOfProperties; j++) { propNames[j] = new QualifiedName("test", "prop" + j); propValues[j] = "value" + j; folder.setPersistentProperty(propNames[j], propValues[j]); folder.setSessionProperty(propNames[j], propValues[j]); } } catch (CoreException e) { fail("2.0", e); } // rename folder IPath dest = destination.getFile(folderName).getFullPath(); try { folder.move(dest, true, getMonitor()); } catch (CoreException e) { fail("3.0", e); } // assert folder was renamed IFolder newFolder = destination.getFolder(folderName); assertDoesNotExistInWorkspace("4.1", folder); assertDoesNotExistInFileSystem("4.2", folder); assertExistsInWorkspace("4.3", newFolder); assertExistsInFileSystem("4.4", newFolder); // assert properties still exist (server, local and session) try { for (int j = 0; j < numberOfProperties; j++) { String persistentValue = newFolder.getPersistentProperty(propNames[j]); Object sessionValue = newFolder.getSessionProperty(propNames[j]); assertEquals("5.1", persistentValue, propValues[j]); assertEquals("5.2", sessionValue, propValues[j]); } } catch (CoreException e) { fail("5.3", e); } // remove garbage try { source.delete(true, true, getMonitor()); destination.delete(true, true, getMonitor()); } catch (CoreException e) { fail("6.0", e); } } /** * Move one folder from one project to another. */ public void testMoveFolderBetweenProjects() throws Exception { // create common objects IProject[] projects = getWorkspace().getRoot().getProjects(); // get folder instance String folderName = "newFolder"; IFolder folder = projects[0].getFolder(folderName); ensureExistsInWorkspace(folder, true); // add some properties to folder (persistent and session) QualifiedName[] propNames = new QualifiedName[numberOfProperties]; String[] propValues = new String[numberOfProperties]; for (int j = 0; j < numberOfProperties; j++) { propNames[j] = new QualifiedName("test", "prop" + j); propValues[j] = "value" + j; folder.setPersistentProperty(propNames[j], propValues[j]); folder.setSessionProperty(propNames[j], propValues[j]); } // rename folder IPath destination = projects[1].getFolder(folderName).getFullPath(); folder.move(destination, true, null); // get new folder instance IFolder newFolder = projects[1].getFolder(folderName); // assert folder was renamed assertDoesNotExistInWorkspace(folder); assertDoesNotExistInFileSystem(folder); assertExistsInWorkspace(newFolder); assertExistsInFileSystem(newFolder); // assert properties still exist (server, local and session) for (int j = 0; j < numberOfProperties; j++) { String persistentValue = newFolder.getPersistentProperty(propNames[j]); Object sessionValue = newFolder.getSessionProperty(propNames[j]); assertTrue("persistent property value is not the same", propValues[j].equals(persistentValue)); assertTrue("session property value is not the same", propValues[j].equals(sessionValue)); } } /** * Move some hierarchy of folders and files. */ public void testMoveHierarchy() throws Exception { // create common objects IProject[] projects = getWorkspace().getRoot().getProjects(); // create the source folder String folderSourceName = "folder source"; IFolder folderSource = projects[0].getFolder(folderSourceName); ensureExistsInWorkspace(folderSource, true); // create hierarchy String[] hierarchy = defineHierarchy(); IResource[] resources = buildResources(folderSource, hierarchy); ensureExistsInWorkspace(resources, true); // add some properties to each resource (persistent and session) String[] propNames = new String[numberOfProperties]; String[] propValues = new String[numberOfProperties]; for (int j = 0; j < numberOfProperties; j++) { propNames[j] = "prop" + j; propValues[j] = "value" + j; for (IResource resource : resources) { QualifiedName propName = new QualifiedName("test", resource.getName() + propNames[j]); String propValue = resource.getName() + propValues[j]; resource.setPersistentProperty(propName, propValue); resource.setSessionProperty(propName, propValue); } } // create the destination folder String folderDestinationName = "folder destination"; IFolder folderDestination = projects[0].getFolder(folderDestinationName); // move hierarchy //IProgressMonitor monitor = new LoggingProgressMonitor(System.out); IProgressMonitor monitor = getMonitor(); folderSource.move(folderDestination.getFullPath(), true, monitor); // get new hierarchy instance IResource[] newResources = buildResources(folderDestination, hierarchy); // assert hierarchy was moved assertDoesNotExistInWorkspace(resources); assertDoesNotExistInFileSystem(resources); assertExistsInWorkspace(newResources); assertExistsInFileSystem(newResources); // assert properties still exist (server, local and session) for (int j = 0; j < numberOfProperties; j++) { for (int i = 0; i < newResources.length; i++) { IResource destResource = newResources[i]; IResource sourceResource = resources[i]; /* The names of the properties will remain the same in both the source and destination hierarchies. So, be sure to use sourceResource to get the name or your qualified name will contain 'folder destination' instead of 'folder source' and the property value will be null. */ QualifiedName propName = new QualifiedName("test", sourceResource.getName() + propNames[j]); String propValue = sourceResource.getName() + propValues[j]; String persistentValue = destResource.getPersistentProperty(propName); Object sessionValue = destResource.getSessionProperty(propName); assertTrue("persistent property value is not the same", propValue.equals(persistentValue)); assertTrue("session property value is not the same", propValue.equals(sessionValue)); } } } /** * Move some hierarchy of folders and files between projects. It also test moving a * hierarchy across volumes. */ public void testMoveHierarchyBetweenProjects() throws Exception { // create common objects IProject[] projects = getWorkspace().getRoot().getProjects(); // create the source folder String folderSourceName = "source"; IFolder folderSource = projects[0].getFolder(folderSourceName); ensureExistsInWorkspace(folderSource, true); // build hierarchy String[] hierarchy = defineHierarchy(); IResource[] resources = buildResources(folderSource, hierarchy); ensureExistsInWorkspace(resources, true); // add some properties to each resource String[] propNames = new String[numberOfProperties]; String[] propValues = new String[numberOfProperties]; for (int j = 0; j < numberOfProperties; j++) { propNames[j] = "prop" + j; propValues[j] = "value" + j; for (IResource resource : resources) { QualifiedName propName = new QualifiedName("test", resource.getName() + propNames[j]); String propValue = resource.getName() + propValues[j]; resource.setPersistentProperty(propName, propValue); resource.setSessionProperty(propName, propValue); } } // create the destination folder String folderDestinationName = "destination"; IFolder folderDestination = projects[1].getFolder(folderDestinationName); // move hierarchy folderSource.move(folderDestination.getFullPath(), true, null); // get new hierarchy instance IResource[] newResources = buildResources(folderDestination, hierarchy); // assert hierarchy was moved assertDoesNotExistInWorkspace(resources); assertDoesNotExistInFileSystem(resources); assertExistsInWorkspace(newResources); assertExistsInFileSystem(newResources); // assert properties still exist (server, local and session) for (int j = 0; j < numberOfProperties; j++) { for (int i = 0; i < newResources.length; i++) { IResource destResource = newResources[i]; IResource sourceResource = resources[i]; /* The names of the properties will remain the same in both the source and destination hierarchies. So, be sure to use sourceResource to get the name or your qualified name will contain 'destination' instead of 'source' and the property value will be null. */ QualifiedName propName = new QualifiedName("test", sourceResource.getName() + propNames[j]); String propValue = sourceResource.getName() + propValues[j]; String persistentValue = destResource.getPersistentProperty(propName); Object sessionValue = destResource.getSessionProperty(propName); assertTrue("persistent property value is not the same", propValue.equals(persistentValue)); assertTrue("session property value is not the same", propValue.equals(sessionValue)); } } } public void testMoveResource() throws Exception { /* create common objects */ IProject[] projects = getWorkspace().getRoot().getProjects(); /* create folder and file */ IFolder folder = projects[0].getFolder("folder"); IFile file = folder.getFile("file.txt"); ensureExistsInWorkspace(folder, true); ensureExistsInWorkspace(file, true); /* move to absolute destination */ IResource destination = projects[0].getFile("file.txt"); file.move(destination.getFullPath(), true, null); assertTrue("1.1", !file.exists()); assertTrue("1.2", destination.exists()); destination.move(file.getFullPath(), true, null); assertTrue("1.3", file.exists()); assertTrue("1.4", !destination.exists()); /* move to relative destination */ IPath path = new Path("destination"); destination = folder.getFile(path); file.move(path, true, null); assertTrue("2.1", !file.exists()); assertTrue("2.2", destination.exists()); destination.move(file.getFullPath(), true, null); assertTrue("2.3", file.exists()); assertTrue("2.4", !destination.exists()); /* move folder to destination under its hierarchy */ destination = folder.getFolder("subfolder"); boolean ok = false; try { folder.move(destination.getFullPath(), true, null); } catch (RuntimeException e) { ok = true; } assertTrue("3.1", ok); /* test flag force = false */ projects[0].refreshLocal(IResource.DEPTH_INFINITE, null); IFolder subfolder = folder.getFolder("aaa"); ensureExistsInFileSystem(subfolder); IFile anotherFile = folder.getFile("bbb"); ensureExistsInFileSystem(anotherFile); destination = projects[0].getFolder("destination"); ok = false; try { folder.move(destination.getFullPath(), false, null); } catch (CoreException e) { ok = true; // FIXME: remove this check? // assertTrue("4.1", e.getStatus().getChildren().length == 2); } assertTrue("4.2", ok); try { folder.move(destination.getFullPath(), false, null); fail("4.2.1"); } catch (CoreException e) { // expected } assertTrue("4.3", folder.exists()); // FIXME: should #move be a best effort operation? // its ok for the root to be moved but ensure the destination child wasn't moved IResource destChild = ((IContainer) destination).getFile(new Path(anotherFile.getName())); assertTrue("4.4", !destination.exists()); assertTrue("4.5", !destChild.exists()); // cleanup and delete the destination try { destination.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); } catch (CoreException e) { fail("4.6", e); } try { destination.delete(true, getMonitor()); } catch (CoreException e) { fail("4.7", e); } folder.refreshLocal(IResource.DEPTH_INFINITE, getMonitor()); try { folder.move(destination.getFullPath(), false, getMonitor()); } catch (CoreException e) { fail("4.8"); } destination.move(folder.getFullPath(), true, null); assertTrue("4.9", folder.exists()); assertTrue("4.10", !destination.exists()); /* move a file that is not local but exists in the workspace */ file = projects[0].getFile("ghost"); final IFile hackFile = file; final Workspace workspace = (Workspace) getWorkspace(); IWorkspaceRunnable operation = monitor -> workspace.createResource(hackFile, false); workspace.run(operation, null); destination = projects[0].getFile("destination"); ok = false; try { file.move(destination.getFullPath(), true, null); } catch (CoreException e) { ok = true; } assertTrue("5.1", ok); /* move file over a phantom */ assertTrue("6.1", file.exists()); operation = monitor -> ((Resource) hackFile).convertToPhantom(); workspace.run(operation, null); assertTrue("6.2", !file.exists()); ResourceInfo info = ((File) file).getResourceInfo(true, false); int flags = ((File) file).getFlags(info); assertTrue("6.3", ((Resource) file).exists(flags, true)); anotherFile = folder.getFile("anotherFile"); ensureExistsInWorkspace(anotherFile, true); anotherFile.move(file.getFullPath(), true, null); assertTrue("6.4", file.exists()); } /** * A simple test that renames a file. */ public void testRenameFile() throws Exception { // create common objects IProject[] projects = getWorkspace().getRoot().getProjects(); // create a folder String fileName = "file.txt"; IFile file = projects[0].getFile(fileName); ensureExistsInWorkspace(file, true); // add some properties to file (persistent and session) QualifiedName[] propNames = new QualifiedName[numberOfProperties]; String[] propValues = new String[numberOfProperties]; for (int j = 0; j < numberOfProperties; j++) { propNames[j] = new QualifiedName("test", "prop" + j); propValues[j] = "value" + j; file.setPersistentProperty(propNames[j], propValues[j]); file.setSessionProperty(propNames[j], propValues[j]); } // rename file String newFileName = "newFile.txt"; IPath destination = projects[0].getFile(newFileName).getFullPath(); file.move(destination, true, null); // get new folder instance IFile newFile = projects[0].getFile(newFileName); // assert file was renamed assertDoesNotExistInWorkspace(file); assertDoesNotExistInFileSystem(file); assertExistsInWorkspace(newFile); assertExistsInFileSystem(newFile); // assert properties still exist (server, local and session) for (int j = 0; j < numberOfProperties; j++) { String persistentValue = newFile.getPersistentProperty(propNames[j]); Object sessionValue = newFile.getSessionProperty(propNames[j]); assertTrue("persistent property value is not the same", propValues[j].equals(persistentValue)); assertTrue("session property value is not the same", propValues[j].equals(sessionValue)); } } /** * A simple test that renames a folder. * * - creates a folder * - set properties (server, local and session) * - rename folder * - assert rename worked * - assert properties still exist */ public void testRenameFolder() throws Exception { // create common objects IProject[] projects = getWorkspace().getRoot().getProjects(); // create a folder String folderName = "folder"; IFolder folder = projects[0].getFolder(folderName); ensureExistsInWorkspace(folder, true); // add some properties to folder (persistent and session) QualifiedName[] propNames = new QualifiedName[numberOfProperties]; String[] propValues = new String[numberOfProperties]; for (int j = 0; j < numberOfProperties; j++) { propNames[j] = new QualifiedName("test", "prop" + j); propValues[j] = "value" + j; folder.setPersistentProperty(propNames[j], propValues[j]); folder.setSessionProperty(propNames[j], propValues[j]); } // rename folder String newFolderName = "newFolder"; IPath destination = projects[0].getFolder(newFolderName).getFullPath(); folder.move(destination, true, null); // get new folder instance IFolder newFolder = projects[0].getFolder(newFolderName); // assert folder was renamed assertDoesNotExistInWorkspace(folder); assertDoesNotExistInFileSystem(folder); assertExistsInWorkspace(newFolder); assertExistsInFileSystem(newFolder); // assert properties still exist (server, local and session) for (int j = 0; j < numberOfProperties; j++) { String persistentValue = newFolder.getPersistentProperty(propNames[j]); Object sessionValue = newFolder.getSessionProperty(propNames[j]); assertTrue("persistent property value is not the same", propValues[j].equals(persistentValue)); assertTrue("session property value is not the same", propValues[j].equals(sessionValue)); } } /** * Renames 3 projects using their names. * * - add properties to projects (server, local and session) * - rename projects * - assert properties are correct * - assert resources are correct */ public void testRenameProjects() throws Exception { /* create common objects */ IProject[] projects = getWorkspace().getRoot().getProjects(); // add some properties to projects (persistent and session) numberOfProperties = numberOfProjects; QualifiedName[] propNames = new QualifiedName[numberOfProperties]; String[] propValues = new String[numberOfProperties]; for (int i = 0; i < numberOfProjects; i++) { propNames[i] = new QualifiedName("test", "prop" + i); propValues[i] = "value" + i; projects[i].setPersistentProperty(propNames[i], propValues[i]); projects[i].setSessionProperty(propNames[i], propValues[i]); } // assert properties exist (persistent and session) for (int i = 0; i < numberOfProjects; i++) { String persistentValue = projects[i].getPersistentProperty(propNames[i]); Object sessionValue = projects[i].getSessionProperty(propNames[i]); assertTrue("1.0." + i, propValues[i].equals(persistentValue)); assertTrue("1.1." + i, propValues[i].equals(sessionValue)); } // move (rename) projects String prefix = "Renamed_PrOjEcT"; for (int i = 0; i < numberOfProjects; i++) { String projectName = prefix + i; IPath destination = getWorkspace().getRoot().getProject(projectName).getFullPath(); projects[i].move(destination, true, null); projectNames[i] = projectName; } // get new projects instances for (int i = 0; i < numberOfProjects; i++) { projects[i] = getWorkspace().getRoot().getProject(projectNames[i]); } // assert properties still exist (persistent and session) for (int i = 0; i < numberOfProjects; i++) { String persistentValue = projects[i].getPersistentProperty(propNames[i]); Object sessionValue = projects[i].getSessionProperty(propNames[i]); assertTrue("2.0." + i, propValues[i].equals(persistentValue)); assertTrue("2.1." + i, propValues[i].equals(sessionValue)); } } }