@@ -7,7 +7,10 @@ import { IrcServer } from "../../src/irc/IrcServer";
77import { MatrixClient } from "matrix-bot-sdk" ;
88import { TestIrcServer } from "matrix-org-irc" ;
99import { IrcConnectionPool } from "../../src/pool-service/IrcConnectionPool" ;
10+ import { expect } from "@jest/globals" ;
1011import dns from 'node:dns' ;
12+ import fs from "node:fs/promises" ;
13+ import { WriteStream , createWriteStream } from "node:fs" ;
1114// Needed to make tests work on GitHub actions. Node 17+ defaults
1215// to IPv6, and the homerunner domain resolves to IPv6, but the
1316// runtime doesn't actually support IPv6 🤦
@@ -24,8 +27,11 @@ interface Opts {
2427 ircNicks ?: string [ ] ;
2528 timeout ?: number ;
2629 config ?: Partial < BridgeConfig > ,
30+ traceToFile ?: boolean ,
2731}
2832
33+ const traceFilePath = '.e2e-traces' ;
34+
2935export class E2ETestMatrixClient extends MatrixClient {
3036
3137 public async waitForPowerLevel (
@@ -160,6 +166,21 @@ export class IrcBridgeE2ETest {
160166 }
161167
162168 static async createTestEnv ( opts : Opts = { } ) : Promise < IrcBridgeE2ETest > {
169+ let traceStream ;
170+ if ( opts . traceToFile ) {
171+ const testName = expect . getState ( ) . currentTestName ?. replace ( / [ ^ a - z A - Z ] / g, '-' ) ;
172+ const tracePath = `${ traceFilePath } /${ testName } .log` ;
173+ try {
174+ await fs . mkdir ( traceFilePath ) ;
175+ }
176+ catch ( ex ) {
177+ if ( ex . code !== 'EEXIST' ) {
178+ throw ex ;
179+ }
180+ }
181+ traceStream = createWriteStream ( tracePath , 'utf-8' ) ;
182+ }
183+
163184 const workerID = parseInt ( process . env . JEST_WORKER_ID ?? '0' ) ;
164185 const { matrixLocalparts, config } = opts ;
165186 const ircTest = new TestIrcServer ( ) ;
@@ -280,7 +301,7 @@ export class IrcBridgeE2ETest {
280301 }
281302 } ) ,
282303 } , registration ) ;
283- return new IrcBridgeE2ETest ( homeserver , ircBridge , registration , postgresDb , ircTest , redisPool )
304+ return new IrcBridgeE2ETest ( homeserver , ircBridge , registration , postgresDb , ircTest , redisPool , traceStream )
284305 }
285306
286307 private constructor (
@@ -289,7 +310,26 @@ export class IrcBridgeE2ETest {
289310 public readonly registration : AppServiceRegistration ,
290311 readonly postgresDb : string ,
291312 public readonly ircTest : TestIrcServer ,
292- public readonly pool ?: IrcConnectionPool ) {
313+ public readonly pool ?: IrcConnectionPool ,
314+ private traceLog ?: WriteStream ,
315+ ) {
316+ const startTime = Date . now ( ) ;
317+ if ( traceLog ) {
318+ for ( const [ clientId , client ] of Object . entries ( ircTest . clients ) ) {
319+ client . on ( 'raw' , ( msg ) => {
320+ traceLog . write (
321+ `${ Date . now ( ) - startTime } ms [IRC:${ clientId } ] ${ JSON . stringify ( msg ) } \n`
322+ ) ;
323+ } )
324+ }
325+ for ( const { client, userId} of Object . values ( homeserver . users ) ) {
326+ client . on ( 'room.event' , ( roomId , eventData ) => {
327+ traceLog . write (
328+ `${ Date . now ( ) - startTime } ms [Matrix:${ userId } ] ${ roomId } ${ JSON . stringify ( eventData ) } \n`
329+ ) ;
330+ } )
331+ }
332+ }
293333 }
294334
295335 public async recreateBridge ( ) {
@@ -317,6 +357,9 @@ export class IrcBridgeE2ETest {
317357 }
318358
319359 public async tearDown ( ) : Promise < void > {
360+ if ( this . traceLog ) {
361+ this . traceLog . close ( ) ;
362+ }
320363 await Promise . allSettled ( [
321364 this . ircBridge ?. kill ( ) ,
322365 this . ircTest . tearDown ( ) ,
0 commit comments