Skip to main content
aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorcvs2svn2005-10-17 01:05:09 +0000
committercvs2svn2005-10-17 01:05:09 +0000
commit18523542e483f6bdf85d7e1bcfc2bd75169c5d94 (patch)
tree7c95a9d05459cd5108fc8ff30156a5db1b533a06 /tests
parent4d7f1ed2fba58c1df04d36f0b1a44c09d668d663 (diff)
downloadeclipse.platform.team-18523542e483f6bdf85d7e1bcfc2bd75169c5d94.tar.gz
eclipse.platform.team-18523542e483f6bdf85d7e1bcfc2bd75169c5d94.tar.xz
eclipse.platform.team-18523542e483f6bdf85d7e1bcfc2bd75169c5d94.zip
This commit was manufactured by cvs2svn to create branch
'branch_20050711_LogicalModelSupport'. Cherrypick from master 2005-10-17 01:05:07 UTC Michael Valenta <mvalenta> 'Bug 57191 (PatchAttached)[Decorators] Display of CVS tag property of a file in mixed project is not correct': bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/ICVSResource.java bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/RemovedHandler.java bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/connection/CVSRepositoryLocation.java bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/RemoteResource.java bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/Util.java bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/dialogs/MultipleYesNoPrompter.java tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/EclipseTest.java tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/mappings/ResourceMapperTests.java tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/mappings/SyncInfoSetTraveralContext.java tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/AllTestsTeamSubscriber.java
Diffstat (limited to 'tests')
-rw-r--r--tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/EclipseTest.java1298
-rw-r--r--tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/mappings/ResourceMapperTests.java534
-rw-r--r--tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/mappings/SyncInfoSetTraveralContext.java76
-rw-r--r--tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/AllTestsTeamSubscriber.java39
4 files changed, 1947 insertions, 0 deletions
diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/EclipseTest.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/EclipseTest.java
new file mode 100644
index 000000000..c261a4b0a
--- /dev/null
+++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/EclipseTest.java
@@ -0,0 +1,1298 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.team.tests.ccvs.core;
+import java.io.*;
+import java.lang.reflect.InvocationTargetException;
+import java.util.*;
+
+import junit.framework.*;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.resources.mapping.ResourceMapping;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.tests.resources.ResourceTest;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.team.core.RepositoryProvider;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.internal.ccvs.core.*;
+import org.eclipse.team.internal.ccvs.core.client.*;
+import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption;
+import org.eclipse.team.internal.ccvs.core.connection.*;
+import org.eclipse.team.internal.ccvs.core.resources.*;
+import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
+import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
+import org.eclipse.team.internal.ccvs.core.util.SyncFileChangeListener;
+import org.eclipse.team.internal.ccvs.ui.operations.*;
+import org.eclipse.team.internal.core.subscribers.SubscriberSyncInfoCollector;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.internal.decorators.DecoratorManager;
+
+public class EclipseTest extends ResourceTest {
+
+ private static final int LOCK_WAIT_TIME = 1000;
+ private static final String CVS_TEST_LOCK_FILE = ".lock";
+ private static final String CVS_TEST_LOCK_PROJECT = "cvsTestLock";
+ protected static IProgressMonitor DEFAULT_MONITOR = new NullProgressMonitor();
+ protected static final int RANDOM_CONTENT_SIZE = 3876;
+ protected static String eol = System.getProperty("line.separator");
+ private static final long LOCK_EXPIRATION_THRESHOLD = 1000 * 60 * 10; // 10 minutes
+ private static final int MAX_LOCK_ATTEMPTS = 60 * 30; // 30 minutes
+ private String lockId;
+
+ public static Test suite(Class c) {
+ String testName = System.getProperty("eclipse.cvs.testName");
+ if (testName == null) {
+ TestSuite suite = new TestSuite(c);
+ return new CVSTestSetup(suite);
+ } else {
+ try {
+ return new CVSTestSetup((Test)c.getConstructor(new Class[] { String.class }).newInstance(new Object[] {testName}));
+ } catch (Exception e) {
+ fail(e.getMessage());
+ // Above will throw so below is never actually reached
+ return null;
+ }
+ }
+ }
+
+ public EclipseTest() {
+ super();
+ if (eol == null) eol = "\n";
+ }
+
+ public EclipseTest(String name) {
+ super(name);
+ if (eol == null) eol = "\n";
+ }
+
+ /*
+ * Get the resources for the given resource names
+ */
+ public IResource[] getResources(IContainer container, String[] hierarchy) throws CoreException {
+ IResource[] resources = new IResource[hierarchy.length];
+ for (int i=0;i<resources.length;i++) {
+ resources[i] = container.findMember(hierarchy[i]);
+ if (resources[i] == null) {
+ resources[i] = buildResources(container, new String[] {hierarchy[i]})[0];
+ }
+ }
+ return resources;
+ }
+
+ /**
+ * Add the resources to an existing container and upload them to CVS
+ */
+ public IResource[] addResources(IContainer container, String[] hierarchy, boolean checkin) throws CoreException, TeamException {
+ IResource[] newResources = buildResources(container, hierarchy, false);
+ addResources(newResources);
+ if (checkin) commitResources(newResources, IResource.DEPTH_ZERO);
+ return newResources;
+ }
+
+ protected void addResources(IResource[] newResources) throws CoreException {
+ if (newResources.length == 0) return;
+ ResourceMapping[] mappings = asResourceMappers(newResources, IResource.DEPTH_INFINITE);
+ add(mappings);
+ }
+
+ protected void add(ResourceMapping[] mappings) throws CVSException {
+ executeHeadless(new AddOperation(null, mappings));
+ }
+
+ /**
+ * Perform a CVS edit of the given resources
+ */
+ public IResource[] editResources(IContainer container, String[] hierarchy) throws CoreException, TeamException {
+ IResource[] resources = getResources(container, hierarchy);
+ getProvider(container).edit(resources, true /* recurse */, true /* notifyServer */, false /* notifyForWritable */, ICVSFile.NO_NOTIFICATION, DEFAULT_MONITOR);
+ assertReadOnly(resources, false /* isReadOnly */, true /* recurse */);
+ return resources;
+ }
+
+ /**
+ * Perform a CVS unedit of the given resources
+ */
+ public IResource[] uneditResources(IContainer container, String[] hierarchy) throws CoreException, TeamException {
+ IResource[] resources = getResources(container, hierarchy);
+ getProvider(container).unedit(resources, true /* recurse */, true/* notifyServer */, DEFAULT_MONITOR);
+ assertReadOnly(resources, true /* isReadOnly */, true /* recurse */);
+ return resources;
+ }
+
+ public void appendText(IResource resource, String text, boolean prepend) throws CoreException, IOException, CVSException {
+ IFile file = (IFile)resource;
+ String contents = getFileContents(file);
+ StringBuffer buffer = new StringBuffer();
+ if (prepend) {
+ buffer.append(text);
+ }
+ buffer.append(contents);
+ if (!prepend) {
+ buffer.append(eol + text);
+ }
+ setContentsAndEnsureModified(file, buffer.toString());
+ }
+
+ public void assertEndsWith(IFile file, String text) throws IOException, CoreException {
+ assertTrue(getFileContents(file).endsWith(text));
+ }
+
+ public void assertStartsWith(IFile file, String text) throws IOException, CoreException {
+ assertTrue(getFileContents(file).startsWith(text));
+ }
+
+ public static String getFileContents(IFile file) throws IOException, CoreException {
+ StringBuffer buf = new StringBuffer();
+ Reader reader = new InputStreamReader(new BufferedInputStream(file.getContents()));
+ try {
+ int c;
+ while ((c = reader.read()) != -1) buf.append((char)c);
+ } finally {
+ reader.close();
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Delete the resources from an existing container and the changes to CVS
+ */
+ public IResource[] changeResources(IContainer container, String[] hierarchy, boolean checkin) throws CoreException, TeamException {
+ List changedResources = new ArrayList(hierarchy.length);
+ for (int i=0;i<hierarchy.length;i++) {
+ IResource resource = container.findMember(hierarchy[i]);
+ if (resource.getType() == IResource.FILE) {
+ changedResources.add(resource);
+ setContentsAndEnsureModified((IFile)resource);
+ }
+ }
+ IResource[] resources = (IResource[])changedResources.toArray(new IResource[changedResources.size()]);
+ if (checkin) commitResources(resources, IResource.DEPTH_ZERO);
+ return resources;
+ }
+
+ /**
+ * Delete the resources from an existing container and the changes to CVS
+ */
+ public IResource[] deleteResources(IContainer container, String[] hierarchy, boolean checkin) throws CoreException, TeamException {
+ IResource[] resources = getResources(container, hierarchy);
+ deleteResources(resources);
+ if (checkin)
+ commitResources(resources, IResource.DEPTH_INFINITE);
+ return resources;
+ }
+
+ /**
+ * Delete the resources and mark them as outgoing deletions.
+ * Deleting the resources is enough since the move/delete hook will
+ * tak care of making them outgoing deletions.
+ */
+ protected void deleteResources(IResource[] resources) throws TeamException, CoreException {
+ if (resources.length == 0) return;
+ for (int i = 0; i < resources.length; i++) {
+ IResource resource = resources[i];
+ resource.delete(false, DEFAULT_MONITOR);
+ }
+ }
+ /**
+ * Unmanage the resources
+ */
+ public void unmanageResources(IContainer container, String[] hierarchy) throws CoreException, TeamException {
+ IResource[] resources = getResources(container, hierarchy);
+ unmanageResources(resources);
+ }
+
+ protected void unmanageResources(IResource[] resources) throws TeamException, CoreException {
+ for (int i=0;i<resources.length;i++) {
+ CVSWorkspaceRoot.getCVSResourceFor(resources[i]).unmanage(null);
+ }
+ }
+
+ /**
+ * Update the resources from an existing container with the changes from the CVS repository
+ */
+ public IResource[] updateResources(IContainer container, String[] hierarchy, boolean ignoreLocalChanges) throws CoreException, TeamException {
+ IResource[] resources = getResources(container, hierarchy);
+ return updateResources(resources, ignoreLocalChanges);
+ }
+
+ /**
+ * Update the resources from an existing container with the changes from the CVS repository
+ */
+ protected IResource[] updateResources(IResource[] resources, boolean ignoreLocalChanges) throws CVSException {
+ LocalOption[] options = Command.NO_LOCAL_OPTIONS;
+ if(ignoreLocalChanges) {
+ options = new LocalOption[] {Update.IGNORE_LOCAL_CHANGES};
+ }
+ ResourceMapping[] mappers = asResourceMappers(resources, IResource.DEPTH_INFINITE);
+ update(mappers, options);
+ return resources;
+ }
+
+ /**
+ * Update the resources contained in the given mappers.
+ */
+ protected void update(ResourceMapping[] mappers, LocalOption[] options) throws CVSException {
+ if (options == null)
+ options = Command.NO_LOCAL_OPTIONS;
+ executeHeadless(new UpdateOperation(null, mappers, options, null));
+ }
+
+ protected void replace(IContainer container, String[] hierarchy, CVSTag tag, boolean recurse) throws CoreException {
+ IResource[] resources = getResources(container, hierarchy);
+ replace(resources, tag, recurse);
+ }
+
+ protected void replace(IResource[] resources, CVSTag tag, boolean recurse) throws CoreException {
+ ReplaceOperation op = new ReplaceOperation(null, resources, tag, recurse);
+ executeHeadless(op);
+ }
+
+ protected void replace(ResourceMapping[] mappers) throws CVSException {
+ executeHeadless(new ReplaceOperation(null, mappers, null));
+ }
+
+ public void updateProject(IProject project, CVSTag tag, boolean ignoreLocalChanges) throws TeamException {
+ LocalOption[] options = Command.NO_LOCAL_OPTIONS;
+ if(ignoreLocalChanges) {
+ options = new LocalOption[] {Update.IGNORE_LOCAL_CHANGES};
+ }
+ executeHeadless(new UpdateOperation(null, new IResource[] {project}, options, tag));
+ }
+
+ public void commitProject(IProject project) throws TeamException, CoreException {
+ commitResources(project, true);
+ }
+
+ public void commitResources(IContainer container, boolean deep) throws TeamException, CoreException {
+ commitResources(new IResource[] {container }, deep?IResource.DEPTH_INFINITE:IResource.DEPTH_ZERO);
+ }
+
+ /**
+ * Commit the resources from an existing container to the CVS repository
+ */
+ public IResource[] commitResources(IContainer container, String[] hierarchy) throws CoreException, TeamException {
+ IResource[] resources = getResources(container, hierarchy);
+ commitResources(resources, IResource.DEPTH_ZERO);
+ return resources;
+ }
+
+ protected void commitResources(IResource[] resources, int depth) throws TeamException, CoreException {
+ commitResources(resources, depth, "");
+ }
+
+ /*
+ * Commit the provided resources which must all be in the same project
+ */
+ protected void commitResources(IResource[] resources, int depth, String message) throws TeamException, CoreException {
+ if (resources.length == 0) return;
+ ResourceMapping[] resourceMappers = asResourceMappers(resources, depth);
+ commit(resourceMappers, message);
+ }
+
+ /**
+ * Commit the resources contained by the mappers.
+ */
+ protected void commit(ResourceMapping[] mappers, String message) throws CVSException {
+ executeHeadless(new CommitOperation(null, mappers, new Command.LocalOption[0], message));
+ }
+
+ /**
+ * Convert the resources to a resource mapper that traverses the resources
+ * to the specified depth.
+ * @param resources the resource
+ * @return a resource mapper for traversing the resources to the depth specified
+ */
+ protected ResourceMapping[] asResourceMappers(IResource[] resources, int depth) {
+ return WorkspaceResourceMapper.asResourceMappers(resources, depth);
+ }
+
+ protected ICVSResource asCVSResource(IResource resource) {
+ return CVSWorkspaceRoot.getCVSResourceFor(resource);
+ }
+
+ /**
+ * Commit the resources from an existing container to the CVS repository
+ */
+ public void tagProject(IProject project, CVSTag tag, boolean force) throws TeamException {
+ ResourceMapping[] mappings = RepositoryProviderOperation.asResourceMappers(new IResource[] {project});
+ tag(mappings, tag, force);
+ }
+
+ /**
+ * Tag the resources contained in the given mappings
+ */
+ protected void tag(ResourceMapping[] mappings, CVSTag tag, boolean force) throws TeamException {
+ ITagOperation op = new TagOperation((IWorkbenchPart)null, mappings);
+ runTag(op, tag, force);
+ }
+
+ public void tagRemoteResource(ICVSRemoteResource resource, CVSTag tag, boolean force) throws TeamException {
+ ITagOperation op = new TagInRepositoryOperation(null, new ICVSRemoteResource[] {resource});
+ runTag(op, tag, force);
+ }
+
+ private void runTag(ITagOperation op, CVSTag tag, boolean force) throws TeamException {
+ if (force) op.moveTag();
+ op.setTag(tag);
+ try {
+ ((CVSOperation)op).run(DEFAULT_MONITOR);
+ } catch (InterruptedException e) {
+ fail("Tag interrupted.");
+ } catch (InvocationTargetException e) {
+ if (e.getTargetException() instanceof TeamException) {
+ throw (TeamException) e.getTargetException();
+ } else {
+ e.printStackTrace();
+ fail("Unexpected error while tagging");
+ }
+ }
+ }
+ public void makeBranch(IResource[] resources, CVSTag version, CVSTag branch, boolean update) throws CVSException {
+ ResourceMapping[] mappings = asResourceMappers(resources, IResource.DEPTH_INFINITE);
+ branch(mappings, version, branch, update);
+ }
+
+ protected void branch(ResourceMapping[] mappings, CVSTag version, CVSTag branch, boolean update) throws CVSException {
+ BranchOperation op = new BranchOperation(null, mappings);
+ op.setTags(version, branch, update);
+ executeHeadless(op);
+ }
+
+ /**
+ * Return a collection of resources defined by hierarchy. The resources
+ * are added to the workspace and to the file system. If the manage flag is true, the
+ * resources are auto-managed, if false, they are left un-managed.
+ */
+ public IResource[] buildResources(IContainer container, String[] hierarchy, boolean includeContainer) throws CoreException {
+ List resources = new ArrayList(hierarchy.length + 1);
+ resources.addAll(Arrays.asList(buildResources(container, hierarchy)));
+ if (includeContainer)
+ resources.add(container);
+ IResource[] result = (IResource[]) resources.toArray(new IResource[resources.size()]);
+ ensureExistsInWorkspace(result, true);
+ for (int i = 0; i < result.length; i++) {
+ if (result[i].getType() == IResource.FILE)
+ // 3786 bytes is the average size of Eclipse Java files!
+ ((IFile) result[i]).setContents(getRandomContents(RANDOM_CONTENT_SIZE), true, false, null);
+ }
+ return result;
+ }
+
+ /*
+ * Checkout a copy of the project into a project with the given postfix
+ */
+ protected IProject checkoutCopy(IProject project, String postfix) throws TeamException {
+ // Check the project out under a different name and validate that the results are the same
+ IProject copy = getWorkspace().getRoot().getProject(project.getName() + postfix);
+ checkout(getRepository(), copy, CVSWorkspaceRoot.getCVSFolderFor(project).getFolderSyncInfo().getRepository(), null, DEFAULT_MONITOR);
+ return copy;
+ }
+
+ protected IProject checkoutCopy(IProject project, CVSTag tag) throws TeamException {
+ // Check the project out under a different name and validate that the results are the same
+ IProject copy = getWorkspace().getRoot().getProject(project.getName() + tag.getName());
+ checkout(getRepository(), copy,
+ CVSWorkspaceRoot.getCVSFolderFor(project).getFolderSyncInfo().getRepository(),
+ tag, DEFAULT_MONITOR);
+ return copy;
+ }
+
+ public static void checkout(
+ final ICVSRepositoryLocation repository,
+ final IProject project,
+ final String sourceModule,
+ final CVSTag tag,
+ IProgressMonitor monitor)
+ throws TeamException {
+
+ RemoteFolder remote = new RemoteFolder(null, repository, sourceModule == null ? project.getName() : sourceModule, tag);
+ executeHeadless(new CheckoutSingleProjectOperation(null, remote, project, null, false /* the project is not preconfigured */) {
+ public boolean promptToOverwrite(String title, String msg) {
+ return true;
+ }
+ });
+
+ }
+
+ protected IProject checkoutProject(IProject project, String moduleName, CVSTag tag) throws TeamException {
+ if (project == null)
+ project = getWorkspace().getRoot().getProject(new Path(moduleName).lastSegment());
+ checkout(getRepository(), project, moduleName, tag, DEFAULT_MONITOR);
+ return project;
+ }
+ /*
+ * This method creates a project with the given resources, imports
+ * it to CVS and checks it out
+ */
+ protected IProject createProject(String prefix, String[] resources) throws CoreException, TeamException {
+ IProject project = getUniqueTestProject(prefix);
+ buildResources(project, resources, true);
+ shareProject(project);
+ assertValidCheckout(project);
+ return project;
+ }
+
+ /*
+ * Create a test project using the currently running test case as the project name prefix
+ */
+ protected IProject createProject(String[] strings) throws CoreException {
+ return createProject(getName(), strings);
+ }
+
+ /*
+ * Compare two projects by comparing thier providers
+ */
+ protected void assertEquals(IProject project1, IProject project2) throws CoreException, IOException {
+ assertEquals(project1, project2, false, false);
+ }
+
+ protected void assertEquals(IProject project1, IProject project2, boolean includeTimestamps, boolean includeTags) throws CoreException, IOException {
+ assertEquals(getProvider(project1), getProvider(project2), includeTimestamps, includeTags);
+ }
+
+ /*
+ * Compare CVS team providers by comparing the cvs resource corresponding to the provider's project
+ */
+ protected void assertEquals(CVSTeamProvider provider1, CVSTeamProvider provider2, boolean includeTimestamps, boolean includeTags) throws CoreException, IOException {
+ assertEquals(Path.EMPTY, CVSWorkspaceRoot.getCVSFolderFor(provider1.getProject()),
+ CVSWorkspaceRoot.getCVSFolderFor(provider2.getProject()),
+ includeTimestamps, includeTags);
+ }
+
+ protected void assertContentsEqual(IContainer c1, IContainer c2) throws CoreException {
+ assertTrue("The number of resource in " + c1.getProjectRelativePath().toString() + " differs",
+ c1.members().length == c2.members().length);
+ IResource[] resources = c1.members();
+ for (int i= 0;i <resources.length;i++) {
+ assertContentsEqual(resources[i], c2.findMember(resources[i].getName()));
+ }
+ }
+
+ protected void assertContentsEqual(IResource resource, IResource resource2) throws CoreException {
+ if (resource.getType() == IResource.FILE) {
+ assertContentsEqual((IFile)resource, (IFile)resource2);
+ } else {
+ assertContentsEqual((IContainer)resource, (IContainer)resource2);
+ }
+ }
+
+ protected void assertContentsEqual(IFile resource, IFile resource2) throws CoreException {
+ assertTrue("Contents of " + resource.getProjectRelativePath() + " do not match", compareContent(resource.getContents(), resource2.getContents()));
+ }
+ /*
+ * Compare resources by casting them to their prpoer type
+ */
+ protected void assertEquals(IPath parent, ICVSResource resource1, ICVSResource resource2, boolean includeTimestamps, boolean includeTags) throws CoreException, CVSException, IOException {
+ if ((resource1 == null && resource2 == null)
+ || (resource1 == null && ! resource2.exists())
+ || (resource2 == null && ! resource1.exists()))
+ return;
+ assertEquals("Resource types do not match for " + parent.append(resource1.getName()), resource1.isFolder(), resource2.isFolder());
+ if (!resource1.isFolder())
+ assertEquals(parent, (ICVSFile)resource1, (ICVSFile)resource2, includeTimestamps, includeTags);
+ else
+ assertEquals(parent, (ICVSFolder)resource1, (ICVSFolder)resource2, includeTimestamps, includeTags);
+ }
+
+ /*
+ * Compare folders by comparing their folder sync info and there children
+ *
+ * XXX What about unmanaged children?
+ */
+ protected void assertEquals(IPath parent, ICVSFolder container1, ICVSFolder container2, boolean includeTimestamps, boolean includeTags) throws CoreException, CVSException, IOException {
+ IPath path = parent.append(container1.getName());
+ assertEquals(path, container1.getFolderSyncInfo(), container2.getFolderSyncInfo(), includeTags);
+ assertTrue("The number of resource in " + path.toString() + " differs",
+ container1.members(ICVSFolder.ALL_EXISTING_MEMBERS).length
+ == container2.members(ICVSFolder.ALL_EXISTING_MEMBERS).length);
+ ICVSResource[] resources = container1.members(ICVSFolder.ALL_EXISTING_MEMBERS);
+ for (int i= 0;i <resources.length;i++) {
+ assertEquals(path, resources[i], container2.getChild(resources[i].getName()), includeTimestamps, includeTags);
+ }
+
+ }
+
+ /*
+ * Compare the files contents and sync information
+ */
+ protected void assertEquals(IPath parent, ICVSFile file1, ICVSFile file2, boolean includeTimestamps, boolean includeTags) throws CoreException, CVSException, IOException {
+ if (file1.getName().equals(".project")) return;
+ // Getting the contents first is important as it will fetch the proper sync info if one of the files is a remote handle
+ assertTrue("Contents of " + parent.append(file1.getName()) + " do not match", compareContent(getContents(file1), getContents(file2)));
+ assertEquals(parent.append(file1.getName()), file1.getSyncInfo(), file2.getSyncInfo(), includeTimestamps, includeTags);
+ }
+
+ /*
+ * Compare sync info by comparing the entry line generated by the sync info
+ */
+ protected void assertEquals(IPath path, ResourceSyncInfo info1, ResourceSyncInfo info2, boolean includeTimestamp, boolean includeTag) throws CoreException, CVSException, IOException {
+ if (info1 == null || info2 == null) {
+ if (info1 == info2) return;
+ if (info1 == null) {
+ fail("Expected no resource sync info for " + path.toString() + " but it was " + info2 + " instead");
+ }
+ if (info2 == null) {
+ fail("Expected resource sync info of " + info1 + " for " + path.toString() + " but there was no sync info.");
+ }
+ fail("Shouldn't be able to get here");
+ return;
+ }
+ String line1;
+ String line2;
+ if(includeTimestamp) {
+ line1 = info1.getEntryLine();
+ line2 = info2.getEntryLine();
+ } else {
+ line1 = info1.getServerEntryLine(null);
+ line2 = info2.getServerEntryLine(null);
+ }
+ if (!includeTag) {
+ // Strip everything past the last slash
+ line1 = line1.substring(0, line1.lastIndexOf('/'));
+ line2 = line2.substring(0, line2.lastIndexOf('/'));
+ }
+ assertEquals("Resource Sync info differs for " + path.toString(), line1, line2);
+ }
+
+ /*
+ * Use the equals of folder sync info unless the tag is not included in which case we just
+ * compare the root and repository
+ */
+ protected void assertEquals(IPath path, FolderSyncInfo info1, FolderSyncInfo info2, boolean includeTag) throws CoreException, CVSException, IOException {
+ if (info1 == null && info2 == null) {
+ return;
+ } else if (info1 == null) {
+ fail("Expected " + path.toString() + " not to be a CVS folder but it is.");
+ } else if (info2 == null) {
+ fail("Expected " + path.toString() + " to be a CVS folder but it isn't.");
+ }
+
+ if (includeTag) {
+ assertTrue("Folder sync info differs for " + path.toString(), info1.equals(info2));
+ } else {
+ assertTrue("Repository Root differs for " + path.toString(), info1.getRoot().equals(info2.getRoot()));
+ assertTrue("Repository relative path differs for " + path.toString(), info1.getRepository().equals(info2.getRepository()));
+ }
+ }
+
+
+ /*
+ * Compare folders by comparing their folder sync info and there children
+ *
+ * XXX What about unmanaged children?
+ */
+ protected void assertEquals(IPath parent, RemoteFolder container1, RemoteFolder container2, boolean includeTags) throws CoreException, TeamException, IOException {
+ IPath path = parent.append(container1.getName());
+ assertEquals(path, container1.getFolderSyncInfo(), container2.getFolderSyncInfo(), includeTags);
+ ICVSRemoteResource[] members1 = container1.getMembers(DEFAULT_MONITOR);
+ ICVSRemoteResource[] members2 = container2.getMembers(DEFAULT_MONITOR);
+ assertTrue("Number of members differ for " + path, members1.length == members2.length);
+ Map memberMap2 = new HashMap();
+ for (int i= 0;i <members2.length;i++) {
+ memberMap2.put(members2[i].getName(), members2[i]);
+ }
+ for (int i= 0;i <members1.length;i++) {
+ ICVSRemoteResource member2 = (ICVSRemoteResource)memberMap2.get(members1[i].getName());
+ assertNotNull("Resource does not exist: " + path.append(members1[i].getName()) + member2);
+ assertEquals(path, members1[i], member2, includeTags);
+ }
+ }
+ protected void assertEquals(IPath parent, ICVSRemoteResource resource1, ICVSRemoteResource resource2, boolean includeTags) throws CoreException, TeamException, IOException {
+ assertEquals("Resource types do not match for " + parent.append(resource1.getName()), resource1.isContainer(), resource2.isContainer());
+ if (resource1.isContainer())
+ assertEquals(parent, (RemoteFolder)resource1, (RemoteFolder)resource2, includeTags);
+ else
+ assertEquals(parent, (ICVSFile)resource1, (ICVSFile)resource2, false, includeTags);
+ }
+
+
+ /*
+ * Compare the local project with the remote state by checking out a copy of the project.
+ */
+ protected void assertLocalStateEqualsRemote(IProject project) throws TeamException, CoreException, IOException {
+ assertEquals(getProvider(project), getProvider(checkoutCopy(project, "-remote")), false, true);
+ }
+
+ /*
+ * Compare the local project with the remote state indicated by the given tag by checking out a copy of the project.
+ */
+ protected void assertLocalStateEqualsRemote(String message, IProject project, CVSTag tag) throws TeamException, CoreException, IOException {
+ assertEquals(getProvider(project), getProvider(checkoutCopy(project, tag)), true, false);
+ }
+
+ protected void assertHasNoRemote(String prefix, IResource[] resources) throws TeamException {
+ for (int i=0;i<resources.length;i++)
+ assertHasNoRemote(prefix, resources[i]);
+ }
+
+ protected void assertHasNoRemote(String prefix, IResource resource) throws TeamException {
+ assertTrue(prefix + " resource should not have a remote", !CVSWorkspaceRoot.hasRemote(resource));
+ }
+
+ protected void assertHasRemote(String prefix, IResource[] resources) throws TeamException {
+ for (int i=0;i<resources.length;i++)
+ assertHasRemote(prefix, resources[i]);
+ }
+
+ protected void assertHasRemote(String prefix, IResource resource) throws TeamException {
+ assertTrue(prefix + " resource should have a remote", CVSWorkspaceRoot.hasRemote(resource));
+ }
+
+ protected void assertIsModified(String prefix, IResource[] resources) throws TeamException {
+ for (int i=0;i<resources.length;i++)
+ assertIsModified(prefix, resources[i]);
+ }
+
+ protected void assertIsModified(String prefix, IResource resource) throws TeamException {
+ // Only check for files as CVS doesn't dirty folders
+ if (resource.getType() == IResource.FILE)
+ assertTrue(prefix + " resource " + resource.getFullPath() + " should be dirty.", ((ICVSFile)getCVSResource(resource)).isModified(null));
+ }
+
+ protected void assertNotModified(String prefix, IResource[] resources) throws TeamException {
+ for (int i=0;i<resources.length;i++)
+ assertNotModified(prefix, resources[i]);
+ }
+
+ protected void assertNotModified(String prefix, IResource resource) throws TeamException {
+ assertTrue(prefix + " resource should be dirty", !((ICVSFile)getCVSResource(resource)).isModified(null));
+ }
+
+ protected void assertIsIgnored(IResource resource, boolean ignoredState) throws TeamException {
+ assertEquals("Resource " + resource.getFullPath() + " should be ignored but isn't.",
+ ignoredState, getCVSResource(resource).isIgnored());
+ }
+
+ protected void assertValidCheckout(IProject project) {
+ // NOTE: Add code to ensure that the project was checkout out properly
+ CVSTeamProvider provider = (CVSTeamProvider)RepositoryProvider.getProvider(project);
+ assertNotNull(provider);
+ }
+
+ protected void assertReadOnly(IResource[] resources, final boolean isReadOnly, final boolean recurse) throws CoreException {
+ for (int i = 0; i < resources.length; i++) {
+ IResource resource = resources[i];
+ resource.accept(new IResourceVisitor() {
+ public boolean visit(IResource resource) throws CoreException {
+ if (resource.getType() == IResource.FILE) {
+ assertEquals(isReadOnly, resource.isReadOnly());
+ }
+ return recurse;
+ }
+ });
+ }
+ }
+
+ protected InputStream getContents(ICVSFile file) throws CVSException, IOException {
+ if (file instanceof ICVSRemoteFile)
+ return ((RemoteFile)file).getContents(DEFAULT_MONITOR);
+ else
+ return new BufferedInputStream(file.getContents());
+ }
+
+ /*
+ * Get the CVS Resource for the given resource
+ */
+ protected ICVSResource getCVSResource(IResource resource) throws CVSException {
+ return CVSWorkspaceRoot.getCVSResourceFor(resource);
+ }
+
+ protected IProject getNamedTestProject(String name) throws CoreException {
+ IProject target = getWorkspace().getRoot().getProject(name);
+ if (!target.exists()) {
+ target.create(null);
+ target.open(null);
+ }
+ assertExistsInFileSystem(target);
+ return target;
+ }
+ protected CVSTeamProvider getProvider(IResource resource) throws TeamException {
+ return (CVSTeamProvider)RepositoryProvider.getProvider(resource.getProject());
+ }
+ protected static InputStream getRandomContents(int sizeAtLeast) {
+ StringBuffer randomStuff = new StringBuffer(sizeAtLeast + 100);
+ while (randomStuff.length() < sizeAtLeast) {
+ randomStuff.append(getRandomSnippet() + eol);
+ }
+ return new ByteArrayInputStream(randomStuff.toString().getBytes());
+ }
+ /**
+ * Return String with some random text to use
+ * as contents for a file resource.
+ */
+ public static String getRandomSnippet() {
+ switch ((int) Math.round(Math.random() * 10)) {
+ case 0 :
+ return "este e' o meu conteudo (portuguese)";
+ case 1 :
+ return "Dann brauchen wir aber auch einen deutschen Satz!";
+ case 2 :
+ return "I'll be back";
+ case 3 :
+ return "don't worry, be happy";
+ case 4 :
+ return "there is no imagination for more sentences";
+ case 5 :
+ return "customize yours";
+ case 6 :
+ return "foo";
+ case 7 :
+ return "bar";
+ case 8 :
+ return "foobar";
+ case 9 :
+ return "case 9";
+ default :
+ return "these are my contents";
+ }
+ }
+ protected IProject getUniqueTestProject(String prefix) throws CoreException {
+ // manage and share with the default stream create by this class
+ return getNamedTestProject(prefix + "-" + Long.toString(System.currentTimeMillis()));
+ }
+
+ protected CVSRepositoryLocation getRepository() {
+ return CVSTestSetup.repository;
+ }
+ protected void importProject(IProject project) throws TeamException {
+
+ // Create the root folder for the import operation
+ ICVSFolder root = CVSWorkspaceRoot.getCVSFolderFor(project);
+
+ // Perform the import
+ IStatus status;
+ Session s = new Session(getRepository(), root);
+ s.open(DEFAULT_MONITOR, true /* open for modification */);
+ try {
+ status = Command.IMPORT.execute(s,
+ Command.NO_GLOBAL_OPTIONS,
+ new LocalOption[] {Import.makeArgumentOption(Command.MESSAGE_OPTION, "Initial Import")},
+ new String[] { project.getName(), getRepository().getUsername(), "start" },
+ null,
+ DEFAULT_MONITOR);
+ } finally {
+ s.close();
+ }
+
+ if (status.getCode() == CVSStatus.SERVER_ERROR) {
+ throw new CVSServerException(status);
+ }
+ }
+
+ protected void shareProject(IProject project) throws TeamException, CoreException {
+ mapNewProject(project);
+ commitNewProject(project);
+ }
+
+ protected void mapNewProject(IProject project) throws TeamException {
+ shareProject(getRepository(), project, null, DEFAULT_MONITOR);
+ }
+
+ /**
+ * Map the given local project to remote folder, creating the remote folder or any of
+ * its ancestors as necessary.
+ * @param location
+ * @param project
+ * @param moduleName
+ * @param default_monitor
+ */
+ protected void shareProject(CVSRepositoryLocation location, IProject project, String moduleName, IProgressMonitor default_monitor) throws CVSException {
+ ShareProjectOperation op = new ShareProjectOperation(null, location, project, moduleName);
+ executeHeadless(op);
+ }
+
+ protected void commitNewProject(IProject project) throws CoreException, CVSException, TeamException {
+ List resourcesToAdd = new ArrayList();
+ IResource[] members = project.members();
+ for (int i = 0; i < members.length; i++) {
+ if ( ! CVSWorkspaceRoot.getCVSResourceFor(members[i]).isIgnored()) {
+ resourcesToAdd.add(members[i]);
+ }
+ }
+ addResources((IResource[]) resourcesToAdd.toArray(new IResource[resourcesToAdd.size()]));
+ commitResources(new IResource[] {project}, IResource.DEPTH_INFINITE);
+ // Pause to ensure that future operations happen later than timestamp of committed resources
+ waitMsec(1500);
+ }
+
+ /**
+ * Return an input stream with some random text to use
+ * as contents for a file resource.
+ */
+ public InputStream getRandomContents() {
+ return getRandomContents(RANDOM_CONTENT_SIZE);
+ }
+
+ protected void setContentsAndEnsureModified(IFile file) throws CoreException, TeamException {
+ setContentsAndEnsureModified(file, getRandomContents().toString());
+ }
+
+ protected void setContentsAndEnsureModified(IFile file, String contents) throws CoreException, CVSException {
+ ICVSFile cvsFile = CVSWorkspaceRoot.getCVSFileFor(file);
+ int count = 0;
+ if (contents == null) contents ="";
+ do {
+ file.setContents(new ByteArrayInputStream(contents.getBytes()), false, false, null);
+ assertTrue("Timestamp granularity is too small. Increase test wait factor", count <= CVSTestSetup.WAIT_FACTOR);
+ if (!cvsFile.isModified(null)) {
+ waitMsec(1500);
+ count++;
+ }
+ } while (!cvsFile.isModified(null));
+ }
+
+ public void waitMsec(int msec) {
+ try {
+ Thread.sleep(msec);
+ } catch(InterruptedException e) {
+ fail("wait-problem");
+ }
+ }
+
+ public static void waitForJobCompletion(Job job) {
+ // process UI events first, give the main thread a chance
+ // to handle any syncExecs or asyncExecs posted as a result
+ // of the event processing thread.
+ while (Display.getCurrent().readAndDispatch()) {};
+
+ // wait for the event handler to process changes.
+ while(job.getState() != Job.NONE) {
+ while (Display.getCurrent().readAndDispatch()) {};
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ }
+ }
+ while (Display.getCurrent().readAndDispatch()) {};
+ }
+
+ public static void waitForIgnoreFileHandling() {
+ waitForJobCompletion(SyncFileChangeListener.getDeferredHandler().getEventHandlerJob());
+ waitForDecorator();
+ }
+
+ protected static void waitForDecorator() {
+ // Wait for the decorator job
+ Job[] decorators = Platform.getJobManager().find(DecoratorManager.FAMILY_DECORATE);
+ for (int i = 0; i < decorators.length; i++) {
+ Job job = decorators[i];
+ waitForJobCompletion(job);
+ }
+ }
+
+ public static void waitForSubscriberInputHandling(SubscriberSyncInfoCollector input) {
+ input.waitForCollector(new IProgressMonitor() {
+ public void beginTask(String name, int totalWork) {
+ }
+ public void done() {
+ }
+ public void internalWorked(double work) {
+ }
+ public boolean isCanceled() {
+ return false;
+ }
+ public void setCanceled(boolean value) {
+ }
+ public void setTaskName(String name) {
+ }
+ public void subTask(String name) {
+ }
+ public void worked(int work) {
+ while (Display.getCurrent().readAndDispatch()) {}
+ }
+ });
+ }
+
+ protected static void executeHeadless(CVSOperation op) throws CVSException {
+ try {
+ try {
+ // Bypass contxt by executing run(IProgressMonitor) directly
+ op.run(DEFAULT_MONITOR);
+ } catch (InvocationTargetException e1) {
+ throw CVSException.wrapException(e1);
+ }
+ } catch (InterruptedException e) {
+ throw new OperationCanceledException();
+ }
+ }
+
+ protected void setUp() throws Exception {
+ obtainCVSServerLock();
+ super.setUp();
+ }
+
+ /* (non-Javadoc)
+ * @see junit.framework.TestCase#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ releaseCVSServerLock();
+ super.tearDown();
+ if (CVSTestSetup.logListener != null) {
+ try {
+ CVSTestSetup.logListener.checkErrors();
+ } catch (CoreException e) {
+ if (CVSTestSetup.FAIL_IF_EXCEPTION_LOGGED) {
+ fail("Exception written to log: ", e);
+ } else {
+ // Write the log to standard out so it can be more easily seen
+ write(e.getStatus(), 0);
+ }
+ }
+ }
+ }
+
+ private void obtainCVSServerLock() {
+ IProject project = null;
+ boolean firstTry = true;
+ while (project == null) {
+ try {
+ project = checkoutProject(null, CVS_TEST_LOCK_PROJECT , null);
+ } catch (TeamException e) {
+ // The checkout of the lock project failed so lets create it if it doesn't exist
+ if (firstTry) {
+ try {
+ createTestLockProject(DEFAULT_MONITOR);
+ } catch (TeamException e1) {
+ // We couldn't check out the project or create it
+ // It's possible someone beat us to it so we'll try the checkout again.
+ }
+ } else {
+ // We tried twice to check out the project and failed.
+ // Lets just go ahead and run but we'll log the fact that we couldn't get the lock
+ write(new CVSStatus(IStatus.ERROR, "Could not obtain the CVS server lock. The test will containue but any performance timings may be affected", e), 0);
+ return;
+ }
+ firstTry = false;
+ }
+ }
+ if (project != null) {
+ IFile lockFile = project.getFile(CVS_TEST_LOCK_FILE);
+ boolean obtained = false;
+ int attempts = 0;
+ while (!obtained) {
+ attempts++;
+ if (lockFile.exists()) {
+ // If the file exists, check if the lock has expired
+ if (hasExpired(lockFile)) {
+ try {
+ overwriteLock(lockFile);
+ return;
+ } catch (CoreException e) {
+ // Ignore the error and continue
+ }
+ }
+ } else {
+ try {
+ writeLock(lockFile);
+ return;
+ } catch (CoreException e) {
+ // Ignore the error, since it probably means someone beat us to it.
+ }
+ }
+ // Wait for a while before testing the lock again
+ try {
+ Thread.sleep(LOCK_WAIT_TIME);
+ } catch (InterruptedException e) {
+ // Ignore
+ }
+ try {
+ // Update the lockfile in case someone else got to it first
+ replace(new IResource[] { lockFile }, null, true);
+ } catch (CoreException e) {
+ // An error updated is not recoverable so just continue
+ write(new CVSStatus(IStatus.ERROR, "Could not obtain the CVS server lock. The test will continue but any performance timings may be affected", e), 0);
+ return;
+ }
+ if (attempts > MAX_LOCK_ATTEMPTS) {
+ write(new CVSStatus(IStatus.ERROR, "Could not obtain the CVS server lock. The test will continue but any performance timings may be affected", new Exception()), 0);
+ return;
+ }
+ }
+ }
+ }
+
+ private boolean hasExpired(IFile lockFile) {
+ long timestamp = lockFile.getLocalTimeStamp();
+ return System.currentTimeMillis() - timestamp > LOCK_EXPIRATION_THRESHOLD;
+ }
+
+ private void overwriteLock(IFile lockFile) throws CoreException {
+ lockFile.setContents(getLockContents(), true, true, null);
+ commitResources(new IResource[] { lockFile }, IResource.DEPTH_ZERO);
+ }
+
+ private void writeLock(IFile lockFile) throws CoreException {
+ lockFile.create(getLockContents(), false, null);
+ addResources(new IResource[] { lockFile });
+ commitResources(new IResource[] { lockFile }, IResource.DEPTH_ZERO);
+ }
+
+ private InputStream getLockContents() {
+ lockId = Long.toString(System.currentTimeMillis());
+ return new ByteArrayInputStream(lockId.getBytes());
+ }
+
+ private void createTestLockProject(IProgressMonitor monitor) throws TeamException {
+ CVSRepositoryLocation repository = getRepository();
+ RemoteFolderTree root = new RemoteFolderTree(null, repository, Path.EMPTY.toString(), null);
+ RemoteFolderTree child = new RemoteFolderTree(root, CVS_TEST_LOCK_PROJECT, repository, new Path(null, root.getRepositoryRelativePath()).append(CVS_TEST_LOCK_PROJECT).toString(), null);
+ root.setChildren(new ICVSRemoteResource[] { child });
+ Session s = new Session(repository, root);
+ s.open(monitor, true /* open for modification */);
+ try {
+ IStatus status = Command.ADD.execute(s,
+ Command.NO_GLOBAL_OPTIONS,
+ Command.NO_LOCAL_OPTIONS,
+ new String[] { CVS_TEST_LOCK_PROJECT },
+ null,
+ monitor);
+ // If we get a warning, the operation most likely failed so check that the status is OK
+ if (status.getCode() == CVSStatus.SERVER_ERROR || ! status.isOK()) {
+ throw new CVSServerException(status);
+ }
+ } finally {
+ s.close();
+ }
+ }
+
+ private void releaseCVSServerLock() {
+ if (lockId != null) {
+ try {
+ IProject project = getWorkspace().getRoot().getProject(CVS_TEST_LOCK_PROJECT);
+ // Update the project and verify we still have the lock
+ IFile file = project.getFile(CVS_TEST_LOCK_FILE);
+ String id = getFileContents(file);
+ if (id.equals(lockId)) {
+ // We have the lock so let's free it (but first check if someone preempted us)
+ ICVSFile cvsFile = CVSWorkspaceRoot.getCVSFileFor(file);
+ byte[] bytes = cvsFile.getSyncBytes();
+ if (bytes != null) {
+ String revision = ResourceSyncInfo.getRevision(bytes);
+ updateResources(new IResource[] { file }, true);
+ bytes = cvsFile.getSyncBytes();
+ if (bytes == null || !ResourceSyncInfo.getRevision(bytes).equals(revision)) {
+ write(new CVSStatus(IStatus.ERROR, "The CVS server lock expired while this test was running. Any performance timings may be affected", new Exception()), 0);
+ return;
+ }
+ }
+ // Delete the lock file and commit
+ deleteResources(project, new String[] { CVS_TEST_LOCK_FILE }, true);
+ }
+ } catch (CoreException e) {
+ write(e.getStatus(), 0);
+ } catch (IOException e) {
+ write(new CVSStatus(IStatus.ERROR, "An error occurred while reading the lock file", e), 0);
+ }
+ }
+ }
+
+ protected void write(IStatus status, int indent) {
+ PrintStream output = System.out;
+ indent(output, indent);
+ output.println("Severity: " + status.getSeverity());
+
+ indent(output, indent);
+ output.println("Plugin ID: " + status.getPlugin());
+
+ indent(output, indent);
+ output.println("Code: " + status.getCode());
+
+ indent(output, indent);
+ output.println("Message: " + status.getMessage());
+
+ Throwable t = status.getException();
+ if (t != null) {
+ t.printStackTrace(output);
+ if (t instanceof CoreException) {
+ write(((CoreException)t).getStatus(), indent + 1);
+ }
+ }
+
+ if (status.isMultiStatus()) {
+ IStatus[] children = status.getChildren();
+ for (int i = 0; i < children.length; i++)
+ write(children[i], indent + 1);
+ }
+ }
+
+ protected static void indent(OutputStream output, int indent) {
+ for (int i = 0; i < indent; i++)
+ try {
+ output.write(" ".getBytes());
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see junit.framework.TestCase#runBare()
+ */
+ public void runBare() throws Throwable {
+ try {
+ super.runBare();
+ } catch (CVSException e) {
+ // If a communication exception occurred
+ // perhaps it is a server problem
+ // Try again, just in case it is
+ if (containsCommunicationException(e)) {
+ super.runBare();
+ } else {
+ throw e;
+ }
+ }
+ }
+
+ private boolean containsCommunicationException(CVSException e) {
+ if (e instanceof CVSCommunicationException) return true;
+ IStatus status = e.getStatus();
+ if (status.getException() instanceof CVSCommunicationException) return true;
+ if (status.isMultiStatus()) {
+ IStatus[] children = status.getChildren();
+ for (int i = 0; i < children.length; i++) {
+ IStatus child = children[i];
+ if (child.getException() instanceof CVSCommunicationException) return true;
+ }
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.tests.harness.EclipseWorkspaceTest#ensureDoesNotExistInWorkspace(org.eclipse.core.resources.IResource)
+ */
+ public void ensureDoesNotExistInWorkspace(IResource resource) {
+ // Overridden to change how the workspace is deleted on teardown
+ if (resource.getType() == IResource.ROOT) {
+ // Delete each project individually
+ Job[] allJobs = Platform.getJobManager().find(null /* all families */);
+ IProject[] projects = ((IWorkspaceRoot)resource).getProjects();
+ try {
+ ensureDoesNotExistInWorkspace(projects);
+ } catch (AssertionFailedError e) {
+ // The delete failed. Write the active jobs to stdout
+ System.out.println(e.getMessage());
+ System.out.println("Jobs active at time of deletion failure: "); //$NON-NLS-1$
+ if (allJobs.length == 0) {
+ System.out.println("None"); //$NON-NLS-1$
+ }
+ for (int i = 0; i < allJobs.length; i++) {
+ Job job = allJobs[i];
+ System.out.println(job.getName());
+ }
+ if (CVSTestSetup.FAIL_IF_EXCEPTION_LOGGED) {
+ throw e;
+ }
+ }
+ } else {
+ ensureNotReadOnly(resource);
+ super.ensureDoesNotExistInWorkspace(resource);
+ }
+ }
+
+ private void ensureNotReadOnly(IResource resource) {
+ if (resource.exists()) {
+ try {
+ resource.accept(new IResourceVisitor() {
+ public boolean visit(IResource resource) throws CoreException {
+ if (resource.exists() && resource.isReadOnly()) {
+ resource.setReadOnly(false);
+ }
+ return true;
+ }
+ });
+ } catch (CoreException e) {
+ fail("#ensureNotReadOnly " + resource.getFullPath(), e);
+ }
+ }
+
+ }
+
+ /**
+ * Delete each project from the workspace and return a status that
+ * contains any failures
+ */
+ public void ensureDoesNotExistInWorkspace(final IProject[] projects) {
+ final Map failures = new HashMap();
+ IWorkspaceRunnable body = new IWorkspaceRunnable() {
+ public void run(IProgressMonitor monitor) {
+ for (int i = 0; i < projects.length; i++) {
+ try {
+ if (projects[i].exists())
+ projects[i].delete(true, null);
+ } catch (CoreException e) {
+ write(new CVSStatus(IStatus.ERROR, "Could not delete project " + projects[i].getName(), e), 0);
+ failures.put(projects[i], e);
+ }
+ }
+ }
+ };
+ try {
+ getWorkspace().run(body, null);
+ } catch (CoreException e) {
+ fail("#ensureDoesNotExistInWorkspace(IResource[])", e);
+ }
+ if (!failures.isEmpty()) {
+ StringBuffer text = new StringBuffer();
+ text.append("Could not delete all projects: ");
+ for (Iterator iter = failures.keySet().iterator(); iter.hasNext();) {
+ IProject project = (IProject) iter.next();
+ text.append(project.getName());
+ }
+ fail(text.toString());
+ }
+ }
+
+ protected void assertStatusContainsCode(IStatus status, int code) {
+ if (status.isMultiStatus()) {
+ IStatus[] children = status.getChildren();
+ for (int i = 0; i < children.length; i++) {
+ IStatus child = children[i];
+ if (child.getCode() == code)
+ return;
+ }
+ fail("Expected status code was not present");
+ } else {
+ assertEquals("Status code is not what is expected", status.getCode(), code);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see junit.framework.TestCase#runTest()
+ */
+ protected void runTest() throws Throwable {
+ if (!CVSTestSetup.RECORD_PROTOCOL_TRAFFIC) {
+ super.runTest();
+ return;
+ }
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ Policy.recorder = new PrintStream(os);
+ try {
+ try {
+ // Override the runTest method in order to print the entire trace of a
+ // test that failed due to a CoreException including nested exceptions
+ super.runTest();
+ } catch (CoreException e) {
+ e.printStackTrace();
+ write(e.getStatus(), 0);
+ throw e;
+ }
+ } catch (Throwable e) {
+ // Transfer the recorded debug info to stdout
+ Policy.recorder.close();
+ System.out.println(new String(os.toByteArray()));
+ throw e;
+ } finally {
+ Policy.recorder.close();
+ Policy.recorder = null;
+ }
+ }
+}
+
diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/mappings/ResourceMapperTests.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/mappings/ResourceMapperTests.java
new file mode 100644
index 000000000..f28c6da4e
--- /dev/null
+++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/mappings/ResourceMapperTests.java
@@ -0,0 +1,534 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.team.tests.ccvs.core.mappings;
+
+import java.io.IOException;
+import java.util.*;
+
+import junit.framework.Test;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.resources.mapping.*;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.core.synchronize.*;
+import org.eclipse.team.internal.ccvs.core.*;
+import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption;
+import org.eclipse.team.internal.ccvs.core.resources.RemoteFolderTree;
+import org.eclipse.team.internal.ccvs.core.resources.RemoteFolderTreeBuilder;
+import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
+import org.eclipse.team.tests.ccvs.core.EclipseTest;
+
+/**
+ * Tests for using CVS operations with deep and shallow resource mappings.
+ */
+public class ResourceMapperTests extends EclipseTest {
+
+ public ResourceMapperTests() {
+ super();
+ }
+
+ public ResourceMapperTests(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ return suite(ResourceMapperTests.class);
+ }
+
+ /**
+ * Update the resources contained in the given mappers and ensure that the
+ * update was performed properly by comparing the result with the reference projects.
+ * @throws Exception
+ */
+ protected void update(ResourceMapping mapper, LocalOption[] options) throws Exception {
+ SyncInfoTree incomingSet = getIncoming(mapper.getProjects());
+ update(new ResourceMapping[] { mapper }, options);
+ assertUpdate(mapper, incomingSet);
+ }
+
+ /**
+ * Replace the resources contained in the given mappers and ensure that the
+ * update was performed properly by comparing the result with the reference projects.
+ * @throws Exception
+ */
+ protected void replace(ResourceMapping mapper) throws Exception {
+ SyncInfoTree incomingSet = getIncoming(mapper.getProjects());
+ replace(new ResourceMapping[] { mapper });
+ assertUpdate(mapper, incomingSet);
+ }
+
+ /**
+ * Commit and check that all resources in containing project that should have been committed were and
+ * that any not contained by the mappers were not.
+ * @throws CoreException
+ * @see org.eclipse.team.tests.ccvs.core.EclipseTest#commit(org.eclipse.core.resources.mapping.IResourceMapper[], java.lang.String)
+ */
+ protected void commit(ResourceMapping mapper, String message) throws CoreException {
+ SyncInfoTree set = getOutgoing(mapper.getProjects());
+ commit(new ResourceMapping[] { mapper }, message);
+ assertCommit(mapper, set);
+ }
+
+ /**
+ * Tag the given resource mappings and assert that only the resources
+ * within the mapping were tagged.
+ * @throws CoreException
+ */
+ protected void tag(ResourceMapping mapping, CVSTag tag) throws CoreException {
+ tag(new ResourceMapping[] { mapping }, tag, false);
+ assertTagged(mapping, tag);
+ }
+
+ /**
+ * Branch the resources in the given mapping.
+ * @throws CoreException
+ * @throws IOException
+ */
+ protected void branch(ResourceMapping mapping, CVSTag branch) throws CoreException, IOException {
+ CVSTag version = new CVSTag("Root_" + branch.getName(), CVSTag.VERSION);
+ branch(new ResourceMapping[] { mapping }, version, branch, true /* update */);
+ assertTagged(mapping, version);
+ assertBranched(mapping, branch);
+ }
+
+ /**
+ * Add any resources contained by the mapping
+ * @param mapping
+ * @throws CoreException
+ */
+ protected void add(ResourceMapping mapping) throws CoreException {
+ SyncInfoTree set = getUnaddedResource(mapping);
+ add(new ResourceMapping[] { mapping });
+ assertAdded(mapping, set);
+ }
+
+ private void assertAdded(ResourceMapping mapping, final SyncInfoTree set) throws CoreException {
+ // Assert that all resources covered by the mapping are now under version control (i.e. are in-sync)
+ // Remove the resources contained in the mapping from the set of unadded resources.
+ visit(mapping, ResourceMappingContext.LOCAL_CONTEXT, new IResourceVisitor() {
+ public boolean visit(IResource resource) throws CoreException {
+ ICVSResource cvsResource = getCVSResource(resource);
+ assertTrue("Resource was not added but should have been: " + resource.getFullPath(),
+ (cvsResource.isManaged()
+ || (cvsResource.isFolder()
+ && ((ICVSFolder)cvsResource).isCVSFolder())));
+ set.remove(resource);
+ return true;
+ }
+ });
+ // Assert that the remaining unadded resources are still unadded
+ SyncInfo[] infos = set.getSyncInfos();
+ for (int i = 0; i < infos.length; i++) {
+ SyncInfo info = infos[i];
+ ICVSResource cvsResource = getCVSResource(info.getLocal());
+ assertTrue("Resource was added but should not have been: " + info.getLocal().getFullPath(), !cvsResource.isManaged());
+ }
+ }
+
+ /*
+ * Need to ensure that only the resources contained in the mapping
+ * have the branch tag associated with them.
+ */
+ private void assertBranched(ResourceMapping mapping, CVSTag branch) throws CoreException, IOException {
+ // First, make sure the proper resources are tagged in the repo
+ assertTagged(mapping, branch);
+ // Now make sure the proper local files are tagged
+ final Map remotes = getTaggedRemoteFilesByPath(mapping, branch);
+ final Map locals = getTaggedLocalFilesByPath(mapping, branch);
+ for (Iterator iter = remotes.keySet().iterator(); iter.hasNext();) {
+ String key = (String)iter.next();
+ ICVSRemoteFile remote = (ICVSRemoteFile)remotes.get(key);
+ ICVSFile local = (ICVSFile)locals.get(key);
+ assertNotNull("Remotely tagged resource was not tagged locally: " + remote.getRepositoryRelativePath(), local);
+ assertEquals(local.getIResource().getParent().getFullPath(), remote, local, false, false /* include tags */);
+ assertEquals("Remotely tagged resource was not tagged locally: " + remote.getRepositoryRelativePath(), branch, local.getSyncInfo().getTag());
+ locals.remove(key);
+ iter.remove();
+ }
+ // The remote map should be empty after traversal
+ for (Iterator iter = remotes.keySet().iterator(); iter.hasNext();) {
+ String path = (String) iter.next();
+ fail("Remote file " + path + " was tagged remotely but not locally.");
+ }
+ // The local map should be empty after traversal
+ for (Iterator iter = locals.keySet().iterator(); iter.hasNext();) {
+ String path = (String) iter.next();
+ fail("Local file " + path + " was tagged locally but not remotely.");
+ }
+ }
+
+ private void assertTagged(ResourceMapping mapping, final CVSTag tag) throws CoreException {
+ final Map tagged = getTaggedRemoteFilesByPath(mapping, tag);
+ // Visit all the resources in the traversal and ensure that they are tagged
+ visit(mapping, ResourceMappingContext.LOCAL_CONTEXT, new IResourceVisitor() {
+ public boolean visit(IResource resource) throws CoreException {
+ if (resource.getType() == IResource.FILE) {
+ ICVSRemoteFile file = popRemote(resource, tagged);
+ assertNotNull("Resource was not tagged: " + resource.getFullPath(), file);
+ }
+ return true;
+ }
+ });
+
+ // The tagged map should be empty after traversal
+ for (Iterator iter = tagged.keySet().iterator(); iter.hasNext();) {
+ String path = (String) iter.next();
+ fail("Remote file " + path + " was tagged but should not have been.");
+ }
+ }
+
+ private Map getTaggedLocalFilesByPath(ResourceMapping mapping, final CVSTag branch) throws CoreException {
+ final Map tagged = new HashMap();
+ IProject[] projects = mapping.getProjects();
+ for (int i = 0; i < projects.length; i++) {
+ IProject project = projects[i];
+ project.accept(new IResourceVisitor() {
+ public boolean visit(IResource resource) throws CoreException {
+ if (resource.getType() == IResource.FILE) {
+ ICVSFile file = (ICVSFile)getCVSResource(resource);
+ ResourceSyncInfo info = file.getSyncInfo();
+ if (info != null && info.getTag() != null && info.getTag().equals(branch)) {
+ tagged.put(file.getRepositoryRelativePath(), file);
+ }
+ }
+ return true;
+ }
+ });
+ }
+ return tagged;
+ }
+
+ private Map getTaggedRemoteFilesByPath(ResourceMapping mapping, final CVSTag tag) throws CVSException {
+ IProject[] projects = mapping.getProjects();
+ ICVSResource[] remotes = getRemoteTrees(projects, tag);
+ final Map tagged = getFilesByPath(remotes);
+ return tagged;
+ }
+
+ private ICVSResource[] getRemoteTrees(IProject[] projects, CVSTag tag) throws CVSException {
+ List result = new ArrayList();
+ for (int i = 0; i < projects.length; i++) {
+ IProject project = projects[i];
+ RemoteFolderTree tree = RemoteFolderTreeBuilder.buildRemoteTree(getRepository(), project, tag, DEFAULT_MONITOR);
+ result.add(tree);
+ }
+ return (ICVSResource[]) result.toArray(new ICVSResource[result.size()]);
+ }
+
+ private Map getFilesByPath(ICVSResource[] remotes) throws CVSException {
+ Map result = new HashMap();
+ for (int i = 0; i < remotes.length; i++) {
+ ICVSResource resource = remotes[i];
+ collectFiles(resource, result);
+ }
+ return result;
+ }
+
+ private void collectFiles(ICVSResource resource, Map result) throws CVSException {
+ if (resource.isFolder()) {
+ ICVSResource[] members = ((ICVSFolder)resource).members(ICVSFolder.ALL_EXISTING_MEMBERS);
+ for (int i = 0; i < members.length; i++) {
+ ICVSResource member = members[i];
+ collectFiles(member, result);
+ }
+ } else {
+ result.put(resource.getRepositoryRelativePath(), resource);
+ }
+ }
+
+ private ICVSRemoteFile popRemote(IResource resource, Map tagged) throws CVSException {
+ ICVSResource cvsResource = getCVSResource(resource);
+ ICVSRemoteFile remote = (ICVSRemoteFile)tagged.get(cvsResource.getRepositoryRelativePath());
+ if (remote != null) {
+ tagged.remove(remote.getRepositoryRelativePath());
+ }
+ return remote;
+ }
+
+ private ResourceMapping asResourceMapping(final IResource[] resources, final int depth) {
+ return new ResourceMapping() {
+ public Object getModelObject() {
+ return ResourcesPlugin.getWorkspace();
+ }
+ public IProject[] getProjects() {
+ return getProjects(resources);
+ }
+ private IProject[] getProjects(IResource[] resources) {
+ Set projects = new HashSet();
+ for (int i = 0; i < resources.length; i++) {
+ IResource resource = resources[i];
+ projects.add(resource.getProject());
+ }
+ return (IProject[]) projects.toArray(new IProject[projects.size()]);
+ }
+ public ResourceTraversal[] getTraversals(ResourceMappingContext context, IProgressMonitor monitor) throws CoreException {
+ return new ResourceTraversal[] {
+ new ResourceTraversal(resources, depth, IResource.NONE)
+ };
+ }
+ };
+ }
+
+ private void assertUpdate(ResourceMapping mapper, final SyncInfoTree set) throws Exception {
+ final Exception[] exception = new Exception[] { null };
+ visit(mapper, new SyncInfoSetTraveralContext(set), new IResourceVisitor() {
+ public boolean visit(IResource resource) throws CoreException {
+ SyncInfo info = set.getSyncInfo(resource);
+ if (info != null) {
+ set.remove(resource);
+ try {
+ // Assert that the local sync info matches the remote info
+ assertEquals(resource.getParent().getFullPath(), getCVSResource(resource), (ICVSResource)info.getRemote(), false, false);
+ } catch (CVSException e) {
+ exception[0] = e;
+ } catch (CoreException e) {
+ exception[0] = e;
+ } catch (IOException e) {
+ exception[0] = e;
+ }
+ }
+ return true;
+ }
+ });
+ if (exception[0] != null) throw exception[0];
+
+ // check the the state of the remaining resources has not changed
+ assertUnchanged(set);
+ }
+
+ private void assertCommit(ResourceMapping mapper, final SyncInfoTree set) throws CoreException {
+ visit(mapper, new SyncInfoSetTraveralContext(set), new IResourceVisitor() {
+ public boolean visit(IResource resource) throws CoreException {
+ SyncInfo info = set.getSyncInfo(resource);
+ if (info != null) {
+ set.remove(resource);
+ assertTrue("Committed resource is not in-sync: " + resource.getFullPath(), getSyncInfo(resource).getKind() == SyncInfo.IN_SYNC);
+ }
+ return true;
+ }
+ });
+ // check the the state of the remaining resources has not changed
+ assertUnchanged(set);
+ }
+
+ /*
+ * Assert that the state of the resources in the set have not changed
+ */
+ private void assertUnchanged(SyncInfoTree set) throws TeamException {
+ //TODO: Need to refresh the subscriber since flush of remote state is deep
+ CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber().refresh(set.getResources(), IResource.DEPTH_ZERO, DEFAULT_MONITOR);
+ SyncInfo[] infos = set.getSyncInfos();
+ for (int i = 0; i < infos.length; i++) {
+ SyncInfo info = infos[i];
+ assertUnchanged(info);
+ }
+ }
+
+ private void assertUnchanged(SyncInfo info) throws TeamException {
+ SyncInfo current = getSyncInfo(info.getLocal());
+ assertEquals("The sync info changed for " + info.getLocal().getFullPath(), info, current);
+ }
+
+ private SyncInfo getSyncInfo(IResource local) throws TeamException {
+ return CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber().getSyncInfo(local);
+ }
+
+ private SyncInfoTree getIncoming(IProject[] projects) throws TeamException {
+ CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber().refresh(projects, IResource.DEPTH_INFINITE, DEFAULT_MONITOR);
+ SyncInfoTree set = getAllOutOfSync(projects);
+ set.removeOutgoingNodes();
+ set.removeConflictingNodes();
+ return set;
+ }
+
+ private SyncInfoTree getOutgoing(IProject[] projects) {
+ SyncInfoTree set = getAllOutOfSync(projects);
+ set.removeIncomingNodes();
+ set.removeConflictingNodes();
+ return set;
+ }
+
+ private SyncInfoTree getUnaddedResource(ResourceMapping mapping) {
+ SyncInfoTree set = getAllOutOfSync(mapping.getProjects());
+ set.selectNodes(new FastSyncInfoFilter() {
+ public boolean select(SyncInfo info) {
+ try {
+ if (info.getLocal().getType() != IResource.PROJECT && info.getRemote() == null && info.getBase() == null) {
+ ICVSResource resource = getCVSResource(info.getLocal());
+ return !resource.isManaged();
+ }
+ } catch (CVSException e) {
+ fail(e.getMessage());
+ }
+ return false;
+ }
+ });
+ return set;
+ }
+
+ private SyncInfoTree getAllOutOfSync(IProject[] projects) {
+ SyncInfoTree set = new SyncInfoTree();
+ CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber().collectOutOfSync(projects, IResource.DEPTH_INFINITE, set, DEFAULT_MONITOR);
+ return set;
+ }
+
+ private void visit(ResourceMapping mapper, ResourceMappingContext context, IResourceVisitor visitor) throws CoreException {
+ ResourceTraversal[] traversals = mapper.getTraversals(context, null);
+ for (int i = 0; i < traversals.length; i++) {
+ ResourceTraversal traversal = traversals[i];
+ visit(traversal, context, visitor);
+ }
+ }
+
+ private void visit(ResourceTraversal traversal, ResourceMappingContext context, IResourceVisitor visitor) throws CoreException {
+ IResource[] resources = traversal.getResources();
+ for (int i = 0; i < resources.length; i++) {
+ IResource resource = resources[i];
+ visit(resource, visitor, context, traversal.getDepth());
+ }
+ }
+
+ private void visit(IResource resource, IResourceVisitor visitor, ResourceMappingContext context, int depth) throws CoreException {
+ if (!visitor.visit(resource) || depth == IResource.DEPTH_ZERO || resource.getType() == IResource.FILE) return;
+ Set members = new HashSet();
+ members.addAll(Arrays.asList(((IContainer)resource).members(false)));
+ if (context instanceof RemoteResourceMappingContext) {
+ RemoteResourceMappingContext remoteContext = (RemoteResourceMappingContext) context;
+ members.addAll(Arrays.asList(remoteContext.fetchMembers((IContainer)resource, DEFAULT_MONITOR)));
+ }
+ for (Iterator iter = members.iterator(); iter.hasNext();) {
+ IResource member = (IResource) iter.next();
+ visit(member, visitor, context, depth == IResource.DEPTH_ONE ? IResource.DEPTH_ZERO : IResource.DEPTH_INFINITE);
+ }
+ }
+
+ public void testUpdate() throws Exception {
+ // Create a test project, import it into cvs and check it out
+ IProject project = createProject("testUpdate", new String[] { "changed.txt", "deleted.txt", "folder1/", "folder1/a.txt", "folder1/b.txt", "folder1/subfolder1/c.txt" });
+
+ // Check the project out under a different name
+ IProject copy = checkoutCopy(project, "-copy");
+
+ // Perform some operations on the copy and commit them all
+ addResources(copy, new String[] { "added.txt", "folder2/", "folder2/added.txt" }, false);
+ setContentsAndEnsureModified(copy.getFile("changed.txt"));
+ deleteResources(new IResource[] {copy.getFile("deleted.txt")});
+ setContentsAndEnsureModified(copy.getFile("folder1/a.txt"));
+ setContentsAndEnsureModified(copy.getFile("folder1/subfolder1/c.txt"));
+ commit(asResourceMapping(new IResource[] { copy }, IResource.DEPTH_INFINITE), "A commit message");
+
+ // Update the project using depth one and ensure we got only what was asked for
+ update(asResourceMapping(new IResource[] { project }, IResource.DEPTH_ONE), null);
+
+ // Update a subfolder using depth one and ensure we got only what was asked for
+ update(asResourceMapping(new IResource[] { project.getFolder("folder1") }, IResource.DEPTH_ONE), null);
+
+ // Update the specific file
+ update(asResourceMapping(new IResource[] { project.getFile("folder1/subfolder1/c.txt") }, IResource.DEPTH_ZERO), null);
+
+ // Update the remaining resources
+ update(asResourceMapping(new IResource[] { project.getFolder("folder2") }, IResource.DEPTH_INFINITE), null);
+ assertEquals(project, copy);
+ }
+
+ public void testReplace() throws Exception {
+ // Create a test project, import it into cvs and check it out
+ IProject project = createProject("testReplace", new String[] { "changed.txt", "deleted.txt", "folder1/", "folder1/a.txt", "folder1/b.txt", "folder1/subfolder1/c.txt" });
+
+ // Check the project out under a different name
+ IProject copy = checkoutCopy(project, "-copy");
+
+ // Perform some operations on the copy and commit them all
+ addResources(copy, new String[] { "added.txt", "folder2/", "folder2/added.txt" }, false);
+ setContentsAndEnsureModified(copy.getFile("changed.txt"));
+ deleteResources(new IResource[] {copy.getFile("deleted.txt")});
+ setContentsAndEnsureModified(copy.getFile("folder1/a.txt"));
+ setContentsAndEnsureModified(copy.getFile("folder1/subfolder1/c.txt"));
+ commit(asResourceMapping(new IResource[] { copy }, IResource.DEPTH_INFINITE), "A commit message");
+
+ // Update the project using depth one and ensure we got only what was asked for
+ replace(asResourceMapping(new IResource[] { project }, IResource.DEPTH_ONE));
+
+ // Update a subfolder using depth one and ensure we got only what was asked for
+ deleteResources(new IResource[] {project.getFile("folder1/b.txt")});
+ replace(asResourceMapping(new IResource[] { project.getFolder("folder1") }, IResource.DEPTH_ONE));
+
+ // Update the specific file
+ replace(asResourceMapping(new IResource[] { project.getFile("folder1/subfolder1/c.txt") }, IResource.DEPTH_ZERO));
+
+ // Update the remaining resources
+ replace(asResourceMapping(new IResource[] { project.getFolder("folder2") }, IResource.DEPTH_INFINITE));
+ assertEquals(project, copy);
+ }
+
+ public void testCommit() throws Exception {
+ // Create a test project, import it into cvs and check it out
+ IProject project = createProject("testCommit", new String[] { "changed.txt", "deleted.txt", "folder1/", "folder1/a.txt", "folder1/b.txt", "folder1/subfolder1/c.txt" });
+
+ // Perform some operations on the copy and commit only the top level
+ addResources(project, new String[] { "added.txt", "folder2/", "folder2/added.txt" }, false);
+ setContentsAndEnsureModified(project.getFile("changed.txt"));
+ deleteResources(new IResource[] {project.getFile("deleted.txt")});
+ setContentsAndEnsureModified(project.getFile("folder1/a.txt"));
+ setContentsAndEnsureModified(project.getFile("folder1/subfolder1/c.txt"));
+
+ // Commit the project shallow
+ commit(asResourceMapping(new IResource[] { project }, IResource.DEPTH_ONE), "A commit message");
+
+ // Commit a subfolder shallow
+ commit(asResourceMapping(new IResource[] { project.getFolder("folder1") }, IResource.DEPTH_ONE), "A commit message");
+
+ // Now commit the file specifically
+ commit(asResourceMapping(new IResource[] { project.getFile("folder1/subfolder1/c.txt") }, IResource.DEPTH_ZERO), "A commit message");
+
+ // Now commit the rest
+ commit(asResourceMapping(new IResource[] { project.getFolder("folder2") }, IResource.DEPTH_INFINITE), "A commit message");
+
+ // Check the project out under a different name
+ IProject copy = checkoutCopy(project, "-copy");
+ assertEquals(project, copy);
+ }
+
+ public void testTag() throws Exception {
+ // Create a test project, import it into cvs and check it out
+ IProject project = createProject("testTag", new String[] { "changed.txt", "deleted.txt", "folder1/", "folder1/a.txt", "folder1/b.txt", "folder1/subfolder1/c.txt" });
+
+ tag(asResourceMapping(new IResource[] { project }, IResource.DEPTH_ONE), new CVSTag("v1", CVSTag.VERSION));
+ tag(asResourceMapping(new IResource[] { project.getFolder("folder1") }, IResource.DEPTH_ONE), new CVSTag("v2", CVSTag.VERSION));
+ tag(asResourceMapping(new IResource[] { project.getFile("folder1/subfolder1/c.txt") }, IResource.DEPTH_ZERO), new CVSTag("v3", CVSTag.VERSION));
+ tag(asResourceMapping(new IResource[] { project}, IResource.DEPTH_INFINITE), new CVSTag("v4", CVSTag.VERSION));
+ }
+
+ public void testBranch() throws Exception {
+ // Create a test project, import it into cvs and check it out
+ IProject project = createProject("testBranch", new String[] { "changed.txt", "deleted.txt", "folder1/", "folder1/a.txt", "folder1/b.txt", "folder1/subfolder1/c.txt" });
+
+ branch(asResourceMapping(new IResource[] { project }, IResource.DEPTH_ONE), new CVSTag("b1", CVSTag.BRANCH));
+ branch(asResourceMapping(new IResource[] { project.getFolder("folder1") }, IResource.DEPTH_ONE), new CVSTag("b2", CVSTag.BRANCH));
+ branch(asResourceMapping(new IResource[] { project.getFile("folder1/subfolder1/c.txt") }, IResource.DEPTH_ZERO), new CVSTag("b3", CVSTag.BRANCH));
+ branch(asResourceMapping(new IResource[] { project }, IResource.DEPTH_INFINITE), new CVSTag("b4", CVSTag.BRANCH));
+ }
+
+ public void testAdd() throws TeamException, CoreException {
+ // Create an empty project
+ IProject project = createProject("testAdd", new String[] { });
+ // add some resources
+ buildResources(project, new String[] { "changed.txt", "deleted.txt", "folder1/", "folder1/a.txt", "folder1/b.txt", "folder1/subfolder1/c.txt" }, false);
+ // add them to CVS
+ add(asResourceMapping(new IResource[] { project }, IResource.DEPTH_ONE));
+ add(asResourceMapping(new IResource[] { project.getFolder("folder1") }, IResource.DEPTH_ONE));
+ add(asResourceMapping(new IResource[] { project.getFile("folder1/subfolder1/c.txt") }, IResource.DEPTH_ZERO));
+ add(asResourceMapping(new IResource[] { project }, IResource.DEPTH_INFINITE));
+ }
+
+}
diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/mappings/SyncInfoSetTraveralContext.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/mappings/SyncInfoSetTraveralContext.java
new file mode 100644
index 000000000..ad14b21ed
--- /dev/null
+++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/mappings/SyncInfoSetTraveralContext.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.team.tests.ccvs.core.mappings;
+
+import java.util.*;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.resources.mapping.RemoteResourceMappingContext;
+import org.eclipse.core.resources.mapping.ResourceTraversal;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.team.core.synchronize.*;
+import org.eclipse.team.core.variants.IResourceVariant;
+
+/**
+ * A traversal context that traverses the local workspace but also
+ * adds resources that exist in the given sync info set but do not exist
+ * locally.
+ */
+public class SyncInfoSetTraveralContext extends RemoteResourceMappingContext {
+
+ SyncInfoTree set;
+
+ public SyncInfoSetTraveralContext(SyncInfoSet set) {
+ this.set = new SyncInfoTree();
+ this.set.addAll(set);
+ }
+
+ protected SyncInfo getSyncInfo(IFile file) {
+ return set.getSyncInfo(file);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.resources.mapping.ITraversalContext#contentDiffers(org.eclipse.core.resources.IFile, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ public boolean contentDiffers(IFile file, IProgressMonitor monitor) throws CoreException {
+ return getSyncInfo(file) != null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.resources.mapping.ITraversalContext#fetchContents(org.eclipse.core.resources.IFile, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ public IStorage fetchContents(IFile file, IProgressMonitor monitor) throws CoreException {
+ SyncInfo info = getSyncInfo(file);
+ //TODO: Speced to throw an exception when remote doesn't exist
+ if (info == null)
+ return file;
+ IResourceVariant remote = info.getRemote();
+ if (remote == null)
+ return null;
+ return remote.getStorage(monitor);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.resources.mapping.ITraversalContext#fetchMembers(org.eclipse.core.resources.IContainer, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ public IResource[] fetchMembers(IContainer container, IProgressMonitor monitor) throws CoreException {
+ Set members = new HashSet();
+ members.addAll(Arrays.asList(container.members(false)));
+ members.addAll(Arrays.asList(set.members(container)));
+ return (IResource[]) members.toArray(new IResource[members.size()]);
+ }
+
+ public void refresh(ResourceTraversal[] traversals, int flags, IProgressMonitor monitor) throws CoreException {
+ // Do nothing
+ }
+
+}
diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/AllTestsTeamSubscriber.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/AllTestsTeamSubscriber.java
new file mode 100644
index 000000000..ef7d17311
--- /dev/null
+++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/AllTestsTeamSubscriber.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 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.team.tests.ccvs.core.subscriber;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.team.tests.ccvs.core.CVSTestSetup;
+import org.eclipse.team.tests.ccvs.core.EclipseTest;
+import org.eclipse.team.tests.ccvs.ui.SynchronizeViewTestAdapter;
+
+public class AllTestsTeamSubscriber extends EclipseTest {
+
+ public AllTestsTeamSubscriber() {
+ super();
+ }
+
+ public AllTestsTeamSubscriber(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(CVSMergeSubscriberTest.suite());
+ suite.addTest(CVSWorkspaceSubscriberTest.suite());
+ suite.addTest(CVSCompareSubscriberTest.suite());
+ suite.addTest(SyncSetTests.suite());
+ //suite.addTest(CVSChangeSetTests.suite());
+ CVSSyncSubscriberTest.setSyncSource(new SynchronizeViewTestAdapter());
+ return new CVSTestSetup(suite);
+ }
+}

Back to the top