@@ -13,6 +13,7 @@ const { AbortController } = require('native-abort-controller')
13
13
const { isWebWorker, isNode } = require ( 'ipfs-utils/src/env' )
14
14
const getIpfsOptions = require ( '../utils/ipfs-options-websockets-filter-all' )
15
15
const first = require ( 'it-first' )
16
+ const sinon = require ( 'sinon' )
16
17
17
18
/**
18
19
* @typedef {import('ipfsd-ctl').Factory } Factory
@@ -44,12 +45,10 @@ module.exports = (factory, options) => {
44
45
let ipfs2Id
45
46
46
47
before ( async ( ) => {
47
- ipfs1 = ( await factory . spawn ( { type : 'proc' , ipfsOptions } ) ) . api
48
- // TODO 'multiple connected nodes' tests fails with go in Firefox
49
- // and JS is flaky everywhere
48
+ ipfs1 = ( await factory . spawn ( { ipfsOptions } ) ) . api
50
49
51
50
// webworkers are not dialable because webrtc is not available
52
- ipfs2 = ( await factory . spawn ( { type : isWebWorker ? 'go ' : undefined } ) ) . api
51
+ ipfs2 = ( await factory . spawn ( { type : isWebWorker ? 'js ' : undefined , ipfsOptions } ) ) . api
53
52
54
53
ipfs1Id = await ipfs1 . id ( )
55
54
ipfs2Id = await ipfs2 . id ( )
@@ -84,6 +83,7 @@ module.exports = (factory, options) => {
84
83
await ipfs1 . pubsub . publish ( topic , uint8ArrayFromString ( 'hi' ) )
85
84
86
85
const msg = await first ( msgStream )
86
+
87
87
expect ( uint8ArrayToString ( msg . data ) ) . to . equal ( 'hi' )
88
88
expect ( msg ) . to . have . property ( 'seqno' )
89
89
expect ( msg . seqno ) . to . be . an . instanceof ( Uint8Array )
@@ -410,6 +410,139 @@ module.exports = (factory, options) => {
410
410
expect ( uint8ArrayToString ( msg . data ) . startsWith ( msgBase ) ) . to . be . true ( )
411
411
} )
412
412
} )
413
+
414
+ it ( 'should receive messages from a different node on lots of topics' , async ( ) => {
415
+ // @ts -ignore this is mocha
416
+ this . timeout ( 5 * 60 * 1000 )
417
+
418
+ const numTopics = 20
419
+ const topics = [ ]
420
+ const expectedStrings = [ ]
421
+ const msgStreams = [ ]
422
+
423
+ for ( let i = 0 ; i < numTopics ; i ++ ) {
424
+ const topic = `pubsub-topic-${ Math . random ( ) } `
425
+ topics . push ( topic )
426
+
427
+ const msgStream1 = pushable ( )
428
+ const msgStream2 = pushable ( )
429
+
430
+ msgStreams . push ( {
431
+ msgStream1,
432
+ msgStream2
433
+ } )
434
+
435
+ /** @type {import('ipfs-core-types/src/pubsub').MessageHandlerFn } */
436
+ const sub1 = msg => {
437
+ msgStream1 . push ( msg )
438
+ msgStream1 . end ( )
439
+ }
440
+ /** @type {import('ipfs-core-types/src/pubsub').MessageHandlerFn } */
441
+ const sub2 = msg => {
442
+ msgStream2 . push ( msg )
443
+ msgStream2 . end ( )
444
+ }
445
+
446
+ await Promise . all ( [
447
+ ipfs1 . pubsub . subscribe ( topic , sub1 ) ,
448
+ ipfs2 . pubsub . subscribe ( topic , sub2 )
449
+ ] )
450
+
451
+ await waitForPeers ( ipfs2 , topic , [ ipfs1Id . id ] , 30000 )
452
+ }
453
+
454
+ await delay ( 5000 ) // gossipsub needs this delay https://github.com/libp2p/go-libp2p-pubsub/issues/331
455
+
456
+ for ( let i = 0 ; i < numTopics ; i ++ ) {
457
+ const expectedString = `hello pubsub ${ Math . random ( ) } `
458
+ expectedStrings . push ( expectedString )
459
+
460
+ await ipfs2 . pubsub . publish ( topics [ i ] , uint8ArrayFromString ( expectedString ) )
461
+ }
462
+
463
+ for ( let i = 0 ; i < numTopics ; i ++ ) {
464
+ const [ sub1Msg ] = await all ( msgStreams [ i ] . msgStream1 )
465
+ expect ( uint8ArrayToString ( sub1Msg . data ) ) . to . equal ( expectedStrings [ i ] )
466
+ expect ( sub1Msg . from ) . to . eql ( ipfs2Id . id )
467
+
468
+ const [ sub2Msg ] = await all ( msgStreams [ i ] . msgStream2 )
469
+ expect ( uint8ArrayToString ( sub2Msg . data ) ) . to . equal ( expectedStrings [ i ] )
470
+ expect ( sub2Msg . from ) . to . eql ( ipfs2Id . id )
471
+ }
472
+ } )
473
+
474
+ it ( 'should unsubscribe multiple handlers' , async ( ) => {
475
+ // @ts -ignore this is mocha
476
+ this . timeout ( 2 * 60 * 1000 )
477
+
478
+ const topic = `topic-${ Math . random ( ) } `
479
+
480
+ const handler1 = sinon . stub ( )
481
+ const handler2 = sinon . stub ( )
482
+
483
+ await Promise . all ( [
484
+ ipfs1 . pubsub . subscribe ( topic , sinon . stub ( ) ) ,
485
+ ipfs2 . pubsub . subscribe ( topic , handler1 ) ,
486
+ ipfs2 . pubsub . subscribe ( topic , handler2 )
487
+ ] )
488
+
489
+ await waitForPeers ( ipfs1 , topic , [ ipfs2Id . id ] , 30000 )
490
+
491
+ expect ( handler1 ) . to . have . property ( 'callCount' , 0 )
492
+ expect ( handler2 ) . to . have . property ( 'callCount' , 0 )
493
+
494
+ await ipfs1 . pubsub . publish ( topic , uint8ArrayFromString ( 'hello world 1' ) )
495
+
496
+ await delay ( 1000 )
497
+
498
+ expect ( handler1 ) . to . have . property ( 'callCount' , 1 )
499
+ expect ( handler2 ) . to . have . property ( 'callCount' , 1 )
500
+
501
+ await ipfs2 . pubsub . unsubscribe ( topic )
502
+
503
+ await ipfs1 . pubsub . publish ( topic , uint8ArrayFromString ( 'hello world 2' ) )
504
+
505
+ await delay ( 1000 )
506
+
507
+ expect ( handler1 ) . to . have . property ( 'callCount' , 1 )
508
+ expect ( handler2 ) . to . have . property ( 'callCount' , 1 )
509
+ } )
510
+
511
+ it ( 'should unsubscribe individual handlers' , async ( ) => {
512
+ // @ts -ignore this is mocha
513
+ this . timeout ( 2 * 60 * 1000 )
514
+
515
+ const topic = `topic-${ Math . random ( ) } `
516
+
517
+ const handler1 = sinon . stub ( )
518
+ const handler2 = sinon . stub ( )
519
+
520
+ await Promise . all ( [
521
+ ipfs1 . pubsub . subscribe ( topic , sinon . stub ( ) ) ,
522
+ ipfs2 . pubsub . subscribe ( topic , handler1 ) ,
523
+ ipfs2 . pubsub . subscribe ( topic , handler2 )
524
+ ] )
525
+
526
+ await waitForPeers ( ipfs1 , topic , [ ipfs2Id . id ] , 30000 )
527
+
528
+ expect ( handler1 ) . to . have . property ( 'callCount' , 0 )
529
+ expect ( handler2 ) . to . have . property ( 'callCount' , 0 )
530
+
531
+ await ipfs1 . pubsub . publish ( topic , uint8ArrayFromString ( 'hello world 1' ) )
532
+
533
+ await delay ( 1000 )
534
+
535
+ expect ( handler1 ) . to . have . property ( 'callCount' , 1 )
536
+ expect ( handler2 ) . to . have . property ( 'callCount' , 1 )
537
+
538
+ await ipfs2 . pubsub . unsubscribe ( topic , handler1 )
539
+ await ipfs1 . pubsub . publish ( topic , uint8ArrayFromString ( 'hello world 2' ) )
540
+
541
+ await delay ( 1000 )
542
+
543
+ expect ( handler1 ) . to . have . property ( 'callCount' , 1 )
544
+ expect ( handler2 ) . to . have . property ( 'callCount' , 2 )
545
+ } )
413
546
} )
414
547
} )
415
548
}
0 commit comments