@@ -7,88 +7,226 @@ const chai = require('chai')
7
7
chai . use ( require ( 'dirty-chai' ) )
8
8
const expect = chai . expect
9
9
const parallel = require ( 'async/parallel' )
10
+ const waterfall = require ( 'async/waterfall' )
10
11
const _times = require ( 'lodash.times' )
11
12
const CID = require ( 'cids' )
13
+ const DelegatedContentRouter = require ( 'libp2p-delegated-content-routing' )
14
+ const sinon = require ( 'sinon' )
15
+ const nock = require ( 'nock' )
12
16
13
17
const createNode = require ( './utils/create-node' )
18
+ const createPeerInfo = createNode . createPeerInfo
14
19
15
20
describe ( '.contentRouting' , ( ) => {
16
- let nodeA
17
- let nodeB
18
- let nodeC
19
- let nodeD
20
- let nodeE
21
-
22
- before ( function ( done ) {
23
- this . timeout ( 5 * 1000 )
24
- const tasks = _times ( 5 , ( ) => ( cb ) => {
25
- createNode ( '/ip4/0.0.0.0/tcp/0' , {
26
- config : {
27
- EXPERIMENTAL : {
28
- dht : true
21
+ describe ( 'via the dht' , ( ) => {
22
+ let nodeA
23
+ let nodeB
24
+ let nodeC
25
+ let nodeD
26
+ let nodeE
27
+
28
+ before ( function ( done ) {
29
+ this . timeout ( 5 * 1000 )
30
+ const tasks = _times ( 5 , ( ) => ( cb ) => {
31
+ createNode ( '/ip4/0.0.0.0/tcp/0' , {
32
+ config : {
33
+ EXPERIMENTAL : {
34
+ dht : true
35
+ }
29
36
}
30
- }
31
- } , ( err , node ) => {
37
+ } , ( err , node ) => {
38
+ expect ( err ) . to . not . exist ( )
39
+ node . start ( ( err ) => cb ( err , node ) )
40
+ } )
41
+ } )
42
+
43
+ parallel ( tasks , ( err , nodes ) => {
32
44
expect ( err ) . to . not . exist ( )
33
- node . start ( ( err ) => cb ( err , node ) )
45
+ nodeA = nodes [ 0 ]
46
+ nodeB = nodes [ 1 ]
47
+ nodeC = nodes [ 2 ]
48
+ nodeD = nodes [ 3 ]
49
+ nodeE = nodes [ 4 ]
50
+
51
+ parallel ( [
52
+ ( cb ) => nodeA . dial ( nodeB . peerInfo , cb ) ,
53
+ ( cb ) => nodeB . dial ( nodeC . peerInfo , cb ) ,
54
+ ( cb ) => nodeC . dial ( nodeD . peerInfo , cb ) ,
55
+ ( cb ) => nodeD . dial ( nodeE . peerInfo , cb ) ,
56
+ ( cb ) => nodeE . dial ( nodeA . peerInfo , cb )
57
+ ] , done )
34
58
} )
35
59
} )
36
60
37
- parallel ( tasks , ( err , nodes ) => {
38
- expect ( err ) . to . not . exist ( )
39
- nodeA = nodes [ 0 ]
40
- nodeB = nodes [ 1 ]
41
- nodeC = nodes [ 2 ]
42
- nodeD = nodes [ 3 ]
43
- nodeE = nodes [ 4 ]
44
-
61
+ after ( ( done ) => {
45
62
parallel ( [
46
- ( cb ) => nodeA . dial ( nodeB . peerInfo , cb ) ,
47
- ( cb ) => nodeB . dial ( nodeC . peerInfo , cb ) ,
48
- ( cb ) => nodeC . dial ( nodeD . peerInfo , cb ) ,
49
- ( cb ) => nodeD . dial ( nodeE . peerInfo , cb ) ,
50
- ( cb ) => nodeE . dial ( nodeA . peerInfo , cb )
63
+ ( cb ) => nodeA . stop ( cb ) ,
64
+ ( cb ) => nodeB . stop ( cb ) ,
65
+ ( cb ) => nodeC . stop ( cb ) ,
66
+ ( cb ) => nodeD . stop ( cb ) ,
67
+ ( cb ) => nodeE . stop ( cb )
51
68
] , done )
52
69
} )
53
- } )
54
70
55
- after ( ( done ) => {
56
- parallel ( [
57
- ( cb ) => nodeA . stop ( cb ) ,
58
- ( cb ) => nodeB . stop ( cb ) ,
59
- ( cb ) => nodeC . stop ( cb ) ,
60
- ( cb ) => nodeD . stop ( cb ) ,
61
- ( cb ) => nodeE . stop ( cb )
62
- ] , done )
71
+ it ( 'should use the nodes dht to provide' , ( done ) => {
72
+ const stub = sinon . stub ( nodeA . _dht , 'provide' ) . callsFake ( ( ) => {
73
+ stub . restore ( )
74
+ done ( )
75
+ } )
76
+
77
+ nodeA . contentRouting . provide ( )
78
+ } )
79
+
80
+ it ( 'should use the nodes dht to find providers' , ( done ) => {
81
+ const stub = sinon . stub ( nodeA . _dht , 'findProviders' ) . callsFake ( ( ) => {
82
+ stub . restore ( )
83
+ done ( )
84
+ } )
85
+
86
+ nodeA . contentRouting . findProviders ( )
87
+ } )
88
+
89
+ describe ( 'le ring' , ( ) => {
90
+ const cid = new CID ( 'QmTp9VkYvnHyrqKQuFPiuZkiX9gPcqj6x5LJ1rmWuSySnL' )
91
+
92
+ it ( 'let kbucket get filled' , ( done ) => {
93
+ setTimeout ( ( ) => done ( ) , 250 )
94
+ } )
95
+
96
+ it ( 'nodeA.contentRouting.provide' , ( done ) => {
97
+ nodeA . contentRouting . provide ( cid , done )
98
+ } )
99
+
100
+ it ( 'nodeE.contentRouting.findProviders for existing record' , ( done ) => {
101
+ nodeE . contentRouting . findProviders ( cid , 5000 , ( err , providers ) => {
102
+ expect ( err ) . to . not . exist ( )
103
+ expect ( providers ) . to . have . length . above ( 0 )
104
+ done ( )
105
+ } )
106
+ } )
107
+
108
+ it ( 'nodeC.contentRouting.findProviders for non existing record (timeout)' , ( done ) => {
109
+ const cid = new CID ( 'QmTp9VkYvnHyrqKQuFPiuZkiX9gPcqj6x5LJ1rmWuSnnnn' )
110
+
111
+ nodeE . contentRouting . findProviders ( cid , 5000 , ( err , providers ) => {
112
+ expect ( err ) . to . not . exist ( )
113
+ expect ( providers ) . to . have . length ( 0 )
114
+ done ( )
115
+ } )
116
+ } )
117
+ } )
63
118
} )
64
119
65
- describe ( 'le ring' , ( ) => {
66
- const cid = new CID ( 'QmTp9VkYvnHyrqKQuFPiuZkiX9gPcqj6x5LJ1rmWuSySnL' )
120
+ describe ( 'via a delegate' , ( ) => {
121
+ let nodeA
122
+ let delegate
67
123
68
- it ( 'let kbucket get filled' , ( done ) => {
69
- setTimeout ( ( ) => done ( ) , 250 )
124
+ before ( ( done ) => {
125
+ waterfall ( [
126
+ ( cb ) => {
127
+ createPeerInfo ( cb )
128
+ } ,
129
+ // Create the node using the delegate
130
+ ( peerInfo , cb ) => {
131
+ delegate = new DelegatedContentRouter ( peerInfo . id , {
132
+ host : '0.0.0.0' ,
133
+ protocol : 'http' ,
134
+ port : '50082'
135
+ } )
136
+ createNode ( '/ip4/0.0.0.0/tcp/0' , {
137
+ modules : {
138
+ contentRouting : delegate
139
+ }
140
+ } , ( err , node ) => {
141
+ expect ( err ) . to . not . exist ( )
142
+ nodeA = node
143
+ nodeA . start ( cb )
144
+ } )
145
+ }
146
+ ] , done )
70
147
} )
71
148
72
- it ( 'nodeA.contentRouting.provide' , ( done ) => {
73
- nodeA . contentRouting . provide ( cid , done )
149
+ afterEach ( ( ) => {
150
+ nock . cleanAll ( )
151
+ nock . restore ( )
74
152
} )
75
153
76
- it ( 'nodeE.contentRouting.findProviders for existing record' , ( done ) => {
77
- nodeE . contentRouting . findProviders ( cid , 5000 , ( err , providers ) => {
78
- expect ( err ) . to . not . exist ( )
79
- expect ( providers ) . to . have . length . above ( 0 )
154
+ it ( 'should use the delegate router to provide' , ( done ) => {
155
+ const stub = sinon . stub ( delegate , 'provide' ) . callsFake ( ( ) => {
156
+ stub . restore ( )
157
+ done ( )
158
+ } )
159
+ nodeA . contentRouting . provide ( )
160
+ } )
161
+
162
+ it ( 'should use the delegate router to find providers' , ( done ) => {
163
+ const stub = sinon . stub ( delegate , 'findProviders' ) . callsFake ( ( ) => {
164
+ stub . restore ( )
80
165
done ( )
81
166
} )
167
+ nodeA . contentRouting . findProviders ( )
82
168
} )
83
169
84
- it ( 'nodeC.contentRouting.findProviders for non existing record (timeout)' , ( done ) => {
85
- const cid = new CID ( 'QmTp9VkYvnHyrqKQuFPiuZkiX9gPcqj6x5LJ1rmWuSnnnn' )
170
+ it ( 'should be able to register as a provider' , ( done ) => {
171
+ const cid = new CID ( 'QmTp9VkYvnHyrqKQuFPiuZkiX9gPcqj6x5LJ1rmWuSySnL' )
172
+ nock . recorder . rec ( )
173
+ // const mockApi = nock('https://ipfs.io')
174
+ // .post('/api/v0/dht/findpeer')
175
+ // .query({
176
+ // arg: peerKey,
177
+ // 'stream-channels': true
178
+ // })
179
+ // .reply(200, `{"Extra":"","ID":"some other id","Responses":null,"Type":0}\n{"Extra":"","ID":"","Responses":[{"Addrs":["/ip4/127.0.0.1/tcp/4001"],"ID":"${peerKey}"}],"Type":2 }\n`, [
180
+ // 'Content-Type', 'application/json',
181
+ // 'X-Chunked-Output', '1'
182
+ // ])
86
183
87
- nodeE . contentRouting . findProviders ( cid , 5000 , ( err , providers ) => {
184
+ nodeA . contentRouting . provide ( cid , ( err , data ) => {
88
185
expect ( err ) . to . not . exist ( )
89
- expect ( providers ) . to . have . length ( 0 )
186
+ expect ( data ) . to . equal ( { } )
187
+ nock . restore ( )
188
+ // expect(mockApi.isDone()).to.equal(true)
90
189
done ( )
91
190
} )
92
191
} )
192
+
193
+ // it('should error when a peer cannot be found', (done) => {
194
+ // const peerKey = 'key of a peer not on the network'
195
+ // const mockApi = nock('https://ipfs.io')
196
+ // .post('/api/v0/dht/findpeer')
197
+ // .query({
198
+ // arg: peerKey,
199
+ // 'stream-channels': true
200
+ // })
201
+ // .reply(200, `{"Extra":"","ID":"some other id","Responses":null,"Type":6}\n{"Extra":"","ID":"yet another id","Responses":null,"Type":0}\n{"Extra":"routing:not found","ID":"","Responses":null,"Type":3}\n`, [
202
+ // 'Content-Type', 'application/json',
203
+ // 'X-Chunked-Output', '1'
204
+ // ])
205
+
206
+ // nodeA.peerRouting.findPeer(peerKey, (err, peerInfo) => {
207
+ // expect(err).to.exist()
208
+ // expect(peerInfo).to.not.exist()
209
+ // expect(mockApi.isDone()).to.equal(true)
210
+ // done()
211
+ // })
212
+ // })
213
+
214
+ // it('should handle errors from the api', (done) => {
215
+ // const peerKey = 'key of a peer not on the network'
216
+ // const mockApi = nock('https://ipfs.io')
217
+ // .post('/api/v0/dht/findpeer')
218
+ // .query({
219
+ // arg: peerKey,
220
+ // 'stream-channels': true
221
+ // })
222
+ // .reply(502)
223
+
224
+ // nodeA.peerRouting.findPeer(peerKey, (err, peerInfo) => {
225
+ // expect(err).to.exist()
226
+ // expect(peerInfo).to.not.exist()
227
+ // expect(mockApi.isDone()).to.equal(true)
228
+ // done()
229
+ // })
230
+ // })
93
231
} )
94
232
} )
0 commit comments