Testing an IResourceChangeListener? [message #333039] |
Fri, 21 November 2008 10:56 ![Go to next message Go to next message](theme/Solstice/images/down.png) |
Eclipse User![Friend of Eclipse Friend](/donate/web-api/friends_decorator.php?email=) |
|
|
|
Originally posted by: nomail.nomail.com
Hi all!
Some of my logic is done in an IResourceChangeListener, automatically
when something in the Workspace changes. I want to write tests that do
modify the Workspace and afterwards check that the
IResourceChangeListener did what it is supposed to do. The modifications
are done in IWorkspaceRunnables that are executed via Workspace.run(...).
But (only) sometimes the IResourceChangeListener gets invoked too late
(i.e. when another test method is running), so the tests fail.
Is it possible to "flush" the queue of IResouceChangeEvents so that I
can be sure, that all events got dispatched when my test method returns?
-ftl
|
|
|
|
Re: Testing an IResourceChangeListener? [message #333041 is a reply to message #333040] |
Fri, 21 November 2008 11:56 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) ![Go to next message Go to next message](theme/Solstice/images/down.png) |
Eclipse User![Friend of Eclipse Friend](/donate/web-api/friends_decorator.php?email=) |
|
|
|
Originally posted by: nomail.nomail.com
>> But (only) sometimes the IResourceChangeListener gets invoked too late
>> (i.e. when another test method is running), so the tests fail.
>
> If you use IWorkspaceRunnable, all events should be sent and all
> listeners should be called by the end of IWorkspace#run. So after #run
> you should have your listener invoked.
> If you run multiple threads in the test, you should register an extra
> listener in your test and check if it was invoked before you proceed.
I found that sometimes the events are dispatched by another thread,
although I don't use multi threading in my tests. At least not explicitly.
The dispatching is done e.g. by NotificationManager$NotifyJob or
InternalWorkspaceJob.
|
|
|
|
Re: Testing an IResourceChangeListener? [message #333119 is a reply to message #333042] |
Wed, 26 November 2008 09:06 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) ![Go to next message Go to next message](theme/Solstice/images/down.png) |
Eclipse User![Friend of Eclipse Friend](/donate/web-api/friends_decorator.php?email=) |
|
|
|
Originally posted by: nomail.nomail.com
The mysterious events are dispatched by the RefreshJob which is
triggered e.g. when project.open(IProject.BACKGROUND_REFRESH,...) is
used to open a project.
As a workaround, a use project.open(IResource.NONE,...) now. I'll write
a test case which demonstrates my problem. But first I have to get a
release out of the door on monday ;-).
Thank you Szymon for your time!
-ftl
Szymon Brandys schrieb:
>> I found that sometimes the events are dispatched by another thread,
>> although I don't use multi threading in my tests. At least not
>> explicitly.
>
> Right.
>
>> The dispatching is done e.g. by NotificationManager$NotifyJob or
>> InternalWorkspaceJob.
>
> So I would suggest to register an extra listener, check if it was
> invoked and if so, continue the test.
>
>
|
|
|
Re: Testing an IResourceChangeListener? [message #333222 is a reply to message #333042] |
Mon, 01 December 2008 14:03 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) |
Eclipse User![Friend of Eclipse Friend](/donate/web-api/friends_decorator.php?email=) |
|
|
|
Originally posted by: nomail.nomail.com
This is a multi-part message in MIME format.
--------------000004090804090400080809
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
Here comes the promised test. What I don't understand is, why the
RefreshJob dispatches the ResourceChangeEvents, although the
IWorkspaceRunnable is finished before the RefreshJob and the changes do
come from the IWorkspaceRunnable.
-ftl
--------------000004090804090400080809
Content-Type: text/java;
name="RefreshJobTest.java"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="RefreshJobTest.java"
import java.io.ByteArrayInputStream;
import junit.framework.TestCase;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
public class RefreshJobTest extends TestCase {
private static class CountingResourceChangeListener implements
IResourceChangeListener {
public int eventCount = 0;
@Override
public void resourceChanged(IResourceChangeEvent event) {
eventCount++;
System.out.println(Thread.currentThread().getName());
new Exception().printStackTrace(System.out);
}
}
private static class TestJobChangeListener extends JobChangeAdapter {
private final String jobName;
public boolean done = false;
public TestJobChangeListener(String jobName) {
this.jobName = jobName;
}
@Override
public void done(IJobChangeEvent event) {
if (event.getJob().getName().equals(jobName))
done = true;
}
}
public void testRefreshJob() throws Exception {
Job.getJobManager().addJobChangeListener(new JobChangeAdapter() {
@Override
public void scheduled(IJobChangeEvent event) {
System.out.println("Scheduled: " + event.getJob().getName());
}
@Override
public void running(IJobChangeEvent event) {
System.out.println("Running: " + event.getJob().getName());
}
@Override
public void done(IJobChangeEvent event) {
System.out.println("Done: " + event.getJob().getName());
}
@Override
public void aboutToRun(IJobChangeEvent event) {
System.out.println("About to run: " + event.getJob().getName());
}
});
TestJobChangeListener jobChangeListener = new TestJobChangeListener(
"Refreshing workspace");
Job.getJobManager().addJobChangeListener(jobChangeListener);
final IWorkspace workspace = ResourcesPlugin.getWorkspace();
CountingResourceChangeListener countingListener = new CountingResourceChangeListener();
workspace.addResourceChangeListener(countingListener);
IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
@Override
public void run(IProgressMonitor monitor) throws CoreException {
System.out.println("Runnable.run started");
IProject project = workspace.getRoot().getProject("test");
project.create(null);
project.open(IProject.BACKGROUND_REFRESH, null);
System.out.println("Project opened");
for (int i = 0; i < 200; i++) {
IFile file = project.getFile("Testfile" + i);
file.create(new ByteArrayInputStream("Test".getBytes()),
true, null);
}
System.out.println("Files created");
sleep(20000); // let the refresh job start
System.out.println("Runnable.run finished");
}
};
System.out.println("Runnable started");
workspace.run(runnable, null);
System.out.println("Runnable finished");
/*
* The runnable is finished before the RefreshJob finishes. Why are
* there not at least notifications about the created files?
*/
assertEquals(0, countingListener.eventCount);
while (!jobChangeListener.done)
sleep(10);
assertEquals(1, countingListener.eventCount);
}
private static void sleep(final int duration) {
try {
Thread.sleep(duration);
} catch (InterruptedException e) {
fail(e.getMessage());
}
}
}
--------------000004090804090400080809--
|
|
|
Powered by
FUDForum. Page generated in 0.03002 seconds