@fluidframework/azure-end-to-end-tests 2.70.0 → 2.71.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/lib/test/multiprocess/childClient.tool.js +22 -11
- package/lib/test/multiprocess/childClient.tool.js.map +1 -1
- package/lib/test/multiprocess/messageTypes.js.map +1 -1
- package/lib/test/multiprocess/orchestratorUtils.js +15 -4
- package/lib/test/multiprocess/orchestratorUtils.js.map +1 -1
- package/lib/test/multiprocess/presenceTest.spec.js +181 -157
- package/lib/test/multiprocess/presenceTest.spec.js.map +1 -1
- package/package.json +26 -26
- package/src/test/multiprocess/childClient.tool.ts +25 -13
- package/src/test/multiprocess/messageTypes.ts +1 -0
- package/src/test/multiprocess/orchestratorUtils.ts +14 -1
- package/src/test/multiprocess/presenceTest.spec.ts +270 -233
|
@@ -43,7 +43,7 @@ const debuggerAttached = inspector.url() !== undefined;
|
|
|
43
43
|
/**
|
|
44
44
|
* Set this to a high number when debugging to avoid timeouts from debugging time.
|
|
45
45
|
*/
|
|
46
|
-
const timeoutMultiplier = debuggerAttached ? 1000 : useAzure ?
|
|
46
|
+
const timeoutMultiplier = debuggerAttached ? 1000 : useAzure ? 5 : 1;
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
49
|
* Sets the timeout for the given test context.
|
|
@@ -131,11 +131,12 @@ describe(`Presence with AzureClient`, () => {
|
|
|
131
131
|
const allAttendeesFullyJoinedTimeoutMs = (2000 + 300 * numClients) * timeoutMultiplier;
|
|
132
132
|
|
|
133
133
|
for (const writeClients of [numClients, 1]) {
|
|
134
|
-
it(`announces 'attendeeConnected' when remote client joins session [${numClients} clients, ${writeClients} writers]`, async function () {
|
|
134
|
+
it(`announces 'attendeeConnected' when remote client joins session [${numClients} clients, ${writeClients} writers]`, async function testAnnouncesAttendeeConnected() {
|
|
135
135
|
setTestTimeout(this, childConnectTimeoutMs + allAttendeesJoinedTimeoutMs + 1000);
|
|
136
136
|
|
|
137
137
|
// Setup
|
|
138
138
|
const { children, childErrorPromise } = await forkChildProcesses(
|
|
139
|
+
this.test?.title ?? "",
|
|
139
140
|
numClients,
|
|
140
141
|
afterCleanUp,
|
|
141
142
|
);
|
|
@@ -153,7 +154,7 @@ describe(`Presence with AzureClient`, () => {
|
|
|
153
154
|
);
|
|
154
155
|
});
|
|
155
156
|
|
|
156
|
-
it(`announces 'attendeeDisconnected' when remote client disconnects [${numClients} clients, ${writeClients} writers]`, async function () {
|
|
157
|
+
it(`announces 'attendeeDisconnected' when remote client disconnects [${numClients} clients, ${writeClients} writers]`, async function testAnnouncesAttendeeDisconnected() {
|
|
157
158
|
if (useAzure && numClients > 50) {
|
|
158
159
|
// Even with increased timeouts, more than 50 clients can be too large for AFR.
|
|
159
160
|
// This may be due to slow responses/inactivity from the clients that are
|
|
@@ -173,6 +174,7 @@ describe(`Presence with AzureClient`, () => {
|
|
|
173
174
|
|
|
174
175
|
// Setup
|
|
175
176
|
const { children, childErrorPromise } = await forkChildProcesses(
|
|
177
|
+
this.test?.title ?? "",
|
|
176
178
|
numClients,
|
|
177
179
|
afterCleanUp,
|
|
178
180
|
);
|
|
@@ -335,78 +337,95 @@ describe(`Presence with AzureClient`, () => {
|
|
|
335
337
|
/**
|
|
336
338
|
* Timeout for child processes to connect to container ({@link ConnectedEvent})
|
|
337
339
|
*/
|
|
338
|
-
const childConnectTimeoutMs = 1000 * numClients * timeoutMultiplier;
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
)
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
340
|
+
const childConnectTimeoutMs = (4000 + 1000 * numClients) * timeoutMultiplier;
|
|
341
|
+
const testCaseTimeoutMs = 1000;
|
|
342
|
+
const testSetupAndActTimeoutMs = childConnectTimeoutMs + testCaseTimeoutMs;
|
|
343
|
+
|
|
344
|
+
// These tests use beforeEach to setup complex state that takes a lot of time
|
|
345
|
+
// and is dependent on number of clients. Keeping the work in beforeEach
|
|
346
|
+
// allows time reporting to report the tested scenario apart from the setup time.
|
|
347
|
+
// So this describe block isolates those beforeEach setups from each distinct
|
|
348
|
+
// client count. Test cases descriptions also have the client count for clarity.
|
|
349
|
+
describe(`with ${numClients} clients`, () => {
|
|
350
|
+
let children: ChildProcess[];
|
|
351
|
+
let childErrorPromise: Promise<never>;
|
|
352
|
+
let containerCreatorAttendeeId: AttendeeId;
|
|
353
|
+
let attendeeIdPromises: Promise<AttendeeId>[];
|
|
354
|
+
let remoteClients: ChildProcess[];
|
|
355
|
+
const testValue = "testValue";
|
|
356
|
+
const workspaceId = "presenceTestWorkspace";
|
|
357
|
+
|
|
358
|
+
beforeEach(async function usingLatestStateObject_beforeEach(): Promise<void> {
|
|
359
|
+
const startTime = performance.now();
|
|
360
|
+
setTestTimeout(this, testSetupAndActTimeoutMs);
|
|
361
|
+
|
|
362
|
+
({ children, childErrorPromise } = await forkChildProcesses(
|
|
363
|
+
this.currentTest?.title ?? "",
|
|
364
|
+
numClients,
|
|
365
|
+
afterCleanUp,
|
|
366
|
+
));
|
|
367
|
+
({ containerCreatorAttendeeId, attendeeIdPromises } = await connectChildProcesses(
|
|
368
|
+
children,
|
|
369
|
+
{ writeClients: numClients, readyTimeoutMs: childConnectTimeoutMs },
|
|
370
|
+
));
|
|
371
|
+
await Promise.all(attendeeIdPromises);
|
|
372
|
+
remoteClients = children.filter((_, index) => index !== 0);
|
|
373
|
+
// NOTE: For testing purposes child clients will expect a Latest value of type string (StateFactory.latest<{ value: string }>).
|
|
374
|
+
await registerWorkspaceOnChildren(children, workspaceId, {
|
|
375
|
+
latest: true,
|
|
376
|
+
timeoutMs: workspaceRegisterTimeoutMs,
|
|
377
|
+
});
|
|
375
378
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
workspaceId,
|
|
380
|
-
value: testValue,
|
|
379
|
+
testConsole.log(
|
|
380
|
+
` Setup for "${this.currentTest?.title}" completed in ${performance.now() - startTime}ms`,
|
|
381
|
+
);
|
|
381
382
|
});
|
|
382
|
-
const updateEvents = await updateEventsPromise;
|
|
383
383
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
384
|
+
it(`allows clients to read Latest state from other clients [${numClients} clients]`, async function () {
|
|
385
|
+
// Setup
|
|
386
|
+
const updateEventsPromise = waitForLatestValueUpdates(
|
|
387
|
+
remoteClients,
|
|
388
|
+
workspaceId,
|
|
389
|
+
childErrorPromise,
|
|
390
|
+
stateUpdateTimeoutMs,
|
|
391
|
+
{ fromAttendeeId: containerCreatorAttendeeId, expectedValue: testValue },
|
|
392
|
+
);
|
|
389
393
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
command: "getLatestValue",
|
|
394
|
+
// Act - Trigger the update
|
|
395
|
+
children[0].send({
|
|
396
|
+
command: "setLatestValue",
|
|
394
397
|
workspaceId,
|
|
395
|
-
|
|
398
|
+
value: testValue,
|
|
396
399
|
});
|
|
397
|
-
|
|
400
|
+
const updateEvents = await updateEventsPromise;
|
|
398
401
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
);
|
|
402
|
+
// Verify all events are from the expected attendee
|
|
403
|
+
for (const updateEvent of updateEvents) {
|
|
404
|
+
assert.strictEqual(updateEvent.attendeeId, containerCreatorAttendeeId);
|
|
405
|
+
assert.deepStrictEqual(updateEvent.value, testValue);
|
|
406
|
+
}
|
|
405
407
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
408
|
+
// Act - Request each remote client to read latest state from container creator
|
|
409
|
+
for (const child of remoteClients) {
|
|
410
|
+
child.send({
|
|
411
|
+
command: "getLatestValue",
|
|
412
|
+
workspaceId,
|
|
413
|
+
attendeeId: containerCreatorAttendeeId,
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
const getResponses = await getLatestValueResponses(
|
|
418
|
+
remoteClients,
|
|
419
|
+
workspaceId,
|
|
420
|
+
childErrorPromise,
|
|
421
|
+
getStateTimeoutMs,
|
|
422
|
+
);
|
|
423
|
+
|
|
424
|
+
// Verify - all responses should contain the expected value
|
|
425
|
+
for (const getResponse of getResponses) {
|
|
426
|
+
assert.deepStrictEqual(getResponse.value, testValue);
|
|
427
|
+
}
|
|
428
|
+
});
|
|
410
429
|
});
|
|
411
430
|
}
|
|
412
431
|
});
|
|
@@ -419,193 +438,211 @@ describe(`Presence with AzureClient`, () => {
|
|
|
419
438
|
/**
|
|
420
439
|
* Timeout for child processes to connect to container ({@link ConnectedEvent})
|
|
421
440
|
*/
|
|
422
|
-
const childConnectTimeoutMs = 1000 * numClients * timeoutMultiplier;
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
)
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
remoteClients,
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
);
|
|
441
|
+
const childConnectTimeoutMs = (4000 + 1000 * numClients) * timeoutMultiplier;
|
|
442
|
+
const testCaseTimeoutMs = 1000;
|
|
443
|
+
const testSetupAndActTimeoutMs = childConnectTimeoutMs + testCaseTimeoutMs;
|
|
444
|
+
|
|
445
|
+
// These tests use beforeEach to setup complex state that takes a lot of time
|
|
446
|
+
// and is dependent on number of clients. Keeping the work in beforeEach
|
|
447
|
+
// allows time reporting to report the tested scenario apart from the setup time.
|
|
448
|
+
// So this describe block isolates those beforeEach setups from each distinct
|
|
449
|
+
// client count. Test cases descriptions also have the client count for clarity.
|
|
450
|
+
describe(`with ${numClients} clients`, () => {
|
|
451
|
+
let children: ChildProcess[];
|
|
452
|
+
let childErrorPromise: Promise<never>;
|
|
453
|
+
let containerCreatorAttendeeId: AttendeeId;
|
|
454
|
+
let attendeeIdPromises: Promise<AttendeeId>[];
|
|
455
|
+
let remoteClients: ChildProcess[];
|
|
456
|
+
const workspaceId = "presenceTestWorkspace";
|
|
457
|
+
const key1 = "player1";
|
|
458
|
+
const key2 = "player2";
|
|
459
|
+
const value1 = { name: "Alice", score: 100 };
|
|
460
|
+
const value2 = { name: "Bob", score: 200 };
|
|
461
|
+
|
|
462
|
+
beforeEach(async function usingLatestMapStateObject_beforeEach(): Promise<void> {
|
|
463
|
+
const startTime = performance.now();
|
|
464
|
+
|
|
465
|
+
setTestTimeout(this, testSetupAndActTimeoutMs);
|
|
466
|
+
|
|
467
|
+
({ children, childErrorPromise } = await forkChildProcesses(
|
|
468
|
+
this.currentTest?.title ?? "",
|
|
469
|
+
numClients,
|
|
470
|
+
afterCleanUp,
|
|
471
|
+
));
|
|
472
|
+
({ containerCreatorAttendeeId, attendeeIdPromises } = await connectChildProcesses(
|
|
473
|
+
children,
|
|
474
|
+
{ writeClients: numClients, readyTimeoutMs: childConnectTimeoutMs },
|
|
475
|
+
));
|
|
476
|
+
await Promise.all(attendeeIdPromises);
|
|
477
|
+
remoteClients = children.filter((_, index) => index !== 0);
|
|
478
|
+
// NOTE: For testing purposes child clients will expect a LatestMap value of type Record<string, string | number> (StateFactory.latestMap<{ value: Record<string, string | number> }, string>).
|
|
479
|
+
await registerWorkspaceOnChildren(children, workspaceId, {
|
|
480
|
+
latestMap: true,
|
|
481
|
+
timeoutMs: workspaceRegisterTimeoutMs,
|
|
482
|
+
});
|
|
465
483
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
workspaceId,
|
|
470
|
-
key: testKey,
|
|
471
|
-
value: testValue,
|
|
484
|
+
testConsole.log(
|
|
485
|
+
` Setup for "${this.currentTest?.title}" completed in ${performance.now() - startTime}ms`,
|
|
486
|
+
);
|
|
472
487
|
});
|
|
473
|
-
const updateEvents = await updateEventsPromise;
|
|
474
488
|
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
489
|
+
it(`allows clients to read LatestMap values from other clients [${numClients} clients]`, async () => {
|
|
490
|
+
// Setup
|
|
491
|
+
const testKey = "cursor";
|
|
492
|
+
const testValue = { x: 150, y: 300 };
|
|
493
|
+
const updateEventsPromise = waitForLatestMapValueUpdates(
|
|
494
|
+
remoteClients,
|
|
495
|
+
workspaceId,
|
|
496
|
+
testKey,
|
|
497
|
+
childErrorPromise,
|
|
498
|
+
stateUpdateTimeoutMs,
|
|
499
|
+
{ fromAttendeeId: containerCreatorAttendeeId, expectedValue: testValue },
|
|
500
|
+
);
|
|
481
501
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
command: "
|
|
502
|
+
// Act
|
|
503
|
+
children[0].send({
|
|
504
|
+
command: "setLatestMapValue",
|
|
485
505
|
workspaceId,
|
|
486
506
|
key: testKey,
|
|
487
|
-
|
|
507
|
+
value: testValue,
|
|
488
508
|
});
|
|
489
|
-
|
|
490
|
-
const getResponses = await getLatestMapValueResponses(
|
|
491
|
-
remoteClients,
|
|
492
|
-
workspaceId,
|
|
493
|
-
testKey,
|
|
494
|
-
childErrorPromise,
|
|
495
|
-
getStateTimeoutMs,
|
|
496
|
-
);
|
|
509
|
+
const updateEvents = await updateEventsPromise;
|
|
497
510
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
511
|
+
// Check all events are from the expected attendee
|
|
512
|
+
for (const updateEvent of updateEvents) {
|
|
513
|
+
assert.strictEqual(updateEvent.attendeeId, containerCreatorAttendeeId);
|
|
514
|
+
assert.strictEqual(updateEvent.key, testKey);
|
|
515
|
+
assert.deepStrictEqual(updateEvent.value, testValue);
|
|
516
|
+
}
|
|
503
517
|
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
);
|
|
520
|
-
const key2UpdateEventsPromise = waitForLatestMapValueUpdates(
|
|
521
|
-
key2Recipients,
|
|
522
|
-
workspaceId,
|
|
523
|
-
key2,
|
|
524
|
-
childErrorPromise,
|
|
525
|
-
stateUpdateTimeoutMs,
|
|
526
|
-
{ fromAttendeeId: attendee1Id, expectedValue: value2 },
|
|
527
|
-
);
|
|
518
|
+
for (const child of remoteClients) {
|
|
519
|
+
child.send({
|
|
520
|
+
command: "getLatestMapValue",
|
|
521
|
+
workspaceId,
|
|
522
|
+
key: testKey,
|
|
523
|
+
attendeeId: containerCreatorAttendeeId,
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
const getResponses = await getLatestMapValueResponses(
|
|
527
|
+
remoteClients,
|
|
528
|
+
workspaceId,
|
|
529
|
+
testKey,
|
|
530
|
+
childErrorPromise,
|
|
531
|
+
getStateTimeoutMs,
|
|
532
|
+
);
|
|
528
533
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
key: key1,
|
|
534
|
-
value: value1,
|
|
535
|
-
});
|
|
536
|
-
const key1UpdateEvents = await key1UpdateEventsPromise;
|
|
537
|
-
children[1].send({
|
|
538
|
-
command: "setLatestMapValue",
|
|
539
|
-
workspaceId,
|
|
540
|
-
key: key2,
|
|
541
|
-
value: value2,
|
|
534
|
+
// Verify
|
|
535
|
+
for (const getResponse of getResponses) {
|
|
536
|
+
assert.deepStrictEqual(getResponse.value, testValue);
|
|
537
|
+
}
|
|
542
538
|
});
|
|
543
|
-
const key2UpdateEvents = await key2UpdateEventsPromise;
|
|
544
539
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
}
|
|
551
|
-
for (const updateEvent of key2UpdateEvents) {
|
|
552
|
-
assert.strictEqual(updateEvent.attendeeId, attendee1Id);
|
|
553
|
-
assert.strictEqual(updateEvent.key, key2);
|
|
554
|
-
assert.deepStrictEqual(updateEvent.value, value2);
|
|
555
|
-
}
|
|
540
|
+
it(`returns per-key values on read [${numClients} clients]`, async function () {
|
|
541
|
+
// Setup
|
|
542
|
+
const allAttendeeIds = await Promise.all(attendeeIdPromises);
|
|
543
|
+
const attendee0Id = containerCreatorAttendeeId;
|
|
544
|
+
const attendee1Id = allAttendeeIds[1];
|
|
556
545
|
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
546
|
+
const key1Recipients = children.filter((_, index) => index !== 0);
|
|
547
|
+
const key2Recipients = children.filter((_, index) => index !== 1);
|
|
548
|
+
const key1UpdateEventsPromise = waitForLatestMapValueUpdates(
|
|
549
|
+
key1Recipients,
|
|
550
|
+
workspaceId,
|
|
551
|
+
key1,
|
|
552
|
+
childErrorPromise,
|
|
553
|
+
stateUpdateTimeoutMs,
|
|
554
|
+
{ fromAttendeeId: attendee0Id, expectedValue: value1 },
|
|
555
|
+
);
|
|
556
|
+
const key2UpdateEventsPromise = waitForLatestMapValueUpdates(
|
|
557
|
+
key2Recipients,
|
|
558
|
+
workspaceId,
|
|
559
|
+
key2,
|
|
560
|
+
childErrorPromise,
|
|
561
|
+
stateUpdateTimeoutMs,
|
|
562
|
+
{ fromAttendeeId: attendee1Id, expectedValue: value2 },
|
|
563
|
+
);
|
|
564
|
+
|
|
565
|
+
// Act
|
|
566
|
+
children[0].send({
|
|
567
|
+
command: "setLatestMapValue",
|
|
561
568
|
workspaceId,
|
|
562
569
|
key: key1,
|
|
563
|
-
|
|
570
|
+
value: value1,
|
|
564
571
|
});
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
workspaceId,
|
|
569
|
-
key1,
|
|
570
|
-
childErrorPromise,
|
|
571
|
-
getStateTimeoutMs,
|
|
572
|
-
);
|
|
573
|
-
|
|
574
|
-
// Read key2 of attendee1 from all children
|
|
575
|
-
for (const child of children) {
|
|
576
|
-
child.send({
|
|
577
|
-
command: "getLatestMapValue",
|
|
572
|
+
const key1UpdateEvents = await key1UpdateEventsPromise;
|
|
573
|
+
children[1].send({
|
|
574
|
+
command: "setLatestMapValue",
|
|
578
575
|
workspaceId,
|
|
579
576
|
key: key2,
|
|
580
|
-
|
|
577
|
+
value: value2,
|
|
581
578
|
});
|
|
582
|
-
|
|
583
|
-
const key2Responses = await getLatestMapValueResponses(
|
|
584
|
-
children,
|
|
585
|
-
workspaceId,
|
|
586
|
-
key2,
|
|
587
|
-
childErrorPromise,
|
|
588
|
-
getStateTimeoutMs,
|
|
589
|
-
);
|
|
579
|
+
const key2UpdateEvents = await key2UpdateEventsPromise;
|
|
590
580
|
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
581
|
+
// Verify all events are from the expected attendees
|
|
582
|
+
for (const updateEvent of key1UpdateEvents) {
|
|
583
|
+
assert.strictEqual(updateEvent.attendeeId, attendee0Id);
|
|
584
|
+
assert.strictEqual(updateEvent.key, key1);
|
|
585
|
+
assert.deepStrictEqual(updateEvent.value, value1);
|
|
586
|
+
}
|
|
587
|
+
for (const updateEvent of key2UpdateEvents) {
|
|
588
|
+
assert.strictEqual(updateEvent.attendeeId, attendee1Id);
|
|
589
|
+
assert.strictEqual(updateEvent.key, key2);
|
|
590
|
+
assert.deepStrictEqual(updateEvent.value, value2);
|
|
591
|
+
}
|
|
602
592
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
593
|
+
// Read key1 of attendee0 from all children
|
|
594
|
+
for (const child of children) {
|
|
595
|
+
child.send({
|
|
596
|
+
command: "getLatestMapValue",
|
|
597
|
+
workspaceId,
|
|
598
|
+
key: key1,
|
|
599
|
+
attendeeId: attendee0Id,
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
const key1Responses = await getLatestMapValueResponses(
|
|
603
|
+
children,
|
|
604
|
+
workspaceId,
|
|
605
|
+
key1,
|
|
606
|
+
childErrorPromise,
|
|
607
|
+
getStateTimeoutMs,
|
|
608
|
+
);
|
|
609
|
+
|
|
610
|
+
// Read key2 of attendee1 from all children
|
|
611
|
+
for (const child of children) {
|
|
612
|
+
child.send({
|
|
613
|
+
command: "getLatestMapValue",
|
|
614
|
+
workspaceId,
|
|
615
|
+
key: key2,
|
|
616
|
+
attendeeId: attendee1Id,
|
|
617
|
+
});
|
|
618
|
+
}
|
|
619
|
+
const key2Responses = await getLatestMapValueResponses(
|
|
620
|
+
children,
|
|
621
|
+
workspaceId,
|
|
622
|
+
key2,
|
|
623
|
+
childErrorPromise,
|
|
624
|
+
getStateTimeoutMs,
|
|
625
|
+
);
|
|
626
|
+
|
|
627
|
+
// Verify
|
|
628
|
+
assert.strictEqual(
|
|
629
|
+
key1Responses.length,
|
|
630
|
+
numClients,
|
|
631
|
+
"Expected responses from all clients for key1",
|
|
632
|
+
);
|
|
633
|
+
assert.strictEqual(
|
|
634
|
+
key2Responses.length,
|
|
635
|
+
numClients,
|
|
636
|
+
"Expected responses from all clients for key2",
|
|
637
|
+
);
|
|
638
|
+
|
|
639
|
+
for (const response of key1Responses) {
|
|
640
|
+
assert.deepStrictEqual(response.value, value1, "Key1 value should match");
|
|
641
|
+
}
|
|
642
|
+
for (const response of key2Responses) {
|
|
643
|
+
assert.deepStrictEqual(response.value, value2, "Key2 value should match");
|
|
644
|
+
}
|
|
645
|
+
});
|
|
609
646
|
});
|
|
610
647
|
}
|
|
611
648
|
});
|