se2p / pynguin

The PYthoN General UnIt Test geNerator is a test-generation tool for Python
https://www.pynguin.eu
MIT License
1.22k stars 74 forks source link

RuntimeError: The current thread shall not be executed any more, thus I kill it. #29

Closed tovmeod closed 1 year ago

tovmeod commented 1 year ago

pynguin 0.27.0 Python 3.10.7 mac arm

I'm getting a RuntimeError logged to the console, I'm trying to figure out what is causing it, I tried setting maximum-search-time to 18000 (30 minutes) and maximum_iterations to 10000 but it still log the same error. Anyway it generates 4 test cases with 3 of them with @pytest.mark.xfail(strict=True)

error below:

ERROR    Exception in Thread: <Thread(Thread-266595 (_execute_test_case), started daemon 6209482752)>                                                execution.py:2081
                    ╭─────────────────────────────────────────────────── Traceback (most recent call last) ───────────────────────────────────────────────────╮                  
                    │ /Users/avraham/.pyenv/versions/3.10.7/lib/python3.10/threading.py:1016 in _bootstrap_inner                                              │                  
                    │                                                                                                                                         │                  
                    │   1013 │   │   │   │   _sys.setprofile(_profile_hook)                                                                                   │                  
                    │   1014 │   │   │                                                                                                                        │                  
                    │   1015 │   │   │   try:                                                                                                                 │                  
                    │ ❱ 1016 │   │   │   │   self.run()                                                                                                       │                  
                    │   1017 │   │   │   except:                                                                                                              │                  
                    │   1018 │   │   │   │   self._invoke_excepthook(self)                                                                                    │                  
                    │   1019 │   │   finally:                                                                                                                 │                  
                    │                                                                                                                                         │                  
                    │ /Users/avraham/.pyenv/versions/3.10.7/lib/python3.10/threading.py:953 in run                                                            │                  
                    │                                                                                                                                         │                  
                    │    950 │   │   """                                                                                                                      │                  
                    │    951 │   │   try:                                                                                                                     │                  
                    │    952 │   │   │   if self._target is not None:                                                                                         │                  
                    │ ❱  953 │   │   │   │   self._target(*self._args, **self._kwargs)                                                                        │                  
                    │    954 │   │   finally:                                                                                                                 │                  
                    │    955 │   │   │   # Avoid a refcycle if the thread is running a function with                                                          │                  
                    │    956 │   │   │   # an argument that has a member that points to the thread.                                                           │                  
                    │                                                                                                                                         │                  
                    │ /Users/avraham/Library/Caches/pypoetry/virtualenvs/M5hsRoCT-py3.10/lib/python3.10/site-packages/pynguin/testcase/execu │                  
                    │ tion.py:2184 in _execute_test_case                                                                                                      │                  
                    │                                                                                                                                         │                  
                    │   2181 │   │   for idx, statement in enumerate(test_case.statements):                                                                   │                  
                    │   2182 │   │   │   ast_node = self._before_statement_execution(statement, exec_ctx)                                                     │                  
                    │   2183 │   │   │   exception = self.execute_ast(ast_node, exec_ctx)                                                                     │                  
                    │ ❱ 2184 │   │   │   self._after_statement_execution(statement, exec_ctx, exception)                                                      │                  
                    │   2185 │   │   │   if exception is not None:                                                                                            │                  
                    │   2186 │   │   │   │   result.report_new_thrown_exception(idx, exception)                                                               │                  
                    │   2187 │   │   │   │   break                                                                                                            │                  
                    │                                                                                                                                         │                  
                    │ /Users/avraham/Library/Caches/pypoetry/virtualenvs/M5hsRoCT-py3.10/lib/python3.10/site-packages/pynguin/testcase/execu │                  
                    │ tion.py:2283 in _after_statement_execution                                                                                              │                  
                    │                                                                                                                                         │                  
                    │   2280 │   │   # See comments in _before_statement_execution                                                                            │                  
                    │   2281 │   │   if self.tracer.current_thread_identifier != threading.current_thread().ident:                                            │                  
                    │   2282 │   │   │   # Kill this thread                                                                                                   │                  
                    │ ❱ 2283 │   │   │   raise RuntimeError(                                                                                                  │                  
                    │   2284 │   │   │   │   "The current thread shall not be executed any more, thus I kill it."                                             │                  
                    │   2285 │   │   │   )                                                                                                                    │                  
                    │   2286                                                                                                                                  │                  
                    ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯                  
                    RuntimeError: The current thread shall not be executed any more, thus I kill it. 
stephanlukasczyk commented 1 year ago

It seems like there was an issue with stopping the test-case execution. Pynguin is running each generated test a separate thread to be able to stop the execution after a certain time. This is done to avoid that Pynguin is stuck, for example, due to infinite loops.

To allow us to introspect this we would like to ask you for some more details: could you please provide us the Pynguin command line you were using together with the Python module you wanted to generate tests for? If that's not possible, for example, because there is some non-disclosure policy to the code, we would need to have a minimal code snippet that shows the same behaviour.

tovmeod commented 1 year ago

This is the command used: PYNGUIN_DANGER_AWARE=1 poetry run pynguin --project-path ./ --output-path ./pynguin-results --module-name company.datetime_utils --seed 1629381673714481067 --maximum-search-time 1800

Can I increase the timeout for the test execution to try to avoid this?

tovmeod commented 1 year ago

I added the following to the command to see if it would help, but it didn't make any difference, I get the same error and the same result: --maximum-test-execution-timeout 30 --test-execution-time-per-statement 30

Wooza commented 1 year ago

The error message that is written to the log is just an indicator that Pynguin created and executed an intermediate test case in a separate thread which timed out. While this output might look strange, it is nothing to worry about, as it is just bad UX from Pynguin's side, sorry for that. Remember that Pynguin is only a research prototype and not tailored towards production use whatsoever.

The resulting test cases which are annotated with @pytest.mark.xfail(strict=True) indicate that the last line of such a test case raises an exception. Generally, such test cases require manual inspection. Removing the last statement might already give you a non-failing test case, but depending on the remaining statements of that test, it might not be useful anymore.

If you need you need more help, we would appreciate a minimum working example, which includes not only the CLI parameters with which Pynguin was launched, but also the source code (+ imported modules) on which it was applied.