@@ -24,6 +24,7 @@ export interface IBesuTestLedgerConstructorOptions {
2424 envVars ?: string [ ] ;
2525 logLevel ?: LogLevelDesc ;
2626 emitContainerLogs ?: boolean ;
27+ networkName ?: string ;
2728}
2829
2930export const BESU_TEST_LEDGER_DEFAULT_OPTIONS = Object . freeze ( {
@@ -32,6 +33,7 @@ export const BESU_TEST_LEDGER_DEFAULT_OPTIONS = Object.freeze({
3233 rpcApiHttpPort : 8545 ,
3334 rpcApiWsPort : 8546 ,
3435 envVars : [ "BESU_NETWORK=dev" ] ,
36+ networkName : "cactus-besu-test-network" ,
3537} ) ;
3638
3739export const BESU_TEST_LEDGER_OPTIONS_JOI_SCHEMA : Joi . Schema =
@@ -48,6 +50,7 @@ export const BESU_TEST_LEDGER_OPTIONS_JOI_SCHEMA: Joi.Schema =
4850 } ) ;
4951
5052export class BesuTestLedger implements ITestLedger {
53+ public static readonly CLASS_NAME = "BesuTestLedger" ;
5154 public readonly containerImageVersion : string ;
5255 public readonly containerImageName : string ;
5356 public readonly rpcApiHttpPort : number ;
@@ -59,9 +62,13 @@ export class BesuTestLedger implements ITestLedger {
5962 private container : Container | undefined ;
6063 private containerId : string | undefined ;
6164
65+ private readonly networkName : string ;
66+
6267 constructor ( public readonly options : IBesuTestLedgerConstructorOptions = { } ) {
6368 if ( ! options ) {
64- throw new TypeError ( `BesuTestLedger#ctor options was falsy.` ) ;
69+ throw new TypeError (
70+ `${ BesuTestLedger . CLASS_NAME } #constructor options was falsy.` ,
71+ ) ;
6572 }
6673 this . containerImageVersion =
6774 options . containerImageVersion ||
@@ -74,6 +81,8 @@ export class BesuTestLedger implements ITestLedger {
7481 this . rpcApiWsPort =
7582 options . rpcApiWsPort || BESU_TEST_LEDGER_DEFAULT_OPTIONS . rpcApiWsPort ;
7683 this . envVars = options . envVars || BESU_TEST_LEDGER_DEFAULT_OPTIONS . envVars ;
84+ this . networkName =
85+ options . networkName || BESU_TEST_LEDGER_DEFAULT_OPTIONS . networkName ;
7786
7887 this . emitContainerLogs = Bools . isBooleanStrict ( options . emitContainerLogs )
7988 ? ( options . emitContainerLogs as boolean )
@@ -98,18 +107,28 @@ export class BesuTestLedger implements ITestLedger {
98107 return `${ this . containerImageName } :${ this . containerImageVersion } ` ;
99108 }
100109
101- public async getRpcApiHttpHost ( ) : Promise < string > {
102- const ipAddress = "127.0.0.1" ;
103- const hostPort : number = await this . getRpcApiPublicPort ( ) ;
104- return `http://${ ipAddress } :${ hostPort } ` ;
110+ public async getRpcApiHttpHost ( asLocalhost : boolean = true ) : Promise < string > {
111+ if ( asLocalhost ) {
112+ const ipAddress = "127.0.0.1" ;
113+ const hostPort : number = await this . getRpcApiPublicPort ( ) ;
114+ return `http://${ ipAddress } :${ hostPort } ` ;
115+ } else {
116+ const hostIp : string = await this . getContainerIpAddress ( ) ;
117+ return `http://${ hostIp } :${ this . rpcApiHttpPort } ` ;
118+ }
105119 }
106120
107- public async getRpcApiWsHost ( ) : Promise < string > {
108- const { rpcApiWsPort } = this ;
109- const ipAddress = "127.0.0.1" ;
110- const containerInfo = await this . getContainerInfo ( ) ;
111- const port = await Containers . getPublicPort ( rpcApiWsPort , containerInfo ) ;
112- return `ws://${ ipAddress } :${ port } ` ;
121+ public async getRpcApiWsHost ( asLocalhost : boolean = true ) : Promise < string > {
122+ if ( asLocalhost ) {
123+ const { rpcApiWsPort } = this ;
124+ const ipAddress = "127.0.0.1" ;
125+ const containerInfo = await this . getContainerInfo ( ) ;
126+ const port = await Containers . getPublicPort ( rpcApiWsPort , containerInfo ) ;
127+ return `ws://${ ipAddress } :${ port } ` ;
128+ } else {
129+ const hostIp : string = await this . getContainerIpAddress ( ) ;
130+ return `ws://${ hostIp } :${ this . rpcApiWsPort } ` ;
131+ }
113132 }
114133
115134 public async getFileContents ( filePath : string ) : Promise < string > {
@@ -255,6 +274,17 @@ export class BesuTestLedger implements ITestLedger {
255274 this . log . debug ( `Pulled ${ imageFqn } OK. Starting container...` ) ;
256275 }
257276
277+ if ( this . networkName ) {
278+ const networks = await docker . listNetworks ( ) ;
279+ const networkExists = networks . some ( ( n ) => n . Name === this . networkName ) ;
280+ if ( ! networkExists ) {
281+ await docker . createNetwork ( {
282+ Name : this . networkName ,
283+ Driver : "bridge" ,
284+ } ) ;
285+ }
286+ }
287+
258288 return new Promise < Container > ( ( resolve , reject ) => {
259289 const eventEmitter : EventEmitter = docker . run (
260290 imageFqn ,
@@ -283,6 +313,7 @@ export class BesuTestLedger implements ITestLedger {
283313 } ,
284314 HostConfig : {
285315 PublishAllPorts : true ,
316+ NetworkMode : this . networkName ,
286317 } ,
287318 Env : this . envVars ,
288319 } ,
@@ -403,23 +434,22 @@ export class BesuTestLedger implements ITestLedger {
403434 }
404435 }
405436
406- public async getContainerIpAddress ( ) : Promise < string > {
437+ public async getContainerIpAddress (
438+ network : string = this . networkName || "bridge" ,
439+ ) : Promise < string > {
407440 const fnTag = "BesuTestLedger#getContainerIpAddress()" ;
408441 const aContainerInfo = await this . getContainerInfo ( ) ;
409442
410- if ( aContainerInfo ) {
411- const { NetworkSettings } = aContainerInfo ;
412- const networkNames : string [ ] = Object . keys ( NetworkSettings . Networks ) ;
413- if ( networkNames . length < 1 ) {
414- throw new Error ( `${ fnTag } container not connected to any networks` ) ;
415- } else {
416- // return IP address of container on the first network that we found
417- // it connected to. Make this configurable?
418- return NetworkSettings . Networks [ networkNames [ 0 ] ] . IPAddress ;
419- }
420- } else {
443+ if ( ! aContainerInfo ) {
421444 throw new Error ( `${ fnTag } cannot find image: ${ this . containerImageName } ` ) ;
422445 }
446+ const { NetworkSettings } = aContainerInfo ;
447+ const networkNames : string [ ] = Object . keys ( NetworkSettings . Networks ) ;
448+ if ( networkNames . length < 1 ) {
449+ throw new Error ( `${ fnTag } container not connected to any networks` ) ;
450+ }
451+
452+ return NetworkSettings . Networks [ network ] . IPAddress ;
423453 }
424454
425455 private pullContainerImage ( containerNameAndTag : string ) : Promise < unknown [ ] > {
@@ -458,4 +488,12 @@ export class BesuTestLedger implements ITestLedger {
458488 ) ;
459489 }
460490 }
491+
492+ public getNetworkName ( ) : string {
493+ const fnTag = `${ BesuTestLedger . CLASS_NAME } #getNetworkName()` ;
494+ if ( this . networkName ) {
495+ return this . networkName ;
496+ }
497+ throw new Error ( `${ fnTag } network name not set` ) ;
498+ }
461499}
0 commit comments