Testing Channels Worker processes

Ok, there may be some terminology mismatch here - let me see if I can clarify without making things worse.

The overall architecture, as I’m using it:
Channels 1

So I’m using the term “Worker” in the context as described at Worker and Background Tasks — Channels 4.0.0 documentation

The consumers:

  • Receive messages from the browser(s),
  • Figures out which worker needs to process that message
  • Forwards the message to the right worker, via the channel layer

The guts of the work is being done in the workers.

What’s not shown in the diagram is that a worker, in the process of handling a message, could post additional messages to also be processed by the same worker, or by a different worker. So running the worker in this context means that the worker process is listening to 4 channels.

That’s what I’m wanting to test. I need to send a message to worker “A”, and (potentially) wait for responses from workers “A” and “B”.

One final aspect of this is that the logic for worker “A” is really quite trivial.

  • Read the message,
  • Get some state information from a Model,
  • Call a function as identified by the combination of message and state
    • Determine the new state,
  • Prepare a response by calling a different function

So what I’m really trying to test here is a state machine.

Testing the logic isn’t the issue. These tests are being created to test all the state transitions and verify that the state machine is accurate.

What I have working:
Current pytest
This works, but every time I make a change to the worker, I need to restart it before restarting the tests.

I wouldn’t really call this E2E, because I’m completely bypassing the Consumer layer. But I acknowledge that it’s not truly a “unit test” either because of the dispatch from worker “A” to worker “B”.
In theory, I should test the message to worker “B” separately from the message to worker “A”, and I’m not ruling that out as an option.

Where I’m trying to get to:
Desired

Now, if I start a separate thread within a fixture, I can (kinda, sorta, effectively) do this now. The problem is that I’m not cleanly stopping that thread after a test.

What I’d really like to get to:
Ultimate

And that’s where I have some ideas.

Also, in thinking more about it based on what you’ve said, I may try the even more simplified version:
Ultimate 1

Like I said - I ain’t done yet…