blob: c5733c652910ee25e0971e53aa71793ceddfec38 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 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 - Initial API and implementation
*******************************************************************************/
package org.eclipse.core.tests.resources.refresh;
import java.util.HashMap;
import java.util.Map;
import junit.framework.AssertionFailedError;
import junit.framework.TestSuite;
import org.eclipse.core.internal.resources.Workspace;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.tests.resources.ResourceTest;
import org.eclipse.core.tests.resources.TestUtil;
/**
* Tests the IRefreshMonitor interface
*/
public class RefreshProviderTest extends ResourceTest {
public static TestSuite suite() {
return new TestSuite(RefreshProviderTest.class);
}
public RefreshProviderTest() {
super();
}
public RefreshProviderTest(String name) {
super(name);
}
/*(non-javadoc)
* Method declared on TestCase.
*/
@Override
protected void setUp() throws Exception {
super.setUp();
TestRefreshProvider.reset();
//turn on autorefresh
Preferences preferences = ResourcesPlugin.getPlugin().getPluginPreferences();
preferences.setValue(ResourcesPlugin.PREF_AUTO_REFRESH, true);
}
/*(non-javadoc)
* Method declared on TestCase.
*/
@Override
protected void tearDown() throws Exception {
super.tearDown();
//turn off autorefresh
TestRefreshProvider.reset();
Preferences preferences = ResourcesPlugin.getPlugin().getPluginPreferences();
preferences.setValue(ResourcesPlugin.PREF_AUTO_REFRESH, false);
}
/**
* Test to ensure that a refresh provider is given the correct events when a linked
* file is created and deleted.
*/
public void testLinkedFile() throws Exception {
IPath location = getRandomLocation();
String name = "testUnmonitorLinkedResource";
try {
IProject project = getWorkspace().getRoot().getProject(name);
ensureExistsInWorkspace(project, true);
joinAutoRefreshJobs();
IFile link = project.getFile("Link");
//ensure we currently have just the project being monitored
TestRefreshProvider provider = TestRefreshProvider.getInstance();
assertEquals("1.0", 1, provider.getMonitoredResources().length);
link.createLink(location, IResource.ALLOW_MISSING_LOCAL, getMonitor());
joinAutoRefreshJobs();
assertEquals("1.1", 2, provider.getMonitoredResources().length);
link.delete(IResource.FORCE, getMonitor());
joinAutoRefreshJobs();
assertEquals("1.2", 1, provider.getMonitoredResources().length);
ensureDoesNotExistInWorkspace(project);
joinAutoRefreshJobs();
assertEquals("1.3", 0, provider.getMonitoredResources().length);
//check provider for other errors
AssertionFailedError[] failures = provider.getFailures();
if (failures.length > 0) {
fail("" + failures.length + " failures", failures[0]);
}
} catch (CoreException e) {
fail("1.99", e);
} finally {
//cleanup
Workspace.clear(location.toFile());
deleteProject(name);
}
}
/**
* Test to ensure that a refresh provider is given the correct events when a project
* is closed or opened.
*/
public void testProjectCloseOpen() throws Exception {
String name = "testProjectCloseOpen";
IProject project = getWorkspace().getRoot().getProject(name);
try {
ensureExistsInWorkspace(project, true);
joinAutoRefreshJobs();
//ensure we currently have just the project being monitored
TestRefreshProvider provider = TestRefreshProvider.getInstance();
assertEquals("1.0", 1, provider.getMonitoredResources().length);
project.close(getMonitor());
joinAutoRefreshJobs();
assertEquals("1.1", 0, provider.getMonitoredResources().length);
project.open(getMonitor());
joinAutoRefreshJobs();
assertEquals("1.2", 1, provider.getMonitoredResources().length);
ensureDoesNotExistInWorkspace(project);
joinAutoRefreshJobs();
assertEquals("1.3", 0, provider.getMonitoredResources().length);
//check provider for other errors
AssertionFailedError[] failures = provider.getFailures();
if (failures.length > 0) {
fail("" + failures.length + " failures", failures[0]);
}
} catch (CoreException e) {
fail("1.99", e);
} finally {
deleteProject(name);
}
}
/**
* Test to ensure that a refresh provider is given the correct events when a project
* is closed or opened.
*/
public void testProjectCreateDelete() throws Exception {
String name = "testProjectCreateDelete";
final int maxRuns = 1000;
int i = 0;
Map<Integer, Throwable> fails = new HashMap<>();
try {
for (; i < maxRuns; i++) {
if (i % 50 == 0) {
TestUtil.waitForJobs(getName(), 5, 100);
}
try {
assertTrue(createProject(name).isAccessible());
assertFalse(deleteProject(name).exists());
} catch (CoreException e) {
fails.put(i, e);
}
}
} finally {
deleteProject(name);
}
if (!fails.isEmpty()) {
fail("Failed " + fails.size() + " times out of " + i, fails.values().iterator().next());
}
}
private IProject createProject(String name) throws Exception {
IProject pro = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
if (pro.exists()) {
pro.delete(true, true, null);
}
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IProject project = root.getProject(name);
if (!project.exists()) {
project.create(null);
} else {
project.refreshLocal(IResource.DEPTH_INFINITE, null);
}
if (!project.isOpen()) {
project.open(null);
}
return project;
}
private static IProject deleteProject(String name) throws Exception {
IProject pro = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
if (pro.exists()) {
pro.delete(true, true, null);
}
return pro;
}
private void joinAutoRefreshJobs() throws InterruptedException {
// We must join on the auto-refresh family because the workspace changes done in the
// tests above may be batched and broadcasted by the RefreshJob, not the main thread.
// There is then a race condition between the main thread, the refresh job and the job
// scheduled by MonitorManager.monitorAsync. Thus, we must join on both the RefreshJob
// and the job scheduled by MonitorManager.monitorAsync. For simplicity, the job
// scheduled by MonitorManager.monitorAsync has been set to belong to the same family
// as the RefreshJob.
Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_REFRESH, null);
}
}