Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse Platform » Testing an IResourceChangeListener?
Testing an IResourceChangeListener? [message #333039] Fri, 21 November 2008 10:56 Go to next message
Eclipse UserFriend
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 #333040 is a reply to message #333039] Fri, 21 November 2008 11:48 Go to previous messageGo to next message
Szymon Brandys is currently offline Szymon BrandysFriend
Messages: 11
Registered: July 2009
Junior Member
> 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.

> 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?

No. The platform decides when to send events.
Re: Testing an IResourceChangeListener? [message #333041 is a reply to message #333040] Fri, 21 November 2008 11:56 Go to previous messageGo to next message
Eclipse UserFriend
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 #333042 is a reply to message #333041] Fri, 21 November 2008 12:01 Go to previous messageGo to next message
Szymon Brandys is currently offline Szymon BrandysFriend
Messages: 11
Registered: July 2009
Junior Member
> 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 #333119 is a reply to message #333042] Wed, 26 November 2008 09:06 Go to previous messageGo to next message
Eclipse UserFriend
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
Eclipse UserFriend
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--
Previous Topic:CompareUI return code
Next Topic:preference extension point logic
Goto Forum:
  


Current Time: Thu Apr 25 01:51:50 GMT 2024

Powered by FUDForum. Page generated in 0.03341 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top