Files: c1997c8a400cf294934a5e97a93d35b3705dec55 / test / random.js
6837 bytesRaw
1 | var pull = require('pull-stream') |
2 | var paramap = require('pull-paramap') |
3 | var ssbKeys = require('ssb-keys') |
4 | var u = require('./util') |
5 | var ssbClient = require('ssb-client') |
6 | |
7 | var tape = require('tape') |
8 | |
9 | var cats = require('cat-names') |
10 | var dogs = require('dog-names') |
11 | |
12 | var generated = {}, F=100,N=10000 |
13 | |
14 | //build a random network, with n members. |
15 | function bar (prog) { |
16 | var r = prog.progress/prog.total |
17 | var s = '\r', M = 50 |
18 | for(var i = 0; i < M; i++) |
19 | s += i < M*r ? '*' : '.' |
20 | |
21 | return s + ' '+prog.progress+'/'+prog.total+' '//+':'+prog.feeds |
22 | } |
23 | |
24 | function isNumber (n) { |
25 | return typeof n === 'number' |
26 | } |
27 | |
28 | function once (fn) { |
29 | var called = false |
30 | return function () { |
31 | if(called) throw new Error('called twice!') |
32 | called = true |
33 | fn.apply(this, arguments) |
34 | } |
35 | } |
36 | |
37 | var createSbot = require('../') |
38 | .use(require('../plugins/friends')) |
39 | .use(require('../plugins/replicate')) |
40 | .use(require('../plugins/gossip')) |
41 | |
42 | function generateAnimals (sbot, feed, f, n, cb) { |
43 | var a = [feed] |
44 | |
45 | while(f --> 0) |
46 | a.push(sbot.createFeed()) |
47 | |
48 | console.log('generate NAMES') |
49 | |
50 | pull( |
51 | pull.values(a), |
52 | paramap(function (feed, cb) { |
53 | var animal = Math.random() > 0.5 ? 'cat' : 'dog' |
54 | var name = animal == 'cat' ? cats.random() : dogs.allRandom() |
55 | |
56 | feed.name = name |
57 | feed.add(u.follow(feed.id), cb) |
58 | }, 10), |
59 | pull.drain(null, function (err) { |
60 | if(err) return cb(err) |
61 | |
62 | var posts = [] |
63 | |
64 | pull( |
65 | pull.count(n), |
66 | paramap(function (n, cb) { |
67 | |
68 | var me = a[~~(Math.random()*a.length)] |
69 | var r = Math.random() |
70 | |
71 | //one in 20 messages is a random follow |
72 | if(r < 0.5) { |
73 | var f = a[~~(Math.random()*a.length)] |
74 | me.add(u.follow(f.id), cb) |
75 | } else if(r < 0.6) { |
76 | me.add({ |
77 | type: 'post', |
78 | text: me.animal === 'dog' ? 'woof' : 'meow', |
79 | }, function (err, msg) { |
80 | posts.push(msg.key) |
81 | if(posts.length > 100) |
82 | posts.shift() |
83 | cb(null, msg) |
84 | }) |
85 | } else { |
86 | var post = posts[~~(Math.random()*posts.length)] |
87 | me.add({ |
88 | type: 'post', |
89 | repliesTo: post, |
90 | text: me.animal === 'dog' ? 'woof woof' : 'purr', |
91 | }, function (err, msg) { |
92 | cb(null, msg) |
93 | }) |
94 | |
95 | } |
96 | }, 32), |
97 | pull.drain(null, cb) |
98 | ) |
99 | |
100 | }) |
101 | ) |
102 | |
103 | } |
104 | |
105 | function latest (sbot, cb) { |
106 | sbot.friends.hops({hops: 3}, once(function (err, keys) { |
107 | if(err) return cb(err) |
108 | var n = Object.keys(keys).length, map = {} |
109 | for(var k in keys) (function (key) { |
110 | sbot.latestSequence(key, once(function (err, value) { |
111 | map[key] = isNumber(value) ? value : value.sequence |
112 | if(--n) return |
113 | cb(null, map) |
114 | })) |
115 | })(k) |
116 | })) |
117 | } |
118 | |
119 | var alice = ssbKeys.generate() |
120 | var bob = ssbKeys.generate() |
121 | |
122 | |
123 | |
124 | var animalNetwork = createSbot({ |
125 | temp: 'test-random-animals', |
126 | port: 45451, host: 'localhost', timeout: 20001, |
127 | replication: {hops: 3}, keys: alice |
128 | }) |
129 | |
130 | pull( |
131 | animalNetwork.replicate.changes(), |
132 | pull.drain(function (prog) { |
133 | prog.id = 'animal network' |
134 | console.log(prog) |
135 | }) |
136 | ) |
137 | |
138 | tape('generate random network', function (t) { |
139 | var start = Date.now() |
140 | generateAnimals(animalNetwork, {add: animalNetwork.publish}, F, N, function (err) { |
141 | if(err) throw err |
142 | console.log('replicate GRAPH') |
143 | var c = 0 |
144 | latest(animalNetwork, function (err, _generated) { |
145 | if(err) throw err |
146 | |
147 | generated = _generated |
148 | var total = 0, feeds = 0 |
149 | for(var k in generated) { |
150 | total += generated[k] |
151 | feeds ++ |
152 | } |
153 | |
154 | var time = (Date.now()-start)/1000 |
155 | console.log('generated', total, 'messages in', time, 'at rate:', total/time) |
156 | console.log('over', feeds, 'feeds') |
157 | t.equal(total, N+1+F+1) |
158 | t.equal(feeds, F+1) |
159 | t.end() |
160 | }) |
161 | }) |
162 | }) |
163 | |
164 | tape('read all history streams', function (t) { |
165 | var opts = { |
166 | host: 'localhost', port: 45451, |
167 | key: alice.id, |
168 | manifest: animalNetwork.manifest() |
169 | } |
170 | |
171 | var dump = createSbot({ |
172 | temp: 'test-random-animals_dump', |
173 | // port: 45453, host: 'localhost', timeout: 20001, |
174 | keys: bob |
175 | }) |
176 | var live = 0, listeners = 0 |
177 | var since = {} |
178 | |
179 | var h = 0 |
180 | |
181 | pull( |
182 | dump.createLogStream({live: true, keys: false}), |
183 | pull.drain(function (e) { |
184 | live ++ |
185 | }) |
186 | ) |
187 | |
188 | var wants = {}, n = 0, c = 0, start = Date.now() |
189 | |
190 | //test just dumping everything! |
191 | //not through network connection, because createLogStream is not on public api |
192 | pull( |
193 | animalNetwork.createLogStream({keys: false}), |
194 | pull.through(function (n) { |
195 | c++ |
196 | }), |
197 | dump.createWriteStream(function (err, data) { |
198 | if(err) throw err |
199 | var time = (Date.now() - start)/1000 |
200 | console.log("dump all messages via createLogStream") |
201 | console.log('all histories dumped', c, 'messages in', time, 'at rate', c/time) |
202 | console.log('read back live:', live, 'over', h, 'histories', listeners, 'listeners') |
203 | pull( |
204 | dump.createLogStream(), |
205 | pull.collect(function (err, ary) { |
206 | if(err) throw err |
207 | console.log(c) |
208 | t.equal(ary.length, F+N+2) |
209 | dump.close() |
210 | t.end() |
211 | }) |
212 | ) |
213 | }) |
214 | ) |
215 | |
216 | }) |
217 | |
218 | tape('replicate social network for animals', function (t) { |
219 | //return t.end() |
220 | var c = 0 |
221 | if(!animalNetwork.friends) |
222 | throw new Error('missing frineds plugin') |
223 | |
224 | var start = Date.now() |
225 | var animalFriends = createSbot({ |
226 | temp: 'test-random-animals2', |
227 | port: 45452, host: 'localhost', timeout: 20001, |
228 | replication: {hops: 3}, |
229 | progress: true, |
230 | seeds: [animalNetwork.getAddress()], |
231 | keys: bob |
232 | }) |
233 | animalFriends.logging |
234 | var connections = 0 |
235 | |
236 | animalFriends.on('rpc:connect', function (rpc) { |
237 | connections++ |
238 | console.log("CONNECT", c) |
239 | rpc.on('closed', function () { |
240 | console.log("DISCONNECT", -c) |
241 | }) |
242 | }) |
243 | |
244 | var drain |
245 | |
246 | pull( |
247 | animalFriends.replicate.changes(), |
248 | drain = pull.drain(function (prog) { |
249 | prog.id = 'animal friends' |
250 | var target = F+N+3 |
251 | console.log(prog, target) |
252 | // progress.push(prog) |
253 | // process.stdout.write(bar(prog)) |
254 | if(prog.progress === target) { |
255 | console.log("DONE!!!!") |
256 | var time = (Date.now() - start) / 1000 |
257 | console.log('replicated', target, 'messages in', time, 'at rate',target/time) |
258 | animalFriends.close(true) |
259 | drain.abort() |
260 | t.end() |
261 | } |
262 | }) |
263 | ) |
264 | |
265 | animalFriends.logging = true |
266 | |
267 | if(!animalFriends.friends) |
268 | throw new Error('missing friends plugin') |
269 | |
270 | animalFriends.publish({ |
271 | type: 'contact', |
272 | contact: animalNetwork.id, |
273 | following: true |
274 | }, function (err, msg) { |
275 | if(err) throw err |
276 | }) |
277 | |
278 | }) |
279 | |
280 | |
281 | tape('shutdown', function (t) { |
282 | animalNetwork.close(true) |
283 | t.end() |
284 | }) |
285 | |
286 |
Built with git-ssb-web