@fluidframework/azure-end-to-end-tests 2.61.0-355990 → 2.61.0-356312
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.
|
@@ -89,6 +89,10 @@ describe(`Presence with AzureClient`, () => {
|
|
|
89
89
|
const allAttendeesJoinedTimeoutMs = (1000 + 200 * numClients) * timeoutMultiplier;
|
|
90
90
|
for (const writeClients of [numClients, 1]) {
|
|
91
91
|
it(`announces 'attendeeConnected' when remote client joins session [${numClients} clients, ${writeClients} writers]`, async function () {
|
|
92
|
+
// AB#48866: Fix intermittently failing presence tests
|
|
93
|
+
if (useAzure) {
|
|
94
|
+
this.skip();
|
|
95
|
+
}
|
|
92
96
|
setTimeout(this, childConnectTimeoutMs + allAttendeesJoinedTimeoutMs + 1000);
|
|
93
97
|
// Setup
|
|
94
98
|
const { children, childErrorPromise } = await forkChildProcesses(numClients, afterCleanUp);
|
|
@@ -101,6 +105,10 @@ describe(`Presence with AzureClient`, () => {
|
|
|
101
105
|
}, childErrorPromise);
|
|
102
106
|
});
|
|
103
107
|
it(`announces 'attendeeDisconnected' when remote client disconnects [${numClients} clients, ${writeClients} writers]`, async function () {
|
|
108
|
+
// AB#48866: Fix intermittently failing presence tests
|
|
109
|
+
if (useAzure) {
|
|
110
|
+
this.skip();
|
|
111
|
+
}
|
|
104
112
|
// TODO: AB#45620: "Presence: perf: update Join pattern for scale" can handle
|
|
105
113
|
// larger counts of read-only attendees. Without protocol changes tests with
|
|
106
114
|
// 20+ attendees exceed current limits.
|
|
@@ -195,7 +203,11 @@ describe(`Presence with AzureClient`, () => {
|
|
|
195
203
|
timeoutMs: workspaceRegisterTimeoutMs,
|
|
196
204
|
});
|
|
197
205
|
});
|
|
198
|
-
it(`allows clients to read Latest state from other clients [${numClients} clients]`, async ()
|
|
206
|
+
it(`allows clients to read Latest state from other clients [${numClients} clients]`, async function () {
|
|
207
|
+
// AB#48866: Fix intermittently failing presence tests
|
|
208
|
+
if (useAzure) {
|
|
209
|
+
this.skip();
|
|
210
|
+
}
|
|
199
211
|
// Setup
|
|
200
212
|
const updateEventsPromise = waitForLatestValueUpdates(remoteClients, workspaceId, childErrorPromise, stateUpdateTimeoutMs, { fromAttendeeId: containerCreatorAttendeeId, expectedValue: testValue });
|
|
201
213
|
// Act - Trigger the update
|
|
@@ -289,7 +301,11 @@ describe(`Presence with AzureClient`, () => {
|
|
|
289
301
|
assert.deepStrictEqual(getResponse.value, testValue);
|
|
290
302
|
}
|
|
291
303
|
});
|
|
292
|
-
it(`returns per-key values on read [${numClients} clients]`, async ()
|
|
304
|
+
it(`returns per-key values on read [${numClients} clients]`, async function () {
|
|
305
|
+
// AB#48866: Fix intermittently failing presence tests
|
|
306
|
+
if (useAzure) {
|
|
307
|
+
this.skip();
|
|
308
|
+
}
|
|
293
309
|
// Setup
|
|
294
310
|
const allAttendeeIds = await Promise.all(attendeeIdPromises);
|
|
295
311
|
const attendee0Id = containerCreatorAttendeeId;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presenceTest.spec.js","sourceRoot":"","sources":["../../../src/test/multiprocess/presenceTest.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,SAAS,MAAM,gBAAgB,CAAC;AAGvC,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAGnF,OAAO,EACN,4BAA4B,EAC5B,0BAA0B,EAC1B,qBAAqB,EACrB,kBAAkB,EAClB,0BAA0B,EAC1B,uBAAuB,EACvB,2BAA2B,EAC3B,WAAW,EACX,4BAA4B,EAC5B,yBAAyB,GACzB,MAAM,wBAAwB,CAAC;AAEhC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,OAAO,CAAC;AAEtD;;GAEG;AACH,MAAM,gBAAgB,GAAG,SAAS,CAAC,GAAG,EAAE,KAAK,SAAS,CAAC;AAEvD;;GAEG;AACH,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAErE;;;;;;;;;GASG;AACH,SAAS,UAAU,CAAC,OAAsB,EAAE,QAAgB;IAC3D,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IACzC,MAAM,UAAU,GACf,gBAAgB,IAAI,cAAc,KAAK,CAAC,IAAI,QAAQ,KAAK,CAAC;QACzD,CAAC,CAAC,CAAC;QACH,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;IACvC,IAAI,UAAU,KAAK,cAAc,EAAE,CAAC;QACnC,WAAW,CAAC,GAAG,CACd,GAAG,OAAO,CAAC,IAAI,EAAE,KAAK,wBAAwB,UAAU,WAAW,cAAc,KAAK,CACtF,CAAC;QACF,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7B,CAAC;AACF,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;;GAIG;AACH,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IAC1C,MAAM,YAAY,GAAmB,EAAE,CAAC;IAExC,6FAA6F;IAC7F,SAAS,CAAC,KAAK,IAAI,EAAE;QACpB,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;YACpC,OAAO,EAAE,CAAC;QACX,CAAC;QACD,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,qEAAqE;IACrE,MAAM,0BAA0B,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;IACpD,gGAAgG;IAChG,KAAK,MAAM,UAAU,IAAI,0BAA0B,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QACjE,MAAM,CAAC,UAAU,GAAG,CAAC,EAAE,gCAAgC,CAAC,CAAC;QACzD;;WAEG;QACH,MAAM,qBAAqB,GAAG,IAAI,GAAG,UAAU,GAAG,iBAAiB,CAAC;QACpE;;WAEG;QACH,MAAM,2BAA2B,GAAG,CAAC,IAAI,GAAG,GAAG,GAAG,UAAU,CAAC,GAAG,iBAAiB,CAAC;QAElF,KAAK,MAAM,YAAY,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC;YAC5C,EAAE,CAAC,mEAAmE,UAAU,aAAa,YAAY,WAAW,EAAE,KAAK;gBAC1H,UAAU,CAAC,IAAI,EAAE,qBAAqB,GAAG,2BAA2B,GAAG,IAAI,CAAC,CAAC;gBAE7E,QAAQ;gBACR,MAAM,EAAE,QAAQ,EAAE,iBAAiB,EAAE,GAAG,MAAM,kBAAkB,CAC/D,UAAU,EACV,YAAY,CACZ,CAAC;gBAEF,oCAAoC;gBACpC,MAAM,0BAA0B,CAC/B,QAAQ,EACR;oBACC,YAAY;oBACZ,qBAAqB,EAAE,UAAU,GAAG,CAAC;oBACrC,qBAAqB;oBACrB,2BAA2B;iBAC3B,EACD,iBAAiB,CACjB,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,oEAAoE,UAAU,aAAa,YAAY,WAAW,EAAE,KAAK;gBAC3H,6EAA6E;gBAC7E,4EAA4E;gBAC5E,uCAAuC;gBACvC,IAAI,UAAU,IAAI,EAAE,IAAI,YAAY,KAAK,CAAC,EAAE,CAAC;oBAC5C,IAAI,CAAC,IAAI,EAAE,CAAC;gBACb,CAAC;gBAED,MAAM,wBAAwB,GAAG,MAAM,GAAG,iBAAiB,CAAC;gBAE5D,UAAU,CACT,IAAI,EACJ,qBAAqB;oBACpB,2BAA2B;oBAC3B,wBAAwB;oBACxB,IAAI,CACL,CAAC;gBAEF,QAAQ;gBACR,MAAM,EAAE,QAAQ,EAAE,iBAAiB,EAAE,GAAG,MAAM,kBAAkB,CAC/D,UAAU,EACV,YAAY,CACZ,CAAC;gBAEF,MAAM,aAAa,GAAG,MAAM,4BAA4B,CAAC,QAAQ,EAAE;oBAClE,YAAY;oBACZ,qBAAqB,EAAE,UAAU,GAAG,CAAC;oBACrC,qBAAqB;iBACrB,CAAC,CAAC;gBAEH,4CAA4C;gBAC5C,iCAAiC;gBACjC,IAAI,mBAAmB,GAAG,CAAC,CAAC;gBAC5B,MAAM,uBAAuB,GAAG,OAAO,CAAC,GAAG;gBAC1C,qEAAqE;gBACrE,aAAa,CAAC,6BAA6B,CAAC,GAAG,CAAC,CAAC,0BAA0B,EAAE,EAAE,CAC9E,0BAA0B,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,mBAAmB,EAAE,CAAC,CAC5D,CACD,CAAC;gBACF,MAAM,YAAY,CAAC,uBAAuB,EAAE;oBAC3C,UAAU,EAAE,2BAA2B;oBACvC,QAAQ,EAAE,gCAAgC;iBAC1C,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;oBAClB,gFAAgF;oBAChF,uEAAuE;oBACvE,WAAW,CAAC,GAAG,CAAC,GAAG,mBAAmB,yCAAyC,CAAC,CAAC;oBACjF,MAAM,KAAK,CAAC;gBACb,CAAC,CAAC,CAAC;gBAEH,MAAM,mBAAmB,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAC/D,KAAK,KAAK,CAAC;oBACV,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE;oBACnB,CAAC,CAAC,cAAc,CACd,CAAC,OAAO,EAAE,EAAE;wBACX,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAqB,EAAE,EAAE;4BAC7C,IACC,GAAG,CAAC,KAAK,KAAK,sBAAsB;gCACpC,GAAG,CAAC,UAAU,KAAK,aAAa,CAAC,0BAA0B,EAC1D,CAAC;gCACF,OAAO,CAAC,GAAG,CAAC,SAAS,KAAK,0BAA0B,CAAC,CAAC;gCACtD,OAAO,EAAE,CAAC;4BACX,CAAC;wBACF,CAAC,CAAC,CAAC;oBACJ,CAAC,EACD;wBACC,UAAU,EAAE,wBAAwB;wBACpC,QAAQ,EAAE,YAAY,KAAK,wBAAwB;qBACnD,CACD,CACH,CAAC;gBAEF,uCAAuC;gBACvC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC,CAAC;gBAEhD,sDAAsD;gBACtD,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC;YAC3E,CAAC,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;IAED,CAAC;QACA;;WAEG;QACH,MAAM,0BAA0B,GAAG,IAAI,CAAC;QACxC;;WAEG;QACH,MAAM,oBAAoB,GAAG,IAAI,CAAC;QAClC;;WAEG;QACH,MAAM,iBAAiB,GAAG,IAAI,CAAC;QAE/B,kFAAkF;QAClF,sFAAsF;QACtF,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;YAC1C,KAAK,MAAM,UAAU,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;gBAClC,MAAM,CAAC,UAAU,GAAG,CAAC,EAAE,gCAAgC,CAAC,CAAC;gBACzD;;mBAEG;gBACH,MAAM,qBAAqB,GAAG,IAAI,GAAG,UAAU,GAAG,iBAAiB,CAAC;gBAEpE,IAAI,QAAwB,CAAC;gBAC7B,IAAI,iBAAiC,CAAC;gBACtC,IAAI,0BAAsC,CAAC;gBAC3C,IAAI,kBAAyC,CAAC;gBAC9C,IAAI,aAA6B,CAAC;gBAClC,MAAM,SAAS,GAAG,WAAW,CAAC;gBAC9B,MAAM,WAAW,GAAG,uBAAuB,CAAC;gBAE5C,UAAU,CAAC,KAAK,IAAI,EAAE;oBACrB,CAAC,EAAE,QAAQ,EAAE,iBAAiB,EAAE,GAAG,MAAM,kBAAkB,CAC1D,UAAU,EACV,YAAY,CACZ,CAAC,CAAC;oBACH,CAAC,EAAE,0BAA0B,EAAE,kBAAkB,EAAE,GAAG,MAAM,qBAAqB,CAChF,QAAQ,EACR,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,qBAAqB,EAAE,CACnE,CAAC,CAAC;oBACH,MAAM,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;oBACtC,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;oBAC3D,+HAA+H;oBAC/H,MAAM,2BAA2B,CAAC,QAAQ,EAAE,WAAW,EAAE;wBACxD,MAAM,EAAE,IAAI;wBACZ,SAAS,EAAE,0BAA0B;qBACrC,CAAC,CAAC;gBACJ,CAAC,CAAC,CAAC;gBAEH,EAAE,CAAC,2DAA2D,UAAU,WAAW,EAAE,KAAK,IAAI,EAAE;oBAC/F,QAAQ;oBACR,MAAM,mBAAmB,GAAG,yBAAyB,CACpD,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,oBAAoB,EACpB,EAAE,cAAc,EAAE,0BAA0B,EAAE,aAAa,EAAE,SAAS,EAAE,CACxE,CAAC;oBAEF,2BAA2B;oBAC3B,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;wBAChB,OAAO,EAAE,gBAAgB;wBACzB,WAAW;wBACX,KAAK,EAAE,SAAS;qBAChB,CAAC,CAAC;oBACH,MAAM,YAAY,GAAG,MAAM,mBAAmB,CAAC;oBAE/C,mDAAmD;oBACnD,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;wBACxC,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,UAAU,EAAE,0BAA0B,CAAC,CAAC;wBACvE,MAAM,CAAC,eAAe,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;oBACtD,CAAC;oBAED,+EAA+E;oBAC/E,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;wBACnC,KAAK,CAAC,IAAI,CAAC;4BACV,OAAO,EAAE,gBAAgB;4BACzB,WAAW;4BACX,UAAU,EAAE,0BAA0B;yBACtC,CAAC,CAAC;oBACJ,CAAC;oBAED,MAAM,YAAY,GAAG,MAAM,uBAAuB,CACjD,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,iBAAiB,CACjB,CAAC;oBAEF,2DAA2D;oBAC3D,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;wBACxC,MAAM,CAAC,eAAe,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;oBACtD,CAAC;gBACF,CAAC,CAAC,CAAC;YACJ,CAAC;QACF,CAAC,CAAC,CAAC;QAEH,qFAAqF;QACrF,kHAAkH;QAClH,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;YAC7C,KAAK,MAAM,UAAU,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;gBAClC,MAAM,CAAC,UAAU,GAAG,CAAC,EAAE,gCAAgC,CAAC,CAAC;gBACzD;;mBAEG;gBACH,MAAM,qBAAqB,GAAG,IAAI,GAAG,UAAU,GAAG,iBAAiB,CAAC;gBAEpE,IAAI,QAAwB,CAAC;gBAC7B,IAAI,iBAAiC,CAAC;gBACtC,IAAI,0BAAsC,CAAC;gBAC3C,IAAI,kBAAyC,CAAC;gBAC9C,IAAI,aAA6B,CAAC;gBAClC,MAAM,WAAW,GAAG,uBAAuB,CAAC;gBAC5C,MAAM,IAAI,GAAG,SAAS,CAAC;gBACvB,MAAM,IAAI,GAAG,SAAS,CAAC;gBACvB,MAAM,MAAM,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;gBAC7C,MAAM,MAAM,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;gBAE3C,UAAU,CAAC,KAAK,IAAI,EAAE;oBACrB,CAAC,EAAE,QAAQ,EAAE,iBAAiB,EAAE,GAAG,MAAM,kBAAkB,CAC1D,UAAU,EACV,YAAY,CACZ,CAAC,CAAC;oBACH,CAAC,EAAE,0BAA0B,EAAE,kBAAkB,EAAE,GAAG,MAAM,qBAAqB,CAChF,QAAQ,EACR,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,qBAAqB,EAAE,CACnE,CAAC,CAAC;oBACH,MAAM,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;oBACtC,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;oBAC3D,+LAA+L;oBAC/L,MAAM,2BAA2B,CAAC,QAAQ,EAAE,WAAW,EAAE;wBACxD,SAAS,EAAE,IAAI;wBACf,SAAS,EAAE,0BAA0B;qBACrC,CAAC,CAAC;gBACJ,CAAC,CAAC,CAAC;gBAEH,EAAE,CAAC,+DAA+D,UAAU,WAAW,EAAE,KAAK,IAAI,EAAE;oBACnG,QAAQ;oBACR,MAAM,OAAO,GAAG,QAAQ,CAAC;oBACzB,MAAM,SAAS,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC;oBACrC,MAAM,mBAAmB,GAAG,4BAA4B,CACvD,aAAa,EACb,WAAW,EACX,OAAO,EACP,iBAAiB,EACjB,oBAAoB,EACpB,EAAE,cAAc,EAAE,0BAA0B,EAAE,aAAa,EAAE,SAAS,EAAE,CACxE,CAAC;oBAEF,MAAM;oBACN,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;wBAChB,OAAO,EAAE,mBAAmB;wBAC5B,WAAW;wBACX,GAAG,EAAE,OAAO;wBACZ,KAAK,EAAE,SAAS;qBAChB,CAAC,CAAC;oBACH,MAAM,YAAY,GAAG,MAAM,mBAAmB,CAAC;oBAE/C,kDAAkD;oBAClD,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;wBACxC,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,UAAU,EAAE,0BAA0B,CAAC,CAAC;wBACvE,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;wBAC7C,MAAM,CAAC,eAAe,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;oBACtD,CAAC;oBAED,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;wBACnC,KAAK,CAAC,IAAI,CAAC;4BACV,OAAO,EAAE,mBAAmB;4BAC5B,WAAW;4BACX,GAAG,EAAE,OAAO;4BACZ,UAAU,EAAE,0BAA0B;yBACtC,CAAC,CAAC;oBACJ,CAAC;oBACD,MAAM,YAAY,GAAG,MAAM,0BAA0B,CACpD,aAAa,EACb,WAAW,EACX,OAAO,EACP,iBAAiB,EACjB,iBAAiB,CACjB,CAAC;oBAEF,SAAS;oBACT,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;wBACxC,MAAM,CAAC,eAAe,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;oBACtD,CAAC;gBACF,CAAC,CAAC,CAAC;gBAEH,EAAE,CAAC,mCAAmC,UAAU,WAAW,EAAE,KAAK,IAAI,EAAE;oBACvE,QAAQ;oBACR,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;oBAC7D,MAAM,WAAW,GAAG,0BAA0B,CAAC;oBAC/C,MAAM,WAAW,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;oBAEtC,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;oBAClE,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;oBAClE,MAAM,uBAAuB,GAAG,4BAA4B,CAC3D,cAAc,EACd,WAAW,EACX,IAAI,EACJ,iBAAiB,EACjB,oBAAoB,EACpB,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,EAAE,CACtD,CAAC;oBACF,MAAM,uBAAuB,GAAG,4BAA4B,CAC3D,cAAc,EACd,WAAW,EACX,IAAI,EACJ,iBAAiB,EACjB,oBAAoB,EACpB,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,EAAE,CACtD,CAAC;oBAEF,MAAM;oBACN,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;wBAChB,OAAO,EAAE,mBAAmB;wBAC5B,WAAW;wBACX,GAAG,EAAE,IAAI;wBACT,KAAK,EAAE,MAAM;qBACb,CAAC,CAAC;oBACH,MAAM,gBAAgB,GAAG,MAAM,uBAAuB,CAAC;oBACvD,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;wBAChB,OAAO,EAAE,mBAAmB;wBAC5B,WAAW;wBACX,GAAG,EAAE,IAAI;wBACT,KAAK,EAAE,MAAM;qBACb,CAAC,CAAC;oBACH,MAAM,gBAAgB,GAAG,MAAM,uBAAuB,CAAC;oBAEvD,oDAAoD;oBACpD,KAAK,MAAM,WAAW,IAAI,gBAAgB,EAAE,CAAC;wBAC5C,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;wBACxD,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;wBAC1C,MAAM,CAAC,eAAe,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;oBACnD,CAAC;oBACD,KAAK,MAAM,WAAW,IAAI,gBAAgB,EAAE,CAAC;wBAC5C,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;wBACxD,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;wBAC1C,MAAM,CAAC,eAAe,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;oBACnD,CAAC;oBAED,2CAA2C;oBAC3C,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;wBAC9B,KAAK,CAAC,IAAI,CAAC;4BACV,OAAO,EAAE,mBAAmB;4BAC5B,WAAW;4BACX,GAAG,EAAE,IAAI;4BACT,UAAU,EAAE,WAAW;yBACvB,CAAC,CAAC;oBACJ,CAAC;oBACD,MAAM,aAAa,GAAG,MAAM,0BAA0B,CACrD,QAAQ,EACR,WAAW,EACX,IAAI,EACJ,iBAAiB,EACjB,iBAAiB,CACjB,CAAC;oBAEF,2CAA2C;oBAC3C,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;wBAC9B,KAAK,CAAC,IAAI,CAAC;4BACV,OAAO,EAAE,mBAAmB;4BAC5B,WAAW;4BACX,GAAG,EAAE,IAAI;4BACT,UAAU,EAAE,WAAW;yBACvB,CAAC,CAAC;oBACJ,CAAC;oBACD,MAAM,aAAa,GAAG,MAAM,0BAA0B,CACrD,QAAQ,EACR,WAAW,EACX,IAAI,EACJ,iBAAiB,EACjB,iBAAiB,CACjB,CAAC;oBAEF,SAAS;oBACT,MAAM,CAAC,WAAW,CACjB,aAAa,CAAC,MAAM,EACpB,UAAU,EACV,8CAA8C,CAC9C,CAAC;oBACF,MAAM,CAAC,WAAW,CACjB,aAAa,CAAC,MAAM,EACpB,UAAU,EACV,8CAA8C,CAC9C,CAAC;oBAEF,KAAK,MAAM,QAAQ,IAAI,aAAa,EAAE,CAAC;wBACtC,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,yBAAyB,CAAC,CAAC;oBAC3E,CAAC;oBACD,KAAK,MAAM,QAAQ,IAAI,aAAa,EAAE,CAAC;wBACtC,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,yBAAyB,CAAC,CAAC;oBAC3E,CAAC;gBACF,CAAC,CAAC,CAAC;YACJ,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;AACF,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\nimport type { ChildProcess } from \"node:child_process\";\nimport inspector from \"node:inspector\";\n\nimport type { AttendeeId } from \"@fluidframework/presence/beta\";\nimport { timeoutAwait, timeoutPromise } from \"@fluidframework/test-utils/internal\";\n\nimport type { MessageFromChild } from \"./messageTypes.js\";\nimport {\n\tconnectAndListenForAttendees,\n\tconnectAndWaitForAttendees,\n\tconnectChildProcesses,\n\tforkChildProcesses,\n\tgetLatestMapValueResponses,\n\tgetLatestValueResponses,\n\tregisterWorkspaceOnChildren,\n\ttestConsole,\n\twaitForLatestMapValueUpdates,\n\twaitForLatestValueUpdates,\n} from \"./orchestratorUtils.js\";\n\nconst useAzure = process.env.FLUID_CLIENT === \"azure\";\n\n/**\n * Detects if the debugger is attached (when code loaded).\n */\nconst debuggerAttached = inspector.url() !== undefined;\n\n/**\n * Set this to a high number when debugging to avoid timeouts from debugging time.\n */\nconst timeoutMultiplier = debuggerAttached ? 1000 : useAzure ? 3 : 1;\n\n/**\n * Sets the timeout for the given test context.\n *\n * @remarks\n * If a debugger is attached, the timeout is set to 0 to prevent timeouts during debugging.\n * Otherwise, it sets the timeout to the maximum of the current timeout and the specified duration.\n *\n * @param context - The Mocha test context.\n * @param duration - The duration in milliseconds to set the timeout to. Zero disables the timeout.\n */\nfunction setTimeout(context: Mocha.Context, duration: number): void {\n\tconst currentTimeout = context.timeout();\n\tconst newTimeout =\n\t\tdebuggerAttached || currentTimeout === 0 || duration === 0\n\t\t\t? 0\n\t\t\t: Math.max(currentTimeout, duration);\n\tif (newTimeout !== currentTimeout) {\n\t\ttestConsole.log(\n\t\t\t`${context.test?.title}: setting timeout to ${newTimeout}ms (was ${currentTimeout}ms)`,\n\t\t);\n\t\tcontext.timeout(newTimeout);\n\t}\n}\n\n/**\n * This test suite is a prototype for a multi-process end to end test for Fluid using the new Presence API on AzureClient.\n * In the future we hope to expand and generalize this pattern to broadly test more Fluid features.\n * Other E2E tests are limited to running multiple clients on a single process which does not effectively\n * simulate real-world production scenarios where clients are usually running on different machines. Since\n * the Fluid Framework client is designed to carry most of the work burden, multi-process testing from a\n * single machine is also not representative but does at least work past some limitations of a single\n * Node.js process handling multiple clients.\n *\n * The pattern demonstrated in this test suite is as follows:\n *\n * This main test file acts as the 'Orchestrator'. The orchestrator's job includes:\n * - Fork child processes to simulate multiple Fluid clients\n * - Send command messages to child clients to perform specific Fluid actions.\n * - Receive response messages from child clients to verify expected behavior.\n * - Clean up child processes after each test.\n *\n * The child processes are located in the `childClient.tool.ts` file. Each child process simulates a Fluid client.\n *\n * The child client's job includes:\n * - Create/Get + connect to Fluid container.\n * - Listen for command messages from the orchestrator.\n * - Perform the requested action.\n * - Send response messages including any relevant data back to the orchestrator to verify expected behavior.\n */\n\n/**\n * This particular test suite tests the following E2E functionality for Presence:\n * - Announce 'attendeeConnected' when remote client joins session.\n * - Announce 'attendeeDisconnected' when remote client disconnects.\n */\ndescribe(`Presence with AzureClient`, () => {\n\tconst afterCleanUp: (() => void)[] = [];\n\n\t// After each test, call any cleanup functions that were registered (kill each child process)\n\tafterEach(async () => {\n\t\tfor (const cleanUp of afterCleanUp) {\n\t\t\tcleanUp();\n\t\t}\n\t\tafterCleanUp.length = 0;\n\t});\n\n\t// Note that on slower systems 50+ clients may take too long to join.\n\tconst numClientsForAttendeeTests = [5, 20, 50, 100];\n\t// TODO: AB#45620: \"Presence: perf: update Join pattern for scale\" may help, then remove .slice.\n\tfor (const numClients of numClientsForAttendeeTests.slice(0, 2)) {\n\t\tassert(numClients > 1, \"Must have at least two clients\");\n\t\t/**\n\t\t * Timeout for child processes to connect to container ({@link ConnectedEvent})\n\t\t */\n\t\tconst childConnectTimeoutMs = 1000 * numClients * timeoutMultiplier;\n\t\t/**\n\t\t * Timeout for presence attendees to connect {@link AttendeeConnectedEvent}\n\t\t */\n\t\tconst allAttendeesJoinedTimeoutMs = (1000 + 200 * numClients) * timeoutMultiplier;\n\n\t\tfor (const writeClients of [numClients, 1]) {\n\t\t\tit(`announces 'attendeeConnected' when remote client joins session [${numClients} clients, ${writeClients} writers]`, async function () {\n\t\t\t\tsetTimeout(this, childConnectTimeoutMs + allAttendeesJoinedTimeoutMs + 1000);\n\n\t\t\t\t// Setup\n\t\t\t\tconst { children, childErrorPromise } = await forkChildProcesses(\n\t\t\t\t\tnumClients,\n\t\t\t\t\tafterCleanUp,\n\t\t\t\t);\n\n\t\t\t\t// Further Setup with Act and Verify\n\t\t\t\tawait connectAndWaitForAttendees(\n\t\t\t\t\tchildren,\n\t\t\t\t\t{\n\t\t\t\t\t\twriteClients,\n\t\t\t\t\t\tattendeeCountRequired: numClients - 1,\n\t\t\t\t\t\tchildConnectTimeoutMs,\n\t\t\t\t\t\tallAttendeesJoinedTimeoutMs,\n\t\t\t\t\t},\n\t\t\t\t\tchildErrorPromise,\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tit(`announces 'attendeeDisconnected' when remote client disconnects [${numClients} clients, ${writeClients} writers]`, async function () {\n\t\t\t\t// TODO: AB#45620: \"Presence: perf: update Join pattern for scale\" can handle\n\t\t\t\t// larger counts of read-only attendees. Without protocol changes tests with\n\t\t\t\t// 20+ attendees exceed current limits.\n\t\t\t\tif (numClients >= 20 && writeClients === 1) {\n\t\t\t\t\tthis.skip();\n\t\t\t\t}\n\n\t\t\t\tconst childDisconnectTimeoutMs = 10_000 * timeoutMultiplier;\n\n\t\t\t\tsetTimeout(\n\t\t\t\t\tthis,\n\t\t\t\t\tchildConnectTimeoutMs +\n\t\t\t\t\t\tallAttendeesJoinedTimeoutMs +\n\t\t\t\t\t\tchildDisconnectTimeoutMs +\n\t\t\t\t\t\t1000,\n\t\t\t\t);\n\n\t\t\t\t// Setup\n\t\t\t\tconst { children, childErrorPromise } = await forkChildProcesses(\n\t\t\t\t\tnumClients,\n\t\t\t\t\tafterCleanUp,\n\t\t\t\t);\n\n\t\t\t\tconst connectResult = await connectAndListenForAttendees(children, {\n\t\t\t\t\twriteClients,\n\t\t\t\t\tattendeeCountRequired: numClients - 1,\n\t\t\t\t\tchildConnectTimeoutMs,\n\t\t\t\t});\n\n\t\t\t\t// Wait for all attendees to be fully joined\n\t\t\t\t// Keep a tally for debuggability\n\t\t\t\tlet childrenFullyJoined = 0;\n\t\t\t\tconst allAttendeesFullyJoined = Promise.all(\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\t\t\t\t\tconnectResult.attendeeCountRequiredPromises.map((attendeeFullyJoinedPromise) =>\n\t\t\t\t\t\tattendeeFullyJoinedPromise.then(() => childrenFullyJoined++),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tawait timeoutAwait(allAttendeesFullyJoined, {\n\t\t\t\t\tdurationMs: allAttendeesJoinedTimeoutMs,\n\t\t\t\t\terrorMsg: \"Not all attendees fully joined\",\n\t\t\t\t}).catch((error) => {\n\t\t\t\t\t// Ideally this information would just be in the timeout error message, but that\n\t\t\t\t\t// must be a resolved string (not dynamic). So, just log it separately.\n\t\t\t\t\ttestConsole.log(`${childrenFullyJoined} attendees fully joined before error...`);\n\t\t\t\t\tthrow error;\n\t\t\t\t});\n\n\t\t\t\tconst waitForDisconnected = children.map(async (child, index) =>\n\t\t\t\t\tindex === 0\n\t\t\t\t\t\t? Promise.resolve()\n\t\t\t\t\t\t: timeoutPromise(\n\t\t\t\t\t\t\t\t(resolve) => {\n\t\t\t\t\t\t\t\t\tchild.on(\"message\", (msg: MessageFromChild) => {\n\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\tmsg.event === \"attendeeDisconnected\" &&\n\t\t\t\t\t\t\t\t\t\t\tmsg.attendeeId === connectResult.containerCreatorAttendeeId\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\tconsole.log(`Child[${index}] saw creator disconnect`);\n\t\t\t\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tdurationMs: childDisconnectTimeoutMs,\n\t\t\t\t\t\t\t\t\terrorMsg: `Attendee[${index}] Disconnected Timeout`,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t),\n\t\t\t\t);\n\n\t\t\t\t// Act - disconnect first child process\n\t\t\t\tchildren[0].send({ command: \"disconnectSelf\" });\n\n\t\t\t\t// Verify - wait for all 'attendeeDisconnected' events\n\t\t\t\tawait Promise.race([Promise.all(waitForDisconnected), childErrorPromise]);\n\t\t\t});\n\t\t}\n\t}\n\n\t{\n\t\t/**\n\t\t * Timeout for workspace registration {@link WorkspaceRegisteredEvent}\n\t\t */\n\t\tconst workspaceRegisterTimeoutMs = 5000;\n\t\t/**\n\t\t * Timeout for presence update events {@link LatestMapValueUpdatedEvent} and {@link LatestValueUpdatedEvent}\n\t\t */\n\t\tconst stateUpdateTimeoutMs = 5000;\n\t\t/**\n\t\t * Timeout for {@link LatestMapValueGetResponseEvent} and {@link LatestValueGetResponseEvent}\n\t\t */\n\t\tconst getStateTimeoutMs = 5000;\n\n\t\t// This test suite focuses on the synchronization of Latest state between clients.\n\t\t// NOTE: For testing purposes child clients will expect a Latest value of type string.\n\t\tdescribe(`using Latest state object`, () => {\n\t\t\tfor (const numClients of [5, 20]) {\n\t\t\t\tassert(numClients > 1, \"Must have at least two clients\");\n\t\t\t\t/**\n\t\t\t\t * Timeout for child processes to connect to container ({@link ConnectedEvent})\n\t\t\t\t */\n\t\t\t\tconst childConnectTimeoutMs = 1000 * numClients * timeoutMultiplier;\n\n\t\t\t\tlet children: ChildProcess[];\n\t\t\t\tlet childErrorPromise: Promise<never>;\n\t\t\t\tlet containerCreatorAttendeeId: AttendeeId;\n\t\t\t\tlet attendeeIdPromises: Promise<AttendeeId>[];\n\t\t\t\tlet remoteClients: ChildProcess[];\n\t\t\t\tconst testValue = \"testValue\";\n\t\t\t\tconst workspaceId = \"presenceTestWorkspace\";\n\n\t\t\t\tbeforeEach(async () => {\n\t\t\t\t\t({ children, childErrorPromise } = await forkChildProcesses(\n\t\t\t\t\t\tnumClients,\n\t\t\t\t\t\tafterCleanUp,\n\t\t\t\t\t));\n\t\t\t\t\t({ containerCreatorAttendeeId, attendeeIdPromises } = await connectChildProcesses(\n\t\t\t\t\t\tchildren,\n\t\t\t\t\t\t{ writeClients: numClients, readyTimeoutMs: childConnectTimeoutMs },\n\t\t\t\t\t));\n\t\t\t\t\tawait Promise.all(attendeeIdPromises);\n\t\t\t\t\tremoteClients = children.filter((_, index) => index !== 0);\n\t\t\t\t\t// NOTE: For testing purposes child clients will expect a Latest value of type string (StateFactory.latest<{ value: string }>).\n\t\t\t\t\tawait registerWorkspaceOnChildren(children, workspaceId, {\n\t\t\t\t\t\tlatest: true,\n\t\t\t\t\t\ttimeoutMs: workspaceRegisterTimeoutMs,\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\tit(`allows clients to read Latest state from other clients [${numClients} clients]`, async () => {\n\t\t\t\t\t// Setup\n\t\t\t\t\tconst updateEventsPromise = waitForLatestValueUpdates(\n\t\t\t\t\t\tremoteClients,\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tchildErrorPromise,\n\t\t\t\t\t\tstateUpdateTimeoutMs,\n\t\t\t\t\t\t{ fromAttendeeId: containerCreatorAttendeeId, expectedValue: testValue },\n\t\t\t\t\t);\n\n\t\t\t\t\t// Act - Trigger the update\n\t\t\t\t\tchildren[0].send({\n\t\t\t\t\t\tcommand: \"setLatestValue\",\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tvalue: testValue,\n\t\t\t\t\t});\n\t\t\t\t\tconst updateEvents = await updateEventsPromise;\n\n\t\t\t\t\t// Verify all events are from the expected attendee\n\t\t\t\t\tfor (const updateEvent of updateEvents) {\n\t\t\t\t\t\tassert.strictEqual(updateEvent.attendeeId, containerCreatorAttendeeId);\n\t\t\t\t\t\tassert.deepStrictEqual(updateEvent.value, testValue);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Act - Request each remote client to read latest state from container creator\n\t\t\t\t\tfor (const child of remoteClients) {\n\t\t\t\t\t\tchild.send({\n\t\t\t\t\t\t\tcommand: \"getLatestValue\",\n\t\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\t\tattendeeId: containerCreatorAttendeeId,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst getResponses = await getLatestValueResponses(\n\t\t\t\t\t\tremoteClients,\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tchildErrorPromise,\n\t\t\t\t\t\tgetStateTimeoutMs,\n\t\t\t\t\t);\n\n\t\t\t\t\t// Verify - all responses should contain the expected value\n\t\t\t\t\tfor (const getResponse of getResponses) {\n\t\t\t\t\t\tassert.deepStrictEqual(getResponse.value, testValue);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t// This test suite focuses on the synchronization of LatestMap state between clients.\n\t\t// NOTE: For testing purposes child clients will expect a LatestMap value of type Record<string, string | number>.\n\t\tdescribe(`using LatestMap state object`, () => {\n\t\t\tfor (const numClients of [5, 20]) {\n\t\t\t\tassert(numClients > 1, \"Must have at least two clients\");\n\t\t\t\t/**\n\t\t\t\t * Timeout for child processes to connect to container ({@link ConnectedEvent})\n\t\t\t\t */\n\t\t\t\tconst childConnectTimeoutMs = 1000 * numClients * timeoutMultiplier;\n\n\t\t\t\tlet children: ChildProcess[];\n\t\t\t\tlet childErrorPromise: Promise<never>;\n\t\t\t\tlet containerCreatorAttendeeId: AttendeeId;\n\t\t\t\tlet attendeeIdPromises: Promise<AttendeeId>[];\n\t\t\t\tlet remoteClients: ChildProcess[];\n\t\t\t\tconst workspaceId = \"presenceTestWorkspace\";\n\t\t\t\tconst key1 = \"player1\";\n\t\t\t\tconst key2 = \"player2\";\n\t\t\t\tconst value1 = { name: \"Alice\", score: 100 };\n\t\t\t\tconst value2 = { name: \"Bob\", score: 200 };\n\n\t\t\t\tbeforeEach(async () => {\n\t\t\t\t\t({ children, childErrorPromise } = await forkChildProcesses(\n\t\t\t\t\t\tnumClients,\n\t\t\t\t\t\tafterCleanUp,\n\t\t\t\t\t));\n\t\t\t\t\t({ containerCreatorAttendeeId, attendeeIdPromises } = await connectChildProcesses(\n\t\t\t\t\t\tchildren,\n\t\t\t\t\t\t{ writeClients: numClients, readyTimeoutMs: childConnectTimeoutMs },\n\t\t\t\t\t));\n\t\t\t\t\tawait Promise.all(attendeeIdPromises);\n\t\t\t\t\tremoteClients = children.filter((_, index) => index !== 0);\n\t\t\t\t\t// 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>).\n\t\t\t\t\tawait registerWorkspaceOnChildren(children, workspaceId, {\n\t\t\t\t\t\tlatestMap: true,\n\t\t\t\t\t\ttimeoutMs: workspaceRegisterTimeoutMs,\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\tit(`allows clients to read LatestMap values from other clients [${numClients} clients]`, async () => {\n\t\t\t\t\t// Setup\n\t\t\t\t\tconst testKey = \"cursor\";\n\t\t\t\t\tconst testValue = { x: 150, y: 300 };\n\t\t\t\t\tconst updateEventsPromise = waitForLatestMapValueUpdates(\n\t\t\t\t\t\tremoteClients,\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\ttestKey,\n\t\t\t\t\t\tchildErrorPromise,\n\t\t\t\t\t\tstateUpdateTimeoutMs,\n\t\t\t\t\t\t{ fromAttendeeId: containerCreatorAttendeeId, expectedValue: testValue },\n\t\t\t\t\t);\n\n\t\t\t\t\t// Act\n\t\t\t\t\tchildren[0].send({\n\t\t\t\t\t\tcommand: \"setLatestMapValue\",\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tkey: testKey,\n\t\t\t\t\t\tvalue: testValue,\n\t\t\t\t\t});\n\t\t\t\t\tconst updateEvents = await updateEventsPromise;\n\n\t\t\t\t\t// Check all events are from the expected attendee\n\t\t\t\t\tfor (const updateEvent of updateEvents) {\n\t\t\t\t\t\tassert.strictEqual(updateEvent.attendeeId, containerCreatorAttendeeId);\n\t\t\t\t\t\tassert.strictEqual(updateEvent.key, testKey);\n\t\t\t\t\t\tassert.deepStrictEqual(updateEvent.value, testValue);\n\t\t\t\t\t}\n\n\t\t\t\t\tfor (const child of remoteClients) {\n\t\t\t\t\t\tchild.send({\n\t\t\t\t\t\t\tcommand: \"getLatestMapValue\",\n\t\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\t\tkey: testKey,\n\t\t\t\t\t\t\tattendeeId: containerCreatorAttendeeId,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tconst getResponses = await getLatestMapValueResponses(\n\t\t\t\t\t\tremoteClients,\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\ttestKey,\n\t\t\t\t\t\tchildErrorPromise,\n\t\t\t\t\t\tgetStateTimeoutMs,\n\t\t\t\t\t);\n\n\t\t\t\t\t// Verify\n\t\t\t\t\tfor (const getResponse of getResponses) {\n\t\t\t\t\t\tassert.deepStrictEqual(getResponse.value, testValue);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tit(`returns per-key values on read [${numClients} clients]`, async () => {\n\t\t\t\t\t// Setup\n\t\t\t\t\tconst allAttendeeIds = await Promise.all(attendeeIdPromises);\n\t\t\t\t\tconst attendee0Id = containerCreatorAttendeeId;\n\t\t\t\t\tconst attendee1Id = allAttendeeIds[1];\n\n\t\t\t\t\tconst key1Recipients = children.filter((_, index) => index !== 0);\n\t\t\t\t\tconst key2Recipients = children.filter((_, index) => index !== 1);\n\t\t\t\t\tconst key1UpdateEventsPromise = waitForLatestMapValueUpdates(\n\t\t\t\t\t\tkey1Recipients,\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tkey1,\n\t\t\t\t\t\tchildErrorPromise,\n\t\t\t\t\t\tstateUpdateTimeoutMs,\n\t\t\t\t\t\t{ fromAttendeeId: attendee0Id, expectedValue: value1 },\n\t\t\t\t\t);\n\t\t\t\t\tconst key2UpdateEventsPromise = waitForLatestMapValueUpdates(\n\t\t\t\t\t\tkey2Recipients,\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tkey2,\n\t\t\t\t\t\tchildErrorPromise,\n\t\t\t\t\t\tstateUpdateTimeoutMs,\n\t\t\t\t\t\t{ fromAttendeeId: attendee1Id, expectedValue: value2 },\n\t\t\t\t\t);\n\n\t\t\t\t\t// Act\n\t\t\t\t\tchildren[0].send({\n\t\t\t\t\t\tcommand: \"setLatestMapValue\",\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tkey: key1,\n\t\t\t\t\t\tvalue: value1,\n\t\t\t\t\t});\n\t\t\t\t\tconst key1UpdateEvents = await key1UpdateEventsPromise;\n\t\t\t\t\tchildren[1].send({\n\t\t\t\t\t\tcommand: \"setLatestMapValue\",\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tkey: key2,\n\t\t\t\t\t\tvalue: value2,\n\t\t\t\t\t});\n\t\t\t\t\tconst key2UpdateEvents = await key2UpdateEventsPromise;\n\n\t\t\t\t\t// Verify all events are from the expected attendees\n\t\t\t\t\tfor (const updateEvent of key1UpdateEvents) {\n\t\t\t\t\t\tassert.strictEqual(updateEvent.attendeeId, attendee0Id);\n\t\t\t\t\t\tassert.strictEqual(updateEvent.key, key1);\n\t\t\t\t\t\tassert.deepStrictEqual(updateEvent.value, value1);\n\t\t\t\t\t}\n\t\t\t\t\tfor (const updateEvent of key2UpdateEvents) {\n\t\t\t\t\t\tassert.strictEqual(updateEvent.attendeeId, attendee1Id);\n\t\t\t\t\t\tassert.strictEqual(updateEvent.key, key2);\n\t\t\t\t\t\tassert.deepStrictEqual(updateEvent.value, value2);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Read key1 of attendee0 from all children\n\t\t\t\t\tfor (const child of children) {\n\t\t\t\t\t\tchild.send({\n\t\t\t\t\t\t\tcommand: \"getLatestMapValue\",\n\t\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\t\tkey: key1,\n\t\t\t\t\t\t\tattendeeId: attendee0Id,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tconst key1Responses = await getLatestMapValueResponses(\n\t\t\t\t\t\tchildren,\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tkey1,\n\t\t\t\t\t\tchildErrorPromise,\n\t\t\t\t\t\tgetStateTimeoutMs,\n\t\t\t\t\t);\n\n\t\t\t\t\t// Read key2 of attendee1 from all children\n\t\t\t\t\tfor (const child of children) {\n\t\t\t\t\t\tchild.send({\n\t\t\t\t\t\t\tcommand: \"getLatestMapValue\",\n\t\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\t\tkey: key2,\n\t\t\t\t\t\t\tattendeeId: attendee1Id,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tconst key2Responses = await getLatestMapValueResponses(\n\t\t\t\t\t\tchildren,\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tkey2,\n\t\t\t\t\t\tchildErrorPromise,\n\t\t\t\t\t\tgetStateTimeoutMs,\n\t\t\t\t\t);\n\n\t\t\t\t\t// Verify\n\t\t\t\t\tassert.strictEqual(\n\t\t\t\t\t\tkey1Responses.length,\n\t\t\t\t\t\tnumClients,\n\t\t\t\t\t\t\"Expected responses from all clients for key1\",\n\t\t\t\t\t);\n\t\t\t\t\tassert.strictEqual(\n\t\t\t\t\t\tkey2Responses.length,\n\t\t\t\t\t\tnumClients,\n\t\t\t\t\t\t\"Expected responses from all clients for key2\",\n\t\t\t\t\t);\n\n\t\t\t\t\tfor (const response of key1Responses) {\n\t\t\t\t\t\tassert.deepStrictEqual(response.value, value1, \"Key1 value should match\");\n\t\t\t\t\t}\n\t\t\t\t\tfor (const response of key2Responses) {\n\t\t\t\t\t\tassert.deepStrictEqual(response.value, value2, \"Key2 value should match\");\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n});\n"]}
|
|
1
|
+
{"version":3,"file":"presenceTest.spec.js","sourceRoot":"","sources":["../../../src/test/multiprocess/presenceTest.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\nimport type { ChildProcess } from \"node:child_process\";\nimport inspector from \"node:inspector\";\n\nimport type { AttendeeId } from \"@fluidframework/presence/beta\";\nimport { timeoutAwait, timeoutPromise } from \"@fluidframework/test-utils/internal\";\n\nimport type { MessageFromChild } from \"./messageTypes.js\";\nimport {\n\tconnectAndListenForAttendees,\n\tconnectAndWaitForAttendees,\n\tconnectChildProcesses,\n\tforkChildProcesses,\n\tgetLatestMapValueResponses,\n\tgetLatestValueResponses,\n\tregisterWorkspaceOnChildren,\n\ttestConsole,\n\twaitForLatestMapValueUpdates,\n\twaitForLatestValueUpdates,\n} from \"./orchestratorUtils.js\";\n\nconst useAzure = process.env.FLUID_CLIENT === \"azure\";\n\n/**\n * Detects if the debugger is attached (when code loaded).\n */\nconst debuggerAttached = inspector.url() !== undefined;\n\n/**\n * Set this to a high number when debugging to avoid timeouts from debugging time.\n */\nconst timeoutMultiplier = debuggerAttached ? 1000 : useAzure ? 3 : 1;\n\n/**\n * Sets the timeout for the given test context.\n *\n * @remarks\n * If a debugger is attached, the timeout is set to 0 to prevent timeouts during debugging.\n * Otherwise, it sets the timeout to the maximum of the current timeout and the specified duration.\n *\n * @param context - The Mocha test context.\n * @param duration - The duration in milliseconds to set the timeout to. Zero disables the timeout.\n */\nfunction setTimeout(context: Mocha.Context, duration: number): void {\n\tconst currentTimeout = context.timeout();\n\tconst newTimeout =\n\t\tdebuggerAttached || currentTimeout === 0 || duration === 0\n\t\t\t? 0\n\t\t\t: Math.max(currentTimeout, duration);\n\tif (newTimeout !== currentTimeout) {\n\t\ttestConsole.log(\n\t\t\t`${context.test?.title}: setting timeout to ${newTimeout}ms (was ${currentTimeout}ms)`,\n\t\t);\n\t\tcontext.timeout(newTimeout);\n\t}\n}\n\n/**\n * This test suite is a prototype for a multi-process end to end test for Fluid using the new Presence API on AzureClient.\n * In the future we hope to expand and generalize this pattern to broadly test more Fluid features.\n * Other E2E tests are limited to running multiple clients on a single process which does not effectively\n * simulate real-world production scenarios where clients are usually running on different machines. Since\n * the Fluid Framework client is designed to carry most of the work burden, multi-process testing from a\n * single machine is also not representative but does at least work past some limitations of a single\n * Node.js process handling multiple clients.\n *\n * The pattern demonstrated in this test suite is as follows:\n *\n * This main test file acts as the 'Orchestrator'. The orchestrator's job includes:\n * - Fork child processes to simulate multiple Fluid clients\n * - Send command messages to child clients to perform specific Fluid actions.\n * - Receive response messages from child clients to verify expected behavior.\n * - Clean up child processes after each test.\n *\n * The child processes are located in the `childClient.tool.ts` file. Each child process simulates a Fluid client.\n *\n * The child client's job includes:\n * - Create/Get + connect to Fluid container.\n * - Listen for command messages from the orchestrator.\n * - Perform the requested action.\n * - Send response messages including any relevant data back to the orchestrator to verify expected behavior.\n */\n\n/**\n * This particular test suite tests the following E2E functionality for Presence:\n * - Announce 'attendeeConnected' when remote client joins session.\n * - Announce 'attendeeDisconnected' when remote client disconnects.\n */\ndescribe(`Presence with AzureClient`, () => {\n\tconst afterCleanUp: (() => void)[] = [];\n\n\t// After each test, call any cleanup functions that were registered (kill each child process)\n\tafterEach(async () => {\n\t\tfor (const cleanUp of afterCleanUp) {\n\t\t\tcleanUp();\n\t\t}\n\t\tafterCleanUp.length = 0;\n\t});\n\n\t// Note that on slower systems 50+ clients may take too long to join.\n\tconst numClientsForAttendeeTests = [5, 20, 50, 100];\n\t// TODO: AB#45620: \"Presence: perf: update Join pattern for scale\" may help, then remove .slice.\n\tfor (const numClients of numClientsForAttendeeTests.slice(0, 2)) {\n\t\tassert(numClients > 1, \"Must have at least two clients\");\n\t\t/**\n\t\t * Timeout for child processes to connect to container ({@link ConnectedEvent})\n\t\t */\n\t\tconst childConnectTimeoutMs = 1000 * numClients * timeoutMultiplier;\n\t\t/**\n\t\t * Timeout for presence attendees to connect {@link AttendeeConnectedEvent}\n\t\t */\n\t\tconst allAttendeesJoinedTimeoutMs = (1000 + 200 * numClients) * timeoutMultiplier;\n\n\t\tfor (const writeClients of [numClients, 1]) {\n\t\t\tit(`announces 'attendeeConnected' when remote client joins session [${numClients} clients, ${writeClients} writers]`, async function () {\n\t\t\t\t// AB#48866: Fix intermittently failing presence tests\n\t\t\t\tif (useAzure) {\n\t\t\t\t\tthis.skip();\n\t\t\t\t}\n\n\t\t\t\tsetTimeout(this, childConnectTimeoutMs + allAttendeesJoinedTimeoutMs + 1000);\n\n\t\t\t\t// Setup\n\t\t\t\tconst { children, childErrorPromise } = await forkChildProcesses(\n\t\t\t\t\tnumClients,\n\t\t\t\t\tafterCleanUp,\n\t\t\t\t);\n\n\t\t\t\t// Further Setup with Act and Verify\n\t\t\t\tawait connectAndWaitForAttendees(\n\t\t\t\t\tchildren,\n\t\t\t\t\t{\n\t\t\t\t\t\twriteClients,\n\t\t\t\t\t\tattendeeCountRequired: numClients - 1,\n\t\t\t\t\t\tchildConnectTimeoutMs,\n\t\t\t\t\t\tallAttendeesJoinedTimeoutMs,\n\t\t\t\t\t},\n\t\t\t\t\tchildErrorPromise,\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tit(`announces 'attendeeDisconnected' when remote client disconnects [${numClients} clients, ${writeClients} writers]`, async function () {\n\t\t\t\t// AB#48866: Fix intermittently failing presence tests\n\t\t\t\tif (useAzure) {\n\t\t\t\t\tthis.skip();\n\t\t\t\t}\n\t\t\t\t// TODO: AB#45620: \"Presence: perf: update Join pattern for scale\" can handle\n\t\t\t\t// larger counts of read-only attendees. Without protocol changes tests with\n\t\t\t\t// 20+ attendees exceed current limits.\n\t\t\t\tif (numClients >= 20 && writeClients === 1) {\n\t\t\t\t\tthis.skip();\n\t\t\t\t}\n\n\t\t\t\tconst childDisconnectTimeoutMs = 10_000 * timeoutMultiplier;\n\n\t\t\t\tsetTimeout(\n\t\t\t\t\tthis,\n\t\t\t\t\tchildConnectTimeoutMs +\n\t\t\t\t\t\tallAttendeesJoinedTimeoutMs +\n\t\t\t\t\t\tchildDisconnectTimeoutMs +\n\t\t\t\t\t\t1000,\n\t\t\t\t);\n\n\t\t\t\t// Setup\n\t\t\t\tconst { children, childErrorPromise } = await forkChildProcesses(\n\t\t\t\t\tnumClients,\n\t\t\t\t\tafterCleanUp,\n\t\t\t\t);\n\n\t\t\t\tconst connectResult = await connectAndListenForAttendees(children, {\n\t\t\t\t\twriteClients,\n\t\t\t\t\tattendeeCountRequired: numClients - 1,\n\t\t\t\t\tchildConnectTimeoutMs,\n\t\t\t\t});\n\n\t\t\t\t// Wait for all attendees to be fully joined\n\t\t\t\t// Keep a tally for debuggability\n\t\t\t\tlet childrenFullyJoined = 0;\n\t\t\t\tconst allAttendeesFullyJoined = Promise.all(\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\t\t\t\t\tconnectResult.attendeeCountRequiredPromises.map((attendeeFullyJoinedPromise) =>\n\t\t\t\t\t\tattendeeFullyJoinedPromise.then(() => childrenFullyJoined++),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tawait timeoutAwait(allAttendeesFullyJoined, {\n\t\t\t\t\tdurationMs: allAttendeesJoinedTimeoutMs,\n\t\t\t\t\terrorMsg: \"Not all attendees fully joined\",\n\t\t\t\t}).catch((error) => {\n\t\t\t\t\t// Ideally this information would just be in the timeout error message, but that\n\t\t\t\t\t// must be a resolved string (not dynamic). So, just log it separately.\n\t\t\t\t\ttestConsole.log(`${childrenFullyJoined} attendees fully joined before error...`);\n\t\t\t\t\tthrow error;\n\t\t\t\t});\n\n\t\t\t\tconst waitForDisconnected = children.map(async (child, index) =>\n\t\t\t\t\tindex === 0\n\t\t\t\t\t\t? Promise.resolve()\n\t\t\t\t\t\t: timeoutPromise(\n\t\t\t\t\t\t\t\t(resolve) => {\n\t\t\t\t\t\t\t\t\tchild.on(\"message\", (msg: MessageFromChild) => {\n\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\tmsg.event === \"attendeeDisconnected\" &&\n\t\t\t\t\t\t\t\t\t\t\tmsg.attendeeId === connectResult.containerCreatorAttendeeId\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\tconsole.log(`Child[${index}] saw creator disconnect`);\n\t\t\t\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tdurationMs: childDisconnectTimeoutMs,\n\t\t\t\t\t\t\t\t\terrorMsg: `Attendee[${index}] Disconnected Timeout`,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t),\n\t\t\t\t);\n\n\t\t\t\t// Act - disconnect first child process\n\t\t\t\tchildren[0].send({ command: \"disconnectSelf\" });\n\n\t\t\t\t// Verify - wait for all 'attendeeDisconnected' events\n\t\t\t\tawait Promise.race([Promise.all(waitForDisconnected), childErrorPromise]);\n\t\t\t});\n\t\t}\n\t}\n\n\t{\n\t\t/**\n\t\t * Timeout for workspace registration {@link WorkspaceRegisteredEvent}\n\t\t */\n\t\tconst workspaceRegisterTimeoutMs = 5000;\n\t\t/**\n\t\t * Timeout for presence update events {@link LatestMapValueUpdatedEvent} and {@link LatestValueUpdatedEvent}\n\t\t */\n\t\tconst stateUpdateTimeoutMs = 5000;\n\t\t/**\n\t\t * Timeout for {@link LatestMapValueGetResponseEvent} and {@link LatestValueGetResponseEvent}\n\t\t */\n\t\tconst getStateTimeoutMs = 5000;\n\n\t\t// This test suite focuses on the synchronization of Latest state between clients.\n\t\t// NOTE: For testing purposes child clients will expect a Latest value of type string.\n\t\tdescribe(`using Latest state object`, () => {\n\t\t\tfor (const numClients of [5, 20]) {\n\t\t\t\tassert(numClients > 1, \"Must have at least two clients\");\n\t\t\t\t/**\n\t\t\t\t * Timeout for child processes to connect to container ({@link ConnectedEvent})\n\t\t\t\t */\n\t\t\t\tconst childConnectTimeoutMs = 1000 * numClients * timeoutMultiplier;\n\n\t\t\t\tlet children: ChildProcess[];\n\t\t\t\tlet childErrorPromise: Promise<never>;\n\t\t\t\tlet containerCreatorAttendeeId: AttendeeId;\n\t\t\t\tlet attendeeIdPromises: Promise<AttendeeId>[];\n\t\t\t\tlet remoteClients: ChildProcess[];\n\t\t\t\tconst testValue = \"testValue\";\n\t\t\t\tconst workspaceId = \"presenceTestWorkspace\";\n\n\t\t\t\tbeforeEach(async () => {\n\t\t\t\t\t({ children, childErrorPromise } = await forkChildProcesses(\n\t\t\t\t\t\tnumClients,\n\t\t\t\t\t\tafterCleanUp,\n\t\t\t\t\t));\n\t\t\t\t\t({ containerCreatorAttendeeId, attendeeIdPromises } = await connectChildProcesses(\n\t\t\t\t\t\tchildren,\n\t\t\t\t\t\t{ writeClients: numClients, readyTimeoutMs: childConnectTimeoutMs },\n\t\t\t\t\t));\n\t\t\t\t\tawait Promise.all(attendeeIdPromises);\n\t\t\t\t\tremoteClients = children.filter((_, index) => index !== 0);\n\t\t\t\t\t// NOTE: For testing purposes child clients will expect a Latest value of type string (StateFactory.latest<{ value: string }>).\n\t\t\t\t\tawait registerWorkspaceOnChildren(children, workspaceId, {\n\t\t\t\t\t\tlatest: true,\n\t\t\t\t\t\ttimeoutMs: workspaceRegisterTimeoutMs,\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\tit(`allows clients to read Latest state from other clients [${numClients} clients]`, async function () {\n\t\t\t\t\t// AB#48866: Fix intermittently failing presence tests\n\t\t\t\t\tif (useAzure) {\n\t\t\t\t\t\tthis.skip();\n\t\t\t\t\t}\n\t\t\t\t\t// Setup\n\t\t\t\t\tconst updateEventsPromise = waitForLatestValueUpdates(\n\t\t\t\t\t\tremoteClients,\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tchildErrorPromise,\n\t\t\t\t\t\tstateUpdateTimeoutMs,\n\t\t\t\t\t\t{ fromAttendeeId: containerCreatorAttendeeId, expectedValue: testValue },\n\t\t\t\t\t);\n\n\t\t\t\t\t// Act - Trigger the update\n\t\t\t\t\tchildren[0].send({\n\t\t\t\t\t\tcommand: \"setLatestValue\",\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tvalue: testValue,\n\t\t\t\t\t});\n\t\t\t\t\tconst updateEvents = await updateEventsPromise;\n\n\t\t\t\t\t// Verify all events are from the expected attendee\n\t\t\t\t\tfor (const updateEvent of updateEvents) {\n\t\t\t\t\t\tassert.strictEqual(updateEvent.attendeeId, containerCreatorAttendeeId);\n\t\t\t\t\t\tassert.deepStrictEqual(updateEvent.value, testValue);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Act - Request each remote client to read latest state from container creator\n\t\t\t\t\tfor (const child of remoteClients) {\n\t\t\t\t\t\tchild.send({\n\t\t\t\t\t\t\tcommand: \"getLatestValue\",\n\t\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\t\tattendeeId: containerCreatorAttendeeId,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst getResponses = await getLatestValueResponses(\n\t\t\t\t\t\tremoteClients,\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tchildErrorPromise,\n\t\t\t\t\t\tgetStateTimeoutMs,\n\t\t\t\t\t);\n\n\t\t\t\t\t// Verify - all responses should contain the expected value\n\t\t\t\t\tfor (const getResponse of getResponses) {\n\t\t\t\t\t\tassert.deepStrictEqual(getResponse.value, testValue);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t// This test suite focuses on the synchronization of LatestMap state between clients.\n\t\t// NOTE: For testing purposes child clients will expect a LatestMap value of type Record<string, string | number>.\n\t\tdescribe(`using LatestMap state object`, () => {\n\t\t\tfor (const numClients of [5, 20]) {\n\t\t\t\tassert(numClients > 1, \"Must have at least two clients\");\n\t\t\t\t/**\n\t\t\t\t * Timeout for child processes to connect to container ({@link ConnectedEvent})\n\t\t\t\t */\n\t\t\t\tconst childConnectTimeoutMs = 1000 * numClients * timeoutMultiplier;\n\n\t\t\t\tlet children: ChildProcess[];\n\t\t\t\tlet childErrorPromise: Promise<never>;\n\t\t\t\tlet containerCreatorAttendeeId: AttendeeId;\n\t\t\t\tlet attendeeIdPromises: Promise<AttendeeId>[];\n\t\t\t\tlet remoteClients: ChildProcess[];\n\t\t\t\tconst workspaceId = \"presenceTestWorkspace\";\n\t\t\t\tconst key1 = \"player1\";\n\t\t\t\tconst key2 = \"player2\";\n\t\t\t\tconst value1 = { name: \"Alice\", score: 100 };\n\t\t\t\tconst value2 = { name: \"Bob\", score: 200 };\n\n\t\t\t\tbeforeEach(async () => {\n\t\t\t\t\t({ children, childErrorPromise } = await forkChildProcesses(\n\t\t\t\t\t\tnumClients,\n\t\t\t\t\t\tafterCleanUp,\n\t\t\t\t\t));\n\t\t\t\t\t({ containerCreatorAttendeeId, attendeeIdPromises } = await connectChildProcesses(\n\t\t\t\t\t\tchildren,\n\t\t\t\t\t\t{ writeClients: numClients, readyTimeoutMs: childConnectTimeoutMs },\n\t\t\t\t\t));\n\t\t\t\t\tawait Promise.all(attendeeIdPromises);\n\t\t\t\t\tremoteClients = children.filter((_, index) => index !== 0);\n\t\t\t\t\t// 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>).\n\t\t\t\t\tawait registerWorkspaceOnChildren(children, workspaceId, {\n\t\t\t\t\t\tlatestMap: true,\n\t\t\t\t\t\ttimeoutMs: workspaceRegisterTimeoutMs,\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\tit(`allows clients to read LatestMap values from other clients [${numClients} clients]`, async () => {\n\t\t\t\t\t// Setup\n\t\t\t\t\tconst testKey = \"cursor\";\n\t\t\t\t\tconst testValue = { x: 150, y: 300 };\n\t\t\t\t\tconst updateEventsPromise = waitForLatestMapValueUpdates(\n\t\t\t\t\t\tremoteClients,\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\ttestKey,\n\t\t\t\t\t\tchildErrorPromise,\n\t\t\t\t\t\tstateUpdateTimeoutMs,\n\t\t\t\t\t\t{ fromAttendeeId: containerCreatorAttendeeId, expectedValue: testValue },\n\t\t\t\t\t);\n\n\t\t\t\t\t// Act\n\t\t\t\t\tchildren[0].send({\n\t\t\t\t\t\tcommand: \"setLatestMapValue\",\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tkey: testKey,\n\t\t\t\t\t\tvalue: testValue,\n\t\t\t\t\t});\n\t\t\t\t\tconst updateEvents = await updateEventsPromise;\n\n\t\t\t\t\t// Check all events are from the expected attendee\n\t\t\t\t\tfor (const updateEvent of updateEvents) {\n\t\t\t\t\t\tassert.strictEqual(updateEvent.attendeeId, containerCreatorAttendeeId);\n\t\t\t\t\t\tassert.strictEqual(updateEvent.key, testKey);\n\t\t\t\t\t\tassert.deepStrictEqual(updateEvent.value, testValue);\n\t\t\t\t\t}\n\n\t\t\t\t\tfor (const child of remoteClients) {\n\t\t\t\t\t\tchild.send({\n\t\t\t\t\t\t\tcommand: \"getLatestMapValue\",\n\t\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\t\tkey: testKey,\n\t\t\t\t\t\t\tattendeeId: containerCreatorAttendeeId,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tconst getResponses = await getLatestMapValueResponses(\n\t\t\t\t\t\tremoteClients,\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\ttestKey,\n\t\t\t\t\t\tchildErrorPromise,\n\t\t\t\t\t\tgetStateTimeoutMs,\n\t\t\t\t\t);\n\n\t\t\t\t\t// Verify\n\t\t\t\t\tfor (const getResponse of getResponses) {\n\t\t\t\t\t\tassert.deepStrictEqual(getResponse.value, testValue);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tit(`returns per-key values on read [${numClients} clients]`, async function () {\n\t\t\t\t\t// AB#48866: Fix intermittently failing presence tests\n\t\t\t\t\tif (useAzure) {\n\t\t\t\t\t\tthis.skip();\n\t\t\t\t\t}\n\t\t\t\t\t// Setup\n\t\t\t\t\tconst allAttendeeIds = await Promise.all(attendeeIdPromises);\n\t\t\t\t\tconst attendee0Id = containerCreatorAttendeeId;\n\t\t\t\t\tconst attendee1Id = allAttendeeIds[1];\n\n\t\t\t\t\tconst key1Recipients = children.filter((_, index) => index !== 0);\n\t\t\t\t\tconst key2Recipients = children.filter((_, index) => index !== 1);\n\t\t\t\t\tconst key1UpdateEventsPromise = waitForLatestMapValueUpdates(\n\t\t\t\t\t\tkey1Recipients,\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tkey1,\n\t\t\t\t\t\tchildErrorPromise,\n\t\t\t\t\t\tstateUpdateTimeoutMs,\n\t\t\t\t\t\t{ fromAttendeeId: attendee0Id, expectedValue: value1 },\n\t\t\t\t\t);\n\t\t\t\t\tconst key2UpdateEventsPromise = waitForLatestMapValueUpdates(\n\t\t\t\t\t\tkey2Recipients,\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tkey2,\n\t\t\t\t\t\tchildErrorPromise,\n\t\t\t\t\t\tstateUpdateTimeoutMs,\n\t\t\t\t\t\t{ fromAttendeeId: attendee1Id, expectedValue: value2 },\n\t\t\t\t\t);\n\n\t\t\t\t\t// Act\n\t\t\t\t\tchildren[0].send({\n\t\t\t\t\t\tcommand: \"setLatestMapValue\",\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tkey: key1,\n\t\t\t\t\t\tvalue: value1,\n\t\t\t\t\t});\n\t\t\t\t\tconst key1UpdateEvents = await key1UpdateEventsPromise;\n\t\t\t\t\tchildren[1].send({\n\t\t\t\t\t\tcommand: \"setLatestMapValue\",\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tkey: key2,\n\t\t\t\t\t\tvalue: value2,\n\t\t\t\t\t});\n\t\t\t\t\tconst key2UpdateEvents = await key2UpdateEventsPromise;\n\n\t\t\t\t\t// Verify all events are from the expected attendees\n\t\t\t\t\tfor (const updateEvent of key1UpdateEvents) {\n\t\t\t\t\t\tassert.strictEqual(updateEvent.attendeeId, attendee0Id);\n\t\t\t\t\t\tassert.strictEqual(updateEvent.key, key1);\n\t\t\t\t\t\tassert.deepStrictEqual(updateEvent.value, value1);\n\t\t\t\t\t}\n\t\t\t\t\tfor (const updateEvent of key2UpdateEvents) {\n\t\t\t\t\t\tassert.strictEqual(updateEvent.attendeeId, attendee1Id);\n\t\t\t\t\t\tassert.strictEqual(updateEvent.key, key2);\n\t\t\t\t\t\tassert.deepStrictEqual(updateEvent.value, value2);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Read key1 of attendee0 from all children\n\t\t\t\t\tfor (const child of children) {\n\t\t\t\t\t\tchild.send({\n\t\t\t\t\t\t\tcommand: \"getLatestMapValue\",\n\t\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\t\tkey: key1,\n\t\t\t\t\t\t\tattendeeId: attendee0Id,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tconst key1Responses = await getLatestMapValueResponses(\n\t\t\t\t\t\tchildren,\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tkey1,\n\t\t\t\t\t\tchildErrorPromise,\n\t\t\t\t\t\tgetStateTimeoutMs,\n\t\t\t\t\t);\n\n\t\t\t\t\t// Read key2 of attendee1 from all children\n\t\t\t\t\tfor (const child of children) {\n\t\t\t\t\t\tchild.send({\n\t\t\t\t\t\t\tcommand: \"getLatestMapValue\",\n\t\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\t\tkey: key2,\n\t\t\t\t\t\t\tattendeeId: attendee1Id,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tconst key2Responses = await getLatestMapValueResponses(\n\t\t\t\t\t\tchildren,\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tkey2,\n\t\t\t\t\t\tchildErrorPromise,\n\t\t\t\t\t\tgetStateTimeoutMs,\n\t\t\t\t\t);\n\n\t\t\t\t\t// Verify\n\t\t\t\t\tassert.strictEqual(\n\t\t\t\t\t\tkey1Responses.length,\n\t\t\t\t\t\tnumClients,\n\t\t\t\t\t\t\"Expected responses from all clients for key1\",\n\t\t\t\t\t);\n\t\t\t\t\tassert.strictEqual(\n\t\t\t\t\t\tkey2Responses.length,\n\t\t\t\t\t\tnumClients,\n\t\t\t\t\t\t\"Expected responses from all clients for key2\",\n\t\t\t\t\t);\n\n\t\t\t\t\tfor (const response of key1Responses) {\n\t\t\t\t\t\tassert.deepStrictEqual(response.value, value1, \"Key1 value should match\");\n\t\t\t\t\t}\n\t\t\t\t\tfor (const response of key2Responses) {\n\t\t\t\t\t\tassert.deepStrictEqual(response.value, value2, \"Key2 value should match\");\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n});\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/azure-end-to-end-tests",
|
|
3
|
-
"version": "2.61.0-
|
|
3
|
+
"version": "2.61.0-356312",
|
|
4
4
|
"description": "Azure client end to end tests",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -33,29 +33,29 @@
|
|
|
33
33
|
"temp-directory": "nyc/.nyc_output"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@fluid-experimental/data-objects": "2.61.0-
|
|
37
|
-
"@fluid-internal/client-utils": "2.61.0-
|
|
38
|
-
"@fluid-internal/mocha-test-setup": "2.61.0-
|
|
39
|
-
"@fluid-private/test-version-utils": "2.61.0-
|
|
40
|
-
"@fluidframework/aqueduct": "2.61.0-
|
|
41
|
-
"@fluidframework/azure-client": "2.61.0-
|
|
36
|
+
"@fluid-experimental/data-objects": "2.61.0-356312",
|
|
37
|
+
"@fluid-internal/client-utils": "2.61.0-356312",
|
|
38
|
+
"@fluid-internal/mocha-test-setup": "2.61.0-356312",
|
|
39
|
+
"@fluid-private/test-version-utils": "2.61.0-356312",
|
|
40
|
+
"@fluidframework/aqueduct": "2.61.0-356312",
|
|
41
|
+
"@fluidframework/azure-client": "2.61.0-356312",
|
|
42
42
|
"@fluidframework/azure-client-legacy": "npm:@fluidframework/azure-client@^1.2.0",
|
|
43
|
-
"@fluidframework/container-definitions": "2.61.0-
|
|
44
|
-
"@fluidframework/container-loader": "2.61.0-
|
|
45
|
-
"@fluidframework/core-interfaces": "2.61.0-
|
|
46
|
-
"@fluidframework/counter": "2.61.0-
|
|
47
|
-
"@fluidframework/datastore-definitions": "2.61.0-
|
|
48
|
-
"@fluidframework/fluid-static": "2.61.0-
|
|
49
|
-
"@fluidframework/map": "2.61.0-
|
|
43
|
+
"@fluidframework/container-definitions": "2.61.0-356312",
|
|
44
|
+
"@fluidframework/container-loader": "2.61.0-356312",
|
|
45
|
+
"@fluidframework/core-interfaces": "2.61.0-356312",
|
|
46
|
+
"@fluidframework/counter": "2.61.0-356312",
|
|
47
|
+
"@fluidframework/datastore-definitions": "2.61.0-356312",
|
|
48
|
+
"@fluidframework/fluid-static": "2.61.0-356312",
|
|
49
|
+
"@fluidframework/map": "2.61.0-356312",
|
|
50
50
|
"@fluidframework/map-legacy": "npm:@fluidframework/map@^1.4.0",
|
|
51
|
-
"@fluidframework/matrix": "2.61.0-
|
|
52
|
-
"@fluidframework/presence": "2.61.0-
|
|
53
|
-
"@fluidframework/runtime-definitions": "2.61.0-
|
|
54
|
-
"@fluidframework/sequence": "2.61.0-
|
|
55
|
-
"@fluidframework/telemetry-utils": "2.61.0-
|
|
56
|
-
"@fluidframework/test-runtime-utils": "2.61.0-
|
|
57
|
-
"@fluidframework/test-utils": "2.61.0-
|
|
58
|
-
"@fluidframework/tree": "2.61.0-
|
|
51
|
+
"@fluidframework/matrix": "2.61.0-356312",
|
|
52
|
+
"@fluidframework/presence": "2.61.0-356312",
|
|
53
|
+
"@fluidframework/runtime-definitions": "2.61.0-356312",
|
|
54
|
+
"@fluidframework/sequence": "2.61.0-356312",
|
|
55
|
+
"@fluidframework/telemetry-utils": "2.61.0-356312",
|
|
56
|
+
"@fluidframework/test-runtime-utils": "2.61.0-356312",
|
|
57
|
+
"@fluidframework/test-utils": "2.61.0-356312",
|
|
58
|
+
"@fluidframework/tree": "2.61.0-356312",
|
|
59
59
|
"axios": "^1.8.4",
|
|
60
60
|
"cross-env": "^7.0.3",
|
|
61
61
|
"mocha": "^10.8.2",
|
|
@@ -68,8 +68,8 @@
|
|
|
68
68
|
"devDependencies": {
|
|
69
69
|
"@biomejs/biome": "~1.9.3",
|
|
70
70
|
"@fluidframework/build-common": "^2.0.3",
|
|
71
|
-
"@fluidframework/build-tools": "^0.58.
|
|
72
|
-
"@fluidframework/driver-definitions": "2.61.0-
|
|
71
|
+
"@fluidframework/build-tools": "^0.58.3",
|
|
72
|
+
"@fluidframework/driver-definitions": "2.61.0-356312",
|
|
73
73
|
"@fluidframework/eslint-config-fluid": "^6.0.0",
|
|
74
74
|
"@types/mocha": "^10.0.10",
|
|
75
75
|
"@types/nock": "^9.3.0",
|
|
@@ -118,6 +118,11 @@ describe(`Presence with AzureClient`, () => {
|
|
|
118
118
|
|
|
119
119
|
for (const writeClients of [numClients, 1]) {
|
|
120
120
|
it(`announces 'attendeeConnected' when remote client joins session [${numClients} clients, ${writeClients} writers]`, async function () {
|
|
121
|
+
// AB#48866: Fix intermittently failing presence tests
|
|
122
|
+
if (useAzure) {
|
|
123
|
+
this.skip();
|
|
124
|
+
}
|
|
125
|
+
|
|
121
126
|
setTimeout(this, childConnectTimeoutMs + allAttendeesJoinedTimeoutMs + 1000);
|
|
122
127
|
|
|
123
128
|
// Setup
|
|
@@ -140,6 +145,10 @@ describe(`Presence with AzureClient`, () => {
|
|
|
140
145
|
});
|
|
141
146
|
|
|
142
147
|
it(`announces 'attendeeDisconnected' when remote client disconnects [${numClients} clients, ${writeClients} writers]`, async function () {
|
|
148
|
+
// AB#48866: Fix intermittently failing presence tests
|
|
149
|
+
if (useAzure) {
|
|
150
|
+
this.skip();
|
|
151
|
+
}
|
|
143
152
|
// TODO: AB#45620: "Presence: perf: update Join pattern for scale" can handle
|
|
144
153
|
// larger counts of read-only attendees. Without protocol changes tests with
|
|
145
154
|
// 20+ attendees exceed current limits.
|
|
@@ -269,7 +278,11 @@ describe(`Presence with AzureClient`, () => {
|
|
|
269
278
|
});
|
|
270
279
|
});
|
|
271
280
|
|
|
272
|
-
it(`allows clients to read Latest state from other clients [${numClients} clients]`, async ()
|
|
281
|
+
it(`allows clients to read Latest state from other clients [${numClients} clients]`, async function () {
|
|
282
|
+
// AB#48866: Fix intermittently failing presence tests
|
|
283
|
+
if (useAzure) {
|
|
284
|
+
this.skip();
|
|
285
|
+
}
|
|
273
286
|
// Setup
|
|
274
287
|
const updateEventsPromise = waitForLatestValueUpdates(
|
|
275
288
|
remoteClients,
|
|
@@ -407,7 +420,11 @@ describe(`Presence with AzureClient`, () => {
|
|
|
407
420
|
}
|
|
408
421
|
});
|
|
409
422
|
|
|
410
|
-
it(`returns per-key values on read [${numClients} clients]`, async ()
|
|
423
|
+
it(`returns per-key values on read [${numClients} clients]`, async function () {
|
|
424
|
+
// AB#48866: Fix intermittently failing presence tests
|
|
425
|
+
if (useAzure) {
|
|
426
|
+
this.skip();
|
|
427
|
+
}
|
|
411
428
|
// Setup
|
|
412
429
|
const allAttendeeIds = await Promise.all(attendeeIdPromises);
|
|
413
430
|
const attendee0Id = containerCreatorAttendeeId;
|