Skip to content

Commit dfb8cc9

Browse files
committed
wip: test for clients sharing a socket
* Related #14 [ci skip]
1 parent 49328d5 commit dfb8cc9

File tree

1 file changed

+126
-3
lines changed

1 file changed

+126
-3
lines changed

tests/concurrency.test.ts

Lines changed: 126 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Logger, { formatting, LogLevel, StreamHandler } from '@matrixai/logger';
66
import QUICServer from '@/QUICServer';
77
import { promise } from '@/utils';
88
import QUICClient from '@/QUICClient';
9+
import QUICSocket from '@/QUICSocket';
910
import { tlsConfigWithCaArb } from './tlsUtils';
1011
import { sleep } from './utils';
1112
import * as testsUtils from './utils';
@@ -138,7 +139,7 @@ describe('Concurrency tests', () => {
138139
})
139140
.noShrink() as fc.Arbitrary<ConnectionData>;
140141
const connectionsArb = fc
141-
.array(connectionArb, { minLength: 1, size: 'small' })
142+
.array(connectionArb, { minLength: 2, size: 'small' })
142143
.noShrink() as fc.Arbitrary<Array<ConnectionData>>;
143144

144145
testProp(
@@ -242,7 +243,6 @@ describe('Concurrency tests', () => {
242243
})();
243244
} catch (e) {
244245
logger.error(`test failed with ${e.message}`);
245-
console.error(e);
246246
throw e;
247247
} finally {
248248
logger.info('STARTING TEST FINALLY');
@@ -255,6 +255,129 @@ describe('Concurrency tests', () => {
255255
}
256256
logger.info('TEST FULLY DONE!');
257257
},
258-
{ numRuns: 3, timeout: 50000 },
258+
{ numRuns: 3 },
259+
);
260+
testProp.only(
261+
'Multiple clients sharing a socket',
262+
[tlsConfigWithCaArb, connectionsArb, streamsArb(3)],
263+
async (tlsConfigProm, clientDatas, serverStreams) => {
264+
const tlsConfig = await tlsConfigProm;
265+
const cleanUpHoldProm = promise<void>();
266+
const serverProm = (async () => {
267+
const server = new QUICServer({
268+
crypto,
269+
logger: logger.getChild(QUICServer.name),
270+
config: {
271+
tlsConfig: tlsConfig.tlsConfig,
272+
verifyPeer: false,
273+
},
274+
});
275+
const connProms: Array<Promise<void>> = [];
276+
server.addEventListener(
277+
'connection',
278+
async (e: events.QUICServerConnectionEvent) => {
279+
const conn = e.detail;
280+
const connProm = (async () => {
281+
const serverStreamProms: Array<Promise<void>> = [];
282+
conn.addEventListener(
283+
'stream',
284+
(streamEvent: events.QUICConnectionStreamEvent) => {
285+
const stream = streamEvent.detail;
286+
const streamData =
287+
serverStreams[
288+
serverStreamProms.length % serverStreams.length
289+
];
290+
serverStreamProms.push(handleStreamProm(stream, streamData));
291+
},
292+
);
293+
try {
294+
await cleanUpHoldProm.p;
295+
await Promise.all(serverStreamProms);
296+
} finally {
297+
await conn.destroy({ force: true });
298+
logger.info(
299+
`server conn result ${JSON.stringify(
300+
await Promise.allSettled(serverStreamProms),
301+
)}`,
302+
);
303+
}
304+
})();
305+
connProms.push(connProm);
306+
},
307+
);
308+
await sleep(100);
309+
await server.start({
310+
host: '127.0.0.1' as Host,
311+
port: 55556 as Port,
312+
});
313+
try {
314+
await cleanUpHoldProm.p;
315+
await Promise.all(connProms);
316+
} finally {
317+
await server.stop({ force: true });
318+
logger.info(
319+
`server result ${JSON.stringify(
320+
await Promise.allSettled(connProms),
321+
)}`,
322+
);
323+
}
324+
})();
325+
// Creating socket
326+
const socket = new QUICSocket({
327+
crypto,
328+
logger: logger.getChild('socket'),
329+
});
330+
await socket.start({
331+
host: '127.0.0.1' as Host,
332+
});
333+
334+
// Creating client activity
335+
logger.info('STARTING CLIENTS');
336+
const clientProms: Array<Promise<void>> = [];
337+
for (const clientData of clientDatas) {
338+
const clientProm = sleep(clientData.startDelay)
339+
.then(() => {
340+
logger.info('STARTING CLIENT');
341+
return QUICClient.createQUICClient({
342+
host: '127.0.0.1' as Host,
343+
port: 55556 as Port,
344+
socket,
345+
crypto,
346+
logger: logger.getChild(QUICClient.name),
347+
config: {
348+
verifyPeer: false,
349+
},
350+
});
351+
})
352+
.then((client) => {
353+
return handleClientProm(client, clientData);
354+
});
355+
clientProms.push(clientProm);
356+
}
357+
// Wait for running activity to finish, should complete without error
358+
logger.info('STARTING TEST');
359+
try {
360+
await (async () => {
361+
await Promise.all(clientProms);
362+
// Allow for streams to be negotiated
363+
await sleep(200);
364+
cleanUpHoldProm.resolveP();
365+
await serverProm;
366+
})();
367+
} catch (e) {
368+
logger.error(`test failed with ${e.message}`);
369+
throw e;
370+
} finally {
371+
logger.info('STARTING TEST FINALLY');
372+
cleanUpHoldProm.resolveP();
373+
logger.info(
374+
`test result ${JSON.stringify(
375+
await Promise.allSettled([...clientProms, serverProm]),
376+
)}`,
377+
);
378+
}
379+
logger.info('TEST FULLY DONE!');
380+
},
381+
{ numRuns: 3 },
259382
);
260383
});

0 commit comments

Comments
 (0)