diff --git a/test/acceptance/user-database-timeout-limit.js b/test/acceptance/user-database-timeout-limit.js new file mode 100644 index 00000000..32976b37 --- /dev/null +++ b/test/acceptance/user-database-timeout-limit.js @@ -0,0 +1,133 @@ +require('../support/test_helper'); + +const assert = require('../support/assert'); +const TestClient = require('../support/test-client'); + +const pointSleepSql = ` + SELECT + pg_sleep(1), + 'SRID=3857;POINT(0 0)'::geometry the_geom_webmercator, + 1 cartodb_id, + 2 val +`; + +const createMapConfig = ({ + version = '1.6.0', + type = 'cartodb', + sql = pointSleepSql, + cartocss = TestClient.CARTOCSS.POINTS, + cartocss_version = '2.3.0', + countBy = 'cartodb_id' +} = {}) => ({ + version, + layers: [{ + type, + options: { + source: { + id: 'a0' + }, + cartocss, + cartocss_version + } + }], + analyses: [ + { + id: 'a0', + type: 'source', + params: { + query: sql + } + } + ], + dataviews: { + count: { + source: { + id: 'a0' + }, + type: 'formula', + options: { + column: countBy, + operation: 'count' + } + } + } +}); + +describe('user database timeout limit', function () { + beforeEach(function (done) { + TestClient.setUserDatabaseTimeoutLimit('localhost', 50, done); + }); + + afterEach(function (done) { + TestClient.setUserDatabaseTimeoutLimit('localhost', 0, done); + }); + + describe('dataview', function () { + beforeEach(function () { + const mapconfig = createMapConfig(); + this.testClient = new TestClient(mapconfig, 1234); + }); + + afterEach(function (done) { + this.testClient.drain(done); + }); + + it('layergroup creation works but dataview request fails due to statement timeout', function (done) { + const params = { + response: { + status: 400, + headers: { + 'Content-Type': 'application/json; charset=utf-8' + } + } + }; + + this.testClient.getDataview('count', params, (err, dataview) => { + assert.ifError(err); + + assert.deepEqual(dataview, { + errors: ['canceling statement due to statement timeout'], + errors_with_context: [{ type: 'unknown', message: 'canceling statement due to statement timeout' }] + }); + + done(); + }); + }); + }); + + describe('torque', function () { + beforeEach(function () { + const mapconfig = createMapConfig({ + type: 'torque', + cartocss: TestClient.CARTOCSS.TORQUE + }); + this.testClient = new TestClient(mapconfig, 1234); + }); + + afterEach(function (done) { + this.testClient.drain(done); + }); + + it('layergroup creation fails due to statement timeout', function (done) { + const expectedResponse = { + status: 400, + headers: { + 'Content-Type': 'application/json; charset=utf-8' + } + }; + + this.testClient.getLayergroup(expectedResponse, (err, timeoutError) => { + assert.deepEqual(timeoutError, { + errors: ["TorqueRenderer: canceling statement due to statement timeout"], + errors_with_context: [{ + type: "layer", + message: "TorqueRenderer: canceling statement due to statement timeout", + layer: { id: 'torque-layer0', index: 0, type: "torque" } + }] + }); + + done(); + }); + }); + }); +}); diff --git a/test/acceptance/user-timeout-limit.js b/test/acceptance/user-render-timeout-limit.js similarity index 75% rename from test/acceptance/user-timeout-limit.js rename to test/acceptance/user-render-timeout-limit.js index 87c07b76..8d7e9a6e 100644 --- a/test/acceptance/user-timeout-limit.js +++ b/test/acceptance/user-render-timeout-limit.js @@ -68,16 +68,8 @@ const createMapConfig = ({ } }); -describe('user timeout limit', function () { - before(function (done) { - TestClient.setUserDatabaseTimeoutLimit('localhost', 900, done); - }); - - after(function (done) { - TestClient.setUserDatabaseTimeoutLimit('localhost', 0, done); - }); - - describe('map instantiation', function () { +describe('user render timeout limit', function () { + describe('map instantiation => validation', function () { beforeEach(function (done) { const mapconfig = createMapConfig({ sql: validationPointSleepSql }); this.testClient = new TestClient(mapconfig, 1234); @@ -122,76 +114,6 @@ describe('user timeout limit', function () { }); }); - describe('dataview', function () { - beforeEach(function () { - const mapconfig = createMapConfig(); - this.testClient = new TestClient(mapconfig, 1234); - }); - - afterEach(function (done) { - this.testClient.drain(done); - }); - - it('layergroup creation works but dataview request fails due to statement timeout', function (done) { - const params = { - response: { - status: 400, - headers: { - 'Content-Type': 'application/json; charset=utf-8' - } - } - }; - - this.testClient.getDataview('count', params, (err, dataview) => { - assert.ifError(err); - - assert.deepEqual(dataview, { - errors: ['canceling statement due to statement timeout'], - errors_with_context: [{ type: 'unknown', message: 'canceling statement due to statement timeout' }] - }); - - done(); - }); - }); - }); - - describe('torque', function () { - beforeEach(function () { - const mapconfig = createMapConfig({ - type: 'torque', - cartocss: TestClient.CARTOCSS.TORQUE - }); - this.testClient = new TestClient(mapconfig, 1234); - }); - - afterEach(function (done) { - this.testClient.drain(done); - }); - - it('layergroup creation fails due to statement timeout', function (done) { - const expectedResponse = { - status: 400, - headers: { - 'Content-Type': 'application/json; charset=utf-8' - } - }; - - this.testClient.getLayergroup(expectedResponse, (err, timeoutError) => { - assert.deepEqual(timeoutError, { - errors: ["TorqueRenderer: canceling statement due to statement timeout"], - errors_with_context: [{ - type: "layer", - message: "TorqueRenderer: canceling statement due to statement timeout", - layer: { id: 'torque-layer0', index: 0, type: "torque" } - }] - }); - - done(); - }); - }); - }); - - describe('raster', function () { describe('with onTileErrorStrategy ENABLED', function () { let onTileErrorStrategy; diff --git a/test/support/test-client.js b/test/support/test-client.js index 80869152..d03fef2e 100644 --- a/test/support/test-client.js +++ b/test/support/test-client.js @@ -850,9 +850,10 @@ TestClient.prototype.setUserRenderTimeoutLimit = function (user, userTimeoutLimi helper.configureMetadata('hmset', params, callback); }; -TestClient.setUserDatabaseTimeoutLimit = function (user, userTimeoutLimit, callback) { +TestClient.setUserDatabaseTimeoutLimit = function (user, timeoutLimit, callback) { const dbname = _.template(global.environment.postgres_auth_user, { user_id: 1 }) + '_db'; const role = _.template(global.environment.postgres_auth_user, { user_id: 1 }) + const publicUser = global.environment.postgres.user; const psql = new PSQL({ user: 'postgres', @@ -862,30 +863,17 @@ TestClient.setUserDatabaseTimeoutLimit = function (user, userTimeoutLimit, callb }); step( - function setTimeoutToUserRole (err, params) { - const next = this; + function configureTimeouts () { + const timeoutSQLs = [ + `ALTER ROLE \"${publicUser}\" SET STATEMENT_TIMEOUT TO ${timeoutLimit}`, + `ALTER ROLE \"${role}\" SET STATEMENT_TIMEOUT TO ${timeoutLimit}`, + `ALTER DATABASE \"${dbname}\" SET STATEMENT_TIMEOUT TO ${timeoutLimit}` + ]; - const timeoutQuery = `ALTER ROLE \"${role}\" SET statement_timeout to ${userTimeoutLimit}`; - psql.query(timeoutQuery, function (err) { - if (err) { - return next(err); - } - next(null, params, psql); - }); + const group = this.group(); + + timeoutSQLs.forEach(sql => psql.query(sql, group())); }, - function setTimeoutToDatabase (err, params, psql) { - assert.ifError(err); - - const timeoutQuery = `ALTER DATABASE \"${dbname}\" SET statement_timeout to ${userTimeoutLimit}`; - - psql.query(timeoutQuery, this); - }, - function finish (err) { - if (err) { - return callback(err); - } - - callback(); - } + callback ); };