diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2020-05-25 13:34:47 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2020-05-25 15:14:04 +0200 |
commit | 953d2704025ef31198f5546ad95cc54401b592a9 (patch) | |
tree | 18fab08c394bf91301ef64bb1f8e3869aae2d213 /uitest | |
parent | 42a37f8ce27ad8fca222f50b712a8fed52dbda95 (diff) |
Do not time out execute_dialog_through_command
If something goes wrong, better keep the testing Python and the tested soffice
process in a state in which the actual problem can (hopefully) be debugged
better.
I happened to run into a hung UITest_options on Linux, where soffice.bin was
still at
> Thread 1 (Thread 0x7fa6371d9fc0 (LWP 1210042)):
> #0 futex_abstimed_wait_cancelable (private=0, abstime=0x7fa633a17f80, clockid=<optimized out>, expected=0, futex_word=0x60e000024e88) at /usr/src/debug/glibc-2.31-17-gab029a2801/sysdeps/nptl/futex-internal.h:320
> #1 __pthread_cond_wait_common (abstime=0x7fa633a17f80, clockid=<optimized out>, mutex=0x60e000024e38, cond=0x60e000024e60) at /usr/src/debug/glibc-2.31-17-gab029a2801/nptl/pthread_cond_wait.c:520
> #2 __pthread_cond_clockwait (abstime=0x7fa633a17f80, clockid=<optimized out>, mutex=0x60e000024e38, cond=0x60e000024e60) at /usr/src/debug/glibc-2.31-17-gab029a2801/nptl/pthread_cond_wait.c:677
> #3 __pthread_cond_clockwait (cond=0x60e000024e60, mutex=0x60e000024e38, clockid=<optimized out>, abstime=0x7fa633a17f80) at /usr/src/debug/glibc-2.31-17-gab029a2801/nptl/pthread_cond_wait.c:665
> #4 0x00007fa66899be08 in std::condition_variable::__wait_until_impl<std::chrono::duration<long, std::ratio<1l, 1000000000l> > >(std::unique_lock<std::mutex>&, std::chrono::time_point<std::chrono::_V2::steady_clock, std::chrono::duration<long, std::ratio<1l, 1000000000l> > > const&) (this=0x60e000024e60, __lock=..., __atime=...) at include/c++/10.0.1/condition_variable:210
> #5 0x00007fa66899b895 in std::condition_variable::wait_until<std::chrono::duration<long, std::ratio<1l, 1000000000l> > >(std::unique_lock<std::mutex>&, std::chrono::time_point<std::chrono::_V2::steady_clock, std::chrono::duration<long, std::ratio<1l, 1000000000l> > > const&) (this=0x60e000024e60, __lock=..., __atime=...) at include/c++/10.0.1/condition_variable:120
> #6 0x00007fa668997505 in std::condition_variable::wait_until<std::chrono::_V2::steady_clock, std::chrono::duration<long, std::ratio<1l, 1000000000l> >, SvpSalInstance::DoYield(bool, bool)::$_2>(std::unique_lock<std::mutex>&, std::chrono::time_point<std::chrono::_V2::steady_clock, std::chrono::duration<long, std::ratio<1l, 1000000000l> > > const&, SvpSalInstance::DoYield(bool, bool)::$_2) (this=0x60e000024e60, __lock=..., __atime=..., __p=...) at include/c++/10.0.1/condition_variable:159
> #7 0x00007fa668995460 in std::condition_variable::wait_for<long, std::ratio<1l, 1000l>, SvpSalInstance::DoYield(bool, bool)::$_2>(std::unique_lock<std::mutex>&, std::chrono::duration<long, std::ratio<1l, 1000l> > const&, SvpSalInstance::DoYield(bool, bool)::$_2) (this=0x60e000024e60, __lock=..., __rtime=..., __p=...) at include/c++/10.0.1/condition_variable:186
> #8 0x00007fa66899408e in SvpSalInstance::DoYield(bool, bool) (this=0x611000001bc0, bWait=true, bHandleAllCurrentEvents=false) at vcl/headless/svpinst.cxx:497
> #9 0x00007fa667e7114d in ImplYield(bool, bool) (i_bWait=true, i_bAllEvents=false) at vcl/source/app/svapp.cxx:455
> #10 0x00007fa667e70708 in Application::Yield() () at vcl/source/app/svapp.cxx:519
> #11 0x00007fa66498f6cd in Dialog::Execute() (this=0x618003c16480) at vcl/source/window/dialog.cxx:1030
> #12 0x00007fa667a93812 in SalInstanceDialog::run() (this=0x616000575780) at vcl/source/app/salvtables.cxx:1482
> #13 0x00007fa2e8711b8d in weld::DialogController::run() (this=0x60c004e70d80) at include/vcl/weld.hxx:2289
> #14 0x00007fa2e98a6cbc in OfaTreeOptionsDialog::run() (this=0x60c004e70d80) at cui/source/options/treeopt.cxx:1937
> #15 0x00007fa2e90c4d15 in CuiAbstractController_Impl::Execute() (this=0x60300187b4f0) at cui/source/factory/dlgfact.cxx:103
> #16 0x00007fa688bc9b2d in SfxApplication::OfaExec_Impl(SfxRequest&) (this=0x604006f2fe10, rReq=...) at sfx2/source/appl/appserv.cxx:1311
> #17 0x00007fa688b17655 in SfxStubSfxApplicationOfaExec_Impl(SfxShell*, SfxRequest&) (pShell=0x604006f2fe10, rReq=...) at workdir/SdiTarget/sfx2/sdi/sfxslots.hxx:1270
> #18 0x00007fa6892521f6 in SfxShell::CallExec(void (*)(SfxShell*, SfxRequest&), SfxRequest&) (this=0x604006f2fe10, pFunc=0x7fa688b17530 <SfxStubSfxApplicationOfaExec_Impl(SfxShell*, SfxRequest&)>, rReq=...) at include/sfx2/shell.hxx:197
> #19 0x00007fa6891dbb1f in SfxDispatcher::Call_Impl(SfxShell&, SfxSlot const&, SfxRequest&, bool) (this=0x6020013430b0, rShell=..., rSlot=..., rReq=..., bRecord=true) at sfx2/source/control/dispatch.cxx:252
> #20 0x00007fa6891defd6 in SfxDispatcher::PostMsgHandler(std::unique_ptr<SfxRequest, std::default_delete<SfxRequest> >) (this=0x6020013430b0, pReq=std::unique_ptr<class SfxRequest> = {...}) at sfx2/source/control/dispatch.cxx:989
[...]
but the Python process was already at
> Traceback (most recent call first):
> <built-in method waitpid of module object at remote 0x60800002d140>
> File "instdir/program/python-core-3.7.7/lib/subprocess.py", line 1611, in _try_wait
> (pid, sts) = os.waitpid(self.pid, wait_flags)
> File "instdir/program/python-core-3.7.7/lib/subprocess.py", line 1653, in _wait
> (pid, sts) = self._try_wait(0)
> File "instdir/program/python-core-3.7.7/lib/subprocess.py", line 1019, in wait
> return self._wait(timeout=timeout)
> File "uitest/libreoffice/connection.py", line 133, in tearDown
> ret = self.soffice.wait()
> File "uitest/libreoffice/connection.py", line 178, in tearDown
> self.connection.tearDown()
> File "uitest/uitest/framework.py", line 46, in tearDown
> self.connection.tearDown()
> File "instdir/program/python-core-3.7.7/lib/unittest/case.py", line 631, in run
> self.tearDown()
> File "instdir/program/python-core-3.7.7/lib/unittest/case.py", line 676, in __call__
> return self.run(*args, **kwds)
> File "instdir/program/python-core-3.7.7/lib/unittest/suite.py", line 122, in run
> test(result)
> File "instdir/program/python-core-3.7.7/lib/unittest/suite.py", line 84, in __call__
> return self.run(*args, **kwds)
> File "instdir/program/python-core-3.7.7/lib/unittest/runner.py", line 176, in run
> test(result)
> File "uitest/test_main.py", line 128, in <module>
> result = unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run(test_suite)
and the relevant
> ======================================================================
> ERROR: test_tdf78133_options_app_colors (tdf78133.tdf78133)
> ----------------------------------------------------------------------
> Traceback (most recent call last):
> File "sw/qa/uitest/options/tdf78133.py", line 38, in test_tdf78133_options_app_colors
> self.ui_test.execute_dialog_through_command(".uno:OptionsTreeDialog") #optionsdialog
> File "uitest/uitest/test.py", line 78, in execute_dialog_through_command
> raise DialogNotExecutedException(command)
> uitest.test.DialogNotExecutedException: Dialog not executed for: .uno:OptionsTreeDialog
had not yet been written to workdir/UITest/options/done.log (Python's unittest
appears to unhelpfully hold back such vital information until the very end of
the full test run).
There appears to be no test code that relies on a timed-out
execute_dialog_through_command throwing an exception instead of hanging (at
least, there is no explicit catching of DialogNotExecutedException anywhere in
the code, and a full `make check screenshot` on Linux kept working with this
change).
(This is similar to 19d3dba72fd744ab8dc1288b1c7c4c811b24ca28 "Do not time out
close_dialog_through_button".)
Change-Id: Ie907a091ae09b59e65c4b2676298e147c9d2da2f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94786
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'uitest')
-rw-r--r-- | uitest/uitest/test.py | 8 |
1 files changed, 2 insertions, 6 deletions
diff --git a/uitest/uitest/test.py b/uitest/uitest/test.py index ab8f650d548d..556fb511cc97 100644 --- a/uitest/uitest/test.py +++ b/uitest/uitest/test.py @@ -81,20 +81,16 @@ class UITest(object): time_ += DEFAULT_SLEEP time.sleep(DEFAULT_SLEEP) - def execute_dialog_through_command(self, command, printNames=False, maxWait=MAX_WAIT): + def execute_dialog_through_command(self, command, printNames=False): with EventListener(self._xContext, "DialogExecute", printNames=printNames) as event: if not self._xUITest.executeDialog(command): raise DialogNotExecutedException(command) - time_ = 0 - while time_ < maxWait: + while True: if event.executed: time.sleep(DEFAULT_SLEEP) return - time_ += DEFAULT_SLEEP time.sleep(DEFAULT_SLEEP) - raise DialogNotExecutedException(command) - def execute_modeless_dialog_through_command(self, command, printNames=False): with EventListener(self._xContext, "ModelessDialogVisible", printNames = printNames) as event: if not self._xUITest.executeCommand(command): |