Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Valenta2005-05-04 16:14:15 -0400
committerMichael Valenta2005-05-04 16:14:15 -0400
commit6a84e65eb7b6036ee3a7b0bc6932464a34dbef6f (patch)
treed2589cb7ffcaa2ec63f9a48ddcd83076bbdeb867
parent12e0072f1bb42c19508a2a404a214743112a5d23 (diff)
downloadeclipse.platform.team-branch_20050504_CVSTestLocking.tar.gz
eclipse.platform.team-branch_20050504_CVSTestLocking.tar.xz
eclipse.platform.team-branch_20050504_CVSTestLocking.zip
-rw-r--r--tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/EclipseTest.java166
1 files changed, 162 insertions, 4 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
index 5b505b402..33a56e8c8 100644
--- 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
@@ -15,8 +15,8 @@ import java.util.*;
import junit.framework.*;
+import org.eclipse.core.internal.resources.mapping.ResourceMapping;
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;
@@ -38,9 +38,15 @@ import org.eclipse.ui.internal.decorators.DecoratorManager;
public class EclipseTest extends ResourceTest {
- protected static IProgressMonitor DEFAULT_MONITOR = new NullProgressMonitor();
+ 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");
@@ -918,10 +924,17 @@ public class EclipseTest extends ResourceTest {
throw new OperationCanceledException();
}
}
- /* (non-Javadoc)
+
+ 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 {
@@ -936,8 +949,153 @@ public class EclipseTest extends ResourceTest {
}
}
}
+
+ 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
+ updateResources(new IResource[] { lockFile }, true);
+ } catch (CVSException 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) {
+ protected void write(IStatus status, int indent) {
PrintStream output = System.out;
indent(output, indent);
output.println("Severity: " + status.getSeverity());

Back to the top