blob: 4e2dd9681323ba6f2103ba924283fee9a5a4d1cb [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 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
******************************************************************************/
package org.eclipse.core.tests.resources.regression;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.tests.harness.CoreTest;
/**
* Tests an error that occurs when a thread tries to read the workspace
* during snapshot. Since snapshot collapses unused trees, it is a destructive
* operation on the tree's parent chain. Any reader traversing the tree parent
* chain during that destructive operation risks encountering the tree in a
* malformed state. The fix was to synchronize the routine that collapses
* unused trees in ElementTree.
*/
public class Bug_134364 extends CoreTest {
public static Test suite() {
return new TestSuite(Bug_134364.class);
}
public Bug_134364() {
super("");
}
public Bug_134364(String name) {
super(name);
}
/**
* Creates a project with a builder attached
*/
private IProject createOtherProject() throws CoreException {
final IWorkspace workspace = ResourcesPlugin.getWorkspace();
IProject other = workspace.getRoot().getProject("Other");
IProjectDescription desc = workspace.newProjectDescription(other.getName());
ICommand command = desc.newCommand();
command.setBuilderName("org.eclipse.core.tests.resources.sortbuilder");
desc.setBuildSpec(new ICommand[] {command});
other.create(desc, null);
other.open(null);
return other;
}
public void test1() throws Exception {
final IProject other = createOtherProject();
final boolean[] done = new boolean[] {false};
final RuntimeException[] failure = new RuntimeException[1];
//create a job that continually tries to read the workspace tree
new Job("Reader-134364") {
@Override
protected IStatus run(IProgressMonitor monitor) {
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
try {
while (!done[0]) {
root.getProjects();
try {
other.members();
} catch (CoreException e) {
//ignore
}
}
return Status.OK_STATUS;
} catch (RuntimeException e) {
failure[0] = e;
throw e;
}
}
}.schedule();
//create a job that continually creates projects, thus causing snapshots to occur
Job writer = new Job("Writer-134364") {
@Override
public IStatus run(IProgressMonitor monitor) {
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject("TestBug134364");
for (int i = 0; i < 100; i++) {
if (failure[0] != null) {
System.out.println("Failure: " + i);
break;
}
try {
//create a few extra tree layers
project.create(null);
project.open(null);
project.touch(null);
project.delete(IResource.NONE, null);
} catch (CoreException e) {
//just bail out
e.printStackTrace();
return Status.OK_STATUS;
}
}
return Status.OK_STATUS;
}
};
writer.schedule();
writer.join();
done[0] = true;
if (failure[0] != null) {
fail("1.0", failure[0]);
}
}
}