@libp2p/interface-compliance-tests 0.0.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +4 -0
- package/README.md +25 -0
- package/dist/src/connection/connection.d.ts +5 -0
- package/dist/src/connection/connection.d.ts.map +1 -0
- package/dist/src/connection/connection.js +148 -0
- package/dist/src/connection/connection.js.map +1 -0
- package/dist/src/connection/index.d.ts +5 -0
- package/dist/src/connection/index.d.ts.map +1 -0
- package/dist/src/connection/index.js +5 -0
- package/dist/src/connection/index.js.map +1 -0
- package/dist/src/crypto/index.d.ts +5 -0
- package/dist/src/crypto/index.d.ts.map +1 -0
- package/dist/src/crypto/index.js +78 -0
- package/dist/src/crypto/index.js.map +1 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +2 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/peer-discovery/index.d.ts +6 -0
- package/dist/src/peer-discovery/index.d.ts.map +1 -0
- package/dist/src/peer-discovery/index.js +63 -0
- package/dist/src/peer-discovery/index.js.map +1 -0
- package/dist/src/pubsub/api.d.ts +6 -0
- package/dist/src/pubsub/api.d.ts.map +1 -0
- package/dist/src/pubsub/api.js +65 -0
- package/dist/src/pubsub/api.js.map +1 -0
- package/dist/src/pubsub/connection-handlers.d.ts +6 -0
- package/dist/src/pubsub/connection-handlers.d.ts.map +1 -0
- package/dist/src/pubsub/connection-handlers.js +279 -0
- package/dist/src/pubsub/connection-handlers.js.map +1 -0
- package/dist/src/pubsub/emit-self.d.ts +6 -0
- package/dist/src/pubsub/emit-self.d.ts.map +1 -0
- package/dist/src/pubsub/emit-self.js +51 -0
- package/dist/src/pubsub/emit-self.js.map +1 -0
- package/dist/src/pubsub/index.d.ts +6 -0
- package/dist/src/pubsub/index.d.ts.map +1 -0
- package/dist/src/pubsub/index.js +17 -0
- package/dist/src/pubsub/index.js.map +1 -0
- package/dist/src/pubsub/messages.d.ts +6 -0
- package/dist/src/pubsub/messages.d.ts.map +1 -0
- package/dist/src/pubsub/messages.js +93 -0
- package/dist/src/pubsub/messages.js.map +1 -0
- package/dist/src/pubsub/multiple-nodes.d.ts +6 -0
- package/dist/src/pubsub/multiple-nodes.d.ts.map +1 -0
- package/dist/src/pubsub/multiple-nodes.js +283 -0
- package/dist/src/pubsub/multiple-nodes.js.map +1 -0
- package/dist/src/pubsub/two-nodes.d.ts +6 -0
- package/dist/src/pubsub/two-nodes.d.ts.map +1 -0
- package/dist/src/pubsub/two-nodes.js +127 -0
- package/dist/src/pubsub/two-nodes.js.map +1 -0
- package/dist/src/pubsub/utils.d.ts +3 -0
- package/dist/src/pubsub/utils.d.ts.map +1 -0
- package/dist/src/pubsub/utils.js +11 -0
- package/dist/src/pubsub/utils.js.map +1 -0
- package/dist/src/record/index.d.ts +5 -0
- package/dist/src/record/index.d.ts.map +1 -0
- package/dist/src/record/index.js +25 -0
- package/dist/src/record/index.js.map +1 -0
- package/dist/src/stream-muxer/base-test.d.ts +5 -0
- package/dist/src/stream-muxer/base-test.d.ts.map +1 -0
- package/dist/src/stream-muxer/base-test.js +123 -0
- package/dist/src/stream-muxer/base-test.js.map +1 -0
- package/dist/src/stream-muxer/close-test.d.ts +5 -0
- package/dist/src/stream-muxer/close-test.d.ts.map +1 -0
- package/dist/src/stream-muxer/close-test.js +103 -0
- package/dist/src/stream-muxer/close-test.js.map +1 -0
- package/dist/src/stream-muxer/index.d.ts +5 -0
- package/dist/src/stream-muxer/index.d.ts.map +1 -0
- package/dist/src/stream-muxer/index.js +13 -0
- package/dist/src/stream-muxer/index.js.map +1 -0
- package/dist/src/stream-muxer/mega-stress-test.d.ts +5 -0
- package/dist/src/stream-muxer/mega-stress-test.d.ts.map +1 -0
- package/dist/src/stream-muxer/mega-stress-test.js +8 -0
- package/dist/src/stream-muxer/mega-stress-test.js.map +1 -0
- package/dist/src/stream-muxer/spawner.d.ts +4 -0
- package/dist/src/stream-muxer/spawner.d.ts.map +1 -0
- package/dist/src/stream-muxer/spawner.js +32 -0
- package/dist/src/stream-muxer/spawner.js.map +1 -0
- package/dist/src/stream-muxer/stress-test.d.ts +5 -0
- package/dist/src/stream-muxer/stress-test.d.ts.map +1 -0
- package/dist/src/stream-muxer/stress-test.js +21 -0
- package/dist/src/stream-muxer/stress-test.js.map +1 -0
- package/dist/src/topology/multicodec-topology.d.ts +5 -0
- package/dist/src/topology/multicodec-topology.d.ts.map +1 -0
- package/dist/src/topology/multicodec-topology.js +109 -0
- package/dist/src/topology/multicodec-topology.js.map +1 -0
- package/dist/src/topology/topology.d.ts +5 -0
- package/dist/src/topology/topology.d.ts.map +1 -0
- package/dist/src/topology/topology.js +29 -0
- package/dist/src/topology/topology.js.map +1 -0
- package/dist/src/transport/dial-test.d.ts +5 -0
- package/dist/src/transport/dial-test.d.ts.map +1 -0
- package/dist/src/transport/dial-test.js +78 -0
- package/dist/src/transport/dial-test.js.map +1 -0
- package/dist/src/transport/filter-test.d.ts +5 -0
- package/dist/src/transport/filter-test.d.ts.map +1 -0
- package/dist/src/transport/filter-test.js +19 -0
- package/dist/src/transport/filter-test.js.map +1 -0
- package/dist/src/transport/index.d.ts +18 -0
- package/dist/src/transport/index.d.ts.map +1 -0
- package/dist/src/transport/index.js +11 -0
- package/dist/src/transport/index.js.map +1 -0
- package/dist/src/transport/listen-test.d.ts +5 -0
- package/dist/src/transport/listen-test.d.ts.map +1 -0
- package/dist/src/transport/listen-test.js +116 -0
- package/dist/src/transport/listen-test.js.map +1 -0
- package/dist/src/transport/utils/index.d.ts +8 -0
- package/dist/src/transport/utils/index.d.ts.map +1 -0
- package/dist/src/transport/utils/index.js +104 -0
- package/dist/src/transport/utils/index.js.map +1 -0
- package/dist/src/utils/peers.d.ts +7 -0
- package/dist/src/utils/peers.d.ts.map +1 -0
- package/dist/src/utils/peers.js +26 -0
- package/dist/src/utils/peers.js.map +1 -0
- package/dist/test/connection/index.spec.d.ts +2 -0
- package/dist/test/connection/index.spec.d.ts.map +1 -0
- package/dist/test/connection/index.spec.js +71 -0
- package/dist/test/connection/index.spec.js.map +1 -0
- package/dist/test/crypto/index.spec.d.ts +2 -0
- package/dist/test/crypto/index.spec.d.ts.map +1 -0
- package/dist/test/crypto/index.spec.js +11 -0
- package/dist/test/crypto/index.spec.js.map +1 -0
- package/dist/test/crypto/mock-crypto.d.ts +4 -0
- package/dist/test/crypto/mock-crypto.d.ts.map +1 -0
- package/dist/test/crypto/mock-crypto.js +93 -0
- package/dist/test/crypto/mock-crypto.js.map +1 -0
- package/dist/test/peer-discovery/index.spec.d.ts +2 -0
- package/dist/test/peer-discovery/index.spec.d.ts.map +1 -0
- package/dist/test/peer-discovery/index.spec.js +18 -0
- package/dist/test/peer-discovery/index.spec.js.map +1 -0
- package/dist/test/peer-discovery/mock-discovery.d.ts +20 -0
- package/dist/test/peer-discovery/mock-discovery.d.ts.map +1 -0
- package/dist/test/peer-discovery/mock-discovery.js +39 -0
- package/dist/test/peer-discovery/mock-discovery.js.map +1 -0
- package/dist/test/topology/mock-peer-store.d.ts +12 -0
- package/dist/test/topology/mock-peer-store.d.ts.map +1 -0
- package/dist/test/topology/mock-peer-store.js +18 -0
- package/dist/test/topology/mock-peer-store.js.map +1 -0
- package/dist/test/topology/multicodec-topology.spec.d.ts +2 -0
- package/dist/test/topology/multicodec-topology.spec.d.ts.map +1 -0
- package/dist/test/topology/multicodec-topology.spec.js +45 -0
- package/dist/test/topology/multicodec-topology.spec.js.map +1 -0
- package/dist/test/topology/topology.spec.d.ts +2 -0
- package/dist/test/topology/topology.spec.d.ts.map +1 -0
- package/dist/test/topology/topology.spec.js +21 -0
- package/dist/test/topology/topology.spec.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +120 -4
- package/src/connection/README.md +256 -0
- package/src/connection/connection.ts +178 -0
- package/src/connection/index.ts +7 -0
- package/src/crypto/index.ts +104 -0
- package/src/index.ts +5 -0
- package/src/peer-discovery/index.ts +87 -0
- package/src/pubsub/api.ts +89 -0
- package/src/pubsub/connection-handlers.ts +356 -0
- package/src/pubsub/emit-self.ts +67 -0
- package/src/pubsub/index.ts +20 -0
- package/src/pubsub/messages.ts +111 -0
- package/src/pubsub/multiple-nodes.ts +353 -0
- package/src/pubsub/two-nodes.ts +175 -0
- package/src/pubsub/utils.ts +13 -0
- package/src/record/index.ts +32 -0
- package/src/stream-muxer/base-test.ts +154 -0
- package/src/stream-muxer/close-test.ts +124 -0
- package/src/stream-muxer/index.ts +15 -0
- package/src/stream-muxer/mega-stress-test.ts +11 -0
- package/src/stream-muxer/spawner.ts +52 -0
- package/src/stream-muxer/stress-test.ts +24 -0
- package/src/topology/multicodec-topology.ts +136 -0
- package/src/topology/topology.ts +38 -0
- package/src/transport/dial-test.ts +98 -0
- package/src/transport/filter-test.ts +26 -0
- package/src/transport/index.ts +29 -0
- package/src/transport/listen-test.ts +152 -0
- package/src/transport/utils/index.ts +123 -0
- package/src/utils/peers.ts +25 -0
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
/* eslint max-nested-callbacks: ["error", 6] */
|
|
2
|
+
import { expect } from 'aegir/utils/chai.js'
|
|
3
|
+
import sinon from 'sinon'
|
|
4
|
+
import delay from 'delay'
|
|
5
|
+
import pDefer from 'p-defer'
|
|
6
|
+
import pWaitFor from 'p-wait-for'
|
|
7
|
+
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
|
|
8
|
+
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
|
|
9
|
+
import { expectSet } from './utils.js'
|
|
10
|
+
import type { TestSetup } from '../index.js'
|
|
11
|
+
import type { PubSub, Message } from '@libp2p/interfaces/pubsub'
|
|
12
|
+
import type { Startable } from '@libp2p/interfaces'
|
|
13
|
+
|
|
14
|
+
export default (common: TestSetup<PubSub & Startable>) => {
|
|
15
|
+
describe('pubsub with multiple nodes', function () {
|
|
16
|
+
describe('every peer subscribes to the topic', () => {
|
|
17
|
+
describe('line', () => {
|
|
18
|
+
// line
|
|
19
|
+
// ◉────◉────◉
|
|
20
|
+
// a b c
|
|
21
|
+
let psA: PubSub & Startable
|
|
22
|
+
let psB: PubSub & Startable
|
|
23
|
+
let psC: PubSub & Startable
|
|
24
|
+
|
|
25
|
+
// Create and start pubsub nodes
|
|
26
|
+
beforeEach(async () => {
|
|
27
|
+
psA = await common.setup()
|
|
28
|
+
psB = await common.setup()
|
|
29
|
+
psC = await common.setup()
|
|
30
|
+
|
|
31
|
+
// Start pubsub modes
|
|
32
|
+
;[psA, psB, psC].map((p) => p.start())
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
// Connect nodes
|
|
36
|
+
beforeEach(async () => {
|
|
37
|
+
// @ts-expect-error protected field
|
|
38
|
+
await psA._libp2p.dial(psB.peerId)
|
|
39
|
+
// @ts-expect-error protected field
|
|
40
|
+
await psB._libp2p.dial(psC.peerId)
|
|
41
|
+
|
|
42
|
+
// Wait for peers to be ready in pubsub
|
|
43
|
+
await pWaitFor(() =>
|
|
44
|
+
psA.peers.size === 1 &&
|
|
45
|
+
psC.peers.size === 1 &&
|
|
46
|
+
psA.peers.size === 1
|
|
47
|
+
)
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
afterEach(async () => {
|
|
51
|
+
sinon.restore()
|
|
52
|
+
|
|
53
|
+
;[psA, psB, psC].map((p) => p.stop())
|
|
54
|
+
await common.teardown()
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
it('subscribe to the topic on node a', async () => {
|
|
58
|
+
const topic = 'Z'
|
|
59
|
+
|
|
60
|
+
psA.subscribe(topic)
|
|
61
|
+
expectSet(psA.subscriptions, [topic])
|
|
62
|
+
|
|
63
|
+
await new Promise((resolve) => psB.once('pubsub:subscription-change', resolve))
|
|
64
|
+
expect(psB.peers.size).to.equal(2)
|
|
65
|
+
|
|
66
|
+
const aPeerId = psA.peerId.toString()
|
|
67
|
+
expectSet(psB.topics.get(topic), [aPeerId])
|
|
68
|
+
|
|
69
|
+
expect(psC.peers.size).to.equal(1)
|
|
70
|
+
expect(psC.topics.get(topic)).to.eql(undefined)
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
it('subscribe to the topic on node b', async () => {
|
|
74
|
+
const topic = 'Z'
|
|
75
|
+
psB.subscribe(topic)
|
|
76
|
+
expectSet(psB.subscriptions, [topic])
|
|
77
|
+
|
|
78
|
+
await Promise.all([
|
|
79
|
+
new Promise((resolve) => psA.once('pubsub:subscription-change', resolve)),
|
|
80
|
+
new Promise((resolve) => psC.once('pubsub:subscription-change', resolve))
|
|
81
|
+
])
|
|
82
|
+
|
|
83
|
+
expect(psA.peers.size).to.equal(1)
|
|
84
|
+
expectSet(psA.topics.get(topic), [psB.peerId.toString()])
|
|
85
|
+
|
|
86
|
+
expect(psC.peers.size).to.equal(1)
|
|
87
|
+
expectSet(psC.topics.get(topic), [psB.peerId.toString()])
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
it('subscribe to the topic on node c', async () => {
|
|
91
|
+
const topic = 'Z'
|
|
92
|
+
const defer = pDefer()
|
|
93
|
+
|
|
94
|
+
psC.subscribe(topic)
|
|
95
|
+
expectSet(psC.subscriptions, [topic])
|
|
96
|
+
|
|
97
|
+
psB.once('pubsub:subscription-change', () => {
|
|
98
|
+
expect(psA.peers.size).to.equal(1)
|
|
99
|
+
expect(psB.peers.size).to.equal(2)
|
|
100
|
+
expectSet(psB.topics.get(topic), [psC.peerId.toString()])
|
|
101
|
+
|
|
102
|
+
defer.resolve()
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
return await defer.promise
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
it('publish on node a', async () => {
|
|
109
|
+
const topic = 'Z'
|
|
110
|
+
const defer = pDefer()
|
|
111
|
+
|
|
112
|
+
psA.subscribe(topic)
|
|
113
|
+
psB.subscribe(topic)
|
|
114
|
+
psC.subscribe(topic)
|
|
115
|
+
|
|
116
|
+
// await subscription change
|
|
117
|
+
await Promise.all([
|
|
118
|
+
new Promise(resolve => psA.once('pubsub:subscription-change', () => resolve(null))),
|
|
119
|
+
new Promise(resolve => psB.once('pubsub:subscription-change', () => resolve(null))),
|
|
120
|
+
new Promise(resolve => psC.once('pubsub:subscription-change', () => resolve(null)))
|
|
121
|
+
])
|
|
122
|
+
|
|
123
|
+
// await a cycle
|
|
124
|
+
await delay(1000)
|
|
125
|
+
|
|
126
|
+
let counter = 0
|
|
127
|
+
|
|
128
|
+
psA.on(topic, incMsg)
|
|
129
|
+
psB.on(topic, incMsg)
|
|
130
|
+
psC.on(topic, incMsg)
|
|
131
|
+
|
|
132
|
+
void psA.publish(topic, uint8ArrayFromString('hey'))
|
|
133
|
+
|
|
134
|
+
function incMsg (msg: Message) {
|
|
135
|
+
expect(uint8ArrayToString(msg.data)).to.equal('hey')
|
|
136
|
+
check()
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function check () {
|
|
140
|
+
if (++counter === 3) {
|
|
141
|
+
psA.removeListener(topic, incMsg)
|
|
142
|
+
psB.removeListener(topic, incMsg)
|
|
143
|
+
psC.removeListener(topic, incMsg)
|
|
144
|
+
defer.resolve()
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return await defer.promise
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
// since the topology is the same, just the publish
|
|
152
|
+
// gets sent by other peer, we reused the same peers
|
|
153
|
+
describe('1 level tree', () => {
|
|
154
|
+
// 1 level tree
|
|
155
|
+
// ┌◉┐
|
|
156
|
+
// │b│
|
|
157
|
+
// ◉─┘ └─◉
|
|
158
|
+
// a c
|
|
159
|
+
|
|
160
|
+
it('publish on node b', async () => {
|
|
161
|
+
const topic = 'Z'
|
|
162
|
+
const defer = pDefer()
|
|
163
|
+
let counter = 0
|
|
164
|
+
|
|
165
|
+
psA.subscribe(topic)
|
|
166
|
+
psB.subscribe(topic)
|
|
167
|
+
psC.subscribe(topic)
|
|
168
|
+
|
|
169
|
+
// await subscription change
|
|
170
|
+
await Promise.all([
|
|
171
|
+
new Promise(resolve => psA.once('pubsub:subscription-change', () => resolve(null))),
|
|
172
|
+
new Promise(resolve => psB.once('pubsub:subscription-change', () => resolve(null))),
|
|
173
|
+
new Promise(resolve => psC.once('pubsub:subscription-change', () => resolve(null)))
|
|
174
|
+
])
|
|
175
|
+
|
|
176
|
+
psA.on(topic, incMsg)
|
|
177
|
+
psB.on(topic, incMsg)
|
|
178
|
+
psC.on(topic, incMsg)
|
|
179
|
+
|
|
180
|
+
// await a cycle
|
|
181
|
+
await delay(1000)
|
|
182
|
+
|
|
183
|
+
void psB.publish(topic, uint8ArrayFromString('hey'))
|
|
184
|
+
|
|
185
|
+
function incMsg (msg: Message) {
|
|
186
|
+
expect(uint8ArrayToString(msg.data)).to.equal('hey')
|
|
187
|
+
check()
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function check () {
|
|
191
|
+
if (++counter === 3) {
|
|
192
|
+
psA.removeListener(topic, incMsg)
|
|
193
|
+
psB.removeListener(topic, incMsg)
|
|
194
|
+
psC.removeListener(topic, incMsg)
|
|
195
|
+
defer.resolve()
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return await defer.promise
|
|
200
|
+
})
|
|
201
|
+
})
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
describe('2 level tree', () => {
|
|
205
|
+
// 2 levels tree
|
|
206
|
+
// ┌◉┐
|
|
207
|
+
// │c│
|
|
208
|
+
// ┌◉─┘ └─◉┐
|
|
209
|
+
// │b d│
|
|
210
|
+
// ◉─┘ └─◉
|
|
211
|
+
// a
|
|
212
|
+
let psA: PubSub & Startable
|
|
213
|
+
let psB: PubSub & Startable
|
|
214
|
+
let psC: PubSub & Startable
|
|
215
|
+
let psD: PubSub & Startable
|
|
216
|
+
let psE: PubSub & Startable
|
|
217
|
+
|
|
218
|
+
// Create and start pubsub nodes
|
|
219
|
+
beforeEach(async () => {
|
|
220
|
+
psA = await common.setup()
|
|
221
|
+
psB = await common.setup()
|
|
222
|
+
psC = await common.setup()
|
|
223
|
+
psD = await common.setup()
|
|
224
|
+
psE = await common.setup()
|
|
225
|
+
|
|
226
|
+
// Start pubsub nodes
|
|
227
|
+
;[psA, psB, psC, psD, psE].map((p) => p.start())
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
// connect nodes
|
|
231
|
+
beforeEach(async () => {
|
|
232
|
+
// @ts-expect-error protected field
|
|
233
|
+
await psA._libp2p.dial(psB.peerId)
|
|
234
|
+
// @ts-expect-error protected field
|
|
235
|
+
await psB._libp2p.dial(psC.peerId)
|
|
236
|
+
// @ts-expect-error protected field
|
|
237
|
+
await psC._libp2p.dial(psD.peerId)
|
|
238
|
+
// @ts-expect-error protected field
|
|
239
|
+
await psD._libp2p.dial(psE.peerId)
|
|
240
|
+
|
|
241
|
+
// Wait for peers to be ready in pubsub
|
|
242
|
+
await pWaitFor(() =>
|
|
243
|
+
psA.peers.size === 1 &&
|
|
244
|
+
psB.peers.size === 2 &&
|
|
245
|
+
psC.peers.size === 2 &&
|
|
246
|
+
psD.peers.size === 2 &&
|
|
247
|
+
psE.peers.size === 1
|
|
248
|
+
)
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
afterEach(async () => {
|
|
252
|
+
[psA, psB, psC, psD, psE].map((p) => p.stop())
|
|
253
|
+
await common.teardown()
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
it('subscribes', () => {
|
|
257
|
+
psA.subscribe('Z')
|
|
258
|
+
expectSet(psA.subscriptions, ['Z'])
|
|
259
|
+
psB.subscribe('Z')
|
|
260
|
+
expectSet(psB.subscriptions, ['Z'])
|
|
261
|
+
psC.subscribe('Z')
|
|
262
|
+
expectSet(psC.subscriptions, ['Z'])
|
|
263
|
+
psD.subscribe('Z')
|
|
264
|
+
expectSet(psD.subscriptions, ['Z'])
|
|
265
|
+
psE.subscribe('Z')
|
|
266
|
+
expectSet(psE.subscriptions, ['Z'])
|
|
267
|
+
})
|
|
268
|
+
|
|
269
|
+
it('publishes from c', async function () {
|
|
270
|
+
const defer = pDefer()
|
|
271
|
+
let counter = 0
|
|
272
|
+
|
|
273
|
+
psA.subscribe('Z')
|
|
274
|
+
psA.on('Z', incMsg)
|
|
275
|
+
psB.subscribe('Z')
|
|
276
|
+
psB.on('Z', incMsg)
|
|
277
|
+
psC.subscribe('Z')
|
|
278
|
+
psC.on('Z', incMsg)
|
|
279
|
+
psD.subscribe('Z')
|
|
280
|
+
psD.on('Z', incMsg)
|
|
281
|
+
psE.subscribe('Z')
|
|
282
|
+
psE.on('Z', incMsg)
|
|
283
|
+
|
|
284
|
+
await Promise.all([
|
|
285
|
+
new Promise((resolve) => psA.once('pubsub:subscription-change', resolve)),
|
|
286
|
+
new Promise((resolve) => psB.once('pubsub:subscription-change', resolve)),
|
|
287
|
+
new Promise((resolve) => psC.once('pubsub:subscription-change', resolve)),
|
|
288
|
+
new Promise((resolve) => psD.once('pubsub:subscription-change', resolve)),
|
|
289
|
+
new Promise((resolve) => psE.once('pubsub:subscription-change', resolve))
|
|
290
|
+
])
|
|
291
|
+
|
|
292
|
+
// await a cycle
|
|
293
|
+
await delay(1000)
|
|
294
|
+
|
|
295
|
+
void psC.publish('Z', uint8ArrayFromString('hey from c'))
|
|
296
|
+
|
|
297
|
+
function incMsg (msg: Message) {
|
|
298
|
+
expect(uint8ArrayToString(msg.data)).to.equal('hey from c')
|
|
299
|
+
check()
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function check () {
|
|
303
|
+
if (++counter === 5) {
|
|
304
|
+
psA.unsubscribe('Z')
|
|
305
|
+
psB.unsubscribe('Z')
|
|
306
|
+
psC.unsubscribe('Z')
|
|
307
|
+
psD.unsubscribe('Z')
|
|
308
|
+
psE.unsubscribe('Z')
|
|
309
|
+
defer.resolve()
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return await defer.promise
|
|
314
|
+
})
|
|
315
|
+
})
|
|
316
|
+
})
|
|
317
|
+
|
|
318
|
+
describe('only some nodes subscribe the networks', () => {
|
|
319
|
+
describe('line', () => {
|
|
320
|
+
// line
|
|
321
|
+
// ◉────◎────◉
|
|
322
|
+
// a b c
|
|
323
|
+
|
|
324
|
+
before(() => { })
|
|
325
|
+
after(() => { })
|
|
326
|
+
})
|
|
327
|
+
|
|
328
|
+
describe('1 level tree', () => {
|
|
329
|
+
// 1 level tree
|
|
330
|
+
// ┌◉┐
|
|
331
|
+
// │b│
|
|
332
|
+
// ◎─┘ └─◉
|
|
333
|
+
// a c
|
|
334
|
+
|
|
335
|
+
before(() => { })
|
|
336
|
+
after(() => { })
|
|
337
|
+
})
|
|
338
|
+
|
|
339
|
+
describe('2 level tree', () => {
|
|
340
|
+
// 2 levels tree
|
|
341
|
+
// ┌◉┐
|
|
342
|
+
// │c│
|
|
343
|
+
// ┌◎─┘ └─◉┐
|
|
344
|
+
// │b d│
|
|
345
|
+
// ◉─┘ └─◎
|
|
346
|
+
// a e
|
|
347
|
+
|
|
348
|
+
before(() => { })
|
|
349
|
+
after(() => { })
|
|
350
|
+
})
|
|
351
|
+
})
|
|
352
|
+
})
|
|
353
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/* eslint max-nested-callbacks: ["error", 6] */
|
|
2
|
+
import { expect } from 'aegir/utils/chai.js'
|
|
3
|
+
import sinon from 'sinon'
|
|
4
|
+
import pDefer from 'p-defer'
|
|
5
|
+
import pWaitFor from 'p-wait-for'
|
|
6
|
+
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
|
|
7
|
+
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
|
|
8
|
+
import type { TestSetup } from '../index.js'
|
|
9
|
+
import type { PubSub, Message } from '@libp2p/interfaces/pubsub'
|
|
10
|
+
import {
|
|
11
|
+
first,
|
|
12
|
+
expectSet
|
|
13
|
+
} from './utils.js'
|
|
14
|
+
import type { Startable } from '@libp2p/interfaces'
|
|
15
|
+
|
|
16
|
+
const topic = 'foo'
|
|
17
|
+
|
|
18
|
+
function shouldNotHappen () {
|
|
19
|
+
expect.fail()
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default (common: TestSetup<PubSub & Startable>) => {
|
|
23
|
+
describe('pubsub with two nodes', () => {
|
|
24
|
+
let psA: PubSub & Startable
|
|
25
|
+
let psB: PubSub & Startable
|
|
26
|
+
|
|
27
|
+
// Create pubsub nodes and connect them
|
|
28
|
+
before(async () => {
|
|
29
|
+
psA = await common.setup()
|
|
30
|
+
psB = await common.setup()
|
|
31
|
+
|
|
32
|
+
expect(psA.peers.size).to.be.eql(0)
|
|
33
|
+
expect(psB.peers.size).to.be.eql(0)
|
|
34
|
+
|
|
35
|
+
// Start pubsub and connect nodes
|
|
36
|
+
await psA.start()
|
|
37
|
+
await psB.start()
|
|
38
|
+
|
|
39
|
+
// @ts-expect-error protected property
|
|
40
|
+
await psA._libp2p.dial(psB.peerId)
|
|
41
|
+
|
|
42
|
+
// Wait for peers to be ready in pubsub
|
|
43
|
+
await pWaitFor(() => psA.peers.size === 1 && psB.peers.size === 1)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
after(async () => {
|
|
47
|
+
sinon.restore()
|
|
48
|
+
|
|
49
|
+
await psA.stop()
|
|
50
|
+
await psB.stop()
|
|
51
|
+
|
|
52
|
+
await common.teardown()
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
it('Subscribe to a topic in nodeA', async () => {
|
|
56
|
+
const defer = pDefer()
|
|
57
|
+
|
|
58
|
+
psB.once('pubsub:subscription-change', ({ peerId: changedPeerId, subscriptions: changedSubs }) => {
|
|
59
|
+
expectSet(psA.subscriptions, [topic])
|
|
60
|
+
expect(psB.peers.size).to.equal(1)
|
|
61
|
+
expectSet(psB.topics.get(topic), [psA.peerId.toString()])
|
|
62
|
+
expect(changedPeerId.toString()).to.equal(first(psB.peers).id.toString())
|
|
63
|
+
expect(changedSubs).to.have.lengthOf(1)
|
|
64
|
+
expect(changedSubs[0].topicID).to.equal(topic)
|
|
65
|
+
expect(changedSubs[0].subscribe).to.equal(true)
|
|
66
|
+
defer.resolve()
|
|
67
|
+
})
|
|
68
|
+
psA.subscribe(topic)
|
|
69
|
+
|
|
70
|
+
return await defer.promise
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
it('Publish to a topic in nodeA', async () => {
|
|
74
|
+
const defer = pDefer()
|
|
75
|
+
|
|
76
|
+
psA.once(topic, (msg) => {
|
|
77
|
+
expect(uint8ArrayToString(msg.data)).to.equal('hey')
|
|
78
|
+
psB.removeListener(topic, shouldNotHappen)
|
|
79
|
+
defer.resolve()
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
psB.once(topic, shouldNotHappen)
|
|
83
|
+
|
|
84
|
+
void psA.publish(topic, uint8ArrayFromString('hey'))
|
|
85
|
+
|
|
86
|
+
return await defer.promise
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('Publish to a topic in nodeB', async () => {
|
|
90
|
+
const defer = pDefer()
|
|
91
|
+
|
|
92
|
+
psA.once(topic, (msg) => {
|
|
93
|
+
psA.once(topic, shouldNotHappen)
|
|
94
|
+
expect(uint8ArrayToString(msg.data)).to.equal('banana')
|
|
95
|
+
|
|
96
|
+
setTimeout(() => {
|
|
97
|
+
psA.removeListener(topic, shouldNotHappen)
|
|
98
|
+
psB.removeListener(topic, shouldNotHappen)
|
|
99
|
+
|
|
100
|
+
defer.resolve()
|
|
101
|
+
}, 100)
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
psB.once(topic, shouldNotHappen)
|
|
105
|
+
|
|
106
|
+
void psB.publish(topic, uint8ArrayFromString('banana'))
|
|
107
|
+
|
|
108
|
+
return await defer.promise
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
it('Publish 10 msg to a topic in nodeB', async () => {
|
|
112
|
+
const defer = pDefer()
|
|
113
|
+
let counter = 0
|
|
114
|
+
|
|
115
|
+
psB.once(topic, shouldNotHappen)
|
|
116
|
+
psA.on(topic, receivedMsg)
|
|
117
|
+
|
|
118
|
+
function receivedMsg (msg: Message) {
|
|
119
|
+
expect(uint8ArrayToString(msg.data)).to.equal('banana')
|
|
120
|
+
expect(msg.from).to.be.eql(psB.peerId.toString())
|
|
121
|
+
expect(msg.seqno).to.be.a('Uint8Array')
|
|
122
|
+
expect(msg.topicIDs).to.be.eql([topic])
|
|
123
|
+
|
|
124
|
+
if (++counter === 10) {
|
|
125
|
+
psA.removeListener(topic, receivedMsg)
|
|
126
|
+
psB.removeListener(topic, shouldNotHappen)
|
|
127
|
+
|
|
128
|
+
defer.resolve()
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
Array.from({ length: 10 }, async (_, i) => await psB.publish(topic, uint8ArrayFromString('banana')))
|
|
133
|
+
|
|
134
|
+
return await defer.promise
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
it('Unsubscribe from topic in nodeA', async () => {
|
|
138
|
+
const defer = pDefer()
|
|
139
|
+
|
|
140
|
+
psA.unsubscribe(topic)
|
|
141
|
+
expect(psA.subscriptions.size).to.equal(0)
|
|
142
|
+
|
|
143
|
+
psB.once('pubsub:subscription-change', ({ peerId: changedPeerId, subscriptions: changedSubs }) => {
|
|
144
|
+
expect(psB.peers.size).to.equal(1)
|
|
145
|
+
expectSet(psB.topics.get(topic), [])
|
|
146
|
+
expect(changedPeerId.toString()).to.equal(first(psB.peers).id.toString())
|
|
147
|
+
expect(changedSubs).to.have.lengthOf(1)
|
|
148
|
+
expect(changedSubs[0].topicID).to.equal(topic)
|
|
149
|
+
expect(changedSubs[0].subscribe).to.equal(false)
|
|
150
|
+
|
|
151
|
+
defer.resolve()
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
return await defer.promise
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
it('Publish to a topic:Z in nodeA nodeB', async () => {
|
|
158
|
+
const defer = pDefer()
|
|
159
|
+
|
|
160
|
+
psA.once('Z', shouldNotHappen)
|
|
161
|
+
psB.once('Z', shouldNotHappen)
|
|
162
|
+
|
|
163
|
+
setTimeout(() => {
|
|
164
|
+
psA.removeListener('Z', shouldNotHappen)
|
|
165
|
+
psB.removeListener('Z', shouldNotHappen)
|
|
166
|
+
defer.resolve()
|
|
167
|
+
}, 100)
|
|
168
|
+
|
|
169
|
+
void psB.publish('Z', uint8ArrayFromString('banana'))
|
|
170
|
+
void psA.publish('Z', uint8ArrayFromString('banana'))
|
|
171
|
+
|
|
172
|
+
return await defer.promise
|
|
173
|
+
})
|
|
174
|
+
})
|
|
175
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { expect } from 'aegir/utils/chai.js'
|
|
2
|
+
|
|
3
|
+
export function first <V> (map: Map<any, V>): V {
|
|
4
|
+
return map.values().next().value
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function expectSet <T> (set?: Set<T>, subs?: T[]) {
|
|
8
|
+
if ((set == null) || (subs == null)) {
|
|
9
|
+
throw new Error('No set or subs passed')
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
expect(Array.from(set.values())).to.eql(subs)
|
|
13
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { expect } from 'aegir/utils/chai.js'
|
|
2
|
+
import type { TestSetup } from '../index.js'
|
|
3
|
+
import type { Record } from '@libp2p/interfaces/record'
|
|
4
|
+
|
|
5
|
+
export default (test: TestSetup<Record>) => {
|
|
6
|
+
describe('record', () => {
|
|
7
|
+
let record: Record
|
|
8
|
+
|
|
9
|
+
beforeEach(async () => {
|
|
10
|
+
record = await test.setup()
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
afterEach(async () => {
|
|
14
|
+
await test.teardown()
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
it('has domain and codec', () => {
|
|
18
|
+
expect(record.domain).to.exist()
|
|
19
|
+
expect(record.codec).to.exist()
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('is able to marshal', () => {
|
|
23
|
+
const rawData = record.marshal()
|
|
24
|
+
expect(rawData).to.be.an.instanceof(Uint8Array)
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
it('is able to compare two records', () => {
|
|
28
|
+
const equals = record.equals(record)
|
|
29
|
+
expect(equals).to.eql(true)
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
}
|