Bug 219086 - RSEInternalFrameworkTestCase.testWaitAndDispatch() fails on my machine
Summary: RSEInternalFrameworkTestCase.testWaitAndDispatch() fails on my machine
Status: RESOLVED FIXED
Alias: None
Product: Target Management
Classification: Tools
Component: RSE (show other bugs)
Version: 3.0   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.0 M5   Edit
Assignee: Martin Oberhuber CLA
QA Contact: Martin Oberhuber CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 219101 219069 219111
  Show dependency tree
 
Reported: 2008-02-15 08:06 EST by Martin Oberhuber CLA
Modified: 2008-02-15 11:16 EST (History)
1 user (show)

See Also:


Attachments
Patch fixing the problem (6.24 KB, patch)
2008-02-15 10:46 EST, Martin Oberhuber CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Oberhuber CLA 2008-02-15 08:06:47 EST
RSEInternalFrameworkTestCase.testWaitAndDispatch() fails on my machine when running RSECombinedTestSuite.

* Using a Workspace on RSE HEAD.
* Using the "RSECombinedTestSuite" checked-in teamConfig Launch for 
JUnit Plug-in test in Run mode
* Using Sun 1.4.2_13 JRE
* Problem happens only when running RSECombinedTestSuite.
   - Does not happen when running testWaitAndDispatch alone
   - Does not happen when running RSEInternalFrameworkTestSuite

* The test runs "With all Workspace and enabled target platform 
plugins". For me, these are:
   - Target Platform: Eclipse 3.4M5, CDT 5.0M5, EMF 2.4M5
      + PHPEclipse 1.2.0-Nightly (From their update site)
      + Subversive from Ganymede M4 with SVNKit connector
      + DSDP-DD from Europa
      + WindRiver Retriever
      + ECF from Ganymede M4
      + SWT MemMonitor
      + RSE M5 Candidate Build
      + J9Launching Plugin
   - Workspace:
      + RSE, Terminal, Discovery, RemoteCDT
      + TCF from WR SVN Repository
      + RXTX latest
      + org.eclipsecon.tmtutorial EclipseCon 07 RSE Examples plugin 
(adapted to Latest RSE, from SVN)
         - This contributes an RSE Event Logging View

Attached are the traceback and the console log.
 
I tried a clean build but the failure remains reproducable.
I switched to an 1.6.0_02 JRE but the problem remained.
I ran the plug-in test in the debugger with an exception breakpoint on 
java.lang.NullPointerException,
and it produced traceback2.txt (attached), this might be the source of 
the problem.

I ran a modified Launch where I disabled RXTX, TCF, DSF, PHPEclipse, CDT,
RSE-Examples, EclipseCon-Examples, but the problem remained.
Then also disabled ECF, Subversive, MemMonitor but the problem remained.

-----------Enter bugs above this line-----------
TM 3.0M5
installation : eclipse-SDK-3.4M5 (I20080207-1530), cdt-4.0.0M5, emf-2.4.0M5
     DSF-N20071113, ECF-2.0m4, PHPEclipse-1.2.0-Nightly, Releng.Tools-3.4M5,
     Subversive-0.7.0m4, SWT-MemMonitor, WR-Retriever-3.0.v20070604
RSE install  : RSE-SDK-I20080212-2045, TM-terminal, TM-discovery
java.runtime : Sun 1.6.0_02-b06 -Xmx512m -XX:MaxPermSize=128m
os.name:     : Windows XP 5.1, Service Pack 2
------------------------------------------------
systemtype   : Windows-local, Dstore-win, Dstore-linux
targetos     : Red Hat Enterprise Linux WS release 4 (Nahant Update 3)
targetuname  : Linux parser 2.6.9-34.EL #1 i686 athlon i386 GNU/Linux
targetvm     : Sun Java HotSpot(TM) Client VM (build 1.4.2_12-b03, mixed mode)
------------------------------------------------
Comment 1 Martin Oberhuber CLA 2008-02-15 08:09:58 EST
It turns out the problem is, that SystemView.moveTreeItems() is passed "null" items in the following traceback. 

The question is, why the SystemView$ResourceChangedJob only runs from inside the RSEWaitAndDispatchUtil.waitAndDispatch(). It looks like this ResourceChangedJob really belongs to a different test, and that test is not fully finished / cleaned up before the event loop test is done.

Anyways, such a situation can occur in an RSE application as well. Something happens to RSE, and the ResourceChangedJob is allowed only to run a lot later (after the resources in question have gone already). Need to investigate how such access to deleted resources can be avoided.

