From c2ac197752e5ca32081193e727bd9bba4033046a Mon Sep 17 00:00:00 2001 From: FZambia Date: Tue, 28 Jan 2025 19:37:45 +0200 Subject: [PATCH] multiple runs for many subs test --- src/centrifuge.test.ts | 156 +++++++++++++++++++++-------------------- 1 file changed, 79 insertions(+), 77 deletions(-) diff --git a/src/centrifuge.test.ts b/src/centrifuge.test.ts index 2313403..2297f36 100644 --- a/src/centrifuge.test.ts +++ b/src/centrifuge.test.ts @@ -660,94 +660,96 @@ test.each(transportCases)("%s: connects and subscribes with token", async (trans }); test.each(transportCases)("%s: subscribes and unsubscribes from many subs", async (transport, endpoint) => { - const c = new Centrifuge([{ - transport: transport as TransportName, - endpoint: endpoint, - }], { - websocket: WebSocket, - fetch: fetch, - eventsource: EventSource, - readableStream: ReadableStream, - emulationEndpoint: 'http://localhost:8000/emulation', - // debug: true - }); - // Keep an array of promises so that we can wait for each subscription's 'unsubscribed' event. - const unsubscribedPromises: Promise[] = []; - - const channels = [ - 'test1', - 'test2', - 'test3', - 'test4', - 'test5', - ]; - - // Subscription tokens for anonymous users without ttl. Using an HMAC secret key used in tests ("secret"). - const testTokens = { - 'test1': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3Mzc1MzIzNDgsImNoYW5uZWwiOiJ0ZXN0MSJ9.eqPQxbBtyYxL8Hvbkm-P6aH7chUsSG_EMWe-rTwF_HI", - 'test2': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3Mzc1MzIzODcsImNoYW5uZWwiOiJ0ZXN0MiJ9.tTJB3uSa8XpEmCvfkmrSKclijofnJ5RkQk6L2SaGtUE", - 'test3': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3Mzc1MzIzOTgsImNoYW5uZWwiOiJ0ZXN0MyJ9.nyLcMrIot441CszOKska7kQIjo2sEm8pSxV1XWfNCsI", - 'test4': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3Mzc1MzI0MDksImNoYW5uZWwiOiJ0ZXN0NCJ9.wWAX2AhJX6Ep4HVexQWSVF3-cWytVhzY9Pm7QsMdCsI", - 'test5': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3Mzc1MzI0MTgsImNoYW5uZWwiOiJ0ZXN0NSJ9.hCSfpHYws5TXLKkN0bW0DU6C-wgEUNuhGaIy8W1sT9o" - } + for (let index = 0; index < 5; index++) { + const c = new Centrifuge([{ + transport: transport as TransportName, + endpoint: endpoint, + }], { + websocket: WebSocket, + fetch: fetch, + eventsource: EventSource, + readableStream: ReadableStream, + emulationEndpoint: 'http://localhost:8000/emulation', + // debug: true + }); + // Keep an array of promises so that we can wait for each subscription's 'unsubscribed' event. + const unsubscribedPromises: Promise[] = []; - c.connect(); + const channels = [ + 'test1', + 'test2', + 'test3', + 'test4', + 'test5', + ]; - const subscriptions: any[] = []; + // Subscription tokens for anonymous users without ttl. Using an HMAC secret key used in tests ("secret"). + const testTokens = { + 'test1': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3Mzc1MzIzNDgsImNoYW5uZWwiOiJ0ZXN0MSJ9.eqPQxbBtyYxL8Hvbkm-P6aH7chUsSG_EMWe-rTwF_HI", + 'test2': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3Mzc1MzIzODcsImNoYW5uZWwiOiJ0ZXN0MiJ9.tTJB3uSa8XpEmCvfkmrSKclijofnJ5RkQk6L2SaGtUE", + 'test3': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3Mzc1MzIzOTgsImNoYW5uZWwiOiJ0ZXN0MyJ9.nyLcMrIot441CszOKska7kQIjo2sEm8pSxV1XWfNCsI", + 'test4': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3Mzc1MzI0MDksImNoYW5uZWwiOiJ0ZXN0NCJ9.wWAX2AhJX6Ep4HVexQWSVF3-cWytVhzY9Pm7QsMdCsI", + 'test5': "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3Mzc1MzI0MTgsImNoYW5uZWwiOiJ0ZXN0NSJ9.hCSfpHYws5TXLKkN0bW0DU6C-wgEUNuhGaIy8W1sT9o" + } - for (const channel of channels) { - const sub = c.newSubscription(channel, { - getToken: async function () { - // Sleep for a random time between 0 and 100 milliseconds to emulate network. - const sleep = (ms: any) => new Promise(resolve => setTimeout(resolve, ms)); - await sleep(Math.random() * 100); - return testTokens[channel]; - } - }); + c.connect(); - // Create a promise for the 'unsubscribed' event of this subscription. - const unsubPromise = new Promise((resolve) => { - sub.on("unsubscribed", (ctx) => { - resolve(ctx); + const subscriptions: any[] = []; + + for (const channel of channels) { + const sub = c.newSubscription(channel, { + getToken: async function () { + // Sleep for a random time between 0 and 100 milliseconds to emulate network. + const sleep = (ms: any) => new Promise(resolve => setTimeout(resolve, ms)); + await sleep(Math.random() * 100); + return testTokens[channel]; + } }); - }); - unsubscribedPromises.push(unsubPromise); - // Actually subscribe. - sub.subscribe(); - subscriptions.push(sub); - } + // Create a promise for the 'unsubscribed' event of this subscription. + const unsubPromise = new Promise((resolve) => { + sub.on("unsubscribed", (ctx) => { + resolve(ctx); + }); + }); + unsubscribedPromises.push(unsubPromise); - // Wait until all subscriptions are in the Subscribed state. - await Promise.all( - subscriptions.map(async (sub) => { - await sub.ready(5000); - expect(sub.state).toBe(SubscriptionState.Subscribed); - }) - ); + // Actually subscribe. + sub.subscribe(); + subscriptions.push(sub); + } - // The client itself should be connected now. - expect(c.state).toBe(State.Connected); + // Wait until all subscriptions are in the Subscribed state. + await Promise.all( + subscriptions.map(async (sub) => { + await sub.ready(5000); + expect(sub.state).toBe(SubscriptionState.Subscribed); + }) + ); - // Unsubscribe from all and then disconnect. - subscriptions.forEach((sub) => { - sub.unsubscribe(); - }); - c.disconnect(); + // The client itself should be connected now. + expect(c.state).toBe(State.Connected); - // Wait until all 'unsubscribed' events are received. - const unsubscribedContexts = await Promise.all(unsubscribedPromises); + // Unsubscribe from all and then disconnect. + subscriptions.forEach((sub) => { + sub.unsubscribe(); + }); + c.disconnect(); - // Confirm each subscription is now Unsubscribed. - subscriptions.forEach((sub) => { - expect(sub.state).toBe(SubscriptionState.Unsubscribed); - }); + // Wait until all 'unsubscribed' events are received. + const unsubscribedContexts = await Promise.all(unsubscribedPromises); - // The client should be disconnected. - expect(c.state).toBe(State.Disconnected); + // Confirm each subscription is now Unsubscribed. + subscriptions.forEach((sub) => { + expect(sub.state).toBe(SubscriptionState.Unsubscribed); + }); - // Assert the correct unsubscribe code for each subscription. - unsubscribedContexts.forEach((ctx) => { - expect(ctx.code).toBe(unsubscribedCodes.unsubscribeCalled); - }); + // The client should be disconnected. + expect(c.state).toBe(State.Disconnected); + + // Assert the correct unsubscribe code for each subscription. + unsubscribedContexts.forEach((ctx) => { + expect(ctx.code).toBe(unsubscribedCodes.unsubscribeCalled); + }); + } });