/******************************************************************************* * Copyright (c) 2000, 2015 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.localstore; import java.io.*; import java.util.*; import junit.framework.Test; import junit.framework.TestSuite; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.filesystem.provider.FileInfo; import org.eclipse.core.internal.localstore.IHistoryStore; import org.eclipse.core.internal.resources.*; import org.eclipse.core.internal.utils.UniversalUniqueIdentifier; import org.eclipse.core.resources.*; import org.eclipse.core.runtime.*; import org.eclipse.core.tests.resources.ResourceTest; /** * This class defines all tests for the HistoryStore Class. */ public class HistoryStoreTest extends ResourceTest { class LogListenerVerifier implements ILogListener { List<Integer> actual = new ArrayList<>(); List<Integer> expected = new ArrayList<>(); void addExpected(int statusCode) { expected.add(Integer.valueOf(statusCode)); } String dump() { StringBuffer buffer = new StringBuffer(); buffer.append("Expected:\n"); for (Integer integer : expected) { buffer.append("\t" + integer + "\n"); } buffer.append("Actual:\n"); for (Integer integer : actual) { buffer.append("\t" + integer + "\n"); } return buffer.toString(); } @Override public void logging(IStatus status, String plugin) { actual.add(Integer.valueOf(status.getCode())); } void reset() { expected = new ArrayList<>(); actual = new ArrayList<>(); } void verify() throws VerificationFailedException { String message; if (expected.size() != actual.size()) { message = "Expected size: " + expected.size() + " does not equal actual size: " + actual.size() + "\n"; message += dump(); throw new VerificationFailedException(message); } for (Integer status : expected) { if (!actual.contains(status)) { message = "Expected and actual results differ.\n"; message += dump(); throw new VerificationFailedException(message); } } } } class VerificationFailedException extends Exception { /** * All serializable objects should have a stable serialVersionUID */ private static final long serialVersionUID = 1L; VerificationFailedException(String message) { super(message); } } private IWorkspaceDescription original; public static void assertEquals(String tag, IFileState expected, IFileState actual) { assertEquals(tag + " path differs", expected.getFullPath(), actual.getFullPath()); assertEquals(tag + " timestamp differs", expected.getModificationTime(), actual.getModificationTime()); assertEquals(tag + " uuid differs", ((FileState) expected).getUUID(), ((FileState) actual).getUUID()); } public static Test suite() { // TestSuite suite = new TestSuite(HistoryStoreTest.class.getName()); // suite.addTest(new HistoryStoreTest("testMoveProject")); // suite.addTest(new HistoryStoreTest("testFindDeleted")); // return suite; return new TestSuite(HistoryStoreTest.class); } /* * This little helper method makes sure that the history store is * completely clean after it is invoked. If a history store entry or * a file is left, it may become part of the history for another file in * another test (if this file has the same name). */ public static void wipeHistoryStore(IProgressMonitor monitor) { IHistoryStore store = ((Workspace) getWorkspace()).getFileSystemManager().getHistoryStore(); // Remove all the entries from the history store index. Note that // this does not cause the history store states to be removed. store.remove(Path.ROOT, monitor); // Now make sure all the states are really removed. store.removeGarbage(); } public HistoryStoreTest() { super(); } public HistoryStoreTest(String name) { super(name); } private int numBytes(InputStream input) { int i = 0; int c = -1; try { c = input.read(); while (c != -1) { i++; c = input.read(); } } catch (IOException e) { i = 0; } if (c != -1) { i = 0; } return i; } public IWorkspaceDescription setMaxFileStates(int maxFileStates) throws CoreException { IWorkspaceDescription currentDescription = getWorkspace().getDescription(); IWorkspaceDescription newDescription = getWorkspace().getDescription(); newDescription.setMaxFileStates(maxFileStates); getWorkspace().setDescription(newDescription); return currentDescription; } @Override protected void setUp() throws Exception { super.setUp(); original = getWorkspace().getDescription(); } @Override protected void tearDown() throws Exception { getWorkspace().setDescription(original); super.tearDown(); wipeHistoryStore(getMonitor()); } /** * Test the various policies in place to ensure that the history store * does not grow to unmanageable size. The policies currently in place * include: * - store only a maximum number of states for each file * - do not store files greater than some stated size * - consider history store information stale after some specified period * of time and discard stale data * * History store states are always stored in order from the newest state to * the oldest state. This will be tested as well * * Scenario: * 1. Create project AddStateAndPoliciesProject * 2. Create file (file.txt) random contents * 3. Set policy information in the workspace description as follows: * - don't store states older than 1 day * - keep a maximum of 5 states per file * - file states must be less than 1 Mb * 4. Make 8 modifications to file.txt (causing 8 states to be created) * 5. Ensure only 5 states were kept. * 6. Ensure states are in order from newest to oldest. * 7. Set policy such that file states must be no greater than 7 bytes. * 8. Create a new file file1.txt * 9. Add 10 bytes of data to this file. * 10. Check each of the states for this file and ensure they are not * greater than 7 bytes. * 11. Revert to policy in #3 * 12. Make sure we still have 5 states for file.txt (the first file we * worked with) * 13. Change the policy so that data older than 10 seconds is stale. * 14. Wait 12 seconds (make it longer than 10 seconds to ensure we don't * encounter granularity issues). * 15. Check file states. There should be none left. */ public void testAddStateAndPolicies() { /* Create common objects. */ IProject project = getWorkspace().getRoot().getProject("Project"); IFile file = project.getFile("file.txt"); try { project.create(getMonitor()); project.open(getMonitor()); file.create(getRandomContents(), true, getMonitor()); } catch (CoreException e) { fail("0.0", e); } /* set local history policies */ IWorkspaceDescription description = getWorkspace().getDescription(); // longevity set to 1 day description.setFileStateLongevity(1000 * 3600 * 24); // keep a max of 5 file states description.setMaxFileStates(5); // max size of file = 1 Mb description.setMaxFileStateSize(1024 * 1024); try { getWorkspace().setDescription(description); } catch (CoreException e) { fail("0.1", e); } /* test max file states */ for (int i = 0; i < 8; i++) { try { ensureOutOfSync(file); file.refreshLocal(IResource.DEPTH_ZERO, getMonitor()); file.setContents(getRandomContents(), true, true, getMonitor()); } catch (CoreException e) { fail("1.0", e); } } IFileState[] states = null; try { states = file.getHistory(getMonitor()); } catch (CoreException e) { fail("1.01", e); } // Make sure we have 8 states as we haven't trimmed yet. assertEquals("1.02", 8, states.length); IFileState[] oldStates = states; try { getWorkspace().save(true, null); states = file.getHistory(getMonitor()); } catch (CoreException e) { fail("1.1", e); } // We added 8 states. Make sure we only have 5 (the max). assertEquals("1.2", description.getMaxFileStates(), states.length); // assert that states are in the correct order (newer ones first) long lastModified = states[0].getModificationTime(); for (int i = 1; i < states.length; i++) { assertTrue("1.3." + i, lastModified >= states[i].getModificationTime()); lastModified = states[i].getModificationTime(); } // assert that the most recent states were preserved for (int i = 0; i < states.length; i++) { assertEquals("1.4." + i, oldStates[i], states[i]); } /* test max file state size */ description.setMaxFileStates(15); // max size of file = 7 bytes description.setMaxFileStateSize(7); try { getWorkspace().setDescription(description); } catch (CoreException e) { fail("2.0.0", e); } file = project.getFile("file1.txt"); try { file.create(new ByteArrayInputStream(new byte[0]), true, getMonitor()); } catch (CoreException e) { fail("2.0", e); } // Add 10 bytes to exceed the max file state size. for (int i = 0; i < 10; i++) { try { file.appendContents(getContents("a"), true, true, getMonitor()); } catch (CoreException e) { fail("2.1", e); } } try { getWorkspace().save(true, null); states = file.getHistory(getMonitor()); // #states = size + 1 for the 0 byte length file to begin with. for (int i = 0; i < states.length; i++) { int bytesRead = numBytes(states[i].getContents()); assertTrue("2.2." + i, bytesRead <= description.getMaxFileStateSize()); } } catch (CoreException e) { fail("2.3", e); } /* test max file longevity */ // use the file of the first test file = project.getFile("file.txt"); // 1 day description.setFileStateLongevity(1000 * 3600 * 24); description.setMaxFileStates(5); // 1 Mb description.setMaxFileStateSize(1024 * 1024); // the description should be the same as the first test try { getWorkspace().setDescription(description); } catch (CoreException e) { fail("3.0", e); } try { states = file.getHistory(getMonitor()); // Make sure we have 5 states for file file.txt assertEquals("3.1", description.getMaxFileStates(), states.length); } catch (CoreException e) { fail("3.2", e); } // change policies // 10 seconds description.setFileStateLongevity(1000 * 10); // 1 Mb description.setMaxFileStateSize(1024 * 1024); try { getWorkspace().setDescription(description); } catch (CoreException e) { fail("3.3", e); } try { // sleep for more than 10 seconds (the granularity varies on // some machines so we will sleep for 12 seconds) Thread.sleep(1000 * 12); } catch (InterruptedException e) { fail("3.4", e); } try { getWorkspace().save(true, null); states = file.getHistory(getMonitor()); // The 5 states for file.txt should have exceeded their longevity // and been removed. Make sure we have 0 states left. assertEquals("3.5", 0, states.length); } catch (CoreException e) { fail("3.6", e); } } public void testBug28238() { // paths to mimic files in the workspace IProject project = getWorkspace().getRoot().getProject("myproject"); IFolder folder = project.getFolder("myfolder"); IFolder destinationFolder = project.getFolder("myfolder2"); IFile file = folder.getFile("myfile.txt"); IFile destinationFile = destinationFolder.getFile(file.getName()); IHistoryStore store = ((Resource) getWorkspace().getRoot()).getLocalManager().getHistoryStore(); // location of the data on disk IFileStore fileStore = getTempStore(); createFileInFileSystem(fileStore); // add the data to the history store FileInfo fileInfo = new FileInfo(file.getName()); fileInfo.setLastModified(System.currentTimeMillis()); store.addState(file.getFullPath(), fileStore, fileInfo, true); IFileState[] states = store.getStates(file.getFullPath(), getMonitor()); assertEquals("2.0", 1, states.length); // copy the data store.copyHistory(folder, destinationFolder, true); states = store.getStates(destinationFile.getFullPath(), getMonitor()); assertEquals("3.0", 1, states.length); } public void testBug28603() { // paths to mimic files in the workspace IProject project = getWorkspace().getRoot().getProject("myproject"); IFolder folder1 = project.getFolder("myfolder1"); IFolder folder2 = project.getFolder("myfolder2"); IFile file1 = folder1.getFile("myfile.txt"); IFile file2 = folder2.getFile(file1.getName()); ensureExistsInWorkspace(new IResource[] {project, folder1, folder2}, true); try { file1.create(getRandomContents(), IResource.FORCE, getMonitor()); file1.setContents(getRandomContents(), IResource.FORCE | IResource.KEEP_HISTORY, getMonitor()); file1.setContents(getRandomContents(), IResource.FORCE | IResource.KEEP_HISTORY, getMonitor()); file1.setContents(getRandomContents(), IResource.FORCE | IResource.KEEP_HISTORY, getMonitor()); setMaxFileStates(50); } catch (CoreException e) { fail("0.0", e); } int maxStates = ResourcesPlugin.getWorkspace().getDescription().getMaxFileStates(); IFileState[] states = null; try { states = file1.getHistory(getMonitor()); } catch (CoreException e) { fail("1.0", e); } assertEquals("1.1", 3, states.length); int currentStates = 3; for (int i = 0; i < maxStates + 10; i++) { try { states = file1.getHistory(getMonitor()); } catch (CoreException e) { fail("2.0." + i, e); } assertEquals("2.1." + i + " file1 states", currentStates, states.length); try { file1.move(file2.getFullPath(), true, true, getMonitor()); } catch (CoreException e) { fail("2.2." + i, e); } try { states = file2.getHistory(getMonitor()); } catch (CoreException e) { fail("2.3." + i, e); } currentStates = currentStates < maxStates ? currentStates + 1 : maxStates; assertEquals("2.4." + i + " file2 states", currentStates, states.length); try { file2.move(file1.getFullPath(), true, true, getMonitor()); } catch (CoreException e) { fail("2.5." + i, e); } try { states = file1.getHistory(getMonitor()); } catch (CoreException e) { fail("2.6." + i, e); } currentStates = currentStates < maxStates ? currentStates + 1 : maxStates; assertEquals("2.7." + i + " file1 states", currentStates, states.length); } } /* * Test the functionality in store.clean() which is called to ensure * the history store to ensure that the history store does not grow to * unmanageable size. The policies currently in place include: * - store only a maximum number of states for each file * - do not store files greater than some stated size * - consider history store information stale after some specified period * of time and discard stale data * */ public void testClean() { /* Create common objects. */ IProject project = getWorkspace().getRoot().getProject("Project"); IFile file = project.getFile("file.txt"); try { project.create(getMonitor()); project.open(getMonitor()); file.create(getRandomContents(), true, getMonitor()); } catch (CoreException e) { fail("0.0", e); } IHistoryStore store = ((Workspace) getWorkspace()).getFileSystemManager().getHistoryStore(); // get another copy for changes IWorkspaceDescription description = getWorkspace().getDescription(); /* test max file states */ // 1 day description.setFileStateLongevity(1000 * 3600 * 24); // 500 states per file max. description.setMaxFileStates(500); // 1Mb max size description.setMaxFileStateSize(1024 * 1024); try { getWorkspace().setDescription(description); } catch (CoreException e) { fail("0.1", e); } // Set up 8 file states for this file when 500 are allowed for (int i = 0; i < 8; i++) { try { ensureOutOfSync(file); file.refreshLocal(IResource.DEPTH_ZERO, getMonitor()); // try { // Thread.sleep(5000); // necessary because of lastmodified granularity in some file systems // } catch (InterruptedException e) { // } file.setContents(getRandomContents(), true, true, getMonitor()); } catch (CoreException e) { fail("1.0", e); } } // All 8 states should exist. long oldLastModTimes[] = new long[8]; try { IFileState[] states = file.getHistory(getMonitor()); assertEquals("1.1", 8, states.length); for (int i = 0; i < 8; i++) { oldLastModTimes[i] = states[i].getModificationTime(); } } catch (CoreException e) { fail("1.2", e); } // Set max. number of file states to be 3 description.setMaxFileStates(3); try { getWorkspace().setDescription(description); } catch (CoreException e) { fail("2.0", e); } // Run 'clean' - should cause 5 of 8 states to be removed store.clean(getMonitor()); // Restore max. number of states/file to 500 description.setMaxFileStates(500); try { getWorkspace().setDescription(description); } catch (CoreException e) { fail("2.2", e); } // Check to ensure only 3 states remain. Make sure these are the 3 // newer states. try { IFileState[] states = file.getHistory(getMonitor()); assertEquals("2.3", 3, states.length); // assert that states are in the correct order (newer ones first) long lastModified = states[0].getModificationTime(); for (int i = 1; i < states.length; i++) { assertTrue("2.4." + i, lastModified >= states[i].getModificationTime()); lastModified = states[i].getModificationTime(); } // Make sure we kept the 3 newer states. for (int i = 0; i < states.length; i++) { assertTrue("2.5." + i, oldLastModTimes[i] == states[i].getModificationTime()); } } catch (CoreException e) { fail("2.6", e); } /* test max file longevity */ file = project.getFile("file.txt"); // use the file of the first test description.setFileStateLongevity(1000 * 3600 * 24); // 1 day description.setMaxFileStates(500); description.setMaxFileStateSize(1024 * 1024); // 1 Mb // the description should be the same as the first test try { getWorkspace().setDescription(description); } catch (CoreException e) { fail("3.0", e); } try { IFileState[] states = file.getHistory(getMonitor()); assertEquals("3.1", 3, states.length); } catch (CoreException e) { fail("3.2", e); } // change policies // 10 seconds description.setFileStateLongevity(1000 * 10); // 1 Mb description.setMaxFileStateSize(1024 * 1024); try { getWorkspace().setDescription(description); } catch (CoreException e) { fail("4.0", e); } try { // sleep for 12 seconds (must exceed 10 seconds). This should // cause all 3 states for file.txt to be considered stale. Thread.sleep(1000 * 12); } catch (InterruptedException e) { fail("4.1", e); } store.clean(getMonitor()); // change policies - restore to original values // 1 day description.setFileStateLongevity(1000 * 3600 * 24); // 1 Mb description.setMaxFileStateSize(1024 * 1024); try { getWorkspace().setDescription(description); } catch (CoreException e) { fail("5.0", e); } // Ensure we have no state information left. It should have been // considered stale. try { IFileState[] states = file.getHistory(getMonitor()); assertEquals("5.1", 0, states.length); } catch (CoreException e) { fail("5.2", e); } } /** * Copy case for History Store of folder when the local history is being * copied. * * Scenario: * 1. Create folder (folder1) * 2. Create file "content 1" * 3. Set new content "content 2" * 4. Set new content "content 3" * 5. Copy folder * 6. Set new content to moved file "content 4" * 7. Set new content to moved file "content 5" * * The original file should have two states available. * But the copied file should have 4 states as it retains the states from * before the copy took place as well. */ public void testCopyFolder() { String[] contents = {"content1", "content2", "content3", "content4", "content5"}; // create common objects IProject project = getWorkspace().getRoot().getProject("CopyFolderProject"); try { project.create(getMonitor()); project.open(getMonitor()); } catch (CoreException e) { fail("0.0", e); } IFile file = project.getFile("file1.txt"); IFolder folder = project.getFolder("folder1"); IFolder folder2 = project.getFolder("folder2"); file = folder.getFile("file1.txt"); try { // Setup folder1 and file1.txt with some local history folder.create(true, true, getMonitor()); file.create(getContents(contents[0]), true, getMonitor()); file.setContents(getContents(contents[1]), true, true, getMonitor()); file.setContents(getContents(contents[2]), true, true, getMonitor()); IFileState[] states = file.getHistory(getMonitor()); assertEquals("1.0", 2, states.length); assertTrue("1.1", compareContent(getContents(contents[1]), states[0].getContents())); assertTrue("1.2", compareContent(getContents(contents[0]), states[1].getContents())); // Now do the move folder.copy(folder2.getFullPath(), true, getMonitor()); // Check to make sure the file has been copied IFile file2 = folder2.getFile("file1.txt"); assertTrue("1.3", file2.getFullPath().toString().endsWith("folder2/file1.txt")); // Give the new (copied file) some new contents file2.setContents(getContents(contents[3]), true, true, getMonitor()); file2.setContents(getContents(contents[4]), true, true, getMonitor()); // Check the local history of both files states = file.getHistory(getMonitor()); assertEquals("2.0", 2, states.length); assertTrue("2.1", compareContent(getContents(contents[1]), states[0].getContents())); assertTrue("2.2", compareContent(getContents(contents[0]), states[1].getContents())); states = file2.getHistory(getMonitor()); assertEquals("2.3", 4, states.length); assertTrue("2.4", compareContent(getContents(contents[3]), states[0].getContents())); assertTrue("2.5", compareContent(getContents(contents[2]), states[1].getContents())); assertTrue("2.6", compareContent(getContents(contents[1]), states[2].getContents())); assertTrue("2.7", compareContent(getContents(contents[0]), states[3].getContents())); } catch (CoreException e) { fail("2.8", e); } try { project.delete(true, getMonitor()); } catch (CoreException e) { fail("3.0", e); } } /* * This test is designed to exercise the public API method * HistoryStore.copyHistory(). The following tests will be performed: * - give a null source path * - give a null destination path * - give the same path for source and destination * - give an invalid source path but a valid destination path * - give an invalid destination path but a valid source path */ public void testCopyHistoryFile() { // Create a project, folder and file so we have some history store // Should have a project that appears as follows: // - project name TestCopyHistoryProject // - has one folder called folder1 // - folder1 has one file called file1.txt // - file1.txt was created with initial data "content1" // - change data in file1.txt to be "content2" // - change data in file1.txt to be "content3" // As a result of the above, there should be 2 history store states for // file1.txt (one with "contents1" and the other with "contents2". String[] contents = {"content0", "content1", "content2", "content3", "content4"}; // create common objects IProject project = getWorkspace().getRoot().getProject("TestCopyHistoryProject"); ensureExistsInWorkspace(project, true); IFolder folder = project.getFolder("folder1"); IFile file = folder.getFile("file1.txt"); IFile file2 = folder.getFile("file2.txt"); try { // Setup folder1 and file1.txt with some local history folder.create(true, true, getMonitor()); file.create(getContents(contents[0]), true, getMonitor()); try { Thread.sleep(1000); } catch (InterruptedException e) { fail("0.0", e); } file.setContents(getContents(contents[1]), true, true, getMonitor()); try { Thread.sleep(1000); } catch (InterruptedException e) { fail("0.1", e); } file.setContents(getContents(contents[2]), true, true, getMonitor()); try { Thread.sleep(1000); } catch (InterruptedException e) { fail("0.2", e); } IFileState[] states = file.getHistory(getMonitor()); assertEquals("1.0", 2, states.length); assertTrue("1.1", compareContent(getContents(contents[1]), states[0].getContents())); assertTrue("1.2", compareContent(getContents(contents[0]), states[1].getContents())); file2.create(getContents(contents[3]), true, getMonitor()); file2.setContents(getContents(contents[4]), true, true, getMonitor()); } catch (CoreException e) { fail("1.3", e); } // Run some tests with illegal arguments LogListenerVerifier verifier = new LogListenerVerifier(); ILog log = ResourcesPlugin.getPlugin().getLog(); log.addLogListener(verifier); // Test with null source and/or destination IHistoryStore store = ((Resource) file).getLocalManager().getHistoryStore(); verifier.addExpected(IResourceStatus.INTERNAL_ERROR); store.copyHistory(null, null, false); try { verifier.verify(); } catch (VerificationFailedException e) { fail("1.4 ", e); } verifier.reset(); verifier.addExpected(IResourceStatus.INTERNAL_ERROR); store.copyHistory(null, file2, false); try { verifier.verify(); } catch (VerificationFailedException e) { fail("1.5 ", e); } verifier.reset(); verifier.addExpected(IResourceStatus.INTERNAL_ERROR); store.copyHistory(file, null, false); try { verifier.verify(); } catch (VerificationFailedException e) { fail("1.6 ", e); } verifier.reset(); // Try to copy the history store stuff to the same location verifier.addExpected(IResourceStatus.INTERNAL_ERROR); store.copyHistory(file, file, false); try { verifier.verify(); } catch (VerificationFailedException e) { fail("1.7 ", e); } verifier.reset(); // Remember to remove the log listener now that we are done // testing illegal arguments. log.removeLogListener(verifier); // Test a valid copy of a file store.copyHistory(file, file2, false); IFileState[] states = null; try { states = file2.getHistory(getMonitor()); } catch (CoreException e) { fail("2.3"); } assertEquals("2.4", 3, states.length); try { assertTrue("2.5", compareContent(getContents(contents[3]), states[0].getContents())); assertTrue("2.6", compareContent(getContents(contents[1]), states[1].getContents())); assertTrue("2.7", compareContent(getContents(contents[0]), states[2].getContents())); } catch (CoreException e) { fail("2.8"); } } public void testCopyHistoryFolder() { String[] contents = {"content0", "content1", "content2", "content3", "content4"}; // create common objects IProject project = getWorkspace().getRoot().getProject("TestCopyHistoryProject"); ensureExistsInWorkspace(project, true); IFolder folder = project.getFolder("folder1"); IFolder folder2 = project.getFolder("folder2"); IFile file = folder.getFile("file1.txt"); IFile file2 = folder2.getFile("file1.txt"); try { // Setup folder1 and file1.txt with some local history folder.create(true, true, getMonitor()); file.create(getContents(contents[0]), true, getMonitor()); try { Thread.sleep(1000); } catch (InterruptedException e) { fail("0.0", e); } file.setContents(getContents(contents[1]), true, true, getMonitor()); try { Thread.sleep(1000); } catch (InterruptedException e) { fail("0.1", e); } file.setContents(getContents(contents[2]), true, true, getMonitor()); try { Thread.sleep(1000); } catch (InterruptedException e) { fail("0.2", e); } IFileState[] states = file.getHistory(getMonitor()); assertEquals("1.0", 2, states.length); assertTrue("1.1", compareContent(getContents(contents[1]), states[0].getContents())); assertTrue("1.2", compareContent(getContents(contents[0]), states[1].getContents())); folder2.create(true, true, getMonitor()); file2.create(getContents(contents[3]), true, getMonitor()); file2.setContents(getContents(contents[4]), true, true, getMonitor()); } catch (CoreException e) { fail("1.9", e); } // Test a valid copy of a folder IHistoryStore store = ((Resource) file).getLocalManager().getHistoryStore(); store.copyHistory(folder, folder2, false); IFileState[] states = null; try { states = file2.getHistory(getMonitor()); } catch (CoreException e) { fail("2.3"); } assertEquals("2.4", 3, states.length); try { assertTrue("2.5", compareContent(getContents(contents[3]), states[0].getContents())); assertTrue("2.6", compareContent(getContents(contents[1]), states[1].getContents())); assertTrue("2.7", compareContent(getContents(contents[0]), states[2].getContents())); } catch (CoreException e) { fail("2.8"); } } public void testCopyHistoryProject() { String[] contents = {"content0", "content1", "content2", "content3", "content4"}; // create common objects IProject project = getWorkspace().getRoot().getProject("TestCopyHistoryProject"); IProject project2 = getWorkspace().getRoot().getProject("TestCopyHistoryProject2"); ensureExistsInWorkspace(new IResource[] {project, project2}, true); IFolder folder = project.getFolder("folder1"); IFolder folder2 = project2.getFolder("folder1"); IFile file = folder.getFile("file1.txt"); IFile file2 = folder2.getFile("file1.txt"); try { // Setup folder1 and file1.txt with some local history folder.create(true, true, getMonitor()); file.create(getContents(contents[0]), true, getMonitor()); try { Thread.sleep(1000); } catch (InterruptedException e) { fail("0.0", e); } file.setContents(getContents(contents[1]), true, true, getMonitor()); try { Thread.sleep(1000); } catch (InterruptedException e) { fail("0.1", e); } file.setContents(getContents(contents[2]), true, true, getMonitor()); try { Thread.sleep(1000); } catch (InterruptedException e) { fail("0.2", e); } IFileState[] states = file.getHistory(getMonitor()); assertEquals("1.0", 2, states.length); assertTrue("1.1", compareContent(getContents(contents[1]), states[0].getContents())); assertTrue("1.2", compareContent(getContents(contents[0]), states[1].getContents())); folder2.create(true, true, getMonitor()); file2.create(getContents(contents[3]), true, getMonitor()); file2.setContents(getContents(contents[4]), true, true, getMonitor()); } catch (CoreException e) { fail("1.9", e); } // Test a valid copy of a folder IHistoryStore store = ((Resource) file).getLocalManager().getHistoryStore(); store.copyHistory(project, project2, false); IFileState[] states = null; try { states = file2.getHistory(getMonitor()); } catch (CoreException e) { fail("2.3"); } assertEquals("2.4", 3, states.length); try { assertTrue("2.5", compareContent(getContents(contents[3]), states[0].getContents())); assertTrue("2.6", compareContent(getContents(contents[1]), states[1].getContents())); assertTrue("2.7", compareContent(getContents(contents[0]), states[2].getContents())); } catch (CoreException e) { fail("2.8"); } } public void testDelete() { // create common objects IProject project = getWorkspace().getRoot().getProject("MyProject"); try { project.create(getMonitor()); project.open(getMonitor()); } catch (CoreException e) { fail("0.0", e); } // test file IFile file = project.getFile("file.txt"); try { file.create(getRandomContents(), true, getMonitor()); file.setContents(getRandomContents(), true, true, getMonitor()); file.setContents(getRandomContents(), true, true, getMonitor()); // Check to see that there are only 2 states before the deletion IFileState[] states = file.getHistory(getMonitor()); assertEquals("1.0", 2, states.length); // Delete the file. This should add a state to the history store. file.delete(true, true, getMonitor()); states = file.getHistory(getMonitor()); assertEquals("1.1", 3, states.length); // Re-create the file. This should not affect the history store. file.create(getRandomContents(), true, getMonitor()); states = file.getHistory(getMonitor()); assertEquals("1.2", 3, states.length); } catch (CoreException e) { fail("1.20", e); } // test folder IFolder folder = project.getFolder("folder"); // Make sure this has a different name as the history store information // for the first 'file.txt' is likely still around. file = folder.getFile("file2.txt"); try { folder.create(true, true, getMonitor()); file.create(getRandomContents(), true, getMonitor()); file.setContents(getRandomContents(), true, true, getMonitor()); file.setContents(getRandomContents(), true, true, getMonitor()); // There should only be 2 history store entries. IFileState[] states = file.getHistory(getMonitor()); assertEquals("2.0", 2, states.length); // Delete the folder. This should cause one more history store entry. folder.delete(true, true, getMonitor()); states = file.getHistory(getMonitor()); assertEquals("2.1", 3, states.length); // Re-create the folder. There should be no new history store entries. folder.create(true, true, getMonitor()); file.create(getRandomContents(), true, getMonitor()); states = file.getHistory(getMonitor()); assertEquals("2.2", 3, states.length); } catch (CoreException e) { fail("2.99", e); } try { project.delete(true, getMonitor()); } catch (CoreException e) { fail("20.0", e); } } /** * Test for existence of file states in the HistoryStore. */ public void testExists() throws Throwable { /* Create common objects. */ IProject project = getWorkspace().getRoot().getProject("Project"); IFile file = project.getFile("removeAllStatesFile.txt"); try { project.create(getMonitor()); project.open(getMonitor()); file.create(getRandomContents(), true, getMonitor()); } catch (CoreException e) { fail("0.0", e); } // Constant for the number of states we will create final int ITERATIONS = 20; /* Add multiple states for one file location. */ for (int i = 0; i < ITERATIONS; i++) { try { file.setContents(getRandomContents(), true, true, getMonitor()); } catch (CoreException e) { fail("3.0." + i, e); } } /* Valid Case: Test retrieved values. */ IFileState[] states = null; try { states = file.getHistory(getMonitor()); } catch (CoreException e) { fail("5.0", e); } // Make sure we have ITERATIONS number of states assertEquals("5.1", ITERATIONS, states.length); // Make sure that each of these states really exists in the filesystem. for (int i = 0; i < states.length; i++) { assertTrue("5.2." + i, states[i].exists()); } } public void testFindDeleted() { // create common objects IWorkspaceRoot root = getWorkspace().getRoot(); IProject project = root.getProject("MyProject"); try { project.create(getMonitor()); project.open(getMonitor()); IFile[] df = project.findDeletedMembersWithHistory(IResource.DEPTH_ONE, getMonitor()); assertEquals("0.1", 0, df.length); } catch (CoreException e) { fail("0.0", e); } // test that a deleted file can be found IFile pfile = project.getFile("findDeletedFile.txt"); try { // create and delete a file pfile.create(getRandomContents(), true, getMonitor()); pfile.delete(true, true, getMonitor()); // the deleted file should show up as a deleted member of project IFile[] df = project.findDeletedMembersWithHistory(IResource.DEPTH_ONE, getMonitor()); assertEquals("0.1", 1, df.length); assertEquals("0.2", pfile, df[0]); df = project.findDeletedMembersWithHistory(IResource.DEPTH_INFINITE, getMonitor()); assertEquals("0.3", 1, df.length); assertEquals("0.4", pfile, df[0]); df = project.findDeletedMembersWithHistory(IResource.DEPTH_ZERO, getMonitor()); assertEquals("0.5", 0, df.length); // the deleted file should show up as a deleted member of workspace root df = root.findDeletedMembersWithHistory(IResource.DEPTH_ONE, getMonitor()); assertEquals("0.5.1", 0, df.length); df = root.findDeletedMembersWithHistory(IResource.DEPTH_INFINITE, getMonitor()); assertEquals("0.5.2", 1, df.length); assertEquals("0.5.3", pfile, df[0]); df = root.findDeletedMembersWithHistory(IResource.DEPTH_ZERO, getMonitor()); assertEquals("0.5.4", 0, df.length); // recreate the file pfile.create(getRandomContents(), true, getMonitor()); // the deleted file should no longer show up as a deleted member of project df = project.findDeletedMembersWithHistory(IResource.DEPTH_ONE, getMonitor()); assertEquals("0.6", 0, df.length); df = project.findDeletedMembersWithHistory(IResource.DEPTH_INFINITE, getMonitor()); assertEquals("0.7", 0, df.length); df = project.findDeletedMembersWithHistory(IResource.DEPTH_ZERO, getMonitor()); assertEquals("0.8", 0, df.length); // the deleted file should no longer show up as a deleted member of ws root df = root.findDeletedMembersWithHistory(IResource.DEPTH_ONE, getMonitor()); assertEquals("0.8.1", 0, df.length); df = root.findDeletedMembersWithHistory(IResource.DEPTH_INFINITE, getMonitor()); assertEquals("0.8.2", 0, df.length); df = root.findDeletedMembersWithHistory(IResource.DEPTH_ZERO, getMonitor()); assertEquals("0.8.3", 0, df.length); } catch (CoreException e) { fail("0.00", e); } // scrub the project try { project.delete(true, getMonitor()); project.create(getMonitor()); project.open(getMonitor()); IFile[] df = project.findDeletedMembersWithHistory(IResource.DEPTH_ONE, getMonitor()); assertEquals("0.9", 0, df.length); } catch (CoreException e) { fail("0.10", e); } // test folder IFolder folder = project.getFolder("folder"); IFile file = folder.getFile("filex.txt"); IFile folderAsFile = project.getFile(folder.getProjectRelativePath()); try { // create and delete a file in a folder folder.create(true, true, getMonitor()); file.create(getRandomContents(), true, getMonitor()); file.delete(true, true, getMonitor()); // the deleted file should show up as a deleted member IFile[] df = project.findDeletedMembersWithHistory(IResource.DEPTH_ONE, getMonitor()); assertEquals("1.1", 0, df.length); df = project.findDeletedMembersWithHistory(IResource.DEPTH_INFINITE, getMonitor()); assertEquals("1.2", 1, df.length); assertEquals("1.3", file, df[0]); df = project.findDeletedMembersWithHistory(IResource.DEPTH_ZERO, getMonitor()); assertEquals("1.4", 0, df.length); // recreate the file file.create(getRandomContents(), true, getMonitor()); // the deleted file should no longer show up as a deleted member df = project.findDeletedMembersWithHistory(IResource.DEPTH_ONE, getMonitor()); assertEquals("1.5", 0, df.length); df = project.findDeletedMembersWithHistory(IResource.DEPTH_INFINITE, getMonitor()); assertEquals("1.6", 0, df.length); df = project.findDeletedMembersWithHistory(IResource.DEPTH_ZERO, getMonitor()); assertEquals("1.7", 0, df.length); // deleting the folder should bring it back folder.delete(true, true, getMonitor()); // the deleted file should show up as a deleted member of project df = project.findDeletedMembersWithHistory(IResource.DEPTH_ONE, getMonitor()); assertEquals("1.8", 0, df.length); df = project.findDeletedMembersWithHistory(IResource.DEPTH_INFINITE, getMonitor()); assertEquals("1.9", 1, df.length); assertEquals("1.10", file, df[0]); df = project.findDeletedMembersWithHistory(IResource.DEPTH_ZERO, getMonitor()); assertEquals("1.11", 0, df.length); // create and delete a file where the folder was folderAsFile.create(getRandomContents(), true, getMonitor()); folderAsFile.delete(true, true, getMonitor()); folder.create(true, true, getMonitor()); // the deleted file should show up as a deleted member of folder df = folder.findDeletedMembersWithHistory(IResource.DEPTH_ZERO, getMonitor()); assertEquals("1.12", 1, df.length); assertEquals("1.13", folderAsFile, df[0]); df = folder.findDeletedMembersWithHistory(IResource.DEPTH_ONE, getMonitor()); assertEquals("1.14", 2, df.length); List<IFile> dfList = Arrays.asList(df); assertTrue("1.15", dfList.contains(file)); assertTrue("1.16", dfList.contains(folderAsFile)); df = folder.findDeletedMembersWithHistory(IResource.DEPTH_INFINITE, getMonitor()); assertEquals("1.17", 2, df.length); dfList = Arrays.asList(df); assertTrue("1.18", dfList.contains(file)); assertTrue("1.19", dfList.contains(folderAsFile)); } catch (CoreException e) { fail("1.00", e); } // scrub the project try { project.delete(true, getMonitor()); project.create(getMonitor()); project.open(getMonitor()); IFile[] df = project.findDeletedMembersWithHistory(IResource.DEPTH_ONE, getMonitor()); assertEquals("1.50", 0, df.length); } catch (CoreException e) { fail("1.51", e); } // test a bunch of deletes folder = project.getFolder("folder"); IFile file1 = folder.getFile("file1.txt"); IFile file2 = folder.getFile("file2.txt"); IFolder folder2 = folder.getFolder("folder2"); IFile file3 = folder2.getFile("file3.txt"); try { // create and delete a file in a folder folder.create(true, true, getMonitor()); folder2.create(true, true, getMonitor()); file1.create(getRandomContents(), true, getMonitor()); file2.create(getRandomContents(), true, getMonitor()); file3.create(getRandomContents(), true, getMonitor()); folder.delete(true, true, getMonitor()); // under root IFile[] df = root.findDeletedMembersWithHistory(IResource.DEPTH_ZERO, getMonitor()); assertEquals("3.1", 0, df.length); df = root.findDeletedMembersWithHistory(IResource.DEPTH_ONE, getMonitor()); assertEquals("3.2", 0, df.length); df = root.findDeletedMembersWithHistory(IResource.DEPTH_INFINITE, getMonitor()); assertEquals("3.3", 3, df.length); List<IFile> dfList = Arrays.asList(df); assertTrue("3.3.1", dfList.contains(file1)); assertTrue("3.3.2", dfList.contains(file2)); assertTrue("3.3.3", dfList.contains(file3)); // under project df = project.findDeletedMembersWithHistory(IResource.DEPTH_ZERO, getMonitor()); assertEquals("3.4", 0, df.length); df = project.findDeletedMembersWithHistory(IResource.DEPTH_ONE, getMonitor()); assertEquals("3.5", 0, df.length); df = project.findDeletedMembersWithHistory(IResource.DEPTH_INFINITE, getMonitor()); assertEquals("3.6", 3, df.length); dfList = Arrays.asList(df); assertTrue("3.6.1", dfList.contains(file1)); assertTrue("3.6.2", dfList.contains(file2)); assertTrue("3.6.3", dfList.contains(file3)); // under folder df = folder.findDeletedMembersWithHistory(IResource.DEPTH_ZERO, getMonitor()); assertEquals("3.7", 0, df.length); df = folder.findDeletedMembersWithHistory(IResource.DEPTH_ONE, getMonitor()); assertEquals("3.8", 2, df.length); df = folder.findDeletedMembersWithHistory(IResource.DEPTH_INFINITE, getMonitor()); assertEquals("3.9", 3, df.length); // under folder2 df = folder2.findDeletedMembersWithHistory(IResource.DEPTH_ZERO, getMonitor()); assertEquals("3.10", 0, df.length); df = folder2.findDeletedMembersWithHistory(IResource.DEPTH_ONE, getMonitor()); assertEquals("3.11", 1, df.length); df = folder2.findDeletedMembersWithHistory(IResource.DEPTH_INFINITE, getMonitor()); assertEquals("3.12", 1, df.length); } catch (CoreException e) { fail("3.00", e); } try { project.delete(true, getMonitor()); } catch (CoreException e) { fail("3.5", e); } // once the project is gone, so is all the history for that project try { // under root IFile[] df = root.findDeletedMembersWithHistory(IResource.DEPTH_ZERO, getMonitor()); assertEquals("4.1", 0, df.length); df = root.findDeletedMembersWithHistory(IResource.DEPTH_ONE, getMonitor()); assertEquals("4.2", 0, df.length); df = root.findDeletedMembersWithHistory(IResource.DEPTH_INFINITE, getMonitor()); assertEquals("4.3", 0, df.length); // under project df = project.findDeletedMembersWithHistory(IResource.DEPTH_ZERO, getMonitor()); assertEquals("4.4", 0, df.length); df = project.findDeletedMembersWithHistory(IResource.DEPTH_ONE, getMonitor()); assertEquals("4.5", 0, df.length); df = project.findDeletedMembersWithHistory(IResource.DEPTH_INFINITE, getMonitor()); assertEquals("4.6", 0, df.length); // under folder df = folder.findDeletedMembersWithHistory(IResource.DEPTH_ZERO, getMonitor()); assertEquals("4.7", 0, df.length); df = folder.findDeletedMembersWithHistory(IResource.DEPTH_ONE, getMonitor()); assertEquals("4.8", 0, df.length); df = folder.findDeletedMembersWithHistory(IResource.DEPTH_INFINITE, getMonitor()); assertEquals("4.9", 0, df.length); // under folder2 df = folder2.findDeletedMembersWithHistory(IResource.DEPTH_ZERO, getMonitor()); assertEquals("4.10", 0, df.length); df = folder2.findDeletedMembersWithHistory(IResource.DEPTH_ONE, getMonitor()); assertEquals("4.11", 0, df.length); df = folder2.findDeletedMembersWithHistory(IResource.DEPTH_INFINITE, getMonitor()); assertEquals("4.12", 0, df.length); } catch (CoreException e) { fail("4.00", e); } } /** * Test for retrieving contents of files with states logged in the HistoryStore. */ public void testGetContents() throws Throwable { final int ITERATIONS = 20; /* Create common objects. */ IProject project = getWorkspace().getRoot().getProject("Project"); try { project.create(getMonitor()); project.open(getMonitor()); } catch (CoreException e) { fail("0.0", e); } /* Create files. */ IFile file = project.getFile("getContentsFile.txt"); String contents = "This file has some contents in testGetContents."; ensureExistsInWorkspace(file, contents); IFile secondValidFile = project.getFile("secondGetContentsFile.txt"); contents = "A file with some other contents in testGetContents."; ensureExistsInWorkspace(secondValidFile, contents); IHistoryStore historyStore = ((Workspace) getWorkspace()).getFileSystemManager().getHistoryStore(); /* Simulated date -- Increment once for each edition added. */ long myLong = 0L; /* Add multiple editions for one file location. */ for (int i = 0; i < ITERATIONS; i++, myLong++) { FileInfo fileInfo = new FileInfo(file.getName()); fileInfo.setLastModified(myLong); historyStore.addState(file.getFullPath(), ((Resource) file).getStore(), fileInfo, true); try { contents = "This file has some contents in testGetContents."; InputStream is = new ByteArrayInputStream(contents.getBytes()); createFileInFileSystem(file.getLocation(), is); file.refreshLocal(IResource.DEPTH_INFINITE, null); } catch (CoreException e) { fail("1.1." + i, e); } } /* Add multiple editions for second file location. */ for (int i = 0; i < ITERATIONS; i++, myLong++) { FileInfo fileInfo = new FileInfo(file.getName()); fileInfo.setLastModified(myLong); historyStore.addState(secondValidFile.getFullPath(), ((Resource) secondValidFile).getStore(), fileInfo, true); try { contents = "A file with some other contents in testGetContents."; InputStream is = new ByteArrayInputStream(contents.getBytes()); createFileInFileSystem(secondValidFile.getLocation(), is); secondValidFile.refreshLocal(IResource.DEPTH_INFINITE, null); } catch (CoreException e) { fail("2.1." + i, e); } } /* Ensure contents of file and retrieved resource are identical. Does not check timestamps. Timestamp checks are performed in a separate test. */ DataInputStream inFile = null; DataInputStream inContents = null; IFileState[] stateArray = null; stateArray = historyStore.getStates(file.getFullPath(), getMonitor()); for (int i = 0; i < stateArray.length; i++, myLong++) { inFile = new DataInputStream(file.getContents(false)); try { inContents = new DataInputStream(historyStore.getContents(stateArray[i])); } catch (CoreException e) { fail("3.1." + i, e); } if (!compareContent(inFile, inContents)) { fail("3.2." + i + " No match, files are not identical."); } } stateArray = historyStore.getStates(secondValidFile.getFullPath(), getMonitor()); for (int i = 0; i < stateArray.length; i++, myLong++) { inFile = new DataInputStream(secondValidFile.getContents(false)); try { inContents = new DataInputStream(historyStore.getContents(stateArray[i])); } catch (CoreException e) { fail("4.1." + i, e); } if (!compareContent(inFile, inContents)) { fail("4.2." + i + " No match, files are not identical."); } } /* Test getting an invalid file state. */ for (int i = 0; i < ITERATIONS; i++) { // Create bogus FileState using invalid uuid. try { InputStream in = historyStore.getContents(new FileState(historyStore, Path.ROOT, myLong, new UniversalUniqueIdentifier())); in.close(); fail("6." + i + " Edition should be invalid."); } catch (CoreException e) { // expected } } /* Test verification using null file state. */ for (int i = 0; i < ITERATIONS; i++) { try { historyStore.getContents(null); fail("7." + i + " Null edition should be invalid."); } catch (RuntimeException e) { // expected } } } public void testModifiedStamp() { /* Initialize common objects. */ IProject project = getWorkspace().getRoot().getProject("Project"); try { project.create(getMonitor()); project.open(getMonitor()); } catch (CoreException e) { fail("0.0", e); } IFile file = project.getFile("file"); try { file.create(getRandomContents(), true, getMonitor()); } catch (CoreException e) { fail("1.0", e); } IFileState[] history = null; try { history = file.getHistory(getMonitor()); } catch (CoreException e) { fail("1.1", e); } // no history yet assertEquals("1.2", 0, history.length); // save the file's current time stamp - it will be remembered in the file state long fileTimeStamp = file.getLocalTimeStamp(); try { file.setContents(getRandomContents(), true, true, getMonitor()); } catch (CoreException e) { fail("2.0", e); } try { history = file.getHistory(getMonitor()); } catch (CoreException e) { fail("2.1", e); } // one state in the history assertEquals("2.2", 1, history.length); // the timestamp in the state should match the previous file's timestamp assertEquals("3.0", fileTimeStamp, history[0].getModificationTime()); } /** * Move case for History Store of folder when the local history is being * copied. * * Scenario: * 1. Create folder (folder1) * 2. Create file "content 1" * 3. Set new content "content 2" * 4. Set new content "content 3" * 5. Move folder * 6. Set new content to moved file "content 4" * 7. Set new content to moved file "content 5" * * The original file should have two states available. * But the moved file should have 4 states as it retains the states from * before the move took place as well. */ public void testMoveFolder() { String[] contents = {"content1", "content2", "content3", "content4", "content5"}; // create common objects IProject project = getWorkspace().getRoot().getProject("MyProject"); try { project.create(getMonitor()); project.open(getMonitor()); } catch (CoreException e) { fail("0.0", e); } IFile file = project.getFile("file1.txt"); IFolder folder = project.getFolder("folder1"); IFolder folder2 = project.getFolder("folder2"); file = folder.getFile("file1.txt"); try { // Setup folder1 and file1.txt with some local history folder.create(true, true, getMonitor()); file.create(getContents(contents[0]), true, getMonitor()); file.setContents(getContents(contents[1]), true, true, getMonitor()); file.setContents(getContents(contents[2]), true, true, getMonitor()); IFileState[] states = file.getHistory(getMonitor()); assertEquals("1.0", 2, states.length); assertTrue("1.1", compareContent(getContents(contents[1]), states[0].getContents())); assertTrue("1.2", compareContent(getContents(contents[0]), states[1].getContents())); // Now do the move folder.move(folder2.getFullPath(), true, getMonitor()); // Check to make sure the file has been moved IFile file2 = folder2.getFile("file1.txt"); assertTrue("1.3", file2.getFullPath().toString().endsWith("folder2/file1.txt")); // Give the new (moved file) some new contents file2.setContents(getContents(contents[3]), true, true, getMonitor()); file2.setContents(getContents(contents[4]), true, true, getMonitor()); // Check the local history of both files states = file.getHistory(getMonitor()); assertEquals("2.0", 2, states.length); assertTrue("2.1", compareContent(getContents(contents[1]), states[0].getContents())); assertTrue("2.2", compareContent(getContents(contents[0]), states[1].getContents())); states = file2.getHistory(getMonitor()); assertEquals("2.3", 4, states.length); assertTrue("2.4", compareContent(getContents(contents[3]), states[0].getContents())); assertTrue("2.5", compareContent(getContents(contents[2]), states[1].getContents())); assertTrue("2.6", compareContent(getContents(contents[1]), states[2].getContents())); assertTrue("2.7", compareContent(getContents(contents[0]), states[3].getContents())); } catch (CoreException e) { fail("2.8", e); } try { project.delete(true, getMonitor()); } catch (CoreException e) { fail("3.0", e); } } /** * Move case for History Store of project. Note that local history is * NOT copied for a project move. * * Scenario: * 1. Create folder (folder1) * 2. Create file "content 1" * 2. Set new content "content 2" * 3. Set new content "content 3" * 4. Copy folder * 5. Set new content to moved file "content 4" * 6. Set new content to moved file "content 5" * * The original file should have two states available. * But the copied file should have 4 states as it retains the states from * before the copy took place as well. */ public void testMoveProject() { String[] contents = {"content1", "content2", "content3", "content4", "content5"}; // create common objects IProject project = getWorkspace().getRoot().getProject("MoveProjectProject"); IProject project2 = getWorkspace().getRoot().getProject("SecondMoveProjectProject"); try { project.create(getMonitor()); project.open(getMonitor()); } catch (CoreException e) { fail("0.0", e); } IFile file = project.getFile("file1.txt"); IFolder folder = project.getFolder("folder1"); file = folder.getFile("file1.txt"); try { // Setup folder1 and file1.txt with some local history folder.create(true, true, getMonitor()); file.create(getContents(contents[0]), true, getMonitor()); file.setContents(getContents(contents[1]), true, true, getMonitor()); file.setContents(getContents(contents[2]), true, true, getMonitor()); IFileState[] states = file.getHistory(getMonitor()); assertEquals("1.0", 2, states.length); assertTrue("1.1", compareContent(getContents(contents[1]), states[0].getContents())); assertTrue("1.2", compareContent(getContents(contents[0]), states[1].getContents())); // Now do the move project.move(new Path("SecondMoveProjectProject"), true, getMonitor()); // Check to make sure the file has been moved IFile file2 = project2.getFile("folder1/file1.txt"); assertTrue("1.3", file2.getFullPath().toString().endsWith("SecondMoveProjectProject/folder1/file1.txt")); // Give the new (copied file) some new contents file2.setContents(getContents(contents[3]), true, true, getMonitor()); file2.setContents(getContents(contents[4]), true, true, getMonitor()); // Check the local history of both files states = file.getHistory(getMonitor()); // original file should not remember history when project is moved assertEquals("2.0", 0, states.length); states = file2.getHistory(getMonitor()); assertEquals("2.3", 4, states.length); assertTrue("2.4", compareContent(getContents(contents[3]), states[0].getContents())); assertTrue("2.5", compareContent(getContents(contents[2]), states[1].getContents())); assertTrue("2.6", compareContent(getContents(contents[1]), states[2].getContents())); assertTrue("2.7", compareContent(getContents(contents[0]), states[3].getContents())); } catch (CoreException e) { fail("2.9", e); } try { project.delete(true, getMonitor()); } catch (CoreException e) { fail("3.0", e); } } public void testRemoveAll() { /* Create common objects. */ IProject project = getWorkspace().getRoot().getProject("Project"); IFile file = project.getFile("removeAllStatesFile.txt"); try { project.create(getMonitor()); project.open(getMonitor()); file.create(getRandomContents(), true, getMonitor()); } catch (CoreException e) { fail("0.0", e); } final int ITERATIONS = 20; /* test remove in a file */ for (int i = 0; i < ITERATIONS; i++) { try { file.setContents(getRandomContents(), true, true, getMonitor()); } catch (CoreException e) { fail("3.0." + i, e); } } /* Valid Case: Ensure correct number of states available. */ IFileState[] states = null; try { states = file.getHistory(getMonitor()); } catch (CoreException e) { fail("4.0", e); } assertEquals("4.1", ITERATIONS, states.length); /* Remove all states, and verify that no states remain. */ try { file.clearHistory(getMonitor()); states = file.getHistory(getMonitor()); assertEquals("5.0", 0, states.length); } catch (CoreException e) { fail("5.1", e); } /* test remove in a folder -- make sure it does not affect other resources' states*/ IFolder folder = project.getFolder("folder"); IFile anotherOne = folder.getFile("anotherOne"); try { folder.create(true, true, getMonitor()); anotherOne.create(getRandomContents(), true, getMonitor()); } catch (CoreException e) { fail("6.0", e); } for (int i = 0; i < ITERATIONS; i++) { try { file.setContents(getRandomContents(), true, true, getMonitor()); anotherOne.setContents(getRandomContents(), true, true, getMonitor()); } catch (CoreException e) { fail("6.1." + i, e); } } try { states = file.getHistory(getMonitor()); assertEquals("6.2", ITERATIONS, states.length); states = anotherOne.getHistory(getMonitor()); assertEquals("6.3", ITERATIONS, states.length); } catch (CoreException e) { fail("6.4", e); } /* Remove all states, and verify that no states remain. */ try { project.clearHistory(getMonitor()); states = file.getHistory(getMonitor()); assertEquals("7.0", 0, states.length); states = anotherOne.getHistory(getMonitor()); assertEquals("7.1", 0, states.length); } catch (CoreException e) { fail("7.2", e); } /* test remove in a folder -- make sure it does not affect other resources' states*/ IFile aaa = project.getFile("aaa"); IFolder bbb = project.getFolder("bbb"); anotherOne = bbb.getFile("anotherOne"); IFile ccc = project.getFile("ccc"); try { bbb.create(true, true, getMonitor()); anotherOne.create(getRandomContents(), true, getMonitor()); aaa.create(getRandomContents(), true, getMonitor()); ccc.create(getRandomContents(), true, getMonitor()); } catch (CoreException e) { fail("8.0", e); } for (int i = 0; i < ITERATIONS; i++) { try { anotherOne.setContents(getRandomContents(), true, true, getMonitor()); aaa.setContents(getRandomContents(), true, true, getMonitor()); ccc.setContents(getRandomContents(), true, true, getMonitor()); } catch (CoreException e) { fail("8.1." + i, e); } } try { states = anotherOne.getHistory(getMonitor()); assertEquals("8.3", ITERATIONS, states.length); states = aaa.getHistory(getMonitor()); assertEquals("8.4", ITERATIONS, states.length); states = ccc.getHistory(getMonitor()); assertEquals("8.5", ITERATIONS, states.length); } catch (CoreException e) { fail("8.6", e); } /* Remove all states, and verify that no states remain. aaa and ccc should not be affected. */ try { bbb.clearHistory(getMonitor()); states = anotherOne.getHistory(getMonitor()); assertEquals("9.1", 0, states.length); states = aaa.getHistory(getMonitor()); assertEquals("9.2", ITERATIONS, states.length); states = ccc.getHistory(getMonitor()); assertEquals("9.3", ITERATIONS, states.length); } catch (CoreException e) { fail("9.4", e); } } /** * Simple copy case for History Store when the local history is being * copied. * * Scenario: * 1. Create file "content 1" * 2. Set new content "content 2" * 3. Set new content "content 3" * 4. Move file * 5. Set new content to copied file "content 4" * 6. Set new content to copied file "content 5" * * The original file should have two states available. * But the copied file should have 4 states as it retains the states from * before the copy took place as well. */ public void testSimpleCopy() { /* Initialize common objects. */ IProject project = getWorkspace().getRoot().getProject("SimpleCopyProject"); try { project.create(getMonitor()); project.open(getMonitor()); } catch (CoreException e) { fail("0.0", e); } String[] contents = {"content1", "content2", "content3", "content4", "content5"}; IFile file = project.getFile("simpleCopyFileWithHistoryCopy"); IFile copyFile = project.getFile("copyOfSimpleCopyFileWithHistoryCopy"); /* Create first file. */ try { file.create(getContents(contents[0]), true, null); } catch (CoreException e) { fail("1.2", e); } /* Set new contents on first file. Should add two entries to the history store. */ try { file.setContents(getContents(contents[1]), true, true, null); file.setContents(getContents(contents[2]), true, true, null); } catch (CoreException e) { fail("2.0", e); } /* Copy first file to the second. Second file should have no history. */ try { file.copy(copyFile.getFullPath(), true, null); } catch (CoreException e) { fail("3.0", e); } /* Check history for both files. */ try { IFileState[] states = file.getHistory(null); assertEquals("4.0", 2, states.length); states = copyFile.getHistory(null); assertEquals("4.1", 2, states.length); } catch (CoreException e) { fail("4.2", e); } /* Set new contents on second file. Should add two entries to the history store. */ try { copyFile.setContents(getContents(contents[3]), true, true, null); copyFile.setContents(getContents(contents[4]), true, true, null); } catch (CoreException e) { fail("5.0", e); } /* Check history for both files. */ try { // Check log for original file. IFileState[] states = file.getHistory(null); assertEquals("6.0", 2, states.length); assertTrue("6.1", compareContent(getContents(contents[1]), states[0].getContents())); assertTrue("6.2", compareContent(getContents(contents[0]), states[1].getContents())); // Check log for copy. states = copyFile.getHistory(null); assertEquals("6.3", 4, states.length); assertTrue("6.4", compareContent(getContents(contents[3]), states[0].getContents())); assertTrue("6.5", compareContent(getContents(contents[2]), states[1].getContents())); assertTrue("6.6", compareContent(getContents(contents[1]), states[2].getContents())); assertTrue("6.7", compareContent(getContents(contents[0]), states[3].getContents())); } catch (CoreException e) { fail("6.8", e); } } /** * Simple move case for History Store when the local history is being * copied. * * Scenario: * 1. Create file "content 1" * 2. Set new content "content 2" * 3. Set new content "content 3" * 4. Move file * 5. Set new content to moved file "content 4" * 6. Set new content to moved file "content 5" * * The original file should have two states available. * But the moved file should have 4 states as it retains the states from * before the move took place as well. */ public void testSimpleMove() { /* Initialize common objects. */ IProject project = getWorkspace().getRoot().getProject("SimpleMoveProject"); try { project.create(getMonitor()); project.open(getMonitor()); } catch (CoreException e) { fail("0.0", e); } String[] contents = {"content1", "content2", "content3", "content4", "content5"}; IFile file = project.getFile("simpleMoveFileWithCopy"); IFile moveFile = project.getFile("copyOfSimpleMoveFileWithCopy"); /* Create first file. */ try { file.create(getContents(contents[0]), true, null); } catch (CoreException e) { fail("1.2", e); } /* Set new contents on source file. Should add two entries to the history store. */ try { file.setContents(getContents(contents[1]), true, true, null); file.setContents(getContents(contents[2]), true, true, null); } catch (CoreException e) { fail("2.0", e); } /* Move source file to second location. * Moved files should have the history of the original file. */ try { file.move(moveFile.getFullPath(), true, null); } catch (CoreException e) { fail("3.0", e); } /* Check history for both files. */ try { IFileState[] states = file.getHistory(null); assertEquals("4.0", 2, states.length); states = moveFile.getHistory(null); assertEquals("4.1", 2, states.length); } catch (CoreException e) { fail("4.2", e); } /* Set new contents on moved file. Should add two entries to the history store. */ try { moveFile.setContents(getContents(contents[3]), true, true, null); moveFile.setContents(getContents(contents[4]), true, true, null); } catch (CoreException e) { fail("5.0", e); } /* Check history for both files. */ try { // Check log for original file. IFileState[] states = file.getHistory(null); assertEquals("6.0", 2, states.length); assertTrue("6.1", compareContent(getContents(contents[1]), states[0].getContents())); assertTrue("6.2", compareContent(getContents(contents[0]), states[1].getContents())); // Check log for moved file. states = moveFile.getHistory(null); assertEquals("6.3", 4, states.length); assertTrue("6.4", compareContent(getContents(contents[3]), states[0].getContents())); assertTrue("6.5", compareContent(getContents(contents[2]), states[1].getContents())); assertTrue("6.6", compareContent(getContents(contents[1]), states[2].getContents())); assertTrue("6.7", compareContent(getContents(contents[0]), states[3].getContents())); } catch (CoreException e) { fail("6.8", e); } } /** * Simple use case for History Store. * * Scenario: # Editions * 1. Create file "content 1" 0 * 2. Set new content "content 2" 1 * 3. Set new content "content 3" 2 * 4. Delete file 3 * 5. Roll back to first version "content 1" 3 * 6. Set new content "content 2" 4 * 7. Roll back to third version "content 3" 5 */ public void testSimpleUse() { /* Initialize common objects. */ IProject project = getWorkspace().getRoot().getProject("Project"); try { project.create(getMonitor()); project.open(getMonitor()); } catch (CoreException e) { fail("0.0", e); } String[] contents = {"content1", "content2", "content3"}; IFile file = project.getFile("file"); /* Create the file. */ try { file.create(getContents(contents[0]), true, getMonitor()); } catch (CoreException e) { fail("1.0", e); } /* Set new contents on the file. Should add two entries to the store. */ try { for (int i = 0; i < 2; i++) { file.setContents(getContents(contents[i + 1]), true, true, getMonitor()); } } catch (CoreException e) { fail("2.0", e); } /* Ensure two entries are available for the file, and that content matches. */ try { IFileState[] states = file.getHistory(getMonitor()); assertEquals("3.0", 2, states.length); assertTrue("3.1.1", compareContent(getContents(contents[1]), states[0].getContents())); assertTrue("3.1.2", compareContent(getContents(contents[0]), states[1].getContents())); } catch (CoreException e) { fail("3.2", e); } /* Delete the file. Should add an entry to the store. */ try { file.delete(true, true, getMonitor()); } catch (CoreException e) { fail("4.0", e); } /* Ensure three entries are available for the file, and that content matches. */ try { IFileState[] states = file.getHistory(getMonitor()); assertEquals("5.0", 3, states.length); assertTrue("5.1.1", compareContent(getContents(contents[2]), states[0].getContents())); assertTrue("5.1.2", compareContent(getContents(contents[1]), states[1].getContents())); assertTrue("5.1.3", compareContent(getContents(contents[0]), states[2].getContents())); } catch (CoreException e) { fail("5.2", e); } /* Roll file back to first version, and ensure that content matches. */ try { IFileState[] states = file.getHistory(getMonitor()); // Create the file with the contents from one of the states. // Won't add another entry to the store. file.create(states[0].getContents(), false, getMonitor()); // Check history store. states = file.getHistory(getMonitor()); assertEquals("6.0", 3, states.length); assertTrue("6.1.1", compareContent(getContents(contents[2]), states[0].getContents())); assertTrue("6.1.2", compareContent(getContents(contents[1]), states[1].getContents())); assertTrue("6.1.3", compareContent(getContents(contents[0]), states[2].getContents())); // Check file contents. assertTrue("6.2", compareContent(getContents(contents[2]), file.getContents(false))); } catch (CoreException e) { fail("6.3", e); } /* Set new contents on the file. Should add an entry to the history store. */ try { file.setContents(getContents(contents[1]), true, true, null); } catch (CoreException e) { fail("7.0", e); } /* Ensure four entries are available for the file, and that entries match. */ try { IFileState[] states = file.getHistory(getMonitor()); assertEquals("8.0", 4, states.length); assertTrue("8.1.1", compareContent(getContents(contents[2]), states[0].getContents())); assertTrue("8.1.2", compareContent(getContents(contents[2]), states[1].getContents())); assertTrue("8.1.3", compareContent(getContents(contents[1]), states[2].getContents())); assertTrue("8.1.4", compareContent(getContents(contents[0]), states[3].getContents())); } catch (CoreException e) { fail("8.2", e); } /* Roll file back to third version, and ensure that content matches. */ try { IFileState[] states = file.getHistory(getMonitor()); // Will add another entry to log. file.setContents(states[2], true, true, getMonitor()); // Check history log. states = file.getHistory(getMonitor()); assertEquals("9.0", 5, states.length); assertTrue("9.1.1", compareContent(getContents(contents[1]), states[0].getContents())); assertTrue("9.1.2", compareContent(getContents(contents[2]), states[1].getContents())); assertTrue("9.1.3", compareContent(getContents(contents[2]), states[2].getContents())); assertTrue("9.1.4", compareContent(getContents(contents[1]), states[3].getContents())); assertTrue("9.1.5", compareContent(getContents(contents[0]), states[4].getContents())); // Check file contents. assertTrue("9.2", compareContent(getContents(contents[1]), file.getContents(false))); } catch (CoreException e) { fail("9.3", e); } } }