Thread [main] (Suspended (breakpoint at line 1505 in SystemView))	
	SystemView.moveTreeItem(Widget, Item, Object, int) line: 1505	
	SystemView.moveTreeItems(Widget, Object[], int) line: 1554	
	SystemView$ResourceChangedJob.runInUIThread(IProgressMonitor) line: 2292	
	UIJob$1.run() line: 94	
	RunnableLock.run() line: 35	
	UISynchronizer(Synchronizer).runAsyncMessages(boolean) line: 130	
	Display.runAsyncMessages(boolean) line: 3737	
	Display.readAndDispatch() line: 3374	
	RSEWaitAndDispatchUtil.waitAndDispatch(long) line: 62	
	RSEInternalFrameworkTestCase.testWaitAndDispatch() line: 110	
	NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
	NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39	
	DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25	
	Method.invoke(Object, Object[]) line: 324	
	RSEInternalFrameworkTestCase(TestCase).runTest() line: 164	
	RSEInternalFrameworkTestCase(RSECoreTestCase).runTest() line: 308	
	RSEInternalFrameworkTestCase(TestCase).runBare() line: 130	
	RSEInternalFrameworkTestCase(RSECoreTestCase).runBare() line: 294	
	TestResult$1.protect() line: 106	
	TestResult.runProtected(Test, Protectable) line: 124	
	TestResult.run(TestCase) line: 109	
	RSEInternalFrameworkTestCase(TestCase).run(TestResult) line: 120	
	RSEInternalFrameworkTestCase(RSECoreTestCase).run(TestResult) line: 263	
	TestSuite.runTest(Test, TestResult) line: 230	
        [...]
Comment 2 Martin Oberhuber CLA 2008-02-15 08:35:25 EST
The "old" ResourceChangedJob comes from FireNewHostEvents... and these, in turn, come from the 
 (1) InitRSEJob,
 (2) HostMoveTest.
 (3) RSEConnectionTestCase.testConnectionCreation()
The point is that in case of (2) and (3), these test cases run on the main thread, but events are ALWAYS fired with Display.getDefault().asyncExec() in the SystemRegistry.
Since the tests are on the main thread, the event loop is never emptied and RSE has no chance handling all these events... they fill up the event queue but the events don't get executed.
So when HostMoveTest#tearDown() is executed, the events are still in the event queue. Now, hosts are deleted. When the eventQueue finally gets a chance to be emptied (through our testWaitAndDispatch() test, the events are finally run - but the corresponding hosts do not exist any more in the SystemRegistry.

It looks like what we need to do is
(a) In FireNewHostEvents, ensure that the corresponding host still exists
    when the event(s) are fired. There is no use in notifying about a new
    host when the host has been deleted again in the meantime.
    The impact of the change can only be for programs that add and remove
    hosts very quickly on the dispatch thread. Because an interactive user
    would need to work on the dispatch thread, so events would get a chance
    to get executed.
(b) Investigate whether we should really do Display.asyncExec() in the
    SystemRegistry.createHost() in the case where we are already on the
    display thread. Perhaps it's wiser to fire the event right away.
    Though the risk with this is, that event listeners destabilize the
    system... we've seen this in the past.
(c) In the test case, since we're running on the main thread, we'll need
    to wait until the system has stabilized before stepping on to the 
    next test. This is necessary because unit tests should always be 
    isolated from each other.

SystemRegistry.createHost(String, IRSESystemType, String, String, String, String, int, boolean, ISystemNewConnectionWizardPage[]) line: 1654	
SystemRegistry.createHost(String, IRSESystemType, String, String, String, String, int, ISystemNewConnectionWizardPage[]) line: 1543	
RSEConnectionManager.findOrCreateConnection(IRSEConnectionProperties) line: 234	
HostMoveTest.createHosts() line: 151	
HostMoveTest.setUp() line: 42	
HostMoveTest(TestCase).runBare() line: 128	
HostMoveTest(RSECoreTestCase).runBare() line: 294	
TestResult$1.protect() line: 106	
TestResult.runProtected(Test, Protectable) line: 124	
TestResult.run(TestCase) line: 109	
HostMoveTest(TestCase).run(TestResult) line: 120	
HostMoveTest(RSECoreTestCase).run(TestResult) line: 263	
TestSuite.runTest(Test, TestResult) line: 230	
TestSuite.run(TestResult) line: 225	
Comment 3 Martin Oberhuber CLA 2008-02-15 10:46:05 EST
Created attachment 89848 [details]
Patch fixing the problem

Attached patch fixes the concrete problem with testWaitAndDispatch(), by shielding tests from each other. This is done by adding a
   flushEventQueue();
method in the RSEBaseTestCase, and calling it from the tearDown() method.
Comment 4 Martin Oberhuber CLA 2008-02-15 11:07:02 EST
Patch committed:
[219086] flush event queue to shield tests from each other

Fixing the immediate issue surfaced problems in other areas of RSE. These are tracked separately by bug 219101, bug 219069 and bug 219111.