-
Notifications
You must be signed in to change notification settings - Fork 535
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
test(client-presence): Example multi-process E2E test #23305
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome work Willie, this looks great! I left some suggestions/questions, but overall this looks like a great start. I agree we should look into other options/frameworks to see what fits our tests best
afterEach(async () => { | ||
// kill all child processes after each test | ||
for (const child of children) { | ||
if (!child.killed) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would probably make more sense to reset the array after each test. Something like -
let children: ChildProcess[] = [];
afterEach(async () => {
// kill all child processes after each test
for (const child of children) {
child.kill();
}
children = [];
}
if (attendee !== presence.getMyself()) { | ||
count++; | ||
attendeesJoined.push(attendee.sessionId); | ||
if (count === numClients) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: You could get rid of count
by comparing attendeesJoined.length === numClients
instead
await timeoutPromise( | ||
(resolve) => { | ||
let count = 0; | ||
presence.events.on("attendeeJoined", (attendee) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to turn off this listener after we are done with it? I'm not sure if it gets cleaned up automatically
const waitForDisconnected = children.map(async (child, index) => | ||
timeoutPromise( | ||
(resolve) => | ||
child.on("message", (msg: MessageFromChild) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same question as above (re: turning off listeners)
}; | ||
}; | ||
|
||
process.on("message", (msg: MessageFromParent) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since I commented on the below listeners I just want to note I think we don't need to turn this listener off since the process will get killed
Not meant to merge
Description
This PR is an example setup of a multi-process end to end test could potentially look like. Each client has their own separate process. There is a client in the parent process who creates the container and child processes that fork from the parent process that get the same container. Through IPC (inter-process communication) calls parent process acts as an orchestrator to its child processes, giving commands about what actions to perform. The child then performs these actions and responds with any information needed to verify correctness. The parent can interact with each child and each child only interacts with the parent.
This was written as an AzureClient E2E test to avoid the complexity of the existing cross-compat in the root e2e test package.
Learnings
This pattern follows something close to the actor model in which the parent process is the only actor that creates other actors. From this experience I realize this concurrent programming model is very different from the traditional single process tests we write now. It would be difficult to integrate this pattern into our current e2e compat test suite. If we build out a new test suite using this actor model for multi-process testing, we'd have to develop new abstractions to make it easy for developers to write tests simply (Actor, Orchestrator, Command/Action, etc.)
Next Steps
We should look into other potential JS frameworks that we could leverage here