redbird/test/test_register.js
2018-06-29 15:47:19 +02:00

422 lines
13 KiB
JavaScript

"use strict";
var Redbird = require('../');
var expect = require('chai').expect;
var opts = {
bunyan: false /* {
name: 'test',
streams: [{
path: '/dev/null',
}]
} */
}
describe("Route registration", function () {
it("should register a simple route", function () {
var redbird = Redbird(opts);
expect(redbird.routing).to.be.an("object");
redbird.register('example.com', '192.168.1.2:8080');
expect(redbird.routing).to.have.property("example.com")
expect(redbird.resolve('example.com')).to.be.an("object");
var host = redbird.routing["example.com"];
expect(host).to.be.an("array");
expect(host[0]).to.have.property('path')
expect(host[0].path).to.be.eql('/');
expect(host[0].urls).to.be.an('array');
expect(host[0].urls.length).to.be.eql(1);
expect(host[0].urls[0].href).to.be.eql('http://192.168.1.2:8080/');
redbird.unregister('example.com', '192.168.1.2:8080');
expect(redbird.resolve('example.com')).to.be.an("undefined")
redbird.close();
});
it("should resolve domains as case insensitive", function () {
var redbird = Redbird(opts);
expect(redbird.routing).to.be.an("object");
redbird.register('example.com', '192.168.1.2:8080');
var target = redbird.resolve('Example.com');
expect(target).to.be.an("object");
expect(target.urls[0].hostname).to.be.equal('192.168.1.2');
redbird.close();
});
it("should register multiple routes", function () {
var redbird = Redbird(opts);
expect(redbird.routing).to.be.an("object");
redbird.register('example1.com', '192.168.1.2:8080');
redbird.register('example2.com', '192.168.1.3:8081');
redbird.register('example3.com', '192.168.1.4:8082');
redbird.register('example4.com', '192.168.1.5:8083');
redbird.register('example5.com', '192.168.1.6:8084');
expect(redbird.routing).to.have.property("example1.com")
expect(redbird.routing).to.have.property("example2.com")
expect(redbird.routing).to.have.property("example3.com")
expect(redbird.routing).to.have.property("example4.com")
expect(redbird.routing).to.have.property("example5.com")
var host;
host = redbird.routing["example1.com"];
expect(host[0].path).to.be.eql('/');
expect(host[0].urls[0].href).to.be.eql('http://192.168.1.2:8080/');
host = redbird.routing["example2.com"];
expect(host[0].path).to.be.eql('/');
expect(host[0].urls[0].href).to.be.eql('http://192.168.1.3:8081/');
host = redbird.routing["example3.com"];
expect(host[0].path).to.be.eql('/');
expect(host[0].urls[0].href).to.be.eql('http://192.168.1.4:8082/');
host = redbird.routing["example4.com"];
expect(host[0].path).to.be.eql('/');
expect(host[0].urls[0].href).to.be.eql('http://192.168.1.5:8083/');
host = redbird.routing["example5.com"];
expect(host[0].path).to.be.eql('/');
expect(host[0].urls[0].href).to.be.eql('http://192.168.1.6:8084/');
redbird.unregister('example1.com');
expect(redbird.resolve('example1.com')).to.be.an("undefined")
redbird.unregister('example2.com');
expect(redbird.resolve('example2.com')).to.be.an("undefined")
redbird.unregister('example3.com');
expect(redbird.resolve('example3.com')).to.be.an("undefined")
redbird.unregister('example4.com');
expect(redbird.resolve('example4.com')).to.be.an("undefined")
redbird.unregister('example5.com');
expect(redbird.resolve('example5.com')).to.be.an("undefined")
redbird.close();
})
it("should register several pathnames within a route", function () {
var redbird = Redbird(opts);
expect(redbird.routing).to.be.an("object");
redbird.register('example.com', '192.168.1.2:8080');
redbird.register('example.com/qux/baz', '192.168.1.5:8080');
redbird.register('example.com/foo', '192.168.1.3:8080');
redbird.register('example.com/bar', '192.168.1.4:8080');
expect(redbird.routing).to.have.property("example.com")
var host = redbird.routing["example.com"];
expect(host).to.be.an("array");
expect(host[0]).to.have.property('path')
expect(host[0].path).to.be.eql('/qux/baz');
expect(host[0].urls).to.be.an('array');
expect(host[0].urls.length).to.be.eql(1);
expect(host[0].urls[0].href).to.be.eql('http://192.168.1.5:8080/');
expect(host[0].path.length).to.be.least(host[1].path.length)
expect(host[1].path.length).to.be.least(host[2].path.length)
expect(host[2].path.length).to.be.least(host[3].path.length)
redbird.unregister('example.com');
expect(redbird.resolve('example.com')).to.be.an("undefined")
expect(redbird.resolve('example.com', '/foo')).to.be.an("object")
redbird.unregister('example.com/foo');
expect(redbird.resolve('example.com', '/foo')).to.be.an("undefined")
redbird.close();
})
it("shouldnt crash process in unregister of unregisted host", function (done) {
var redbird = Redbird(opts);
redbird.unregister('example.com');
done()
redbird.close();
})
})
describe("Route resolution", function () {
it("should resolve to a correct route", function () {
var redbird = Redbird(opts);
expect(redbird.routing).to.be.an("object");
redbird.register('example.com', '192.168.1.2:8080');
redbird.register('example.com/qux/baz', '192.168.1.5:8080');
redbird.register('example.com/foo', '192.168.1.3:8080');
redbird.register('example.com/bar', '192.168.1.4:8080');
redbird.register('example.com/foo/baz', '192.168.1.3:8080');
var route = redbird.resolve('example.com', '/foo/asd/1/2');
expect(route.path).to.be.eql('/foo')
expect(route.urls.length).to.be.eql(1);
expect(route.urls[0].href).to.be.eql('http://192.168.1.3:8080/');
redbird.close();
})
it("should resolve to a correct route with complex path", function () {
var redbird = Redbird(opts);
expect(redbird.routing).to.be.an("object");
redbird.register('example.com', '192.168.1.2:8080');
redbird.register('example.com/qux/baz', '192.168.1.5:8080');
redbird.register('example.com/foo', '192.168.1.3:8080');
redbird.register('example.com/bar', '192.168.1.4:8080');
redbird.register('example.com/foo/baz', '192.168.1.7:8080');
var route = redbird.resolve('example.com', '/foo/baz/a/b/c');
expect(route.path).to.be.eql('/foo/baz')
expect(route.urls.length).to.be.eql(1);
expect(route.urls[0].href).to.be.eql('http://192.168.1.7:8080/');
redbird.close();
})
it("should resolve to undefined if route not available", function () {
var redbird = Redbird(opts);
expect(redbird.routing).to.be.an("object");
redbird.register('example.com', '192.168.1.2:8080');
redbird.register('example.com/qux/baz', '192.168.1.5:8080');
redbird.register('example.com/foo', '192.168.1.3:8080');
redbird.register('foobar.com/bar', '192.168.1.4:8080');
redbird.register('foobar.com/foo/baz', '192.168.1.3:8080');
var route = redbird.resolve('wrong.com');
expect(route).to.be.an('undefined')
var route = redbird.resolve('foobar.com');
expect(route).to.be.an('undefined')
redbird.close();
})
it("should get a target if route available", function () {
var redbird = Redbird(opts);
expect(redbird.routing).to.be.an("object");
redbird.register('example.com', '192.168.1.2:8080');
redbird.register('example.com/qux/baz', '192.168.1.5:8080');
redbird.register('example.com/foo', '192.168.1.3:8080');
redbird.register('foobar.com/bar', '192.168.1.4:8080');
redbird.register('foobar.com/foo/baz', '192.168.1.7:8080');
redbird.register('foobar.com/media', '192.168.1.7:8080');
var route = redbird.resolve('example.com', '/qux/a/b/c');
expect(route.path).to.be.eql('/');
var route = redbird.resolve('foobar.com', '/medias/');
expect(route).to.be.undefined;
var route = redbird.resolve('foobar.com', '/mediasa');
expect(route).to.be.undefined;
var route = redbird.resolve('foobar.com', '/media/sa');
expect(route.path).to.be.eql('/media');
var target = redbird._getTarget('example.com', { url: '/foo/baz/a/b/c' });
expect(target.href).to.be.eql('http://192.168.1.3:8080/')
redbird.close();
})
it("should get a target with path when necessary", function () {
var redbird = Redbird(opts);
expect(redbird.routing).to.be.an("object");
redbird.register('example.com', '192.168.1.2:8080');
redbird.register('example.com/qux/baz', '192.168.1.5:8080');
redbird.register('example.com/foo', '192.168.1.3:8080/a/b');
redbird.register('foobar.com/bar', '192.168.1.4:8080');
redbird.register('foobar.com/foo/baz', '192.168.1.7:8080');
var route = redbird.resolve('example.com', '/qux/a/b/c');
expect(route.path).to.be.eql('/');
var req = { url: '/foo/baz/a/b/c' }
var target = redbird._getTarget('example.com', req);
expect(target.href).to.be.eql('http://192.168.1.3:8080/a/b')
expect(req.url).to.be.eql('/a/b/baz/a/b/c')
redbird.close();
})
})
describe("TLS/SSL", function () {
it("should allow TLS/SSL certificates", function () {
var redbird = Redbird({
ssl: {
port: 4430
},
bunyan: false
});
expect(redbird.routing).to.be.an("object");
redbird.register('example.com', '192.168.1.1:8080', {
ssl: {
key: 'dummy',
cert: 'dummy'
}
});
redbird.register('example.com', '192.168.1.2:8080');
expect(redbird.certs).to.be.an("object");
expect(redbird.certs['example.com']).to.be.an("object");
redbird.unregister('example.com', '192.168.1.1:8080');
expect(redbird.resolve('example.com')).to.not.be.an("undefined")
expect(redbird.certs['example.com']).to.not.be.an("undefined");
redbird.unregister('example.com', '192.168.1.2:8080');
expect(redbird.resolve('example.com')).to.be.an("undefined")
expect(redbird.certs['example.com']).to.be.an("undefined");
})
it('Should bind https servers to different ip addresses', function(testDone) {
var isPortTaken = function(port, ip, done) {
var net = require('net')
var tester = net.createServer()
.once('error', function (err) {
if (err.code != 'EADDRINUSE') return done(err)
done(null, true)
})
.once('listening', function() {
tester.once('close', function() { done(null, false) })
.close()
})
.listen(port, ip)
}
var redbird = Redbird({
bunyan: false,
port: 8080,
// Specify filenames to default SSL certificates (in case SNI is not supported by the
// user's browser)
ssl: [
{
port: 4433,
key: 'dummy',
cert: 'dummy',
ip: '127.0.0.1'
},
{
port: 4434,
key: 'dummy',
cert: 'dummy',
ip: '127.0.0.1'
}
]
});
redbird.register('mydomain.com', 'http://127.0.0.1:8001', {
ssl: {
key: 'dummy',
cert: 'dummy',
ca: 'dummym'
}
});
var portsTaken = 0;
var portsChecked = 0;
function portsTakenDone(err, taken) {
portsChecked++;
if (err) { throw err; }
if (taken) { portsTaken++; }
if ( portsChecked == 2 ) {
portsCheckDone();
}
}
function portsCheckDone() {
expect(portsTaken).to.be.eql(2);
redbird.close();
testDone();
}
isPortTaken(4433, '127.0.0.1', portsTakenDone);
isPortTaken(4434, '127.0.0.1', portsTakenDone);
});
})
describe("Load balancing", function () {
it("should load balance between several targets", function () {
var redbird = Redbird(opts);
expect(redbird.routing).to.be.an("object");
redbird.register('example.com', '192.168.1.1:8080');
redbird.register('example.com', '192.168.1.2:8080');
redbird.register('example.com', '192.168.1.3:8080');
redbird.register('example.com', '192.168.1.4:8080');
expect(redbird.routing['example.com'][0].urls.length).to.be.eql(4);
expect(redbird.routing['example.com'][0].rr).to.be.eql(0);
var route = redbird.resolve('example.com', '/foo/qux/a/b/c');
expect(route.urls.length).to.be.eql(4);
for (var i = 0; i < 1000; i++) {
var target = redbird._getTarget('example.com', { url: '/a/b/c' });
expect(target.href).to.be.eql('http://192.168.1.1:8080/')
expect(redbird.routing['example.com'][0].rr).to.be.eql(1);
var target = redbird._getTarget('example.com', { url: '/x/y' });
expect(target.href).to.be.eql('http://192.168.1.2:8080/')
expect(redbird.routing['example.com'][0].rr).to.be.eql(2);
var target = redbird._getTarget('example.com', { url: '/j' });
expect(target.href).to.be.eql('http://192.168.1.3:8080/')
expect(redbird.routing['example.com'][0].rr).to.be.eql(3);
var target = redbird._getTarget('example.com', { url: '/k/' });
expect(target.href).to.be.eql('http://192.168.1.4:8080/')
expect(redbird.routing['example.com'][0].rr).to.be.eql(0);
}
redbird.unregister('example.com', '192.168.1.1:8080');
expect(redbird.resolve('example.com')).to.not.be.an("undefined")
redbird.unregister('example.com', '192.168.1.2:8080');
expect(redbird.resolve('example.com')).to.not.be.an("undefined")
redbird.unregister('example.com', '192.168.1.3:8080');
expect(redbird.resolve('example.com')).to.not.be.an("undefined")
redbird.unregister('example.com', '192.168.1.4:8080');
expect(redbird.resolve('example.com')).to.be.an("undefined")
redbird.close();
});
});