1 |
|
2 |
|
3 | 'use strict'
|
4 |
|
5 | const chai = require('chai')
|
6 | chai.use(require('dirty-chai'))
|
7 | const expect = chai.expect
|
8 |
|
9 | const IPFS = require('ipfs')
|
10 | const each = require('async/each')
|
11 | const clone = require('lodash.clonedeep')
|
12 |
|
13 | const Room = require('../')
|
14 | const createRepo = require('./utils/create-repo-node')
|
15 |
|
16 | const topic = 'pubsub-room-concurrency-test-' + Date.now() + '-' + Math.random()
|
17 |
|
18 | const ipfsOptions = {
|
19 | EXPERIMENTAL: {
|
20 | pubsub: true
|
21 | },
|
22 | config: {
|
23 | Addresses: {
|
24 | Swarm: [
|
25 | '/dns4/ws-star.discovery.libp2p.io/tcp/443/wss/p2p-websocket-star'
|
26 | ]
|
27 | }
|
28 | }
|
29 | }
|
30 |
|
31 | describe('concurrent rooms', function () {
|
32 | this.timeout(30000)
|
33 | const repos = []
|
34 | let node1, node2
|
35 | let id1, id2
|
36 | let room1A, room1B, room2A, room2B
|
37 | const topicA = topic + '-A'
|
38 | const topicB = topic + '-B'
|
39 |
|
40 | before((done) => {
|
41 | const repo = createRepo()
|
42 | repos.push(repo)
|
43 | const options = Object.assign({}, clone(ipfsOptions), {
|
44 | repo: repo
|
45 | })
|
46 | node1 = new IPFS(options)
|
47 | node1.once('ready', () => {
|
48 | node1.id((err, info) => {
|
49 | expect(err).to.not.exist()
|
50 | id1 = info.id
|
51 | done()
|
52 | })
|
53 | })
|
54 | })
|
55 |
|
56 | before((done) => {
|
57 | const repo = createRepo()
|
58 | repos.push(repo)
|
59 | const options = Object.assign({}, clone(ipfsOptions), {
|
60 | repo: repo
|
61 | })
|
62 | node2 = new IPFS(options)
|
63 | node2.once('ready', () => {
|
64 | node2.id((err, info) => {
|
65 | expect(err).to.not.exist()
|
66 | id2 = info.id
|
67 | done()
|
68 | })
|
69 | })
|
70 | })
|
71 |
|
72 | after((done) => each(repos, (repo, cb) => { repo.teardown(cb) }, done))
|
73 |
|
74 | it('can create a room, and they find each other', (done) => {
|
75 | room1A = Room(node1, topicA)
|
76 | room2A = Room(node2, topicA)
|
77 | room1B = Room(node1, topicB)
|
78 | room2B = Room(node2, topicB)
|
79 | room1A.on('warning', console.log)
|
80 | room2A.on('warning', console.log)
|
81 | room1B.on('warning', console.log)
|
82 | room2B.on('warning', console.log)
|
83 |
|
84 | const roomNodes = [
|
85 | [room1A, id2],
|
86 | [room2A, id1],
|
87 | [room1B, id2],
|
88 | [room2A, id1]
|
89 | ]
|
90 |
|
91 | each(roomNodes, (roomNode, cb) => {
|
92 | const room = roomNode[0]
|
93 | const waitingFor = roomNode[1]
|
94 | room.once('peer joined', (id) => {
|
95 | expect(id).to.equal(waitingFor)
|
96 | cb()
|
97 | })
|
98 | }, done)
|
99 | })
|
100 |
|
101 | it('has peer', (done) => {
|
102 | expect(room1A.getPeers()).to.deep.equal([id2])
|
103 | expect(room1B.getPeers()).to.deep.equal([id2])
|
104 | expect(room2A.getPeers()).to.deep.equal([id1])
|
105 | expect(room2B.getPeers()).to.deep.equal([id1])
|
106 | done()
|
107 | })
|
108 |
|
109 | it('can broadcast', (done) => {
|
110 | let gotMessage = false
|
111 | const crash = Crash('no broadcast message should leak to room B')
|
112 | room1B.on('message', crash)
|
113 | room1A.once('message', (message) => {
|
114 | if (gotMessage) {
|
115 | throw new Error('double message')
|
116 | }
|
117 | gotMessage = true
|
118 | expect(message.from).to.equal(id2)
|
119 | expect(message.data.toString()).to.equal('message 1')
|
120 |
|
121 | room1B.removeListener('message', crash)
|
122 | done()
|
123 | })
|
124 | room2A.broadcast('message 1')
|
125 | })
|
126 |
|
127 | it('can send private message', (done) => {
|
128 | const crash = Crash('no private message should leak to room B')
|
129 |
|
130 | room2B.on('message', crash)
|
131 | room2A.once('message', (message) => {
|
132 | expect(message.from).to.equal(id1)
|
133 | expect(message.seqno.toString()).to.equal(Buffer.from([0]).toString())
|
134 | expect(message.topicIDs).to.deep.equal([topicA])
|
135 | expect(message.topicCIDs).to.deep.equal([topicA])
|
136 | expect(message.data.toString()).to.equal('message 2')
|
137 | room2B.removeListener('message', crash)
|
138 | done()
|
139 | })
|
140 | room1A.sendTo(id2, 'message 2')
|
141 | })
|
142 |
|
143 | it('can leave room', (done) => {
|
144 | room1A.once('peer left', (peer) => {
|
145 | expect(peer).to.equal(id2)
|
146 | done()
|
147 | })
|
148 | room2A.leave()
|
149 | })
|
150 |
|
151 | it('after leaving, it does not receive more messages', (done) => {
|
152 | room2A.on('message', Crash('should not receive this'))
|
153 | room2A.leave()
|
154 | room1A.broadcast('message 3')
|
155 | setTimeout(done, 3000)
|
156 | })
|
157 | })
|
158 |
|
159 | function Crash (message) {
|
160 | return function () {
|
161 | throw new Error(message)
|
162 | }
|
163 | }
|