csernazs / pytest-httpserver

Http server for pytest to test http clients
MIT License
209 stars 27 forks source link

Enable using a threaded WSGI server #323

Closed delthas closed 2 months ago

delthas commented 2 months ago

Hi,

I'm making tests where I need to check the behavior of my application when there are two concurrent requests to my server, while one is sleeping:

(I can't just start two servers on two different ports, this has to be on the same port.)

This would normally mean just doing time.sleep in my handler for request 1; but this does not work because the WSGI server created by pytest-httpserver is not threaded:

https://github.com/csernazs/pytest-httpserver/blob/master/pytest_httpserver/httpserver.py#L745

(threaded=False, processes=1 by default)

It would be nice to enable the user to specify whether the underlying WSGI server should be threaded, ie adding a threaded named argument somewhere (in start() or in init()), then passing that flag to the WSGI server.

Would you accept such a PR? Or is there another way to achieve what I'm trying to do?

csernazs commented 2 months ago

hi @delthas ,

Is this related to #263? Were you able to test that example? :)

I'm ok with adding a kwarg-only boolean flag threaded to HTTPServer.__init__. This could be then used at make_server, in a similar way to self.ssl_context, provided this is the only modification needed..

If there are other modifications needed, I suggest creating a subclass, extracting make_server to a method, which is then overridden. That subclass would do the thread-specific overrides needed (vs. having multiple if self.threaded: blocks).

My main concern is how it performs if there is a handler running in a thread and let's say the client timeouts and the test continues to run. In such case the handler would be still running (eg. handler has sleep(1500)). Threads cannot be stopped (killed) easily, and in the case of pytest-httpserver we want to provide a clean http server instance (which means: no handlers registered, log cleared, no handlers processing anything from the last test, no cross-talk. So if there's a way, I would suggest waiting (joining) for all the running handlers' threads before we move on to the next test.

So in summary, I'm open to the idea, but we need to do it very carefully. We can also document and indicate that this is experimental, "do it at your own risk", if needed.

What do you think?

I'm happy to work on the code as well, but it is also ok if you open a PR. Just make sure docstrings are updated.

Zsolt

csernazs commented 1 month ago

@delthas FYI, your MR has just been relased as v 1.0.11 with documentations in the howto section. Thanks again for your contribution and apologies for the delayed release!

Zsolt