Merge pull request #385 from CartoDB/remove-state-dependant-test
Fix acceptance test
This commit is contained in:
commit
28dec57dd2
@ -631,7 +631,7 @@ it('SELECT INTO with paging ', function(done){
|
|||||||
}),
|
}),
|
||||||
headers: {host: 'vizzuality.cartodb.com'},
|
headers: {host: 'vizzuality.cartodb.com'},
|
||||||
method: 'GET'
|
method: 'GET'
|
||||||
},{}, function(err, res) { next(null, res); });
|
}, {}, function(err, res) { next(null, res); });
|
||||||
},
|
},
|
||||||
function check_drop(err, res) {
|
function check_drop(err, res) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
|
@ -124,7 +124,7 @@ describe('batch multiquery', function() {
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
var jobsQueue = queue(2);
|
var jobsQueue = queue(1);
|
||||||
|
|
||||||
jobs.forEach(function(job) {
|
jobs.forEach(function(job) {
|
||||||
jobsQueue.defer(function(payload, done) {
|
jobsQueue.defer(function(payload, done) {
|
||||||
@ -165,7 +165,7 @@ describe('batch multiquery', function() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
var expectedStatus = [JobStatus.FAILED, JobStatus.DONE];
|
var expectedStatus = [JobStatus.FAILED, JobStatus.DONE];
|
||||||
var jobsQueue = queue(2);
|
var jobsQueue = queue(1);
|
||||||
|
|
||||||
jobs.forEach(function(job) {
|
jobs.forEach(function(job) {
|
||||||
jobsQueue.defer(function(payload, done) {
|
jobsQueue.defer(function(payload, done) {
|
||||||
@ -207,7 +207,7 @@ describe('batch multiquery', function() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
var expectedStatus = [JobStatus.DONE, JobStatus.FAILED];
|
var expectedStatus = [JobStatus.DONE, JobStatus.FAILED];
|
||||||
var jobsQueue = queue(2);
|
var jobsQueue = queue(1);
|
||||||
|
|
||||||
jobs.forEach(function(job) {
|
jobs.forEach(function(job) {
|
||||||
jobsQueue.defer(function(payload, done) {
|
jobsQueue.defer(function(payload, done) {
|
||||||
|
@ -76,16 +76,9 @@ describe('batch happy cases', function() {
|
|||||||
'select * from private_table',
|
'select * from private_table',
|
||||||
'select * from private_table',
|
'select * from private_table',
|
||||||
'select * from private_table',
|
'select * from private_table',
|
||||||
'select * from private_table',
|
|
||||||
'select * from private_table',
|
|
||||||
'select * from private_table',
|
|
||||||
'select * from private_table',
|
|
||||||
'select * from private_table',
|
|
||||||
'select * from private_table',
|
|
||||||
'select * from private_table'
|
|
||||||
];
|
];
|
||||||
|
|
||||||
var jobsQueue = queue(4);
|
var jobsQueue = queue(1);
|
||||||
|
|
||||||
jobs.forEach(function(job) {
|
jobs.forEach(function(job) {
|
||||||
jobsQueue.defer(function(payload, done) {
|
jobsQueue.defer(function(payload, done) {
|
||||||
@ -115,19 +108,12 @@ describe('batch happy cases', function() {
|
|||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var jobs = [
|
var jobs = [
|
||||||
'select * from unexistent_table',
|
|
||||||
'select * from unexistent_table',
|
|
||||||
'select * from unexistent_table',
|
|
||||||
'select * from unexistent_table',
|
|
||||||
'select * from unexistent_table',
|
|
||||||
'select * from unexistent_table',
|
|
||||||
'select * from unexistent_table',
|
|
||||||
'select * from unexistent_table',
|
'select * from unexistent_table',
|
||||||
'select * from unexistent_table',
|
'select * from unexistent_table',
|
||||||
'select * from unexistent_table'
|
'select * from unexistent_table'
|
||||||
];
|
];
|
||||||
|
|
||||||
var jobsQueue = queue(4);
|
var jobsQueue = queue(1);
|
||||||
|
|
||||||
jobs.forEach(function(job) {
|
jobs.forEach(function(job) {
|
||||||
jobsQueue.defer(function(payload, done) {
|
jobsQueue.defer(function(payload, done) {
|
||||||
|
@ -2,6 +2,7 @@ require('../../helper');
|
|||||||
|
|
||||||
var assert = require('../../support/assert');
|
var assert = require('../../support/assert');
|
||||||
var BatchTestClient = require('../../support/batch-test-client');
|
var BatchTestClient = require('../../support/batch-test-client');
|
||||||
|
var JobStatus = require('../../../batch/job_status');
|
||||||
|
|
||||||
describe('batch work in progress endpoint happy cases', function() {
|
describe('batch work in progress endpoint happy cases', function() {
|
||||||
|
|
||||||
@ -22,7 +23,7 @@ describe('batch work in progress endpoint happy cases', function() {
|
|||||||
it('should get a list of work in progress jobs group by user', function (done) {
|
it('should get a list of work in progress jobs group by user', function (done) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var user = 'vizzuality';
|
var user = 'vizzuality';
|
||||||
var queries = ['select pg_sleep(0.5)'];
|
var queries = ['select pg_sleep(3)'];
|
||||||
var payload = jobPayload(queries);
|
var payload = jobPayload(queries);
|
||||||
|
|
||||||
self.batchTestClient.createJob(payload, function(err, jobResult) {
|
self.batchTestClient.createJob(payload, function(err, jobResult) {
|
||||||
@ -30,48 +31,67 @@ describe('batch work in progress endpoint happy cases', function() {
|
|||||||
return done(err);
|
return done(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(function () {
|
jobResult.getStatus(JobStatus.RUNNING, function (err) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
self.batchTestClient.getWorkInProgressJobs(function (err, workInProgressJobs) {
|
self.batchTestClient.getWorkInProgressJobs(function (err, workInProgressJobs) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return done(err);
|
return done(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!workInProgressJobs[user]) {
|
||||||
|
return done(new Error('User should be in work-in-progress list'));
|
||||||
|
}
|
||||||
|
|
||||||
assert.ok(Array.isArray(workInProgressJobs[user]));
|
assert.ok(Array.isArray(workInProgressJobs[user]));
|
||||||
assert.ok(workInProgressJobs[user].length >= 1);
|
assert.ok(workInProgressJobs[user].length >= 1);
|
||||||
for (var i = 0; i < workInProgressJobs[user].length; i++) {
|
for (var i = 0; i < workInProgressJobs[user].length; i++) {
|
||||||
if (workInProgressJobs[user][i] === jobResult.job.job_id) {
|
if (workInProgressJobs[user][i] === jobResult.job.job_id) {
|
||||||
return done();
|
return jobResult.cancel(done);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return done(new Error('Job should not be in work-in-progress list'));
|
||||||
});
|
});
|
||||||
}, 100);
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get a list of work in progress jobs w/o the finished ones', function (done) {
|
it('should get a list of work in progress jobs w/o the finished ones', function (done) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var user = 'vizzuality';
|
var user = 'vizzuality';
|
||||||
var queries = ['select pg_sleep(0.1)'];
|
var queries = ['select pg_sleep(0)'];
|
||||||
var payload = jobPayload(queries);
|
var payload = jobPayload(queries);
|
||||||
|
|
||||||
self.batchTestClient.createJob(payload, function(err, jobResult) {
|
self.batchTestClient.createJob(payload, function(err, jobResult) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return done(err);
|
return done(err);
|
||||||
}
|
}
|
||||||
setTimeout(function () {
|
|
||||||
|
jobResult.getStatus(function (err) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
self.batchTestClient.getWorkInProgressJobs(function (err, workInProgressJobs) {
|
self.batchTestClient.getWorkInProgressJobs(function (err, workInProgressJobs) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return done(err);
|
return done(err);
|
||||||
}
|
}
|
||||||
assert.ok(Array.isArray(workInProgressJobs[user]));
|
|
||||||
assert.ok(workInProgressJobs[user].length >= 1);
|
if (workInProgressJobs[user]) {
|
||||||
for (var i = 0; i < workInProgressJobs[user].length; i++) {
|
assert.ok(Array.isArray(workInProgressJobs[user]));
|
||||||
if (workInProgressJobs[user][i] === jobResult.job.job_id) {
|
assert.ok(workInProgressJobs[user].length >= 1);
|
||||||
return done(new Error('Job should not be in work-in-progress list'));
|
for (var i = 0; i < workInProgressJobs[user].length; i++) {
|
||||||
|
if (workInProgressJobs[user][i] === jobResult.job.job_id) {
|
||||||
|
return done(new Error('Job should not be in work-in-progress list'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return done();
|
done();
|
||||||
});
|
});
|
||||||
}, 200);
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,219 +1,124 @@
|
|||||||
require('../../helper');
|
require('../../helper');
|
||||||
|
|
||||||
var assert = require('../../support/assert');
|
var assert = require('../../support/assert');
|
||||||
var redisUtils = require('../../support/redis_utils');
|
var TestClient = require('../../support/test-client');
|
||||||
var server = require('../../../app/server')();
|
var JobStatus = require('../../../batch/job_status');
|
||||||
var querystring = require('qs');
|
var BatchTestClient = require('../../support/batch-test-client');
|
||||||
var metadataBackend = require('cartodb-redis')({ pool: redisUtils.getPool() });
|
|
||||||
var batchFactory = require('../../../batch/index');
|
|
||||||
var jobStatus = require('../../../batch/job_status');
|
|
||||||
|
|
||||||
describe('Batch API callback templates', function () {
|
describe('Batch API callback templates', function () {
|
||||||
|
before(function () {
|
||||||
function createJob(jobDefinition, callback) {
|
this.batchTestClient = new BatchTestClient();
|
||||||
assert.response(server, {
|
this.testClient = new TestClient();
|
||||||
url: '/api/v2/sql/job?api_key=1234',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
host: 'vizzuality.cartodb.com'
|
|
||||||
},
|
|
||||||
method: 'POST',
|
|
||||||
data: querystring.stringify(jobDefinition)
|
|
||||||
}, {
|
|
||||||
status: 201
|
|
||||||
}, function (err, res) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
return callback(null, JSON.parse(res.body));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getJobStatus(jobId, callback) {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + jobId + '?api_key=1234&',
|
|
||||||
headers: {
|
|
||||||
host: 'vizzuality.cartodb.com'
|
|
||||||
},
|
|
||||||
method: 'GET'
|
|
||||||
}, {
|
|
||||||
status: 200
|
|
||||||
}, function (err, res) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
return callback(null, JSON.parse(res.body));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getQueryResult(query, callback) {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql?' + querystring.stringify({q: query, api_key: 1234}),
|
|
||||||
headers: {
|
|
||||||
host: 'vizzuality.cartodb.com'
|
|
||||||
},
|
|
||||||
method: 'GET'
|
|
||||||
}, {
|
|
||||||
status: 200
|
|
||||||
}, function (err, res) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
return callback(null, JSON.parse(res.body));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function validateExpectedResponse(actual, expected) {
|
|
||||||
actual.query.forEach(function(actualQuery, index) {
|
|
||||||
var expectedQuery = expected.query[index];
|
|
||||||
assert.ok(expectedQuery);
|
|
||||||
Object.keys(expectedQuery).forEach(function(expectedKey) {
|
|
||||||
assert.equal(
|
|
||||||
actualQuery[expectedKey],
|
|
||||||
expectedQuery[expectedKey],
|
|
||||||
'Expected value for key "' + expectedKey + '" does not match: ' + actualQuery[expectedKey] + ' ==' +
|
|
||||||
expectedQuery[expectedKey] + ' at query index=' + index + '. Full response: ' +
|
|
||||||
JSON.stringify(actual, null, 4)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
var propsToCheckDate = ['started_at', 'ended_at'];
|
|
||||||
propsToCheckDate.forEach(function(propToCheckDate) {
|
|
||||||
if (actualQuery.hasOwnProperty(propToCheckDate)) {
|
|
||||||
assert.ok(new Date(actualQuery[propToCheckDate]));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
assert.equal(actual.onsuccess, expected.onsuccess);
|
|
||||||
assert.equal(actual.onerror, expected.onerror);
|
|
||||||
}
|
|
||||||
|
|
||||||
var batch = batchFactory(metadataBackend, redisUtils.getPool());
|
|
||||||
|
|
||||||
before(function (done) {
|
|
||||||
batch.start();
|
|
||||||
batch.on('ready', done);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
after(function (done) {
|
after(function (done) {
|
||||||
batch.stop();
|
this.batchTestClient.drain(done);
|
||||||
redisUtils.clean('batch:*', done);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe.skip('should use templates for error_message and job_id onerror callback', function () {
|
it('should use templates for error_message and job_id onerror callback' +
|
||||||
var jobResponse;
|
' and keep the original templated query but use the error message', function (done) {
|
||||||
before(function(done) {
|
var self = this;
|
||||||
getQueryResult('create table test_batch_errors (job_id text, error_message text)', function(err) {
|
var payload = {
|
||||||
|
"query": {
|
||||||
|
"query": [
|
||||||
|
{
|
||||||
|
"query": "SELECT * FROM invalid_table",
|
||||||
|
"onerror": "INSERT INTO test_batch_errors " +
|
||||||
|
"values ('<%= job_id %>', '<%= error_message %>')"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var expectedQuery = {
|
||||||
|
query: [
|
||||||
|
{
|
||||||
|
"query": "SELECT * FROM invalid_table",
|
||||||
|
"onerror": "INSERT INTO test_batch_errors values ('<%= job_id %>', '<%= error_message %>')",
|
||||||
|
status: 'failed',
|
||||||
|
fallback_status: 'done'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
self.testClient.getResult(
|
||||||
|
'create table test_batch_errors (job_id text, error_message text)', function (err) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.batchTestClient.createJob(payload, function(err, jobResult) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return done(err);
|
return done(err);
|
||||||
}
|
}
|
||||||
createJob({
|
|
||||||
"query": {
|
jobResult.getStatus(JobStatus.FAILED, function (err, job) {
|
||||||
"query": [
|
if (err) {
|
||||||
{
|
return done(err);
|
||||||
"query": "SELECT * FROM invalid_table",
|
|
||||||
"onerror": "INSERT INTO test_batch_errors " +
|
|
||||||
"values ('<%= job_id %>', '<%= error_message %>')"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}, function(err, job) {
|
jobResult.validateExpectedResponse(expectedQuery);
|
||||||
jobResponse = job;
|
self.testClient.getResult('select * from test_batch_errors', function(err, rows) {
|
||||||
return done(err);
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
assert.equal(rows[0].job_id, job.job_id);
|
||||||
|
assert.equal(rows[0].error_message, 'relation "invalid_table" does not exist');
|
||||||
|
self.testClient.getResult('drop table test_batch_errors', done);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should keep the original templated query but use the error message', function (done) {
|
|
||||||
var expectedQuery = {
|
|
||||||
query: [
|
|
||||||
{
|
|
||||||
"query": "SELECT * FROM invalid_table",
|
|
||||||
"onerror": "INSERT INTO test_batch_errors values ('<%= job_id %>', '<%= error_message %>')",
|
|
||||||
status: 'failed',
|
|
||||||
fallback_status: 'done'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
var interval = setInterval(function () {
|
|
||||||
getJobStatus(jobResponse.job_id, function(err, job) {
|
|
||||||
if (job.status === jobStatus.FAILED) {
|
|
||||||
clearInterval(interval);
|
|
||||||
validateExpectedResponse(job.query, expectedQuery);
|
|
||||||
getQueryResult('select * from test_batch_errors', function(err, result) {
|
|
||||||
if (err) {
|
|
||||||
return done(err);
|
|
||||||
}
|
|
||||||
assert.equal(result.rows[0].job_id, jobResponse.job_id);
|
|
||||||
assert.equal(result.rows[0].error_message, 'relation "invalid_table" does not exist');
|
|
||||||
getQueryResult('drop table test_batch_errors', done);
|
|
||||||
});
|
|
||||||
} else if (job.status === jobStatus.DONE || job.status === jobStatus.CANCELLED) {
|
|
||||||
clearInterval(interval);
|
|
||||||
done(new Error('Job ' + job.job_id + ' is ' + job.status + ', expected to be "failed"'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 50);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('should use template for job_id onsuccess callback', function () {
|
it('should use template for job_id onsuccess callback ' +
|
||||||
var jobResponse;
|
'and keep the original templated query but use the job_id', function (done) {
|
||||||
before(function(done) {
|
var self = this;
|
||||||
createJob({
|
var payload = {
|
||||||
"query": {
|
"query": {
|
||||||
"query": [
|
"query": [
|
||||||
{
|
|
||||||
query: "create table batch_jobs (job_id text)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"query": "SELECT 1",
|
|
||||||
"onsuccess": "INSERT INTO batch_jobs values ('<%= job_id %>')"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}, function(err, job) {
|
|
||||||
jobResponse = job;
|
|
||||||
return done(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should keep the original templated query but use the job_id', function (done) {
|
|
||||||
var expectedQuery = {
|
|
||||||
query: [
|
|
||||||
{
|
{
|
||||||
query: "create table batch_jobs (job_id text)",
|
query: "create table batch_jobs (job_id text)"
|
||||||
status: 'done'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
query: "SELECT 1",
|
"query": "SELECT 1",
|
||||||
onsuccess: "INSERT INTO batch_jobs values ('<%= job_id %>')",
|
"onsuccess": "INSERT INTO batch_jobs values ('<%= job_id %>')"
|
||||||
status: 'done',
|
|
||||||
fallback_status: 'done'
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
var expectedQuery = {
|
||||||
|
query: [
|
||||||
|
{
|
||||||
|
query: "create table batch_jobs (job_id text)",
|
||||||
|
status: 'done'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
query: "SELECT 1",
|
||||||
|
onsuccess: "INSERT INTO batch_jobs values ('<%= job_id %>')",
|
||||||
|
status: 'done',
|
||||||
|
fallback_status: 'done'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
var interval = setInterval(function () {
|
self.batchTestClient.createJob(payload, function(err, jobResult) {
|
||||||
getJobStatus(jobResponse.job_id, function(err, job) {
|
if (err) {
|
||||||
if (job.status === jobStatus.DONE) {
|
return done(err);
|
||||||
clearInterval(interval);
|
}
|
||||||
validateExpectedResponse(job.query, expectedQuery);
|
jobResult.getStatus(function (err, job) {
|
||||||
getQueryResult('select * from batch_jobs', function(err, result) {
|
if (err) {
|
||||||
if (err) {
|
return done(err);
|
||||||
return done(err);
|
}
|
||||||
}
|
|
||||||
assert.equal(result.rows[0].job_id, jobResponse.job_id);
|
jobResult.validateExpectedResponse(expectedQuery);
|
||||||
getQueryResult('drop table batch_jobs', done);
|
self.testClient.getResult('select * from batch_jobs', function(err, rows) {
|
||||||
});
|
if (err) {
|
||||||
} else if (job.status === jobStatus.FAILED || job.status === jobStatus.CANCELLED) {
|
return done(err);
|
||||||
clearInterval(interval);
|
|
||||||
done(new Error('Job ' + job.job_id + ' is ' + job.status + ', expected to be "done"'));
|
|
||||||
}
|
}
|
||||||
|
assert.equal(rows[0].job_id, job.job_id);
|
||||||
|
|
||||||
|
self.testClient.getResult('drop table batch_jobs', done);
|
||||||
});
|
});
|
||||||
}, 50);
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -157,7 +157,6 @@ describe('job module', function() {
|
|||||||
status: 400
|
status: 400
|
||||||
}, function(err, res) {
|
}, function(err, res) {
|
||||||
var error = JSON.parse(res.body);
|
var error = JSON.parse(res.body);
|
||||||
console.log(error);
|
|
||||||
assert.deepEqual(error , {
|
assert.deepEqual(error , {
|
||||||
error: ['Job with id irrelevantJob not found']
|
error: ['Job with id irrelevantJob not found']
|
||||||
});
|
});
|
||||||
|
@ -1,195 +1,113 @@
|
|||||||
require('../../helper');
|
require('../../helper');
|
||||||
|
|
||||||
var assert = require('../../support/assert');
|
var BatchTestClient = require('../../support/batch-test-client');
|
||||||
var redisUtils = require('../../support/redis_utils');
|
var JobStatus = require('../../../batch/job_status');
|
||||||
var server = require('../../../app/server')();
|
|
||||||
var querystring = require('qs');
|
|
||||||
var metadataBackend = require('cartodb-redis')({ pool: redisUtils.getPool() });
|
|
||||||
var batchFactory = require('../../../batch');
|
|
||||||
var jobStatus = require('../../../batch/job_status');
|
|
||||||
|
|
||||||
describe('Batch API query timing', function () {
|
describe('Batch API query timing', function () {
|
||||||
|
before(function() {
|
||||||
function createJob(jobDefinition, callback) {
|
this.batchTestClient = new BatchTestClient();
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job?api_key=1234',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
host: 'vizzuality.cartodb.com'
|
|
||||||
},
|
|
||||||
method: 'POST',
|
|
||||||
data: querystring.stringify(jobDefinition)
|
|
||||||
}, {
|
|
||||||
status: 201
|
|
||||||
}, function (err, res) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
return callback(null, JSON.parse(res.body));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getJobStatus(jobId, callback) {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + jobId + '?api_key=1234&',
|
|
||||||
headers: {
|
|
||||||
host: 'vizzuality.cartodb.com'
|
|
||||||
},
|
|
||||||
method: 'GET'
|
|
||||||
}, {
|
|
||||||
status: 200
|
|
||||||
}, function (err, res) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
return callback(null, JSON.parse(res.body));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function validateExpectedResponse(actual, expected) {
|
|
||||||
actual.query.forEach(function(actualQuery, index) {
|
|
||||||
var expectedQuery = expected.query[index];
|
|
||||||
assert.ok(expectedQuery);
|
|
||||||
Object.keys(expectedQuery).forEach(function(expectedKey) {
|
|
||||||
assert.equal(actualQuery[expectedKey], expectedQuery[expectedKey]);
|
|
||||||
});
|
|
||||||
var propsToCheckDate = ['started_at', 'ended_at'];
|
|
||||||
propsToCheckDate.forEach(function(propToCheckDate) {
|
|
||||||
if (actualQuery.hasOwnProperty(propToCheckDate)) {
|
|
||||||
assert.ok(new Date(actualQuery[propToCheckDate]));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
assert.equal(actual.onsuccess, expected.onsuccess);
|
|
||||||
assert.equal(actual.onerror, expected.onerror);
|
|
||||||
}
|
|
||||||
|
|
||||||
var batch = batchFactory(metadataBackend, redisUtils.getPool());
|
|
||||||
|
|
||||||
before(function (done) {
|
|
||||||
batch.start();
|
|
||||||
batch.on('ready', done);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
after(function (done) {
|
after(function(done) {
|
||||||
batch.stop();
|
this.batchTestClient.drain(done);
|
||||||
redisUtils.clean('batch:*', done);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('should report start and end time for each query with fallback queries', function () {
|
it('should report start and end time for each query with fallback queries' +
|
||||||
var jobResponse;
|
'and expose started_at and ended_at for all queries with fallback mechanism', function (done) {
|
||||||
before(function(done) {
|
var expectedQuery = {
|
||||||
createJob({
|
query: [{
|
||||||
"query": {
|
query: 'SELECT * FROM untitle_table_4 limit 1',
|
||||||
"query": [
|
onerror: 'SELECT * FROM untitle_table_4 limit 2',
|
||||||
{
|
status: 'done',
|
||||||
"query": "SELECT * FROM untitle_table_4 limit 1",
|
fallback_status: 'skipped'
|
||||||
"onerror": "SELECT * FROM untitle_table_4 limit 2"
|
}, {
|
||||||
},
|
query: 'SELECT * FROM untitle_table_4 limit 3',
|
||||||
{
|
onerror: 'SELECT * FROM untitle_table_4 limit 4',
|
||||||
"query": "SELECT * FROM untitle_table_4 limit 3",
|
status: 'done',
|
||||||
"onerror": "SELECT * FROM untitle_table_4 limit 4"
|
fallback_status: 'skipped'
|
||||||
}
|
}],
|
||||||
],
|
onerror: 'SELECT * FROM untitle_table_4 limit 5'
|
||||||
"onerror": "SELECT * FROM untitle_table_4 limit 5"
|
};
|
||||||
}
|
|
||||||
}, function(err, job) {
|
|
||||||
jobResponse = job;
|
|
||||||
return done(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should expose started_at and ended_at for all queries with fallback mechanism', function (done) {
|
var payload = {
|
||||||
var expectedQuery = {
|
"query": {
|
||||||
query: [{
|
"query": [
|
||||||
query: 'SELECT * FROM untitle_table_4 limit 1',
|
{
|
||||||
onerror: 'SELECT * FROM untitle_table_4 limit 2',
|
"query": "SELECT * FROM untitle_table_4 limit 1",
|
||||||
status: 'done',
|
"onerror": "SELECT * FROM untitle_table_4 limit 2"
|
||||||
fallback_status: 'skipped'
|
},
|
||||||
}, {
|
{
|
||||||
query: 'SELECT * FROM untitle_table_4 limit 3',
|
"query": "SELECT * FROM untitle_table_4 limit 3",
|
||||||
onerror: 'SELECT * FROM untitle_table_4 limit 4',
|
"onerror": "SELECT * FROM untitle_table_4 limit 4"
|
||||||
status: 'done',
|
|
||||||
fallback_status: 'skipped'
|
|
||||||
}],
|
|
||||||
onerror: 'SELECT * FROM untitle_table_4 limit 5'
|
|
||||||
};
|
|
||||||
|
|
||||||
var interval = setInterval(function () {
|
|
||||||
getJobStatus(jobResponse.job_id, function(err, job) {
|
|
||||||
if (job.status === jobStatus.DONE) {
|
|
||||||
clearInterval(interval);
|
|
||||||
validateExpectedResponse(job.query, expectedQuery);
|
|
||||||
job.query.query.forEach(function(actualQuery) {
|
|
||||||
assert.ok(actualQuery.started_at);
|
|
||||||
assert.ok(actualQuery.ended_at);
|
|
||||||
});
|
|
||||||
done();
|
|
||||||
} else if (job.status === jobStatus.FAILED || job.status === jobStatus.CANCELLED) {
|
|
||||||
clearInterval(interval);
|
|
||||||
done(new Error('Job ' + job.job_id + ' is ' + job.status + ', expected to be "done"'));
|
|
||||||
}
|
}
|
||||||
});
|
],
|
||||||
}, 50);
|
"onerror": "SELECT * FROM untitle_table_4 limit 5"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.batchTestClient.createJob(payload, function(err, jobResult) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
jobResult.getStatus(function (err) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
jobResult.validateExpectedResponse(expectedQuery);
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('should report start and end time for each query also for failing queries', function () {
|
|
||||||
var jobResponse;
|
|
||||||
before(function(done) {
|
|
||||||
createJob({
|
|
||||||
"query": {
|
|
||||||
"query": [
|
|
||||||
{
|
|
||||||
"query": "SELECT * FROM untitle_table_4 limit 1",
|
|
||||||
"onerror": "SELECT * FROM untitle_table_4 limit 2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"query": "SELECT * FROM untitle_table_4 limit 3 failed",
|
|
||||||
"onerror": "SELECT * FROM untitle_table_4 limit 4"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"onerror": "SELECT * FROM untitle_table_4 limit 5"
|
|
||||||
}
|
|
||||||
}, function(err, job) {
|
|
||||||
jobResponse = job;
|
|
||||||
return done(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should expose started_at and ended_at for all queries with fallback mechanism (failed)', function (done) {
|
it('should report start and end time for each query also for failing queries' +
|
||||||
var expectedQuery = {
|
'and expose started_at and ended_at for all queries with fallback mechanism (failed)', function (done) {
|
||||||
query: [{
|
var expectedQuery = {
|
||||||
query: 'SELECT * FROM untitle_table_4 limit 1',
|
query: [{
|
||||||
onerror: 'SELECT * FROM untitle_table_4 limit 2',
|
query: 'SELECT * FROM untitle_table_4 limit 1',
|
||||||
status: 'done',
|
onerror: 'SELECT * FROM untitle_table_4 limit 2',
|
||||||
fallback_status: 'skipped'
|
status: 'done',
|
||||||
}, {
|
fallback_status: 'skipped'
|
||||||
query: 'SELECT * FROM untitle_table_4 limit 3 failed',
|
}, {
|
||||||
onerror: 'SELECT * FROM untitle_table_4 limit 4',
|
query: 'SELECT * FROM untitle_table_4 limit 3 failed',
|
||||||
status: 'failed',
|
onerror: 'SELECT * FROM untitle_table_4 limit 4',
|
||||||
fallback_status: 'done'
|
status: 'failed',
|
||||||
}],
|
fallback_status: 'done'
|
||||||
onerror: 'SELECT * FROM untitle_table_4 limit 5'
|
}],
|
||||||
};
|
onerror: 'SELECT * FROM untitle_table_4 limit 5'
|
||||||
|
};
|
||||||
|
|
||||||
var interval = setInterval(function () {
|
var payload = {
|
||||||
getJobStatus(jobResponse.job_id, function(err, job) {
|
"query": {
|
||||||
if (job.status === jobStatus.FAILED) {
|
"query": [
|
||||||
clearInterval(interval);
|
{
|
||||||
validateExpectedResponse(job.query, expectedQuery);
|
"query": "SELECT * FROM untitle_table_4 limit 1",
|
||||||
job.query.query.forEach(function(actualQuery) {
|
"onerror": "SELECT * FROM untitle_table_4 limit 2"
|
||||||
assert.ok(actualQuery.started_at);
|
},
|
||||||
assert.ok(actualQuery.ended_at);
|
{
|
||||||
});
|
"query": "SELECT * FROM untitle_table_4 limit 3 failed",
|
||||||
done();
|
"onerror": "SELECT * FROM untitle_table_4 limit 4"
|
||||||
} else if (job.status === jobStatus.DONE || job.status === jobStatus.CANCELLED) {
|
|
||||||
clearInterval(interval);
|
|
||||||
done(new Error('Job ' + job.job_id + ' is ' + job.status + ', expected to be "failed"'));
|
|
||||||
}
|
}
|
||||||
});
|
],
|
||||||
}, 50);
|
"onerror": "SELECT * FROM untitle_table_4 limit 5"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.batchTestClient.createJob(payload, function(err, jobResult) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
jobResult.getStatus(JobStatus.FAILED, function (err) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
jobResult.validateExpectedResponse(expectedQuery);
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,91 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* Requires the database and tables setup in config/environments/test.js to exist
|
|
||||||
* Ensure the user is present in the pgbouncer auth file too
|
|
||||||
* TODO: Add OAuth tests.
|
|
||||||
*
|
|
||||||
* To run this test, ensure that cartodb_test_user_1_db metadata exists
|
|
||||||
* in Redis for the vizzuality.cartodb.com domain
|
|
||||||
*
|
|
||||||
* SELECT 5
|
|
||||||
* HSET rails:users:vizzuality id 1
|
|
||||||
* HSET rails:users:vizzuality database_name cartodb_test_user_1_db
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
require('../../helper');
|
|
||||||
|
|
||||||
var server = require('../../../app/server')();
|
|
||||||
var assert = require('../../support/assert');
|
|
||||||
var redisUtils = require('../../support/redis_utils');
|
|
||||||
var querystring = require('querystring');
|
|
||||||
var metadataBackend = require('cartodb-redis')({ pool: redisUtils.getPool() });
|
|
||||||
var batchFactory = require('../../../batch/index');
|
|
||||||
|
|
||||||
describe('Use case 1: cancel and modify a done job', function () {
|
|
||||||
var batch = batchFactory(metadataBackend, redisUtils.getPool());
|
|
||||||
|
|
||||||
before(function (done) {
|
|
||||||
batch.start();
|
|
||||||
batch.on('ready', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function (done) {
|
|
||||||
batch.stop();
|
|
||||||
redisUtils.clean('batch:*', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
var doneJob = {};
|
|
||||||
|
|
||||||
it('Step 1, should create a job', function (done) {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'POST',
|
|
||||||
data: querystring.stringify({
|
|
||||||
query: "SELECT * FROM untitle_table_4"
|
|
||||||
})
|
|
||||||
}, {
|
|
||||||
status: 201
|
|
||||||
}, function (err, res) {
|
|
||||||
doneJob = JSON.parse(res.body);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 2, job should be done', function (done) {
|
|
||||||
var interval = setInterval(function () {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + doneJob.job_id + '?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'GET'
|
|
||||||
}, {
|
|
||||||
status: 200
|
|
||||||
}, function (err, res) {
|
|
||||||
var job = JSON.parse(res.body);
|
|
||||||
if (job.status === "done") {
|
|
||||||
clearInterval(interval);
|
|
||||||
done();
|
|
||||||
} else if (job.status === "failed" || job.status === "cancelled") {
|
|
||||||
clearInterval(interval);
|
|
||||||
done(new Error('Job ' + job.job_id + ' is ' + job.status + ', expected to be done'));
|
|
||||||
} else {
|
|
||||||
console.log('Job ' + job.job_id + ' is ' + job.status + ', expecting to be done');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 50);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 3, cancel a done job should give an error', function (done){
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + doneJob.job_id + '?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'DELETE'
|
|
||||||
}, {
|
|
||||||
status: 400
|
|
||||||
}, function(err, res) {
|
|
||||||
var errors = JSON.parse(res.body);
|
|
||||||
assert.equal(errors.error[0], "Cannot set status from done to cancelled");
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,95 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* Requires the database and tables setup in config/environments/test.js to exist
|
|
||||||
* Ensure the user is present in the pgbouncer auth file too
|
|
||||||
* TODO: Add OAuth tests.
|
|
||||||
*
|
|
||||||
* To run this test, ensure that cartodb_test_user_1_db metadata exists
|
|
||||||
* in Redis for the vizzuality.cartodb.com domain
|
|
||||||
*
|
|
||||||
* SELECT 5
|
|
||||||
* HSET rails:users:vizzuality id 1
|
|
||||||
* HSET rails:users:vizzuality database_name cartodb_test_user_1_db
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
require('../../helper');
|
|
||||||
|
|
||||||
var server = require('../../../app/server')();
|
|
||||||
var assert = require('../../support/assert');
|
|
||||||
var redisUtils = require('../../support/redis_utils');
|
|
||||||
var querystring = require('querystring');
|
|
||||||
var metadataBackend = require('cartodb-redis')({ pool: redisUtils.getPool() });
|
|
||||||
var batchFactory = require('../../../batch/index');
|
|
||||||
|
|
||||||
describe('Use case 10: cancel and modify a done multiquery job', function () {
|
|
||||||
var batch = batchFactory(metadataBackend, redisUtils.getPool());
|
|
||||||
|
|
||||||
before(function (done) {
|
|
||||||
batch.start();
|
|
||||||
batch.on('ready', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function (done) {
|
|
||||||
batch.stop();
|
|
||||||
redisUtils.clean('batch:*', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
var doneJob = {};
|
|
||||||
|
|
||||||
it('Step 1, should create a multiquery job', function (done) {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'POST',
|
|
||||||
data: querystring.stringify({
|
|
||||||
query: [
|
|
||||||
"SELECT * FROM untitle_table_4",
|
|
||||||
"SELECT * FROM untitle_table_4",
|
|
||||||
"SELECT * FROM untitle_table_4"
|
|
||||||
]
|
|
||||||
})
|
|
||||||
}, {
|
|
||||||
status: 201
|
|
||||||
}, function (err, res) {
|
|
||||||
doneJob = JSON.parse(res.body);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 2, multiquery job should be done', function (done) {
|
|
||||||
var interval = setInterval(function () {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + doneJob.job_id + '?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'GET'
|
|
||||||
}, {
|
|
||||||
status: 200
|
|
||||||
}, function (err, res) {
|
|
||||||
var job = JSON.parse(res.body);
|
|
||||||
if (job.status === "done") {
|
|
||||||
clearInterval(interval);
|
|
||||||
done();
|
|
||||||
} else if (job.status === "failed" || job.status === "cancelled") {
|
|
||||||
clearInterval(interval);
|
|
||||||
done(new Error('Job ' + job.job_id + ' is ' + job.status + ', expected to be done'));
|
|
||||||
} else {
|
|
||||||
console.log('Job ' + job.job_id + ' is ' + job.status + ', expecting to be done');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 50);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 3, cancel a done multiquery job should give an error', function (done){
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + doneJob.job_id + '?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'DELETE'
|
|
||||||
}, {
|
|
||||||
status: 400
|
|
||||||
}, function(err, res) {
|
|
||||||
var errors = JSON.parse(res.body);
|
|
||||||
assert.equal(errors.error[0], "Cannot set status from done to cancelled");
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,121 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* Requires the database and tables setup in config/environments/test.js to exist
|
|
||||||
* Ensure the user is present in the pgbouncer auth file too
|
|
||||||
* TODO: Add OAuth tests.
|
|
||||||
*
|
|
||||||
* To run this test, ensure that cartodb_test_user_1_db metadata exists
|
|
||||||
* in Redis for the vizzuality.cartodb.com domain
|
|
||||||
*
|
|
||||||
* SELECT 5
|
|
||||||
* HSET rails:users:vizzuality id 1
|
|
||||||
* HSET rails:users:vizzuality database_name cartodb_test_user_1_db
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
require('../../helper');
|
|
||||||
|
|
||||||
var server = require('../../../app/server')();
|
|
||||||
var assert = require('../../support/assert');
|
|
||||||
var redisUtils = require('../../support/redis_utils');
|
|
||||||
var querystring = require('querystring');
|
|
||||||
var metadataBackend = require('cartodb-redis')({ pool: redisUtils.getPool() });
|
|
||||||
var batchFactory = require('../../../batch/index');
|
|
||||||
|
|
||||||
describe('Use case 2: cancel a running job', function() {
|
|
||||||
var batch = batchFactory(metadataBackend, redisUtils.getPool());
|
|
||||||
|
|
||||||
before(function (done) {
|
|
||||||
batch.start();
|
|
||||||
batch.on('ready', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function (done) {
|
|
||||||
batch.stop();
|
|
||||||
redisUtils.clean('batch:*', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
var runningJob = {};
|
|
||||||
var cancelledJob = {};
|
|
||||||
|
|
||||||
it('Step 1, should create a new job', function (done){
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'POST',
|
|
||||||
data: querystring.stringify({
|
|
||||||
query: "SELECT * FROM untitle_table_4; select pg_sleep(3)"
|
|
||||||
})
|
|
||||||
}, {
|
|
||||||
status: 201
|
|
||||||
}, function(err, res) {
|
|
||||||
runningJob = JSON.parse(res.body);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 2, job should be running', function (done){
|
|
||||||
var interval = setInterval(function () {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + runningJob.job_id + '?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'GET'
|
|
||||||
}, {
|
|
||||||
status: 200
|
|
||||||
}, function(err, res) {
|
|
||||||
var job = JSON.parse(res.body);
|
|
||||||
if (job.status === "running") {
|
|
||||||
clearInterval(interval);
|
|
||||||
done();
|
|
||||||
} else if (job.status === "done" || job.status === "failed" || job.status === "cancelled") {
|
|
||||||
clearInterval(interval);
|
|
||||||
done(new Error('Job ' + job.job_id + ' is ' + job.status + ', expected to be running'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 50);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 3, cancel a job', function (done){
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + runningJob.job_id + '?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'DELETE'
|
|
||||||
}, {
|
|
||||||
status: 200
|
|
||||||
}, function(err, res) {
|
|
||||||
cancelledJob = JSON.parse(res.body);
|
|
||||||
assert.equal(cancelledJob.status, "cancelled");
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 4, job should be cancelled', function (done){
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + runningJob.job_id + '?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'GET'
|
|
||||||
}, {
|
|
||||||
status: 200
|
|
||||||
}, function(err, res) {
|
|
||||||
var job = JSON.parse(res.body);
|
|
||||||
if (job.status === "cancelled") {
|
|
||||||
done();
|
|
||||||
} else {
|
|
||||||
done(new Error('Job status is not cancelled, ' + job.status));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 5, cancel a cancelled should give an error', function (done) {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + cancelledJob.job_id + '?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'DELETE'
|
|
||||||
}, {
|
|
||||||
status: 400
|
|
||||||
}, function(err, res) {
|
|
||||||
var errors = JSON.parse(res.body);
|
|
||||||
assert.equal(errors.error[0], "Cannot set status from cancelled to cancelled");
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,121 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* Requires the database and tables setup in config/environments/test.js to exist
|
|
||||||
* Ensure the user is present in the pgbouncer auth file too
|
|
||||||
* TODO: Add OAuth tests.
|
|
||||||
*
|
|
||||||
* To run this test, ensure that cartodb_test_user_1_db metadata exists
|
|
||||||
* in Redis for the vizzuality.cartodb.com domain
|
|
||||||
*
|
|
||||||
* SELECT 5
|
|
||||||
* HSET rails:users:vizzuality id 1
|
|
||||||
* HSET rails:users:vizzuality database_name cartodb_test_user_1_db
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
require('../../helper');
|
|
||||||
|
|
||||||
var server = require('../../../app/server')();
|
|
||||||
var assert = require('../../support/assert');
|
|
||||||
var redisUtils = require('../../support/redis_utils');
|
|
||||||
var querystring = require('querystring');
|
|
||||||
var metadataBackend = require('cartodb-redis')({ pool: redisUtils.getPool() });
|
|
||||||
var batchFactory = require('../../../batch/index');
|
|
||||||
|
|
||||||
describe('Use case 3: cancel a pending job', function() {
|
|
||||||
var batch = batchFactory(metadataBackend, redisUtils.getPool());
|
|
||||||
|
|
||||||
before(function (done) {
|
|
||||||
batch.start();
|
|
||||||
batch.on('ready', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function (done) {
|
|
||||||
batch.stop();
|
|
||||||
redisUtils.clean('batch:*', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
var runningJob = {};
|
|
||||||
var pendingJob = {};
|
|
||||||
|
|
||||||
it('Step 1, should create a job', function (done) {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'POST',
|
|
||||||
data: querystring.stringify({
|
|
||||||
query: "SELECT * FROM untitle_table_4; select pg_sleep(3)"
|
|
||||||
})
|
|
||||||
}, {
|
|
||||||
status: 201
|
|
||||||
}, function (err, res) {
|
|
||||||
runningJob = JSON.parse(res.body);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 2, should create a another job', function (done) {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'POST',
|
|
||||||
data: querystring.stringify({
|
|
||||||
query: "SELECT * FROM untitle_table_4"
|
|
||||||
})
|
|
||||||
}, {
|
|
||||||
status: 201
|
|
||||||
}, function(err, res) {
|
|
||||||
pendingJob = JSON.parse(res.body);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 3, job should be pending', function (done){
|
|
||||||
var interval = setInterval(function () {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + pendingJob.job_id + '?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'GET'
|
|
||||||
}, {
|
|
||||||
status: 200
|
|
||||||
}, function(err, res) {
|
|
||||||
var job = JSON.parse(res.body);
|
|
||||||
if (job.status === "pending") {
|
|
||||||
clearInterval(interval);
|
|
||||||
done();
|
|
||||||
} else {
|
|
||||||
clearInterval(interval);
|
|
||||||
done(new Error('Job ' + job.job_id + ' is ' + job.status + ', expected to be pending'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 50);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 4, cancel a pending job should be cancelled', function (done){
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + pendingJob.job_id + '?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'DELETE'
|
|
||||||
}, {
|
|
||||||
status: 200
|
|
||||||
}, function(err, res) {
|
|
||||||
var jobGot = JSON.parse(res.body);
|
|
||||||
assert.equal(jobGot.job_id, pendingJob.job_id);
|
|
||||||
assert.equal(jobGot.status, "cancelled");
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 5, running job should be cancelled', function (done){
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + runningJob.job_id + '?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'DELETE'
|
|
||||||
}, {
|
|
||||||
status: 200
|
|
||||||
}, function(err, res) {
|
|
||||||
var cancelledJob = JSON.parse(res.body);
|
|
||||||
assert.equal(cancelledJob.status, "cancelled");
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,106 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* Requires the database and tables setup in config/environments/test.js to exist
|
|
||||||
* Ensure the user is present in the pgbouncer auth file too
|
|
||||||
* TODO: Add OAuth tests.
|
|
||||||
*
|
|
||||||
* To run this test, ensure that cartodb_test_user_1_db metadata exists
|
|
||||||
* in Redis for the vizzuality.cartodb.com domain
|
|
||||||
*
|
|
||||||
* SELECT 5
|
|
||||||
* HSET rails:users:vizzuality id 1
|
|
||||||
* HSET rails:users:vizzuality database_name cartodb_test_user_1_db
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
require('../../helper');
|
|
||||||
|
|
||||||
var server = require('../../../app/server')();
|
|
||||||
var assert = require('../../support/assert');
|
|
||||||
var redisUtils = require('../../support/redis_utils');
|
|
||||||
var querystring = require('querystring');
|
|
||||||
var metadataBackend = require('cartodb-redis')({ pool: redisUtils.getPool() });
|
|
||||||
var batchFactory = require('../../../batch');
|
|
||||||
|
|
||||||
describe('Use case 4: modify a pending job', function() {
|
|
||||||
var batch = batchFactory(metadataBackend, redisUtils.getPool());
|
|
||||||
|
|
||||||
before(function (done) {
|
|
||||||
batch.start();
|
|
||||||
batch.on('ready', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function (done) {
|
|
||||||
batch.stop();
|
|
||||||
redisUtils.clean('batch:*', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
var runningJob = {};
|
|
||||||
var pendingJob = {};
|
|
||||||
|
|
||||||
it('Step 1, should create a job', function (done) {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'POST',
|
|
||||||
data: querystring.stringify({
|
|
||||||
query: "SELECT * FROM untitle_table_4; select pg_sleep(3)"
|
|
||||||
})
|
|
||||||
}, {
|
|
||||||
status: 201
|
|
||||||
}, function(err, res) {
|
|
||||||
runningJob = JSON.parse(res.body);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 2, should create another job', function (done) {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'POST',
|
|
||||||
data: querystring.stringify({
|
|
||||||
query: "SELECT * FROM untitle_table_4"
|
|
||||||
})
|
|
||||||
}, {
|
|
||||||
status: 201
|
|
||||||
}, function(err, res) {
|
|
||||||
pendingJob = JSON.parse(res.body);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 3, job should be pending', function (done){
|
|
||||||
var interval = setInterval(function () {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + pendingJob.job_id + '?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'GET'
|
|
||||||
}, {
|
|
||||||
status: 200
|
|
||||||
}, function(err, res) {
|
|
||||||
var job = JSON.parse(res.body);
|
|
||||||
if (job.status === "pending") {
|
|
||||||
clearInterval(interval);
|
|
||||||
done();
|
|
||||||
} else {
|
|
||||||
clearInterval(interval);
|
|
||||||
done(new Error('Job ' + job.job_id + ' is ' + job.status + ', expected to be pending'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 50);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 5, running job should be cancelled', function (done){
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + runningJob.job_id + '?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'DELETE'
|
|
||||||
}, {
|
|
||||||
status: 200
|
|
||||||
}, function(err, res) {
|
|
||||||
var cancelledJob = JSON.parse(res.body);
|
|
||||||
assert.equal(cancelledJob.status, "cancelled");
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,89 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* Requires the database and tables setup in config/environments/test.js to exist
|
|
||||||
* Ensure the user is present in the pgbouncer auth file too
|
|
||||||
* TODO: Add OAuth tests.
|
|
||||||
*
|
|
||||||
* To run this test, ensure that cartodb_test_user_1_db metadata exists
|
|
||||||
* in Redis for the vizzuality.cartodb.com domain
|
|
||||||
*
|
|
||||||
* SELECT 5
|
|
||||||
* HSET rails:users:vizzuality id 1
|
|
||||||
* HSET rails:users:vizzuality database_name cartodb_test_user_1_db
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
require('../../helper');
|
|
||||||
|
|
||||||
var server = require('../../../app/server')();
|
|
||||||
var assert = require('../../support/assert');
|
|
||||||
var redisUtils = require('../../support/redis_utils');
|
|
||||||
var querystring = require('querystring');
|
|
||||||
var metadataBackend = require('cartodb-redis')({ pool: redisUtils.getPool() });
|
|
||||||
var batchFactory = require('../../../batch');
|
|
||||||
|
|
||||||
describe('Use case 5: modify a running job', function() {
|
|
||||||
var batch = batchFactory(metadataBackend, redisUtils.getPool());
|
|
||||||
|
|
||||||
before(function (done) {
|
|
||||||
batch.start();
|
|
||||||
batch.on('ready', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function (done) {
|
|
||||||
batch.stop();
|
|
||||||
redisUtils.clean('batch:*', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
var runningJob = {};
|
|
||||||
|
|
||||||
it('Step 1, should create job', function (done) {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'POST',
|
|
||||||
data: querystring.stringify({
|
|
||||||
query: "SELECT * FROM untitle_table_4; select pg_sleep(3)"
|
|
||||||
})
|
|
||||||
}, {
|
|
||||||
status: 201
|
|
||||||
}, function (err, res) {
|
|
||||||
runningJob = JSON.parse(res.body);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 2, job should be running', function (done){
|
|
||||||
var interval = setInterval(function () {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + runningJob.job_id + '?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'GET'
|
|
||||||
}, {
|
|
||||||
status: 200
|
|
||||||
}, function(err, res) {
|
|
||||||
var job = JSON.parse(res.body);
|
|
||||||
if (job.status === "running") {
|
|
||||||
clearInterval(interval);
|
|
||||||
done();
|
|
||||||
} else if (job.status === "done" || job.status === "failed" || job.status === "cancelled") {
|
|
||||||
clearInterval(interval);
|
|
||||||
done(new Error('Job ' + job.job_id + ' is ' + job.status + ', expected to be running'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 50);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 4, running job should be cancelled', function (done){
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + runningJob.job_id + '?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'DELETE'
|
|
||||||
}, {
|
|
||||||
status: 200
|
|
||||||
}, function(err, res) {
|
|
||||||
var cancelledJob = JSON.parse(res.body);
|
|
||||||
assert.equal(cancelledJob.status, "cancelled");
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,75 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* Requires the database and tables setup in config/environments/test.js to exist
|
|
||||||
* Ensure the user is present in the pgbouncer auth file too
|
|
||||||
* TODO: Add OAuth tests.
|
|
||||||
*
|
|
||||||
* To run this test, ensure that cartodb_test_user_1_db metadata exists
|
|
||||||
* in Redis for the vizzuality.cartodb.com domain
|
|
||||||
*
|
|
||||||
* SELECT 5
|
|
||||||
* HSET rails:users:vizzuality id 1
|
|
||||||
* HSET rails:users:vizzuality database_name cartodb_test_user_1_db
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
require('../../helper');
|
|
||||||
|
|
||||||
var server = require('../../../app/server')();
|
|
||||||
var assert = require('../../support/assert');
|
|
||||||
var redisUtils = require('../../support/redis_utils');
|
|
||||||
var querystring = require('querystring');
|
|
||||||
var metadataBackend = require('cartodb-redis')({ pool: redisUtils.getPool() });
|
|
||||||
var batchFactory = require('../../../batch');
|
|
||||||
|
|
||||||
describe('Use case 6: modify a done job', function() {
|
|
||||||
var batch = batchFactory(metadataBackend, redisUtils.getPool());
|
|
||||||
|
|
||||||
before(function (done) {
|
|
||||||
batch.start();
|
|
||||||
batch.on('ready', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function (done) {
|
|
||||||
batch.stop();
|
|
||||||
redisUtils.clean('batch:*', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
var doneJob = {};
|
|
||||||
|
|
||||||
it('Step 1, should create job', function (done) {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'POST',
|
|
||||||
data: querystring.stringify({
|
|
||||||
query: "SELECT * FROM untitle_table_4"
|
|
||||||
})
|
|
||||||
}, {
|
|
||||||
status: 201
|
|
||||||
}, function (err, res) {
|
|
||||||
doneJob = JSON.parse(res.body);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 2, job should be done', function (done) {
|
|
||||||
var interval = setInterval(function () {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + doneJob.job_id + '?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'GET'
|
|
||||||
}, {
|
|
||||||
status: 200
|
|
||||||
}, function(err, res) {
|
|
||||||
var job = JSON.parse(res.body);
|
|
||||||
if (job.status === "done") {
|
|
||||||
clearInterval(interval);
|
|
||||||
done();
|
|
||||||
} else if (job.status === "failed" || job.status === "cancelled") {
|
|
||||||
clearInterval(interval);
|
|
||||||
done(new Error('Job ' + job.job_id + ' is ' + job.status + ', expected to be done'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 50);
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,89 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* Requires the database and tables setup in config/environments/test.js to exist
|
|
||||||
* Ensure the user is present in the pgbouncer auth file too
|
|
||||||
* TODO: Add OAuth tests.
|
|
||||||
*
|
|
||||||
* To run this test, ensure that cartodb_test_user_1_db metadata exists
|
|
||||||
* in Redis for the vizzuality.cartodb.com domain
|
|
||||||
*
|
|
||||||
* SELECT 5
|
|
||||||
* HSET rails:users:vizzuality id 1
|
|
||||||
* HSET rails:users:vizzuality database_name cartodb_test_user_1_db
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
require('../../helper');
|
|
||||||
|
|
||||||
var server = require('../../../app/server')();
|
|
||||||
var assert = require('../../support/assert');
|
|
||||||
var redisUtils = require('../../support/redis_utils');
|
|
||||||
var querystring = require('querystring');
|
|
||||||
var metadataBackend = require('cartodb-redis')({ pool: redisUtils.getPool() });
|
|
||||||
var batchFactory = require('../../../batch');
|
|
||||||
|
|
||||||
describe('Use case 7: cancel a job with quotes', function() {
|
|
||||||
var batch = batchFactory(metadataBackend, redisUtils.getPool());
|
|
||||||
|
|
||||||
before(function (done) {
|
|
||||||
batch.start();
|
|
||||||
batch.on('ready', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function (done) {
|
|
||||||
batch.stop();
|
|
||||||
redisUtils.clean('batch:*', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
var runningJob = {};
|
|
||||||
|
|
||||||
it('Step 1, should create job with quotes', function (done) {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'POST',
|
|
||||||
data: querystring.stringify({
|
|
||||||
query: "SELECT name FROM untitle_table_4 WHERE name = 'Hawai'; select pg_sleep(3)"
|
|
||||||
})
|
|
||||||
}, {
|
|
||||||
status: 201
|
|
||||||
}, function (err, res) {
|
|
||||||
runningJob = JSON.parse(res.body);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 2, job should be running', function (done){
|
|
||||||
var interval = setInterval(function () {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + runningJob.job_id + '?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'GET'
|
|
||||||
}, {
|
|
||||||
status: 200
|
|
||||||
}, function(err, res) {
|
|
||||||
var job = JSON.parse(res.body);
|
|
||||||
if (job.status === "running") {
|
|
||||||
clearInterval(interval);
|
|
||||||
done();
|
|
||||||
} else if (job.status === "done" || job.status === "failed" || job.status === "cancelled") {
|
|
||||||
clearInterval(interval);
|
|
||||||
done(new Error('Job ' + job.job_id + ' is ' + job.status + ', expected to be running'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 50);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 3, running job should be cancelled', function (done){
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + runningJob.job_id + '?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'DELETE'
|
|
||||||
}, {
|
|
||||||
status: 200
|
|
||||||
}, function(err, res) {
|
|
||||||
var cancelledJob = JSON.parse(res.body);
|
|
||||||
assert.equal(cancelledJob.status, "cancelled");
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,125 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* Requires the database and tables setup in config/environments/test.js to exist
|
|
||||||
* Ensure the user is present in the pgbouncer auth file too
|
|
||||||
* TODO: Add OAuth tests.
|
|
||||||
*
|
|
||||||
* To run this test, ensure that cartodb_test_user_1_db metadata exists
|
|
||||||
* in Redis for the vizzuality.cartodb.com domain
|
|
||||||
*
|
|
||||||
* SELECT 5
|
|
||||||
* HSET rails:users:vizzuality id 1
|
|
||||||
* HSET rails:users:vizzuality database_name cartodb_test_user_1_db
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
require('../../helper');
|
|
||||||
|
|
||||||
var server = require('../../../app/server')();
|
|
||||||
var assert = require('../../support/assert');
|
|
||||||
var redisUtils = require('../../support/redis_utils');
|
|
||||||
var querystring = require('querystring');
|
|
||||||
var metadataBackend = require('cartodb-redis')({ pool: redisUtils.getPool() });
|
|
||||||
var batchFactory = require('../../../batch');
|
|
||||||
|
|
||||||
describe('Use case 8: cancel a running multiquery job', function() {
|
|
||||||
var batch = batchFactory(metadataBackend, redisUtils.getPool());
|
|
||||||
|
|
||||||
before(function (done) {
|
|
||||||
batch.start();
|
|
||||||
batch.on('ready', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function (done) {
|
|
||||||
batch.stop();
|
|
||||||
redisUtils.clean('batch:*', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
var runningJob = {};
|
|
||||||
var cancelledJob = {};
|
|
||||||
|
|
||||||
it('Step 1, should create a new multiquery job', function (done) {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'POST',
|
|
||||||
data: querystring.stringify({
|
|
||||||
query: [
|
|
||||||
"select pg_sleep(1)",
|
|
||||||
"select pg_sleep(1)",
|
|
||||||
"select pg_sleep(1)"
|
|
||||||
]
|
|
||||||
})
|
|
||||||
}, {
|
|
||||||
status: 201
|
|
||||||
}, function(err, res) {
|
|
||||||
runningJob = JSON.parse(res.body);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 2, multiquery job should be running', function (done){
|
|
||||||
var interval = setInterval(function () {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + runningJob.job_id + '?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'GET'
|
|
||||||
}, {
|
|
||||||
status: 200
|
|
||||||
}, function(err, res) {
|
|
||||||
var job = JSON.parse(res.body);
|
|
||||||
if (job.status === "running") {
|
|
||||||
clearInterval(interval);
|
|
||||||
done();
|
|
||||||
} else if (job.status === "done" || job.status === "failed" || job.status === "cancelled") {
|
|
||||||
clearInterval(interval);
|
|
||||||
done(new Error('Job ' + job.job_id + ' is ' + job.status + ', expected to be running'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 50);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 3, cancel a multiquery job', function (done){
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + runningJob.job_id + '?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'DELETE'
|
|
||||||
}, {
|
|
||||||
status: 200
|
|
||||||
}, function(err, res) {
|
|
||||||
cancelledJob = JSON.parse(res.body);
|
|
||||||
assert.equal(cancelledJob.status, "cancelled");
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 4, multiquery job should be cancelled', function (done){
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + runningJob.job_id + '?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'GET'
|
|
||||||
}, {
|
|
||||||
status: 200
|
|
||||||
}, function(err, res) {
|
|
||||||
var job = JSON.parse(res.body);
|
|
||||||
if (job.status === "cancelled") {
|
|
||||||
done();
|
|
||||||
} else {
|
|
||||||
done(new Error('Job status is not cancelled, ' + job.status));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 5, cancel a cancelled multiquery job should give an error', function (done) {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + cancelledJob.job_id + '?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'DELETE'
|
|
||||||
}, {
|
|
||||||
status: 400
|
|
||||||
}, function(err, res) {
|
|
||||||
var errors = JSON.parse(res.body);
|
|
||||||
assert.equal(errors.error[0], "Cannot set status from cancelled to cancelled");
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,112 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* Requires the database and tables setup in config/environments/test.js to exist
|
|
||||||
* Ensure the user is present in the pgbouncer auth file too
|
|
||||||
* TODO: Add OAuth tests.
|
|
||||||
*
|
|
||||||
* To run this test, ensure that cartodb_test_user_1_db metadata exists
|
|
||||||
* in Redis for the vizzuality.cartodb.com domain
|
|
||||||
*
|
|
||||||
* SELECT 5
|
|
||||||
* HSET rails:users:vizzuality id 1
|
|
||||||
* HSET rails:users:vizzuality database_name cartodb_test_user_1_db
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
require('../../helper');
|
|
||||||
|
|
||||||
var server = require('../../../app/server')();
|
|
||||||
var assert = require('../../support/assert');
|
|
||||||
var redisUtils = require('../../support/redis_utils');
|
|
||||||
var querystring = require('querystring');
|
|
||||||
var metadataBackend = require('cartodb-redis')({ pool: redisUtils.getPool() });
|
|
||||||
var batchFactory = require('../../../batch');
|
|
||||||
|
|
||||||
describe('Use case 9: modify a pending multiquery job', function() {
|
|
||||||
var batch = batchFactory(metadataBackend, redisUtils.getPool());
|
|
||||||
|
|
||||||
before(function (done) {
|
|
||||||
batch.start();
|
|
||||||
batch.on('ready', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function (done) {
|
|
||||||
batch.stop();
|
|
||||||
redisUtils.clean('batch:*', done);
|
|
||||||
});
|
|
||||||
|
|
||||||
var runningJob = {};
|
|
||||||
var pendingJob = {};
|
|
||||||
|
|
||||||
it('Step 1, should create a multiquery job', function (done) {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'POST',
|
|
||||||
data: querystring.stringify({
|
|
||||||
query: [
|
|
||||||
"select pg_sleep(3)",
|
|
||||||
"SELECT * FROM untitle_table_4"
|
|
||||||
]
|
|
||||||
})
|
|
||||||
}, {
|
|
||||||
status: 201
|
|
||||||
}, function(err, res) {
|
|
||||||
runningJob = JSON.parse(res.body);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 2, should create another multiquery job', function (done) {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'POST',
|
|
||||||
data: querystring.stringify({
|
|
||||||
query: [
|
|
||||||
"SELECT pg_sleep(1)",
|
|
||||||
"SELECT * FROM untitle_table_4"
|
|
||||||
]
|
|
||||||
})
|
|
||||||
}, {
|
|
||||||
status: 201
|
|
||||||
}, function(err, res) {
|
|
||||||
pendingJob = JSON.parse(res.body);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 3, multiquery job should be pending', function (done){
|
|
||||||
var interval = setInterval(function () {
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + pendingJob.job_id + '?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'GET'
|
|
||||||
}, {
|
|
||||||
status: 200
|
|
||||||
}, function(err, res) {
|
|
||||||
var job = JSON.parse(res.body);
|
|
||||||
if (job.status === "pending") {
|
|
||||||
clearInterval(interval);
|
|
||||||
done();
|
|
||||||
} else {
|
|
||||||
clearInterval(interval);
|
|
||||||
done(new Error('Job ' + job.job_id + ' is ' + job.status + ', expected to be pending'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 50);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Step 5, running multiquery job should be cancelled', function (done){
|
|
||||||
assert.response(server, {
|
|
||||||
url: '/api/v2/sql/job/' + runningJob.job_id + '?api_key=1234',
|
|
||||||
headers: { 'host': 'vizzuality.cartodb.com', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
method: 'DELETE'
|
|
||||||
}, {
|
|
||||||
status: 200
|
|
||||||
}, function(err, res) {
|
|
||||||
var cancelledJob = JSON.parse(res.body);
|
|
||||||
assert.equal(cancelledJob.status, "cancelled");
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -2,8 +2,6 @@ require('../../helper');
|
|||||||
|
|
||||||
var assert = require('../../support/assert');
|
var assert = require('../../support/assert');
|
||||||
var redisUtils = require('../../support/redis_utils');
|
var redisUtils = require('../../support/redis_utils');
|
||||||
var batchFactory = require('../../../batch/index');
|
|
||||||
var metadataBackend = require('cartodb-redis')({ pool: redisUtils.getPool() });
|
|
||||||
var TestClient = require('../../support/test-client');
|
var TestClient = require('../../support/test-client');
|
||||||
|
|
||||||
describe('max queued jobs', function() {
|
describe('max queued jobs', function() {
|
||||||
@ -20,23 +18,8 @@ describe('max queued jobs', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
after(function (done) {
|
after(function (done) {
|
||||||
var self = this;
|
|
||||||
global.settings.batch_max_queued_jobs = this.batch_max_queued_jobs;
|
global.settings.batch_max_queued_jobs = this.batch_max_queued_jobs;
|
||||||
var batch = batchFactory(metadataBackend, redisUtils.getPool());
|
redisUtils.clean('batch:*', done);
|
||||||
batch.start();
|
|
||||||
batch.on('ready', function() {
|
|
||||||
// this is not ideal as the first job might not be committed yet
|
|
||||||
setTimeout(function() {
|
|
||||||
batch.stop(function() {
|
|
||||||
self.testClient.getResult('select count(*) from max_queued_jobs_inserts', function(err, rows) {
|
|
||||||
assert.ok(!err);
|
|
||||||
assert.equal(rows[0].count, 1);
|
|
||||||
|
|
||||||
redisUtils.clean('batch:*', done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}, 100);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function createJob(server, status, callback) {
|
function createJob(server, status, callback) {
|
||||||
|
188
test/acceptance/batch/use-cases.test.js
Normal file
188
test/acceptance/batch/use-cases.test.js
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
require('../../helper');
|
||||||
|
|
||||||
|
var assert = require('../../support/assert');
|
||||||
|
var JobStatus = require('../../../batch/job_status');
|
||||||
|
var BatchTestClient = require('../../support/batch-test-client');
|
||||||
|
|
||||||
|
describe('Use cases', function () {
|
||||||
|
before(function() {
|
||||||
|
this.batchTestClient = new BatchTestClient();
|
||||||
|
});
|
||||||
|
|
||||||
|
after(function(done) {
|
||||||
|
this.batchTestClient.drain(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('cancel a done job should return an error', function (done) {
|
||||||
|
var payload = {
|
||||||
|
query: "SELECT * FROM untitle_table_4"
|
||||||
|
};
|
||||||
|
|
||||||
|
this.batchTestClient.createJob(payload, function(err, jobResult) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
jobResult.getStatus(JobStatus.DONE, function (err, job) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.equal(job.status, JobStatus.DONE);
|
||||||
|
|
||||||
|
jobResult.tryCancel(function (err, body) {
|
||||||
|
assert.equal(body.error[0], "Cannot set status from done to cancelled");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('cancel a running job', function (done) {
|
||||||
|
var payload = {
|
||||||
|
query: "SELECT * FROM untitle_table_4; select pg_sleep(3)"
|
||||||
|
};
|
||||||
|
|
||||||
|
this.batchTestClient.createJob(payload, function(err, jobResult) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
jobResult.getStatus(JobStatus.RUNNING, function (err, job) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.equal(job.status, JobStatus.RUNNING);
|
||||||
|
|
||||||
|
jobResult.cancel(function (err, job) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.equal(job.status, JobStatus.CANCELLED);
|
||||||
|
|
||||||
|
jobResult.tryCancel(function (err, body) {
|
||||||
|
assert.equal(body.error[0], "Cannot set status from cancelled to cancelled");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('cancel a pending job', function (done) {
|
||||||
|
var self = this;
|
||||||
|
var payload1 = {
|
||||||
|
query: "SELECT * FROM untitle_table_4; select pg_sleep(3)"
|
||||||
|
};
|
||||||
|
|
||||||
|
this.batchTestClient.createJob(payload1, function(err, jobResult1) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
var payload2 = {
|
||||||
|
query: "SELECT * FROM untitle_table_4"
|
||||||
|
};
|
||||||
|
|
||||||
|
self.batchTestClient.createJob(payload2, function(err, jobResult2) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
jobResult2.getStatus(JobStatus.PENDING, function (err, job) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.equal(job.status, JobStatus.PENDING);
|
||||||
|
|
||||||
|
jobResult2.cancel(function (err, job) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.equal(job.status, JobStatus.CANCELLED);
|
||||||
|
|
||||||
|
jobResult1.cancel(function (err, job) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.equal(job.status, JobStatus.CANCELLED);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('cancel a job with quotes', function (done) {
|
||||||
|
var payload = {
|
||||||
|
query: "SELECT name FROM untitle_table_4 WHERE name = 'Hawai'; select pg_sleep(3)"
|
||||||
|
};
|
||||||
|
|
||||||
|
this.batchTestClient.createJob(payload, function(err, jobResult) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
jobResult.getStatus(JobStatus.RUNNING, function (err, job) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.equal(job.status, JobStatus.RUNNING);
|
||||||
|
|
||||||
|
jobResult.cancel(function (err, job) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.equal(job.status, JobStatus.CANCELLED);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('cancel a running multiquery job', function (done) {
|
||||||
|
var payload = {
|
||||||
|
query: [
|
||||||
|
"select pg_sleep(1)",
|
||||||
|
"select pg_sleep(1)",
|
||||||
|
"select pg_sleep(1)"
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
this.batchTestClient.createJob(payload, function(err, jobResult) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
jobResult.getStatus(JobStatus.RUNNING, function (err, job) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.equal(job.status, JobStatus.RUNNING);
|
||||||
|
|
||||||
|
jobResult.cancel(function (err, job) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.equal(job.status, JobStatus.CANCELLED);
|
||||||
|
|
||||||
|
jobResult.tryCancel(function (err, body) {
|
||||||
|
assert.equal(body.error[0], "Cannot set status from cancelled to cancelled");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -66,6 +66,31 @@ describe('job backend', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('.get() should return a job with the given id', function (done) {
|
||||||
|
var jobData = createWadusJob();
|
||||||
|
|
||||||
|
jobBackend.create(jobData.data, function (err, jobCreated) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.ok(jobCreated.job_id);
|
||||||
|
|
||||||
|
jobBackend.get(jobCreated.job_id, function (err, job) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.equal(job.job_id, jobCreated.job_id);
|
||||||
|
assert.equal(job.user, jobData.data.user);
|
||||||
|
assert.equal(job.query, jobData.data.query);
|
||||||
|
assert.equal(job.host, jobData.data.host);
|
||||||
|
assert.equal(job.status, jobStatus.PENDING);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('.update() should update an existent job', function (done) {
|
it('.update() should update an existent job', function (done) {
|
||||||
var job = createWadusJob();
|
var job = createWadusJob();
|
||||||
|
|
||||||
@ -100,6 +125,24 @@ describe('job backend', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('.save() should save a job', function (done) {
|
||||||
|
var job = createWadusJob();
|
||||||
|
|
||||||
|
jobBackend.save(job.data, function (err, jobSaved) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.ok(jobSaved.job_id);
|
||||||
|
|
||||||
|
assert.equal(jobSaved.user, job.data.user);
|
||||||
|
assert.equal(jobSaved.query, job.data.query);
|
||||||
|
assert.equal(jobSaved.host, job.data.host);
|
||||||
|
assert.equal(jobSaved.status, jobStatus.PENDING);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('.addWorkInProgressJob() should add current job to user and host lists', function (done) {
|
it('.addWorkInProgressJob() should add current job to user and host lists', function (done) {
|
||||||
var job = createWadusJob();
|
var job = createWadusJob();
|
||||||
|
|
||||||
@ -156,4 +199,21 @@ describe('job backend', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('.clearWorkInProgressJob() should remove job from work in progress list', function (done) {
|
||||||
|
var job = createWadusJob();
|
||||||
|
|
||||||
|
jobBackend.addWorkInProgressJob(job.data.user, job.data.job_id, function (err) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
jobBackend.clearWorkInProgressJob(job.data.user, job.data.job_id, function (err) {
|
||||||
|
if (err) {
|
||||||
|
return done(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -34,7 +34,7 @@ assert.response = function(server, req, res, callback) {
|
|||||||
url: 'http://' + host + ':' + port + req.url,
|
url: 'http://' + host + ':' + port + req.url,
|
||||||
method: req.method || 'GET',
|
method: req.method || 'GET',
|
||||||
headers: req.headers || {},
|
headers: req.headers || {},
|
||||||
timeout: req.timeout || 0,
|
timeout: req.timeout || 5000,
|
||||||
encoding: req.encoding || 'utf8'
|
encoding: req.encoding || 'utf8'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,7 +18,8 @@ function response(code) {
|
|||||||
|
|
||||||
var RESPONSE = {
|
var RESPONSE = {
|
||||||
OK: response(200),
|
OK: response(200),
|
||||||
CREATED: response(201)
|
CREATED: response(201),
|
||||||
|
BAD_REQUEST: response(400)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -86,7 +87,8 @@ BatchTestClient.prototype.getJobStatus = function(jobId, override, callback) {
|
|||||||
headers: {
|
headers: {
|
||||||
host: this.getHost(override)
|
host: this.getHost(override)
|
||||||
},
|
},
|
||||||
method: 'GET'
|
method: 'GET',
|
||||||
|
timeout: override.timeout
|
||||||
},
|
},
|
||||||
RESPONSE.OK,
|
RESPONSE.OK,
|
||||||
function (err, res) {
|
function (err, res) {
|
||||||
@ -127,13 +129,13 @@ BatchTestClient.prototype.cancelJob = function(jobId, override, callback) {
|
|||||||
assert.response(
|
assert.response(
|
||||||
this.server,
|
this.server,
|
||||||
{
|
{
|
||||||
url: this.getUrl(jobId),
|
url: this.getUrl(override, jobId),
|
||||||
headers: {
|
headers: {
|
||||||
host: this.getHost(override)
|
host: this.getHost(override)
|
||||||
},
|
},
|
||||||
method: 'DELETE'
|
method: 'DELETE'
|
||||||
},
|
},
|
||||||
RESPONSE.OK,
|
override.statusCode,
|
||||||
function (err, res) {
|
function (err, res) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
@ -174,25 +176,105 @@ function JobResult(job, batchTestClient, override) {
|
|||||||
this.override = override;
|
this.override = override;
|
||||||
}
|
}
|
||||||
|
|
||||||
JobResult.prototype.getStatus = function(callback) {
|
JobResult.prototype.getStatus = function(requiredStatus, callback) {
|
||||||
|
if (!callback) {
|
||||||
|
callback = requiredStatus;
|
||||||
|
requiredStatus = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
var attempts = 1;
|
||||||
|
self.override.timeout = 1000;
|
||||||
|
|
||||||
var interval = setInterval(function () {
|
var interval = setInterval(function () {
|
||||||
self.batchTestClient.getJobStatus(self.job.job_id, self.override, function (err, job) {
|
self.batchTestClient.getJobStatus(self.job.job_id, self.override, function (err, job) {
|
||||||
if (err) {
|
if (err) {
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
attempts += 1;
|
||||||
|
|
||||||
if (JobStatus.isFinal(job.status)) {
|
if (attempts > 20) {
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
|
return callback(new Error('Reached maximum number of request (20) to check job status'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasRequiredStatus(job, requiredStatus)) {
|
||||||
|
clearInterval(interval);
|
||||||
|
self.job = job;
|
||||||
return callback(null, job);
|
return callback(null, job);
|
||||||
} else {
|
} else {
|
||||||
debug('Job %s [status=%s] waiting to be done', self.job.job_id, job.status);
|
debug('Job %s [status=%s] waiting to be done', self.job.job_id, job.status);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, 50);
|
}, 100);
|
||||||
};
|
};
|
||||||
|
|
||||||
JobResult.prototype.cancel = function(callback) {
|
function hasRequiredStatus(job, requiredStatus) {
|
||||||
this.batchTestClient.cancelJob(this.job.job_id, this.override, callback);
|
if (requiredStatus) {
|
||||||
|
return job.status === requiredStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (JobStatus.isFinal(job.status)) {
|
||||||
|
if (job.fallback_status !== undefined) {
|
||||||
|
if (JobStatus.isFinal(job.fallback_status) || job.fallback_status === JobStatus.SKIPPED) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
JobResult.prototype.cancel = function (callback) {
|
||||||
|
var self = this;
|
||||||
|
this.override.statusCode = response(RESPONSE.OK);
|
||||||
|
this.batchTestClient.cancelJob(this.job.job_id, this.override, function (err, job) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
self.job = job;
|
||||||
|
callback(null, job);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
JobResult.prototype.tryCancel = function (callback) {
|
||||||
|
var self = this;
|
||||||
|
this.override.statusCode = response();
|
||||||
|
this.batchTestClient.cancelJob(this.job.job_id, this.override, function (err, job) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
self.job = job;
|
||||||
|
callback(null, job);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
JobResult.prototype.validateExpectedResponse = function (expected) {
|
||||||
|
var actual = this.job.query;
|
||||||
|
|
||||||
|
actual.query.forEach(function(actualQuery, index) {
|
||||||
|
var expectedQuery = expected.query[index];
|
||||||
|
assert.ok(expectedQuery);
|
||||||
|
Object.keys(expectedQuery).forEach(function(expectedKey) {
|
||||||
|
assert.equal(
|
||||||
|
actualQuery[expectedKey],
|
||||||
|
expectedQuery[expectedKey],
|
||||||
|
'Expected value for key "' + expectedKey + '" does not match: ' + actualQuery[expectedKey] + ' ==' +
|
||||||
|
expectedQuery[expectedKey] + ' at query index=' + index + '. Full response: ' +
|
||||||
|
JSON.stringify(actual, null, 4)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
var propsToCheckDate = ['started_at', 'ended_at'];
|
||||||
|
propsToCheckDate.forEach(function(propToCheckDate) {
|
||||||
|
if (actualQuery.hasOwnProperty(propToCheckDate)) {
|
||||||
|
assert.ok(new Date(actualQuery[propToCheckDate]));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.equal(actual.onsuccess, expected.onsuccess);
|
||||||
|
assert.equal(actual.onerror, expected.onerror);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user