How to handle unexpected error dialogs in UITests?

Stephan Bergmann sbergman at redhat.com
Thu Mar 26 10:07:51 UTC 2020


With a combination of pre 
<https://gerrit.libreoffice.org/plugins/gitiles/core/+/23245f723fb29262b8543d6447d1b0bb69cb50fb%5E!/> 
"external/nss: Fix rpath for Linux et al" (so that the call to 
NSS_NoDB_Init in comphelper/source/misc/hash.cxx failed) and post 
<https://gerrit.libreoffice.org/plugins/gitiles/core/+/b23b0452dde6608b13d3fcb7feaff92bee019927%5E!/> 
"Check call to NSS_NoDB_Init for success" (so that that failure causes a 
css::uno::RuntimeException), UITest_calc_tests hangs.

The python.bin process is at

> Traceback (most recent call last):
>   File "sc/qa/uitest/calc_tests/tdf120161.py", line 78, in test_tdf120161
>     self.assertFalse(self.verifyExport(xDoc, xContext, "A1:G1", b"DejaVuSans"))
>   File "sc/qa/uitest/calc_tests/tdf120161.py", line 66, in verifyExport
>     return self.verifyExportToFile(xDoc, xContext, xRange, xFontName, xFilename)
>   File "sc/qa/uitest/calc_tests/tdf120161.py", line 53, in verifyExportToFile
>     xDispatcher.executeDispatch(xDocFrame, '.uno:ExportToPDF', '', 0, xParams)

while the soffice.bin process is blocked at

