Mac and mock fix
Part of fix for django/channels#962.
Allows tests to pass on a mac, and for a reactor to be passed into the server.
I fixed a space in an isort:skip I added which caused travis build to fail. (ok now I think I got it all)
Super. Thanks. I shall take a look later in the week.
I'm just guessing, but it might be because I changed it to using spawn instead of fork for DaphneProcess.
Since my pull request in django/channels#1372 doesn't use DaphneProcess, I can refactor this pull request to just allowing a reactor to be sent to the Daphne Server.
For Daphne tests to work on a mac, then #247 would need to be pulled in.
Would it make sense to accept #247, and then I'll rebase from that?
Hi @shjohnson-pi. Yes, it looks like that is the way to go. #247 resolves both the failing test cases here and the hang of the Channels live server test cases.
Happy to look at extra changes here and some version of https://github.com/django/channels/pull/1372 but currently lacking extra tests there showing what's gained (and that we didn't break anything... 😬)
@carltongibson I definitely agree tests would be great, but I'm not sure how to test ChannelsLiveServerTestCase because of all the setup Django needs and expects (especially with databases). Do you have any ideas?
The only thing that comes to mind is an example app that uses it, but I'm not sure how channel's pytest could run the example app's pytest and confirm correct output.
Anyways, whenever you're able to merge #247 I'll rebase these pull requests. Thank you for spending time on this.
Hey @shjohnson-pi — Yes... For me a test project at least demonstrating the win would be good. It doesn't necessarily have to be run by CI.
Great! Then I'll work on that example app.
@carltongibson Ok, I think everything is all set. This pull request just allows passing in a reactor to Daphne Server, and adds a small test for Daphne Process.
My other pull request django/channels#1372 now includes a test_example project under the tests directory with a README on how to run pytest in it. I wasn't sure how you wanted that example app, so let me know if you just want a tar.gz or something instead of it being committed. It has some tests that demonstrate that mocking and in-memory databases work with my threaded version of the live test case.
Python 3.8 changed the default multiprocessing start method on macOS from 'fork' to 'spawn'. I'm seeing some breakage using the tests from the Channels tutorial such as:
======================================================================
ERROR: test_when_chat_message_posted_then_not_seen_by_anyone_in_different_room (chat.tests.ChatTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/chainz/tmp/channels-tutorial/venv/lib/python3.8/site-packages/django/test/testcases.py", line 267, in __call__
self._pre_setup()
File "/Users/chainz/tmp/channels-tutorial/venv/lib/python3.8/site-packages/channels/testing/live.py", line 52, in _pre_setup
self._server_process.start()
File "/Users/chainz/.pyenv/versions/3.8.1/lib/python3.8/multiprocessing/process.py", line 121, in start
self._popen = self._Popen(self)
File "/Users/chainz/.pyenv/versions/3.8.1/lib/python3.8/multiprocessing/context.py", line 224, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
File "/Users/chainz/.pyenv/versions/3.8.1/lib/python3.8/multiprocessing/context.py", line 283, in _Popen
return Popen(process_obj)
File "/Users/chainz/.pyenv/versions/3.8.1/lib/python3.8/multiprocessing/popen_spawn_posix.py", line 32, in __init__
super().__init__(process_obj)
File "/Users/chainz/.pyenv/versions/3.8.1/lib/python3.8/multiprocessing/popen_fork.py", line 19, in __init__
self._launch(process_obj)
File "/Users/chainz/.pyenv/versions/3.8.1/lib/python3.8/multiprocessing/popen_spawn_posix.py", line 47, in _launch
reduction.dump(process_obj, fp)
File "/Users/chainz/.pyenv/versions/3.8.1/lib/python3.8/multiprocessing/reduction.py", line 60, in dump
ForkingPickler(file, protocol).dump(obj)
AttributeError: Can't pickle local object 'DaphneProcess.__init__.<locals>.<lambda>'
Using the head commit here fixes those errors 👍
Yes... This is sitting here because I never got back to it after the first round of review. That it was 3x slower that the process approach left me a little cold.
I appreciate MacOS has it's issues. (c.f. Django test suite which we can't run parallel there on Python 3.8+...) But I wasn't at all sure about handicapping everyone for that reason.
Would be very happy if anyone could do the work to lay out clearly what the right course is.
Wasn't aware that Django test suite doesn't work in parallel on 3.8+ either.
I should be able to look into this whilst working on client project using channels with most developers on macOS.
Good point on #310, ref Python 3.8 + macOS:
My current workaround is to call `multiprocessing.set_start_method('fork') in my django manage.py file.
At some point this'll presumably stop working on future macOS, but for the now it reverts to the Python 3.7 behaviour (which we've been using without problems for a while now...)
Superseded by #440. Resolved in Channels/Daphne v4