New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Empty component hierarchy sometimes #157

Open
bigianb opened this Issue Jun 4, 2015 · 4 comments

Comments

Projects
None yet
2 participants
@bigianb

bigianb commented Jun 4, 2015

This is probably more suited to a mailing list / forum, but the mail list comment appeared to point me here.
I have a unit test which tests a dialog. I am using cacio-tta to enable it to run headless. This seems to run reliably in Windows and much of the time in Linux ... but maybe half of the time in linux the component lookup fails. When it fails, the component hierarchy is empty.

The failure looks as follows (I am running under junit4 with the CacioTestRunner)

org.assertj.swing.exception.ComponentLookupException: Unable to find component using matcher org.assertj.swing.core.NameMatcher[name='amendmentReasonLabel', type=javax.swing.JLabel, requireShowing=true].

Component hierarchy:
com.ccm.backtest.fund.AdhocTradeEntryDlg[name='dialog1', title='Amend Trade', enabled=true, modal=true, visible=true, showing=true]

    at org.assertj.swing.core.BasicComponentFinder.componentNotFound(BasicComponentFinder.java:290)
    at org.assertj.swing.core.BasicComponentFinder.find(BasicComponentFinder.java:275)
    at org.assertj.swing.core.BasicComponentFinder.find(BasicComponentFinder.java:268)
    at org.assertj.swing.core.BasicComponentFinder.findByName(BasicComponentFinder.java:203)
    at org.assertj.swing.fixture.AbstractContainerFixture.findByName(AbstractContainerFixture.java:622)
    at org.assertj.swing.fixture.AbstractContainerFixture.label(AbstractContainerFixture.java:291)
    at com.ccm.backtest.fund.AdhocTradeEntryDlgTest.testAmendETFuture(AdhocTradeEntryDlgTest.java:103)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)

The relevant test code that is failing is...

    @Test
    public void testAmendETFuture()
    {
        MockAssetFactory assetFactory = new MockAssetFactory();
        Date today = java.sql.Date.valueOf("2015-01-02");
        ETFuture future = new ETFuture(today, assetFactory.get("FTH16"), 2, Side.SELL, 1.234, today);
        future.setBrokerageFee(2.34, assetFactory.get("CAD"));
        future.setClearingFee(5.67, assetFactory.get("EUR"));
        setupDialog("book", future, assetFactory, AdhocTradeEntryDlg.Operation.AMEND);

        dialogFixture.label("amendmentReasonLabel").requireVisible();

where the setupDialog() code looks like:

    private void setupDialog(String book, Transaction trade, IAssetFactory assetFactory, AdhocTradeEntryDlg.Operation operation)
    {
        dialog = GuiActionRunner.execute(new GuiQuery<AdhocTradeEntryDlg>()
        {
            protected AdhocTradeEntryDlg executeInEDT()
            {
                AdhocTradeEntryDlg dlg = new AdhocTradeEntryDlg(book, trade, assetFactory, operation);
                dlg.pack();
                return dlg;
            }
        });

        // IMPORTANT: note the call to 'robot()'
        // we must use the Robot from AssertJSwingJUnitTestCase
        dialogFixture = new DialogFixture(robot(), dialog);
        dialogFixture.show(new Dimension(800, 800));
    }

I added the pack() call which makes the issue appear less often ... and so I am guessing there is a synchronisation issue at play here. The other interesting thing is that there are 4 almost identical tests in this test case - they all call setupDialog (it's not in onSetUp because there is more than one flavor as I require different tests to call different constructors for the object).
What would be a good way to debug this?

Ian

@bigianb

This comment has been minimized.

Show comment
Hide comment
@bigianb

bigianb Jun 4, 2015

Extra Info: It's nothing to do with using cacio-tta (which is a great solution for headless automation)... if I don't use that test runner so that I see the dialogs pop up on screen then I get the same errors.

bigianb commented Jun 4, 2015

Extra Info: It's nothing to do with using cacio-tta (which is a great solution for headless automation)... if I don't use that test runner so that I see the dialogs pop up on screen then I get the same errors.

@bigianb

This comment has been minimized.

Show comment
Hide comment
@bigianb

bigianb Jun 4, 2015

Adding this to the test seems to avoid the issue. Very odd as this just adds code that is already being called.

@Override
    protected void onTearDown()
    {
        // Should not be necessary as base class does it on the robot.
        if (dialogFixture != null){
            dialogFixture.cleanUp();
        }
    }

bigianb commented Jun 4, 2015

Adding this to the test seems to avoid the issue. Very odd as this just adds code that is already being called.

@Override
    protected void onTearDown()
    {
        // Should not be necessary as base class does it on the robot.
        if (dialogFixture != null){
            dialogFixture.cleanUp();
        }
    }
@croesch

This comment has been minimized.

Show comment
Hide comment
@croesch

croesch Jul 8, 2015

Collaborator

I would say the only way to debug this is juggling with console-output and breakpoints. I prefer setting a breakpoint at a location where I expect the code to fail.

Did you check org.assertj.swing.core.BasicRobot.disposeWindows(ComponentHierarchy) if your dialog actually appears and is disposed by base test? That would be one of my first choices.

Collaborator

croesch commented Jul 8, 2015

I would say the only way to debug this is juggling with console-output and breakpoints. I prefer setting a breakpoint at a location where I expect the code to fail.

Did you check org.assertj.swing.core.BasicRobot.disposeWindows(ComponentHierarchy) if your dialog actually appears and is disposed by base test? That would be one of my first choices.

@bigianb

This comment has been minimized.

Show comment
Hide comment
@bigianb

bigianb Jul 8, 2015

The dialog does appear and is disposed. The issue occurs on the second or third dialog created by the test class. Add a breakpoint and the issue goes away. Add the code above in onTearDown and it seems to go away too - so it would appear to be a timing issue (I'm guessing something uses a class finaliser in swing - so what we expect to be disposed may not be yet ... maybe adding the second cleanup causes it to be synchronised).
It's very odd and is repeatable on both linux and windows 8.1, so the issue is in the java rather than the native libraries.

bigianb commented Jul 8, 2015

The dialog does appear and is disposed. The issue occurs on the second or third dialog created by the test class. Add a breakpoint and the issue goes away. Add the code above in onTearDown and it seems to go away too - so it would appear to be a timing issue (I'm guessing something uses a class finaliser in swing - so what we expect to be disposed may not be yet ... maybe adding the second cleanup causes it to be synchronised).
It's very odd and is repeatable on both linux and windows 8.1, so the issue is in the java rather than the native libraries.

@croesch croesch added the bug label Feb 15, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment