Skip to content
This repository was archived by the owner on Aug 1, 2023. It is now read-only.

Commit 5c46bc3

Browse files
committed
test: add ipns pubsub tests
1 parent b271ea8 commit 5c46bc3

File tree

5 files changed

+404
-18
lines changed

5 files changed

+404
-18
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@
5151
"form-data": "^2.3.2",
5252
"go-ipfs-dep": "~0.4.17",
5353
"hat": "0.0.3",
54-
"ipfs": "~0.33.0-rc.2",
55-
"ipfs-api": "^25.0.0",
54+
"ipfs": "ipfs/js-ipfs#feat/ipns-over-pubsub",
55+
"ipfs-api": "ipfs/js-ipfs-api#master",
5656
"ipfs-unixfs": "~0.1.15",
5757
"ipfsd-ctl": "~0.39.1",
5858
"left-pad": "^1.3.0",

test/name-pubsub.js

Lines changed: 376 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,376 @@
1+
/* eslint-env mocha */
2+
'use strict'
3+
4+
const chai = require('chai')
5+
const dirtyChai = require('dirty-chai')
6+
const expect = chai.expect
7+
chai.use(dirtyChai)
8+
9+
const { fromB58String } = require('multihashes')
10+
11+
const parallel = require('async/parallel')
12+
const retry = require('async/retry')
13+
const series = require('async/series')
14+
15+
const IPFS = require('ipfs')
16+
const DaemonFactory = require('ipfsd-ctl')
17+
18+
const waitFor = require('./utils/wait-for')
19+
20+
const config = {
21+
Addresses: {
22+
API: '/ip4/0.0.0.0/tcp/0',
23+
Gateway: '/ip4/0.0.0.0/tcp/0',
24+
Swarm: []
25+
},
26+
Bootstrap: []
27+
}
28+
29+
const spawnJsDaemon = (callback) => {
30+
// DaemonFactory.create({ type: 'js' })
31+
DaemonFactory.create({ type: 'proc', exec: IPFS }) // TODO change after debuggin
32+
.spawn({
33+
disposable: true,
34+
initOptions: { bits: 512 },
35+
args: ['--enable-namesys-pubsub'], // enable ipns over pubsub
36+
config
37+
}, callback)
38+
}
39+
40+
const spawnGoDaemon = (callback) => {
41+
DaemonFactory.create()
42+
.spawn({
43+
disposable: true,
44+
initOptions: { bits: 1024 },
45+
args: ['--enable-namesys-pubsub'],
46+
config
47+
}, callback)
48+
}
49+
50+
const subscribeToReceiveByPubsub = (nodeA, nodeB, nodeAId, callback) => {
51+
const topic = `/ipns/${fromB58String(nodeAId.id).toString()}`
52+
let subscribed = false
53+
54+
nodeB.api.name.resolve(nodeAId.id, (err) => {
55+
expect(err).to.exist()
56+
57+
function checkMessage(msg) {
58+
subscribed = true
59+
}
60+
61+
series([
62+
(cb) => waitForPeerToSubscribe(nodeB.api, cb),
63+
(cb) => nodeB.api.pubsub.subscribe(topic, checkMessage, cb),
64+
(cb) => nodeA.api.name.publish(ipfsRef, { resolve: false }, cb),
65+
(cb) => nodeA.api.name.resolve(nodeAId.id, cb),
66+
/* (cb) => waitFor(() => subscribed === true, cb), */ (cb) => setTimeout(() => cb(), 10000),
67+
(cb) => nodeB.api.name.resolve(nodeAId.id, cb)
68+
], (err, res) => {
69+
expect(err).to.not.exist()
70+
expect(res).to.exist()
71+
72+
expect(res[2].name).to.equal(nodeAId.id) // Published to Node A ID
73+
expect(res[3].path || res[3]).to.equal(ipfsRef) // TODO: remove path once not using proc daemon
74+
expect(res[5].path || res[5]).to.equal(ipfsRef)
75+
76+
callback()
77+
})
78+
})
79+
}
80+
81+
const ipfsRef = '/ipfs/QmPFVLPmp9zv5Z5KUqLhe2EivAGccQW2r7M7jhVJGLZoZU'
82+
83+
describe.only('name-pubsub', () => {
84+
describe('js nodes', () => {
85+
let nodeAId
86+
let nodes = []
87+
88+
// Spawn daemons
89+
before(function (done) {
90+
// CI takes longer to instantiate the daemon, so we need to increase the timeout
91+
this.timeout(80 * 1000)
92+
93+
series([
94+
(cb) => spawnJsDaemon(cb),
95+
(cb) => spawnJsDaemon(cb),
96+
], (err, daemons) => {
97+
expect(err).to.not.exist()
98+
nodes = daemons
99+
done()
100+
})
101+
})
102+
103+
// Get node id
104+
before(function (done) {
105+
nodes[0].api.id((err, res) => {
106+
expect(err).to.not.exist()
107+
expect(res.id).to.exist()
108+
109+
nodeAId = res
110+
nodes[1].api.swarm.connect(res.addresses[0], done)
111+
})
112+
})
113+
114+
after(function (done) {
115+
this.timeout(60 * 1000)
116+
parallel(nodes.map((node) => (cb) => node.stop(cb)), done)
117+
})
118+
119+
it('should get enabled state of pubsub', function (done) {
120+
nodes[0].api.name.pubsub.state((err, state) => {
121+
expect(err).to.not.exist()
122+
expect(state).to.exist()
123+
expect(state.enabled).to.equal(true)
124+
125+
done()
126+
})
127+
})
128+
129+
it('should publish the received record to a js node subscriber', function (done) {
130+
this.timeout(300 * 1000)
131+
132+
subscribeToReceiveByPubsub(nodes[0], nodes[1], nodeAId, done)
133+
})
134+
})
135+
136+
describe('go nodes', () => {
137+
let nodeAId
138+
let nodes = []
139+
140+
// Spawn daemons
141+
before(function (done) {
142+
// CI takes longer to instantiate the daemon, so we need to increase the timeout
143+
this.timeout(80 * 1000)
144+
145+
series([
146+
(cb) => spawnGoDaemon(cb),
147+
(cb) => spawnGoDaemon(cb),
148+
], (err, daemons) => {
149+
expect(err).to.not.exist()
150+
nodes = daemons
151+
152+
done()
153+
})
154+
})
155+
156+
// Connect nodes
157+
before(function (done) {
158+
nodes[0].api.id((err, res) => {
159+
expect(err).to.not.exist()
160+
expect(res.id).to.exist()
161+
162+
nodeAId = res
163+
nodes[1].api.swarm.connect(res.addresses[0], done)
164+
})
165+
})
166+
167+
after(function (done) {
168+
this.timeout(60 * 1000)
169+
parallel(nodes.map((node) => (cb) => node.stop(cb)), done)
170+
})
171+
172+
it('should get enabled state of pubsub', function (done) {
173+
nodes[0].api.name.pubsub.state((err, state) => {
174+
expect(err).to.not.exist()
175+
expect(state).to.exist()
176+
expect(state.enabled).to.equal(true)
177+
178+
done()
179+
})
180+
})
181+
182+
it('should publish the received record to a go node subscriber', function (done) {
183+
this.timeout(300 * 1000)
184+
185+
subscribeToReceiveByPubsub(nodes[0], nodes[1], nodeAId, done)
186+
})
187+
})
188+
189+
describe.skip('bybrid nodes', () => {
190+
let nodeAId
191+
let nodeBId
192+
let nodes = []
193+
194+
// Spawn daemons
195+
before(function (done) {
196+
// CI takes longer to instantiate the daemon, so we need to increase the timeout
197+
this.timeout(80 * 1000)
198+
199+
series([
200+
(cb) => spawnGoDaemon(cb),
201+
(cb) => spawnJsDaemon(cb),
202+
], (err, daemons) => {
203+
expect(err).to.not.exist()
204+
nodes = daemons
205+
206+
done()
207+
})
208+
})
209+
210+
// Get node ids
211+
before(function (done) {
212+
this.timeout(60 * 1000)
213+
214+
parallel([
215+
(cb) => nodes[0].api.id(cb),
216+
(cb) => nodes[1].api.id(cb)
217+
], (err, ids) => {
218+
expect(err).to.not.exist()
219+
expect(ids).to.exist()
220+
expect(ids[0].id).to.exist()
221+
expect(ids[1].id).to.exist()
222+
223+
nodeAId = ids[0]
224+
nodeBId = ids[1]
225+
226+
nodes[1].api.swarm.connect(ids[0].addresses[0], done)
227+
})
228+
})
229+
230+
after(function (done) {
231+
this.timeout(60 * 1000)
232+
parallel(nodes.map((node) => (cb) => node.stop(cb)), done)
233+
})
234+
235+
it('should get enabled state of pubsub', function (done) {
236+
nodes[0].api.name.pubsub.state((err, state) => {
237+
expect(err).to.not.exist()
238+
expect(state).to.exist()
239+
expect(state.enabled).to.equal(true)
240+
241+
done()
242+
})
243+
})
244+
245+
it('should publish the received record to a go node and a js subscriber should receive it', function (done) {
246+
this.timeout(250 * 1000)
247+
const topic = `/ipns/${fromB58String(nodeAId.id).toString()}`
248+
let subscribed = false
249+
250+
nodes[1].api.name.resolve(nodeAId.id, (err) => {
251+
expect(err).to.exist()
252+
253+
function checkMessage(msg) {
254+
console.log('msg received', msg)
255+
subscribed = true
256+
}
257+
258+
series([
259+
(cb) => waitForPeerToSubscribe(nodes[1].api, cb),
260+
(cb) => nodes[1].api.pubsub.subscribe(topic, checkMessage, cb),
261+
(cb) => nodes[0].api.name.publish(ipfsRef, { resolve: false }, cb),
262+
(cb) => nodes[0].api.name.resolve(nodeAId.id, cb),
263+
// (cb) => waitFor(() => subscribed === true, 50 * 1000, cb),
264+
(cb) => setTimeout(() => cb(), 10000),
265+
(cb) => nodes[1].api.name.resolve(nodeAId.id, cb)
266+
], (err, res) => {
267+
console.log('res', res)
268+
console.log('err', err)
269+
expect(err).to.not.exist()
270+
expect(res).to.exist()
271+
272+
expect(res[2].name).to.equal(nodeAId.id) // Published to Node A ID
273+
expect(res[3].path).to.equal(ipfsRef)
274+
expect(res[5].path).to.equal(ipfsRef)
275+
done()
276+
})
277+
})
278+
})
279+
280+
it('should publish the received record to a js node and a go subscriber should receive it', function (done) {
281+
this.timeout(350 * 1000)
282+
const topic = `/ipns/${fromB58String(nodeBId.id).toString()}`
283+
let subscribed = false
284+
285+
nodes[0].api.name.resolve(nodeBId.id, (err, res) => {
286+
expect(err).to.exist()
287+
288+
function checkMessage(msg) {
289+
console.log('msg received')
290+
subscribed = true
291+
}
292+
293+
series([
294+
(cb) => waitForPeerToSubscribe(nodes[0].api, cb),
295+
// (cb) => nodes[0].api.pubsub.subscribe(topic, checkMessage, cb),
296+
(cb) => nodes[1].api.name.publish(ipfsRef, { resolve: false }, cb),
297+
(cb) => setTimeout(cb, 30000),
298+
(cb) => nodes[1].api.name.resolve(nodeBId.id, cb),
299+
// (cb) => waitFor(() => subscribed === true, 50 * 1000, cb),
300+
(cb) => nodes[0].api.name.resolve(nodeBId.id, cb)
301+
], (err, res) => {
302+
console.log('res', res)
303+
console.log('err', err)
304+
expect(err).to.not.exist()
305+
expect(res).to.exist()
306+
307+
expect(res[2].name).to.equal(nodeBId.id) // Published to Node A ID
308+
expect(res[3]).to.equal(ipfsRef)
309+
expect(res[5]).to.equal(ipfsRef)
310+
done()
311+
})
312+
})
313+
})
314+
})
315+
})
316+
317+
// Wait until a peer subscribes a topic
318+
const waitForPeerToSubscribe = (daemon, callback) => {
319+
retry({
320+
times: 5,
321+
interval: 2000
322+
}, (next) => {
323+
daemon.name.pubsub.subs((error, res) => {
324+
if (error) {
325+
return next(error)
326+
}
327+
328+
if (!res || !res.length) {
329+
return next(new Error('Could not find subscription'))
330+
}
331+
332+
return next(null, res[0])
333+
})
334+
}, callback)
335+
}
336+
337+
/*
338+
// Wait until a peer subscribes a topic
339+
const waitForPeerToSubscribe2 = (daemon, callback) => {
340+
retry({
341+
times: 5,
342+
interval: 2000
343+
}, (next) => {
344+
daemon.pubsub.ls((error, res) => {
345+
if (error) {
346+
return next(error)
347+
}
348+
349+
if (!res || !res.length) {
350+
return next(new Error('Could not find subscription'))
351+
}
352+
353+
return next(null, res[0])
354+
})
355+
}, callback)
356+
}
357+
358+
const waitForPeerKnowingOfTheSubscription = (daemon, subscription, callback) => {
359+
retry({
360+
times: 5,
361+
interval: 2000
362+
}, (next) => {
363+
daemon.pubsub.peers(subscription, (error, res) => {
364+
if (error) {
365+
return next(error)
366+
}
367+
368+
if (!res || !res.length) {
369+
return next(new Error('Peer did not subscribe'))
370+
}
371+
372+
return next(null, res[0])
373+
})
374+
}, callback)
375+
}
376+
*/

test/node.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ require('./exchange-files')
88
require('./kad-dht')
99
require('./pin')
1010
require('./files')
11+
require('./name-pubsub')

0 commit comments

Comments
 (0)