Community
Participate
Working Groups
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) ------------------------------------------------
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 [...]
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
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.
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.