mirror of
https://github.com/amark/gun.git
synced 2025-03-30 15:08:33 +00:00
Merge branch 'manhattan' of http://github.com/amark/gun into manhattan
This commit is contained in:
commit
fed500dd69
6
gun.js
6
gun.js
@ -449,7 +449,7 @@
|
||||
// PERF: Consider commenting this out to force disk-only reads for perf testing? // TODO: .keys( is slow
|
||||
node && (function go(){
|
||||
S = +new Date;
|
||||
var i = 0, k, put = {};
|
||||
var i = 0, k, put = {}, tmp;
|
||||
while(i < 9 && (k = keys[i++])){
|
||||
state_ify(put, k, state_is(node, k), node[k], soul);
|
||||
}
|
||||
@ -1009,7 +1009,7 @@
|
||||
|
||||
function stun(as, id){
|
||||
if(!id){ return } id = (id._||'').id||id;
|
||||
tmp = as.root.stun || (as.root.stun = as.ta);
|
||||
var tmp = as.root.stun || (as.root.stun = as.ta);
|
||||
var it = {run: as.run, stun: as.stun};
|
||||
(tmp[id]? (tmp[id].last.next = it) : (tmp[id] = it)).last = it;
|
||||
}
|
||||
@ -1703,4 +1703,4 @@
|
||||
});
|
||||
})(USE, './localStorage');
|
||||
|
||||
}());
|
||||
}());
|
||||
|
85
lib/hub.js
85
lib/hub.js
@ -6,58 +6,55 @@ const gun = Gun();
|
||||
let chokidar;
|
||||
|
||||
try { chokidar = require('chokidar') } catch (error) {
|
||||
console.log('Type "npm i chokidar" if you want to use the hub feature !')
|
||||
} // Must install chokidar to use this feature.
|
||||
|
||||
function watch(what) {
|
||||
function watch(what, opt) {
|
||||
opt = opt || { }
|
||||
|
||||
// Set up the file watcher !
|
||||
const watcher = chokidar.watch(what, {
|
||||
ignored: /(^|[\/\\])\../, // ignore dotfiles
|
||||
persistent: true
|
||||
});
|
||||
let modifiedPath = (opt.file || "");
|
||||
|
||||
const log = console.log.bind(console);
|
||||
|
||||
// Handle events !
|
||||
|
||||
watcher
|
||||
.on('add', async function(path) {
|
||||
|
||||
log(`File ${path} has been added`);
|
||||
gun.get('hub').get(path).put({
|
||||
|
||||
file: path, // Add the path to the file.
|
||||
content: fs.readFileSync(path, 'utf8') // Add the content of the file
|
||||
|
||||
}).then(console.log('Done!'));
|
||||
|
||||
})
|
||||
.on('change', async function(path) {
|
||||
let watcher;
|
||||
try {
|
||||
// Set up the file watcher.
|
||||
watcher = chokidar.watch(what, {
|
||||
ignored: /(^|[\/\\])\../, // ignore dotfiles
|
||||
persistent: true
|
||||
});
|
||||
|
||||
log(`File ${path} has been changed`);
|
||||
|
||||
gun.get('hub').get(path).put({
|
||||
content: fs.readFileSync(path, 'utf8') // Just update the content not the path. (Performance)
|
||||
}).then(console.log('Done!'))
|
||||
const log = console.log.bind(console);
|
||||
|
||||
})
|
||||
.on('unlink', async function (path) {
|
||||
|
||||
log(`File ${path} has been removed`);
|
||||
|
||||
gun.get('hub').get(path).put({
|
||||
file: null, // Delete references to the file givent that it's been deleted.
|
||||
content: null,
|
||||
// Handle events !
|
||||
watcher
|
||||
.on('add', async function(path) {
|
||||
|
||||
log(`File ${path} has been added`);
|
||||
gun.get('hub').get(modifiedPath + '/' + path).put(fs.readFileSync(path, 'utf-8'))
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
.on('addDir', path => log(`Directory ${path} has been added`))
|
||||
.on('unlinkDir', path => log(`Directory ${path} has been removed`))
|
||||
.on('error', error => log(`Watcher error: ${error}`))
|
||||
.on('ready', () => log('Initial scan complete. Ready for changes'))
|
||||
.on('change', async function(path) {
|
||||
|
||||
log(`File ${path} has been changed`);
|
||||
gun.get('hub').get(modifiedPath + '/' + path).put(fs.readFileSync(path, 'utf-8'))
|
||||
|
||||
})
|
||||
.on('unlink', async function (path) {
|
||||
|
||||
log(`File ${path} has been removed`);
|
||||
gun.get('hub').get(modifiedPath + '/' + path).put(null)
|
||||
|
||||
})
|
||||
.on('addDir', path => log(`Directory ${path} has been added`))
|
||||
.on('unlinkDir', path => log(`Directory ${path} has been removed`))
|
||||
.on('error', error => log(`Watcher error: ${error}`))
|
||||
.on('ready', () => log('Initial scan complete. Ready for changes'))
|
||||
|
||||
} catch (err) {
|
||||
console.log('If you want to use the hub feature, you must install `chokidar` by typing `npm i chokidar` in your terminal.')
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { watch : watch, }
|
||||
gun.get('hub').on(data => {
|
||||
console.log(data);
|
||||
})
|
||||
|
||||
module.exports = { watch : watch, }
|
||||
|
@ -14,7 +14,6 @@
|
||||
"prepublishOnly": "npm run unbuild",
|
||||
"test": "echo 'Did you run PANIC holy-grail, 1~X, on-recover, etc.?' && mocha",
|
||||
"testsea": "mocha test/sea/sea.js",
|
||||
"testaxe": "mocha test/axe/holy-grail.js",
|
||||
"e2e": "mocha e2e/distributed.js",
|
||||
"docker": "hooks/build",
|
||||
"minify": "uglifyjs gun.js -o gun.min.js -c -m",
|
||||
@ -83,4 +82,4 @@
|
||||
"panic-server": "^1.1.1",
|
||||
"uglify-js": "^3.6.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
6
sea.js
6
sea.js
@ -278,7 +278,7 @@
|
||||
|
||||
SEA.work = SEA.work || (async (data, pair, cb, opt) => { try { // used to be named `proof`
|
||||
var salt = (pair||{}).epub || pair; // epub not recommended, salt should be random!
|
||||
var opt = opt || {};
|
||||
opt = opt || {};
|
||||
if(salt instanceof Function){
|
||||
cb = salt;
|
||||
salt = u;
|
||||
@ -517,7 +517,7 @@
|
||||
|
||||
const importGen = async (key, salt, opt) => {
|
||||
//const combo = shim.Buffer.concat([shim.Buffer.from(key, 'utf8'), salt || shim.random(8)]).toString('utf8') // old
|
||||
var opt = opt || {};
|
||||
opt = opt || {};
|
||||
const combo = key + (salt || shim.random(8)).toString('utf8'); // new
|
||||
const hash = shim.Buffer.from(await sha256hash(combo), 'binary')
|
||||
|
||||
@ -1427,4 +1427,4 @@
|
||||
// TODO: Potential bug? If pub/priv key starts with `-`? IDK how possible.
|
||||
|
||||
})(USE, './index');
|
||||
}());
|
||||
}());
|
||||
|
331
test/panic/axe/data_balance.js
Normal file
331
test/panic/axe/data_balance.js
Normal file
@ -0,0 +1,331 @@
|
||||
/**
|
||||
* AXE test data balance
|
||||
* What we want here: (1) Superpeer and (n) peers
|
||||
* - The peers receives only the requested data.
|
||||
* - If the Superpeer crash, must recreate all subscriptions and update the peers.
|
||||
* - If some peer crash or go offline, when connected again must receive the changes made by others while out.
|
||||
*
|
||||
* Tip: to run this `npm run testaxe`
|
||||
* Tip 2: if you clone the gun repo, you need to create a link do gun package. Do `npm install && cd node_modules && ln -s ../ gun`
|
||||
* Tip 3: If you not in localhost, run the browsers in anonymous mode because of domain security policies. https://superuser.com/questions/565409/how-to-stop-an-automatic-redirect-from-http-to-https-in-chrome
|
||||
*/
|
||||
var config = {
|
||||
IP: require('ip').address(),
|
||||
port: 8765,
|
||||
servers: 2,
|
||||
browsers: 2,
|
||||
route: {
|
||||
'/': __dirname + '/index.html',
|
||||
'/gun.js': __dirname + '/../../../gun.js',
|
||||
'/gun/axe.js': __dirname + '/../../../axe.js',
|
||||
'/jquery.js': __dirname + '/../../../examples/jquery.js'
|
||||
}
|
||||
}
|
||||
|
||||
var panic = require('panic-server');
|
||||
panic.server().on('request', function(req, res){
|
||||
config.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);
|
||||
}).listen(config.port);
|
||||
|
||||
var clients = panic.clients;
|
||||
var manager = require('panic-manager')();
|
||||
manager.start({
|
||||
clients: Array(config.servers).fill().map(function(u, i){
|
||||
return {
|
||||
type: 'node',
|
||||
port: config.port + (i + 1)
|
||||
}
|
||||
}),
|
||||
panic: 'http://' + config.IP + ':' + config.port
|
||||
});
|
||||
|
||||
var servers = clients.filter('Node.js');
|
||||
var server = servers.pluck(1);
|
||||
var server2 = servers.excluding(server).pluck(1);
|
||||
var browsers = clients.excluding(servers);
|
||||
var alice = browsers.pluck(1);
|
||||
var bob = browsers.excluding(alice).pluck(1);
|
||||
var again = {};
|
||||
|
||||
describe("The Holy Grail AXE Test!", function(){
|
||||
console.time('TOTAL TEST TIME');
|
||||
this.timeout(5 * 60 * 1000);
|
||||
// this.timeout(10 * 60 * 1000);
|
||||
|
||||
it("Servers have joined!", function(){
|
||||
return servers.atLeast(config.servers);
|
||||
});
|
||||
|
||||
it("GUN started!", function(){
|
||||
return server.run(function(test){
|
||||
var env = test.props;
|
||||
test.async();
|
||||
try{ require('fs').unlinkSync(env.i+'dataaxe') }catch(e){}
|
||||
try{ require('fs').unlinkSync((env.i+1)+'dataaxe') }catch(e){}
|
||||
var port = env.config.port + env.i;
|
||||
var server = require('http').createServer(function(req, res){
|
||||
res.end("I am "+ env.i +"!");
|
||||
});
|
||||
var Gun = require('gun');
|
||||
require('gun/axe');
|
||||
var gun = Gun({
|
||||
file: env.i+'dataaxe',
|
||||
web: server
|
||||
});
|
||||
server.listen(port, function(){
|
||||
test.done();
|
||||
});
|
||||
}, {i: 1, config: config});
|
||||
});
|
||||
|
||||
it(config.browsers +" browser(s) have joined!", function(){
|
||||
console.log("PLEASE OPEN http://"+ config.IP +":"+ config.port +" IN "+ config.browsers +" BROWSER(S)!");
|
||||
return browsers.atLeast(config.browsers);
|
||||
});
|
||||
|
||||
it("Browsers initialized gun!", function(){
|
||||
var tests = [], i = 0;
|
||||
browsers.each(function(client, id){
|
||||
tests.push(client.run(function(test){
|
||||
localStorage.clear(); console.log('Clear localStorage!!!');
|
||||
var env = test.props;
|
||||
var gun = window.gun = Gun({peers:['http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun'], wait: 1000});
|
||||
window.ref = gun.get('holy').get('grail');
|
||||
}, {i: i += 1, config: config}));
|
||||
});
|
||||
return Promise.all(tests);
|
||||
});
|
||||
|
||||
it("Wait for Alice and Bob...", function(done){
|
||||
setTimeout(done, 1000);
|
||||
});
|
||||
|
||||
it("Alice Write: Hi Bob!", function(){
|
||||
return alice.run(function(test){
|
||||
console.log("I AM ALICE");
|
||||
test.async();
|
||||
ref.once(function() { // TODO: Need `.once` first for subscription. If Alice do a `.put` before a `.once`, Alice will get old data from localStorage if Bob update
|
||||
ref.put('Hi Bob!', function(ack) {
|
||||
console.log(ack);
|
||||
setTimeout(test.done, 10000);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("Bob receive ONCE from Alice: Hi Bob!", function(){
|
||||
return bob.run(function(test){
|
||||
console.log("I AM BOB");
|
||||
test.async();
|
||||
ref.once(function(data){
|
||||
if('Hi Bob!' === data){
|
||||
console.log('[OK] Bob receive the question: ', data);
|
||||
return test.done();
|
||||
} else {
|
||||
var err = '[FAIL] Bob MUST receive: Hi Bob! but receive: ' + data + ' Storage: ' + localStorage.getItem('gun/');
|
||||
console.log(err);
|
||||
return test.fail(err);
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
it("Bob Write response: Hi Alice!", function(){
|
||||
return bob.run(function(test){
|
||||
test.async();
|
||||
ref.put('Hi Alice!', function(ack) {
|
||||
console.log('[OK] Bob Write response: Hi Alice!', ack);
|
||||
setTimeout(test.done, 2000);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("Alice Read response from Bob: Hi Alice!", function(){
|
||||
return alice.run(function(test){
|
||||
test.async();
|
||||
ref.once(function(data){
|
||||
if('Hi Alice!' === data){
|
||||
console.log('[OK] Alice receive the response: ', data);
|
||||
return test.done();
|
||||
} else {
|
||||
//TODO: aqui em duvida.. está pegando do localStorage, mas Bob alterou o dado.
|
||||
var err = '[FAIL] Alice receive wrong response: "' + data + '" and must be "Hi Alice!"';
|
||||
console.log(err);
|
||||
return test.fail(err);
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
it("Bob Write in some data, Alice not subscribed", function(){
|
||||
return bob.run(function(test){
|
||||
test.async();
|
||||
gun.get('bob').get('mine').put('Alice dont want this data!', function() {
|
||||
setTimeout(test.done, 2000);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("Alice not subscribed. Must NOT receive data from Bob", function(){
|
||||
return alice.run(function(test){
|
||||
test.async();
|
||||
/// This must be empty, because alice don't make a subscription to this node.
|
||||
var bobdata = JSON.parse(localStorage.getItem('gun/')).bob;
|
||||
if (bobdata) {
|
||||
var err = '[FAIL] Alice receive not subscribed data: ' + JSON.stringify(bobdata);
|
||||
console.log(err);
|
||||
return test.fail(err);
|
||||
} else {
|
||||
console.log('[OK] Alice Read must NOT receive data from Bob: ', bobdata);
|
||||
return test.done();
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
it("Alice subscription Bob data with ONCE, MUST receive", function(){
|
||||
return alice.run(function(test){
|
||||
test.async();
|
||||
gun.get('bob').once(function(data){
|
||||
if(data){
|
||||
console.log('[OK] Alice receive the value: ', data);
|
||||
return test.done();
|
||||
} else {
|
||||
var err = '[FAIL] Alice receive the value: ' + data;
|
||||
console.log(err);
|
||||
return test.fail(err);
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
it("Bob Write in some data. Now Alice is subscribed.", function(){
|
||||
return bob.run(function(test){
|
||||
test.async();
|
||||
gun.get('bob').get('mine').put('Alice WANT this data now!', function() {
|
||||
setTimeout(test.done, 2000);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("Alice must receive updates from Bob node", function(){
|
||||
return alice.run(function(test){
|
||||
test.async();
|
||||
if (gun._.graph.bob && gun._.graph.bob.mine === 'Alice WANT this data now!') {
|
||||
console.log('[OK] GRAPH: ', gun._.graph.bob);
|
||||
test.done();
|
||||
} else {
|
||||
var err = '[FAIL] GRAPH: ' + JSON.stringify(gun._.graph.bob);
|
||||
console.log(err);
|
||||
test.fail(err);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
it("Server has crashed!", function(){
|
||||
return server.run(function(test){
|
||||
console.log(3);
|
||||
// var env = test.props;
|
||||
// try{ require('fs').unlinkSync(env.i+'data'); }catch(e){}
|
||||
process.exit(0);
|
||||
}, {i: 1, config: config})
|
||||
});
|
||||
|
||||
it("Wait...", function(done){
|
||||
console.log(4);
|
||||
setTimeout(done, 2000);
|
||||
});
|
||||
|
||||
it("Alice update the data (superpeer crashed yet).", function(){
|
||||
return alice.run(function(test){
|
||||
var env = test.props;
|
||||
if(window.WebSocket){
|
||||
var err;
|
||||
try{ new WebSocket('http://'+ env.config.IP + ':' + (env.config.port + 2) + '/gun') }catch(e){ err = e }
|
||||
if(!err){
|
||||
test.fail("Server did not crash.");
|
||||
}
|
||||
}
|
||||
test.async()
|
||||
ref.put("Superpeer? Where are you?", function() {
|
||||
setTimeout(test.done, 100);
|
||||
});
|
||||
}, {config: config});
|
||||
});
|
||||
|
||||
it("Bob can't see what Alice change because Superpeer is out.", function(){
|
||||
return bob.run(function(test){
|
||||
test.async();
|
||||
ref.once(function(data){
|
||||
if('Superpeer? Where are you?' !== data){
|
||||
console.log('[OK] Bob have old data: ', data);
|
||||
return test.done();
|
||||
} else {
|
||||
var err = '[FAIL] Bob MUST not receive: "Superpeer? Where are you?", but receive: ' + data;
|
||||
console.log(err);
|
||||
return test.fail(err);
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
it("Superpeer come started again!", function(){
|
||||
return server2.run(function(test){
|
||||
var env = test.props;
|
||||
test.async();
|
||||
// try{ require('fs').unlinkSync(env.i+'dataaxe') }catch(e){}
|
||||
// try{ require('fs').unlinkSync((env.i+1)+'dataaxe') }catch(e){}
|
||||
var port = env.config.port + env.i;
|
||||
var server = require('http').createServer(function(req, res){
|
||||
res.end("I am "+ env.i +"!");
|
||||
});
|
||||
var Gun = require('gun');
|
||||
require('gun/axe');
|
||||
var gun = Gun({
|
||||
file: env.i+'dataaxe',
|
||||
web: server
|
||||
});
|
||||
server.listen(port, function(){
|
||||
test.done();
|
||||
});
|
||||
}, {i: 1, config: config});
|
||||
});
|
||||
|
||||
it("Wait sync...", function(done){
|
||||
console.log(4);
|
||||
setTimeout(done, 5000);
|
||||
});
|
||||
|
||||
it("Bob now receive what Alice change because Superpeer is on.", function(){
|
||||
return bob.run(function(test){
|
||||
test.async();
|
||||
ref.once(function(data){
|
||||
if('Superpeer? Where are you?' === data){
|
||||
console.log('[OK] Bob have old data: ', data);
|
||||
return test.done();
|
||||
} else {
|
||||
var err = '[FAIL] Bob MUST not receive: "Superpeer? Where are you?", but receive: ' + data;
|
||||
console.log(err);
|
||||
return test.fail(err);
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
it("All finished!", function(done){
|
||||
console.log("Done! Cleaning things up...");
|
||||
setTimeout(function(){
|
||||
done();
|
||||
},1000);
|
||||
});
|
||||
after("Everything shut down.", function(){
|
||||
browsers.run(function(){
|
||||
//location.reload();
|
||||
//setTimeout(function(){
|
||||
//}, 15 * 1000);
|
||||
});
|
||||
return servers.run(function(){
|
||||
process.exit();
|
||||
});
|
||||
console.timeEnd('TOTAL TEST TIME');
|
||||
});
|
||||
});
|
@ -1,13 +1,9 @@
|
||||
/**
|
||||
* AXE test 1
|
||||
* AXE test data balance webrtc
|
||||
* What we want here: (1) Superpeer and (n) peers
|
||||
* - The peers receives only the requested data.
|
||||
* - If the Superpeer crash, after restart, must recreate all subscriptions and update the peers.
|
||||
* - If some peer crash or go offline, must receive the changes via RTC.
|
||||
*
|
||||
* Tip: to run this `npm run testaxe`
|
||||
* Tip 2: if you clone the gun repo, you need to create a link do gun package. Do `npm install && cd node_modules && ln -s ../ gun`
|
||||
* Tip 3: If you not in localhost, run the browsers in anonymous mode because of domain security policies. https://superuser.com/questions/565409/how-to-stop-an-automatic-redirect-from-http-to-https-in-chrome
|
||||
*/
|
||||
var config = {
|
||||
IP: require('ip').address(),
|
||||
@ -16,11 +12,10 @@ var config = {
|
||||
browsers: 3,
|
||||
route: {
|
||||
'/': __dirname + '/index.html',
|
||||
'/gun.js': __dirname + '/../../gun.js',
|
||||
'/gun/axe.js': __dirname + '/../../axe.js',
|
||||
'/gun/lib/radix.js': __dirname + '/../../lib/radix.js',
|
||||
'/gun/lib/webrtc.js': __dirname + '/../../lib/webrtc.js',
|
||||
'/jquery.js': __dirname + '/../../examples/jquery.js'
|
||||
'/gun.js': __dirname + '/../../../gun.js',
|
||||
'/gun/axe.js': __dirname + '/../../../axe.js',
|
||||
'/gun/lib/webrtc.js': __dirname + '/../../../lib/webrtc.js',
|
||||
'/jquery.js': __dirname + '/../../../examples/jquery.js'
|
||||
}
|
||||
}
|
||||
var panic = require('panic-server');
|
172
test/panic/axe/load_balance.js
Normal file
172
test/panic/axe/load_balance.js
Normal file
@ -0,0 +1,172 @@
|
||||
/**
|
||||
* AXE test loadbalance
|
||||
*
|
||||
* Bob, Carl, Dave, Ed, subscribed to Zebra(relay).
|
||||
*
|
||||
* Test case 3) Bob Carl Dave Ed browser peers, all subscribed to Zebra(Relay). Alice joins, gets Zebra. Relay should only load balance GET to 3 other peers, as acks will have matching hashes and therefore stop propagating. (if acks are inconsistent, it will keep propagating, but we're not testing that here). The tricky thing is you'll have to hijack requests to make sure the 4th peer doesn't get the GET.
|
||||
*/
|
||||
|
||||
var config = { IP: require('ip').address(), port: 8765, servers: 1, browsers:4, i:0,
|
||||
route: {
|
||||
'/': __dirname + '/index.html',
|
||||
'/gun.js': __dirname + '/../../../gun.js',
|
||||
'/gun/axe.js': __dirname + '/../../../axe.js',
|
||||
'/jquery.js': __dirname + '/../../../examples/jquery.js'
|
||||
}
|
||||
};
|
||||
|
||||
var panic = require('panic-server');
|
||||
panic.server().on('request', function(req, res){ config.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);}).listen(config.port);
|
||||
|
||||
var clients = panic.clients;
|
||||
var manager = require('panic-manager')();
|
||||
manager.start({
|
||||
clients: Array(config.servers).fill().map(function(u, i){ return { type: 'node', port: config.port + (i + 1) } }),
|
||||
panic : 'http://' + config.IP + ':' + config.port
|
||||
});
|
||||
|
||||
var servers = clients.filter('Node.js');
|
||||
var server = servers.pluck(1);
|
||||
var browsers = clients.excluding(servers);
|
||||
|
||||
describe("AXE Test: LOADBALANCE", function(){
|
||||
this.timeout(5 * 60 * 1000);
|
||||
|
||||
it("Servers have joined!", function(){ return servers.atLeast(config.servers); });
|
||||
|
||||
it("GUN started!", function(){
|
||||
return server.run(function(test){
|
||||
var env = test.props;
|
||||
test.async();
|
||||
try{ require('fs').unlinkSync(env.i+'dataaxe') }catch(e){}
|
||||
try{ require('fs').unlinkSync((env.i+1)+'dataaxe') }catch(e){}
|
||||
var port = env.config.port + env.i;
|
||||
var server = require('http').createServer(function(req, res){ res.end("I am "+ env.i +"!"); });
|
||||
var Gun = require('gun');
|
||||
// require('gun/axe');
|
||||
var gun = global.gun = Gun({ file: env.i+'dataaxe', web: server, pid:'Relay_pid' });
|
||||
console.log(' [ RELAY PID ] '+gun._.opt.pid);
|
||||
Gun.on('create', function(root){
|
||||
this.to.next(root);
|
||||
root.on('in', function(msg){
|
||||
console.log('[ GET RELAY ]* PID:'+gun._.opt.pid+' RELAY MESSAGE: ', (msg));
|
||||
this.to.next(msg);
|
||||
});
|
||||
root.on('out', function(msg){
|
||||
console.log('[ OUT RELAY ]* ', msg);
|
||||
this.to.next(msg);
|
||||
});
|
||||
|
||||
});
|
||||
server.listen(port, function(){ test.done(); });
|
||||
gun.get('ref_soul').put({ 'hi':'value_'+String.random(3) });
|
||||
}, {i: 1, config: config});
|
||||
});
|
||||
|
||||
it(config.browsers +" browser(s) have joined!", function(){
|
||||
require('../util/open').web(config.browsers, "http://"+ config.IP +":"+ config.port);
|
||||
// console.log(" PLEASE OPEN http://"+ config.IP +":"+ config.port +" IN "+ config.browsers +" BROWSER(S)!");
|
||||
return browsers.atLeast(config.browsers);
|
||||
});
|
||||
|
||||
it("Browsers initialized gun!", function(){
|
||||
var tests = [], i=0;
|
||||
browsers.each(function(client, id){
|
||||
tests.push(client.run(function(test){
|
||||
localStorage.clear(); //console.log('Clear localStorage!!!');
|
||||
window.uuid = function(l){ return new Date(Gun.state()).toISOString() + '/' + String.random(l||3) };
|
||||
var env = test.props;
|
||||
var opt = {
|
||||
peers:['http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun'],
|
||||
// pid:'Peer_'+('0'+(env.config.i+1)).slice(-2)+'_',
|
||||
uuid
|
||||
};
|
||||
|
||||
Gun.on('create', function(root){
|
||||
this.to.next(root);
|
||||
root.on('in', function(msg){
|
||||
this.to.next(msg);
|
||||
if (msg.get && msg.get['#'] && msg.get['#'] !== 'balance') {
|
||||
++gun.total_gets; /// increment each peer total `in` events
|
||||
var hash = (msg['#'] ? '_'+msg['#'] : '') + (msg['><'] ? '_O ' : '');
|
||||
gun.get('balance').set(gun._.opt.pid+' '+(msg['#'] ? '_msg_id_'+msg['#'] : ''));
|
||||
}
|
||||
});
|
||||
});
|
||||
var gun = window.gun = Gun(opt);
|
||||
gun.total_gets=0;
|
||||
}, {i: i += 1, config: config}));
|
||||
++config.i;
|
||||
});
|
||||
return Promise.all(tests);
|
||||
});
|
||||
|
||||
it("Peers subscribe", function(){
|
||||
var tests = [], i=0;
|
||||
browsers.each(function(client, id){
|
||||
tests.push(client.run(function(test){
|
||||
test.async();
|
||||
function done(v,k) {
|
||||
// console.log('!!!!!!! Peer subscribed pid:' + gun._.opt.pid + ' msg:' + JSON.stringify({ k, v }));
|
||||
test.done();
|
||||
}
|
||||
gun.get('ref_soul').once(done);
|
||||
}, {i: i += 1, config: config}));
|
||||
});
|
||||
return Promise.all(tests);
|
||||
});
|
||||
|
||||
it("Check balance!", function(){
|
||||
return server.run(function(test){
|
||||
function onlyUnique(value, index, self) { return self.indexOf(value) === index; }
|
||||
console.log('RELAY PID:' + gun._.opt.pid);
|
||||
test.async();
|
||||
gun.get('balance').once(function(v,k) {
|
||||
var tmp = [], i=0, participants=[], keys = Object.keys(v['_']).sort();
|
||||
for (i=0;i<keys.length;++i) { participants.push(v[ keys[ i ] ]); }
|
||||
participants.sort();
|
||||
var pid, pids = Object.keys(v).sort();
|
||||
var pids_sorted = Object.keys(v['_']['>']).map(soul => v[soul].split(' ')[0]).filter(onlyUnique).sort();
|
||||
var msgs_id = Object.keys(v['_']['>']).map(soul => v[soul].split(' ')[1]).filter(onlyUnique);
|
||||
var msgs_sorted_bytime = Object.keys(v['_']['>']).sort();
|
||||
var table={}, msg_id, peer_id;
|
||||
|
||||
for (i=0;i<msgs_sorted_bytime.length;++i) {
|
||||
tmp =v[msgs_sorted_bytime[i]].split(' ');
|
||||
peer_id = tmp[0];
|
||||
msg_id = tmp[1];
|
||||
if (!table[msg_id]) { table[msg_id]=[]; }
|
||||
table[msg_id].push(peer_id);
|
||||
if (table[msg_id].length > 4) { console.log('Ouch!!!!', table); test.fail('Msg ('+msg_id+') with more then 4 requests.'); return; }
|
||||
}
|
||||
for (i=0;i<pids_sorted.length;++i) {
|
||||
if (typeof pids_sorted[i] !== 'string') { continue; }
|
||||
pid = pids_sorted[i];
|
||||
}
|
||||
for (i=0;i<pids.length;++i) {
|
||||
var p1=pids[i-1], p2=pids[i];
|
||||
if (!v[p1] || !v[p2]) { continue; }
|
||||
if ('string' !== typeof v[p1]) { v[p1]='relay'; }
|
||||
if ('string' !== typeof v[p2]) { v[p2]='relay'; }
|
||||
}
|
||||
// console.log('TABLE: ', table);/// NOTE: this data have each peer_id who participant of a message delivery.
|
||||
setTimeout(test.done, 1000);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("All finished!", function(done){
|
||||
// browsers.each(function(client, id){ client.run(function() { console.log('TOTAL gets PID:'+gun._.opt.pid+': ', gun.total_gets); }); });
|
||||
console.log("Done! Cleaning things up...");
|
||||
setTimeout(done, 2000);
|
||||
});
|
||||
|
||||
after("Everything shut down.", function(){
|
||||
require('../util/open').cleanup() || browsers.run(function(){
|
||||
setTimeout(function(){
|
||||
location.reload();
|
||||
}, 15 * 1000);
|
||||
});
|
||||
return servers.run(function(){ process.exit(); });
|
||||
});
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user