Skip to content
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

Halting pytest.main() when invoked via multiprocessing #7165

Closed
ptrivedi2610 opened this issue May 5, 2020 · 9 comments
Closed

Halting pytest.main() when invoked via multiprocessing #7165

ptrivedi2610 opened this issue May 5, 2020 · 9 comments
Labels
status: needs information reporter needs to provide more information; can be closed after 2 or more weeks of inactivity

Comments

@ptrivedi2610
Copy link

Hi,

I currently am facing issue to stop execution of pytest from below scenario

  1. 'ProcessM' is my main process
  2. 'ProcessS' is created using multiprocessing module.
  3. ProcessS has some python code. On top of that, its has a call to pytest.main()
  4. When I call ProcessS.terminate(), from ProcessM, I want pytest to halt as well.

How to achieve this ?
I tried using pytest.exit() from ProcessS, sys.exit() from ProcessS etc. but does not work

@ptrivedi2610 ptrivedi2610 changed the title Halting pytest.main() when invoked from subprocess Halting pytest.main() when invoked via multiprocessing May 5, 2020
@bluetech
Copy link
Member

bluetech commented May 5, 2020

Hi @ptrivedi2610,

When you say it doesn't work, what does it mean exactly? Nothing happens?

Also, please specify the details requested in the issue template, it will help us understand the issue better.

@bluetech bluetech added the status: needs information reporter needs to provide more information; can be closed after 2 or more weeks of inactivity label May 5, 2020
@ptrivedi2610
Copy link
Author

ptrivedi2610 commented May 7, 2020

@bluetech
That is slight difficult. Lets make this a bit simpler
Lets say I am calling pytest.main() from ScriptP.py

Is there a way to programatically stop pytest session from ScriptP.py, such that ScriptP.py need not to be stopped ?

@nicoddemus
Copy link
Member

nicoddemus commented May 7, 2020

One way to accomplish that is setting session.shouldstop to a string, which will make pytest display that string and stop the test run.

You can do that via the pytest_sessionstart hook, something like this:

class StopPlugin:

    def pytest_sessionstart(self, session):
        self.session = session

    def stop(self):
        self.session.shouldstop = "stopped by parent process"


stop_plugin = StopPlugin()
pytest.main(argv, plugins=[stop_plugin])

Then you need to somehow make the parent process communicate with the child process and call stop_plugin.stop().

@ptrivedi2610
Copy link
Author

ptrivedi2610 commented May 8, 2020

@nicoddemus Thanks a lot for the quick help.
I noticed it doesn't immediately halt the session. The test still move further for sometime and then the session is halted.

Is there a way to fix this ? I need immediate halting of pytest

I even tried to use self.session.Interrupted as mentioned in #3574 but didn't work

@RonnyPfannschmidt
Copy link
Member

For a direct halt, termination of the process is required

@ptrivedi2610
Copy link
Author

ptrivedi2610 commented May 8, 2020

@RonnyPfannschmidt Yes, but then when calling process.terminate(), I am loosing all the teardowns. I want a behavior similar to SIGINT

Below is more info on the issue

  1. I have invoked pytest.main() from ProcessS. ProcessS was forked from main process ProcessM (using multiprocessing)
  2. Now I want to stop pytest session execution mid run, such a a way that no further test runs, but also all teardown are shut successfully.
  3. Ideally ,os.kill() on Linux and MAC machine does the job. However there is bug in windows python regarding os.kill(). Refer https://bugs.python.org/issue23948
  4. This means the only option to halt the ProcessS and pytest.main() is using ProcessS.terminate(). However multiprocessing.terminate() uses SIGTERM. So I loose all the teardown here.

Thus I have to manually code some workaround that would programatically halt pytest, but after passing through all teardowns

@RonnyPfannschmidt
Copy link
Member

based on your information there doesnt seem to be a way to make what you ask for work on windows

@nicoddemus
Copy link
Member

Thus I have to manually code some workaround that would programatically halt pytest, but after passing through all teardowns

pytest will check session.shouldstop after each test, I think that's the only way to ask pytest to stop running in a controlled manner. There's no way to just interrupt the current test mid-way, as pytest doesn't use threads to run tests.

Unfortunately I don't think it is possible to accomplish what you want, I'm afraid.

I'm closing this for now because I think we have exhausted all our options, but feel free to post further questions and we can reopen this if there are more suggestions to try out. 👍

@ptrivedi2610
Copy link
Author

@nicoddemus
Sure, thanks a lot for all the conceptual explanations and help :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: needs information reporter needs to provide more information; can be closed after 2 or more weeks of inactivity
Projects
None yet
Development

No branches or pull requests

4 participants