You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

223 lines
5.2 KiB

const tape = require('tape')
const dht = require('./')
const blake2b = require('./lib/blake2b')
tape('simple update', function (t) {
bootstrap(function (port, node) {
const a = dht({ bootstrap: port })
const b = dht({ bootstrap: port })
a.command('echo', {
query (data, callback) {
t.fail('should not query')
callback(new Error('nope'))
},
update (data, callback) {
t.same(data.value, Buffer.from('Hello, World!'), 'expected data')
callback(null, data.value)
}
})
a.ready(function () {
b.update('echo', a.id, Buffer.from('Hello, World!'), function (err, responses) {
a.destroy()
b.destroy()
node.destroy()
t.error(err, 'no errors')
t.same(responses.length, 1, 'one response')
t.same(responses[0].value, Buffer.from('Hello, World!'), 'echoed data')
t.end()
})
})
})
})
tape('simple query', function (t) {
bootstrap(function (port, node) {
const a = dht({ bootstrap: port })
const b = dht({ bootstrap: port })
a.command('hello', {
query (data, callback) {
t.same(data.value, null, 'expected data')
callback(null, Buffer.from('world'))
}
})
a.ready(function () {
b.query('hello', a.id, function (err, responses) {
a.destroy()
b.destroy()
node.destroy()
t.error(err, 'no errors')
t.same(responses.length, 1, 'one response')
t.same(responses[0].value, Buffer.from('world'), 'responded')
t.end()
})
})
})
})
tape('query and update', function (t) {
bootstrap(function (port, node) {
const a = dht({ bootstrap: port })
const b = dht({ bootstrap: port })
a.command('hello', {
query (data, callback) {
t.same(data.value, null, 'expected query data')
callback(null, Buffer.from('world'))
},
update (data, callback) {
t.same(data.value, null, 'expected update data')
callback(null, Buffer.from('world'))
}
})
a.ready(function () {
b.queryAndUpdate('hello', a.id, function (err, responses) {
a.destroy()
b.destroy()
node.destroy()
t.error(err, 'no errors')
t.same(responses.length, 2, 'two responses')
t.same(responses[0].value, Buffer.from('world'), 'responded')
t.same(responses[1].value, Buffer.from('world'), 'responded')
t.ok(responses[0].type !== responses[1].type, 'not the same type')
t.end()
})
})
})
})
tape('swarm query', function (t) {
bootstrap(function (port, node) {
const swarm = []
var closest = 0
loop()
function done () {
t.pass('created swarm')
const key = blake2b(Buffer.from('hello'))
const me = dht({ bootstrap: port })
me.update('kv', key, Buffer.from('hello'), function (err, responses) {
t.error(err, 'no error')
t.same(closest, 20, '20 closest nodes')
t.same(responses.length, 20, '20 responses')
const stream = me.query('kv', key)
stream.on('data', function (data) {
if (data.value) {
t.same(data.value, Buffer.from('hello'), 'echoed value')
t.end()
swarm.forEach(function (node) {
node.destroy()
})
me.destroy()
node.destroy()
stream.destroy()
}
})
})
}
function loop () {
if (swarm.length === 256) return done()
const node = dht({ bootstrap: port })
swarm.push(node)
var value = null
node.command('kv', {
update (data, cb) {
closest++
value = data.value
cb()
},
query (data, cb) {
cb(null, value)
}
})
node.ready(loop)
}
})
})
tape('holepunch api', function (t) {
bootstrap(function (port, node) {
const a = dht({ bootstrap: port })
const b = dht({ bootstrap: port })
var holepunched = false
a.ready(function () {
b.ready(function () {
node.on('holepunch', function (from, to) {
t.same(from.port, a.address().port)
t.same(to.port, b.address().port)
holepunched = true
})
a.holepunch({
host: '127.0.0.1',
port: b.address().port,
referrer: {
host: '127.0.0.1',
port: node.address().port
}
}, function (err) {
t.error(err, 'no error')
t.ok(holepunched)
t.end()
node.destroy()
a.destroy()
b.destroy()
})
})
})
})
})
tape('timeouts', function (t) {
bootstrap(function (port, node) {
const a = dht({ bootstrap: port, ephemeral: true })
const b = dht({ bootstrap: port })
var tries = 0
b.command('nope', {
update (query, cb) {
tries++
t.pass('ignoring update')
}
})
b.ready(function () {
a.update('nope', Buffer.alloc(32), function (err) {
t.ok(err, 'errored')
t.same(tries, 3)
t.end()
node.destroy()
a.destroy()
b.destroy()
})
})
})
})
function bootstrap (done) {
const node = dht({
ephemeral: true
})
node.listen(0, function () {
done(node.address().port, node)
})
}