> #0  futex_wait_cancelable (private=0, expected=0, futex_word=0x608000002848) at /usr/src/debug/glibc-2.30-34-g994e529a37/sysdeps/unix/sysv/linux/futex-internal.h:80
> #1  __pthread_cond_wait_common (abstime=0x0, clockid=0, mutex=0x608000002850, cond=0x608000002820) at /usr/src/debug/glibc-2.30-34-g994e529a37/nptl/pthread_cond_wait.c:508
> #2  __pthread_cond_wait (cond=0x608000002820, mutex=0x608000002850) at /usr/src/debug/glibc-2.30-34-g994e529a37/nptl/pthread_cond_wait.c:638
> #3  0x00007f7f98841933 in osl_waitCondition(oslCondition, TimeValue const*) (Condition=0x608000002820, pTimeout=0x0) at sal/osl/unx/conditn.cxx:231
> #4  0x00007f7f654f1a5e in osl::Condition::wait(TimeValue const*) (this=0x60e000024e28, pTimeout=0x0) at include/osl/conditn.hxx:119
> #5  0x00007f7f66484d11 in SvpSalInstance::DoYield(bool, bool) (this=0x611000001d00, bWait=true, bHandleAllCurrentEvents=false) at vcl/headless/svpinst.cxx:521
> #6  0x00007f7f659637a4 in ImplYield(bool, bool) (i_bWait=true, i_bAllEvents=false) at vcl/source/app/svapp.cxx:454
> #7  0x00007f7f65962d28 in Application::Yield() () at vcl/source/app/svapp.cxx:518
> #8  0x00007f7f6249fded in Dialog::Execute() (this=0x619000547480) at vcl/source/window/dialog.cxx:1032
> #9  0x00007f7f655a64e2 in SalInstanceDialog::run() (this=0x6170000fb280) at vcl/source/app/salvtables.cxx:1480
> #10 0x00007f7f71617f31 in aWndFunc(weld::Window*, DialogMask, rtl::OUString const&, rtl::OUString const&) (pWin=0x6160001ece38, nFlags=4353, rErr="General Error.\nGeneral input/output error.", rAction="Error saving the document tdf120161") at svtools/source/misc/ehdl.cxx:118
> #11 0x00007f7f61e838cd in ErrorHandler::HandleError(ErrCode, weld::Window*, DialogMask) (nErrCodeId=..., pParent=0x6160001ece38, nFlags=DialogMask::MAX) at vcl/source/window/errinf.cxx:173
> #12 0x00007f7f88188487 in SfxObjectShell::ExecFile_Impl(SfxRequest&) (this=0x61d0000d2080, rReq=...) at sfx2/source/doc/objserv.cxx:871
> #13 0x00007f7f88178de0 in SfxStubSfxObjectShellExecFile_Impl(SfxShell*, SfxRequest&) (pShell=0x61d0000d2080, rReq=...) at workdir/SdiTarget/sfx2/sdi/sfxslots.hxx:219
> #14 0x00007f7f87047ce6 in SfxShell::CallExec(void (*)(SfxShell*, SfxRequest&), SfxRequest&) (this=0x61d0000d2080, pFunc=0x7f7f88178ca0 <SfxStubSfxObjectShellExecFile_Impl(SfxShell*, SfxRequest&)>, rReq=...) at include/sfx2/shell.hxx:197
> #15 0x00007f7f86fcfdac in SfxDispatcher::Call_Impl(SfxShell&, SfxSlot const&, SfxRequest&, bool) (this=0x60200051fd70, rShell=..., rSlot=..., rReq=..., bRecord=false) at sfx2/source/control/dispatch.cxx:254
> #16 0x00007f7f86fe5120 in SfxDispatcher::Execute_(SfxShell&, SfxSlot const&, SfxRequest&, SfxCallMode) (this=0x60200051fd70, rShell=..., rSlot=..., rReq=..., eCallMode=SfxCallMode::SYNCHRON) at sfx2/source/control/dispatch.cxx:754
> #17 0x00007f7f86fe6067 in SfxDispatcher::Execute(unsigned short, SfxCallMode, SfxItemSet const*, SfxItemSet const*, unsigned short) (this=0x60200051fd70, nSlot=6673, nCall=SfxCallMode::SYNCHRON, pArgs=0x604000a32390, pInternalArgs=0x7f7e95a4e240, nModi=0) at sfx2/source/control/dispatch.cxx:812
> #18 0x00007f7f87461a43 in SfxDispatchController_Impl::dispatch(com::sun::star::util::URL const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&, com::sun::star::uno::Reference<com::sun::star::frame::XDispatchResultListener> const&) (this=0x60f000087b80, aURL=..., aArgs=uno::Sequence of length 4 = {...}, rListener=uno::Reference to (class framework::DispatchHelper *) 0x60c000161ef8) at sfx2/source/control/unoctitm.cxx:735
> #19 0x00007f7f87464cc6 in SfxOfficeDispatch::dispatchWithNotification(com::sun::star::util::URL const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&, com::sun::star::uno::Reference<com::sun::star::frame::XDispatchResultListener> const&) (this=0x6080001c2420, aURL=..., aArgs=uno::Sequence of length 4 = {...}, rListener=uno::Reference to (class framework::DispatchHelper *) 0x60c000161ef8) at sfx2/source/control/unoctitm.cxx:240
> #20 0x00007f7f47561c3b in framework::DispatchHelper::executeDispatch(com::sun::star::uno::Reference<com::sun::star::frame::XDispatch> const&, com::sun::star::util::URL const&, bool, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&) (this=0x60c000161ec0, xDispatch=uno::Reference to (class SfxOfficeDispatch *) 0x6080001c2448, aURL=..., SyncronFlag=true, lArguments=uno::Sequence of length 3 = {...}) at framework/source/services/dispatchhelper.cxx:151
> #21 0x00007f7f47560b92 in framework::DispatchHelper::executeDispatch(com::sun::star::uno::Reference<com::sun::star::frame::XDispatchProvider> const&, rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&) (this=0x60c000161ec0, xDispatchProvider=uno::Reference to (class (anonymous namespace)::XFrameImpl *) 0x6160001926d8, sURL=".uno:ExportToPDF", sTargetFrameName="", nSearchFlags=0, lArguments=uno::Sequence of length 3 = {...}) at framework/source/services/dispatchhelper.cxx:109
> #22 0x00007f7f47562378 in non-virtual thunk to framework::DispatchHelper::executeDispatch(com::sun::star::uno::Reference<com::sun::star::frame::XDispatchProvider> const&, rtl::OUString const&, rtl::OUString const&, int, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&) () at instdir/program/libfwelo.so
> #23 0x00007f7f2c56108c in gcc3::callVirtualMethod(void*, unsigned int, void*, _typelib_TypeDescriptionReference*, bool, unsigned long*, unsigned int, unsigned long*, double*) (pThis=0x7f7ec91a41a0, nVtableIndex=24688, pRegisterReturn=0x60c0000397c8, pReturnTypeRef=0x7f7ec91a4200, bSimpleReturn=false, pStack=0x6080000ab520, nStack=1, pGPR=0x7f7e9594b460, pFPR=0x7f7e9594b4c0) at bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx:77
> #24 0x00007f7f2c55b0c2 in cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy*, bridges::cpp_uno::shared::VtableSlot, _typelib_TypeDescriptionReference*, int, _typelib_MethodParameter*, void*, void**, _uno_Any**) (pThis=0x606000630740, aVtableSlot=..., pReturnTypeRef=0x60700001b300, nParams=5, pParams=0x60c000188800, pUnoReturn=0x603000fb4130, pUnoArgs=0x606000632d80, ppUnoExc=0x7f7e95aa76c0) at bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx:233
> #25 0x00007f7f2c557b4b in bridges::cpp_uno::shared::unoInterfaceProxyDispatch(uno_Interface*, typelib_TypeDescription const*, void*, void**, uno_Any**) (pUnoI=0x606000630740, pMemberDescr=0x60f0000acb10, pReturn=0x603000fb4130, pArgs=0x606000632d80, ppException=0x7f7e95aa76c0) at bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx:413
> #26 0x00007f7f276a8e13 in binaryurp::IncomingRequest::execute_throw(binaryurp::BinaryAny*, std::__debug::vector<binaryurp::BinaryAny, std::allocator<binaryurp::BinaryAny> >*) const (this=0x60d000358710, returnValue=0x7f7e95a49020, outArguments=0x7f7e95a49060) at binaryurp/source/incomingrequest.cxx:235
[...]

showing a VCL error dialog after catching that 
css::uno::RuntimeException in frame 12.

The question is how UITests should avoid such deadlocks.  The behavior 
of ErrorHandler::HandleError (vcl/source/window/errinf.cxx) can be 
modified via ErrorRegistry::RegisterDisplay 
(vcl/source/window/errinf.cxx), to call a user-provided 
BasicDisplayErrorFunc instead of showing a VCL error dialog.  But:

* There appears to be no UNO API to call ErrorRegistry::RegisterDisplay 
remotely from the UITest's Python code.

* There appears to be no way to only temporarily set 
ErrorRegistry::RegisterDisplay and then undo it again.  So it would be 
problematic for a UITest to do some tests (which explicitly want to test 
interaction with a VCL error dialog, say) without a set 
ErrorRegistry::RegisterDisplay, while doing all the its other tests with 
a set ErrorRegistry::RegisterDisplay (so as to avoid deadlocks caused by 
unexpected errors raising unexpected VCL error dialogs).

Any thoughts?



More information about the LibreOffice mailing list