rate limits acceptance tests

This commit is contained in:
Simon Martín
2018-02-20 10:57:29 +01:00
parent 98907a886c
commit a0f560ca1a
2 changed files with 262 additions and 12 deletions
+250
View File
@@ -0,0 +1,250 @@
require('../support/test_helper');
const assert = require('../support/assert');
const TestClient = require('../support/test-client');
const redis = require('redis');
const {
RATE_LIMIT_ENDPOINTS_GROUPS,
RATE_LIMIT_STORE_KEY
} = require('../../lib/cartodb/middleware/rate-limit');
let redisClient;
let testClient;
let keysToDelete = ['user:localhost:mapviews:global'];
const user = 'cdb';
const query = `
SELECT
ST_Transform('SRID=4326;POINT(-180 85.05112877)'::geometry, 3857) the_geom_webmercator,
1 cartodb_id,
2 val
`;
const createMapConfig = ({
version = '1.6.0',
type = 'cartodb',
sql = query,
cartocss = TestClient.CARTOCSS.POINTS,
cartocss_version = '2.3.0',
interactivity = 'cartodb_id',
countBy = 'cartodb_id'
} = {}) => ({
version,
layers: [{
type,
options: {
source: {
id: 'a0'
},
cartocss,
cartocss_version,
interactivity
}
}],
analyses: [
{
id: 'a0',
type: 'source',
params: {
query: sql
}
}
],
dataviews: {
count: {
source: {
id: 'a0'
},
type: 'formula',
options: {
column: countBy,
operation: 'count'
}
}
}
});
function setLimit(count, period, burst) {
redisClient.SELECT(8, function(err) {
if (err) {
return;
}
const key = RATE_LIMIT_STORE_KEY + user + ':' + RATE_LIMIT_ENDPOINTS_GROUPS.ENDPOINT_1;
redisClient.hset(key, 'b', burst, 'c', count, 'p', period, function() {
keysToDelete.push(key);
});
});
}
describe('rate limit acceptance', function() {
before(function() {
redisClient = redis.createClient(global.environment.redis.port);
testClient = new TestClient(createMapConfig(), 1234);
});
afterEach(function(done) {
keysToDelete.forEach( key => {
redisClient.del(key);
});
redisClient.SELECT(0, () => {
redisClient.del('user:localhost:mapviews:global');
redisClient.SELECT(5, () => {
redisClient.del('user:localhost:mapviews:global');
done();
});
});
});
it('should not be rate limited', function (done) {
const count = 1;
const period = 1;
const burst = 1;
setLimit(count, period, burst);
let response = {
status: 200,
headers: {
'Content-Type': 'application/json; charset=utf-8',
'X-Rate-Limit-Limit': '2',
'X-Rate-Limit-Remaining': '1',
'X-Rate-Limit-Reset': '1',
'X-Rate-Limit-Retry-After': '-1'
}
};
testClient.getLayergroup({ response }, (err) => {
assert.ifError(err);
setTimeout(done, period * 1000);
});
});
it("1 req/sec: 5 request (1 per 250ms) should be limited: OK, KO, KO, KO, OK", function(done) {
const count = 1;
const period = 1;
const burst = 1;
setLimit(count, period, burst);
let response = {
status: 200,
headers: {
'Content-Type': 'application/json; charset=utf-8',
'X-Rate-Limit-Limit': '2',
'X-Rate-Limit-Remaining': '1',
'X-Rate-Limit-Reset': '1',
'X-Rate-Limit-Retry-After': '-1'
}
};
testClient.getLayergroup({ response }, (err, res) => {
assert.ifError(err);
});
setTimeout(
function() {
let response = {
status: 200,
headers: {
'Content-Type': 'application/json; charset=utf-8',
'X-Rate-Limit-Limit': '2',
'X-Rate-Limit-Remaining': '0',
'X-Rate-Limit-Reset': '1',
'X-Rate-Limit-Retry-After': '-1'
}
};
testClient.getLayergroup({ response }, (err) => {
assert.ifError(err);
});
},
250
);
setTimeout(
function() {
let response = {
status: 200,
headers: {
'Content-Type': 'application/json; charset=utf-8',
'X-Rate-Limit-Limit': '2',
'X-Rate-Limit-Remaining': '0',
'X-Rate-Limit-Reset': '2',
'X-Rate-Limit-Retry-After': '-1'
}
};
testClient.getLayergroup({ response }, (err) => {
assert.ifError(err);
});
},
500
);
setTimeout(
function() {
let response = {
status: 429,
headers: {
'Content-Type': 'application/json; charset=utf-8',
'X-Rate-Limit-Limit': '2',
'X-Rate-Limit-Remaining': '0',
'X-Rate-Limit-Reset': '2',
'X-Rate-Limit-Retry-After': '1'
}
};
testClient.getLayergroup({ response }, (err) => {
assert.ifError(err);
});
},
750
);
setTimeout(
function() {
let response = {
status: 429,
headers: {
'Content-Type': 'application/json; charset=utf-8',
'X-Rate-Limit-Limit': '2',
'X-Rate-Limit-Remaining': '0',
'X-Rate-Limit-Reset': '2',
'X-Rate-Limit-Retry-After': '1'
}
};
testClient.getLayergroup({ response }, (err) => {
assert.ifError(err);
});
},
950
);
setTimeout(
function() {
let response = {
status: 200,
headers: {
'Content-Type': 'application/json; charset=utf-8',
'X-Rate-Limit-Limit': '2',
'X-Rate-Limit-Remaining': '0',
'X-Rate-Limit-Reset': '2',
'X-Rate-Limit-Retry-After': '-1'
}
};
testClient.getLayergroup({ response }, (err) => {
assert.ifError(err);
done();
});
},
1050
);
});
});
+12 -12
View File
@@ -38,7 +38,7 @@ function getReqAndRes() {
};
}
describe.only('rate-limit', function() {
describe('rate limit unit', function() {
before(function() {
const redisPool = new RedisPool(global.environment.redis);
const metadataBackend = cartodbRedis({pool: redisPool});
@@ -66,7 +66,7 @@ describe.only('rate-limit', function() {
"X-Rate-Limit-Limit": burst + 1,
"X-Rate-Limit-Remaining": burst,
"X-Rate-Limit-Reset": period,
"X-Rate-Limit-Retry-After": -1
"X-Rate-Limit-Retry-After": -1
});
setTimeout(done, period * 1000);
@@ -86,7 +86,7 @@ describe.only('rate-limit', function() {
"X-Rate-Limit-Limit": burst + 1,
"X-Rate-Limit-Remaining": burst,
"X-Rate-Limit-Reset": period,
"X-Rate-Limit-Retry-After": -1
"X-Rate-Limit-Retry-After": -1
});
});
@@ -99,7 +99,7 @@ describe.only('rate-limit', function() {
"X-Rate-Limit-Limit": burst + 1,
"X-Rate-Limit-Remaining": burst,
"X-Rate-Limit-Reset": period,
"X-Rate-Limit-Retry-After": -1
"X-Rate-Limit-Retry-After": -1
});
});
},
@@ -115,7 +115,7 @@ describe.only('rate-limit', function() {
"X-Rate-Limit-Limit": burst + 1,
"X-Rate-Limit-Remaining": burst,
"X-Rate-Limit-Reset": period,
"X-Rate-Limit-Retry-After": -1
"X-Rate-Limit-Retry-After": -1
});
setTimeout(done, period * 1000);
@@ -151,7 +151,7 @@ describe.only('rate-limit', function() {
"X-Rate-Limit-Limit": burst + 1,
"X-Rate-Limit-Remaining": count - 1,
"X-Rate-Limit-Reset": period,
"X-Rate-Limit-Retry-After": -1
"X-Rate-Limit-Retry-After": -1
});
});
},
@@ -167,10 +167,10 @@ describe.only('rate-limit', function() {
"X-Rate-Limit-Limit": burst + 1,
"X-Rate-Limit-Remaining": 0,
"X-Rate-Limit-Reset": period,
"X-Rate-Limit-Retry-After": 1
"X-Rate-Limit-Retry-After": 1
});
assert.equal(err.message, 'You are over the limits.');
assert.equal(err.http_status, 429);
assert.equal(err.http_status, 429);
});
},
500
@@ -185,7 +185,7 @@ describe.only('rate-limit', function() {
"X-Rate-Limit-Limit": burst + 1,
"X-Rate-Limit-Remaining": 0,
"X-Rate-Limit-Reset": period,
"X-Rate-Limit-Retry-After": 1
"X-Rate-Limit-Retry-After": 1
});
assert.equal(err.message, 'You are over the limits.');
assert.equal(err.http_status, 429);
@@ -203,10 +203,10 @@ describe.only('rate-limit', function() {
"X-Rate-Limit-Limit": burst + 1,
"X-Rate-Limit-Remaining": 0,
"X-Rate-Limit-Reset": period,
"X-Rate-Limit-Retry-After": 1
"X-Rate-Limit-Retry-After": 1
});
assert.equal(err.message, 'You are over the limits.');
assert.equal(err.http_status, 429);
assert.equal(err.http_status, 429);
});
},
950
@@ -221,7 +221,7 @@ describe.only('rate-limit', function() {
"X-Rate-Limit-Limit": burst + 1,
"X-Rate-Limit-Remaining": count - 1,
"X-Rate-Limit-Reset": period,
"X-Rate-Limit-Retry-After": -1
"X-Rate-Limit-Retry-After": -1
});
setTimeout(done, 1000);
});