mirror of
https://github.com/knex/knex.git
synced 2026-01-03 10:38:37 +00:00
Removed old docker tests, new stress test setup tests are testing the same stuff (#2474)
Currently stress tests are run locally manually, but CI could be set up to run them for a few minutes and record request counts and memory usage during tests.
This commit is contained in:
parent
7ff766f7a3
commit
d4a85db410
@ -34,7 +34,6 @@
|
||||
"babel-preset-es2015": "^6.24.1",
|
||||
"chai": "^4.1.2",
|
||||
"coveralls": "~3.0.0",
|
||||
"dockerode": "^2.5.3",
|
||||
"eslint": "4.16.0",
|
||||
"eslint-plugin-import": "^2.8.0",
|
||||
"estraverse": "^4.2.0",
|
||||
@ -76,8 +75,7 @@
|
||||
"lint": "eslint src/**",
|
||||
"plaintest": "mocha --check-leaks -b -R spec test/index.js && npm run tape",
|
||||
"prepublish": "npm run babel",
|
||||
"docker_test": "bash ./scripts/docker-for-test.sh",
|
||||
"pre_test": "npm run lint && npm run docker_test",
|
||||
"pre_test": "npm run lint",
|
||||
"tape": "node test/tape/index.js | tap-spec",
|
||||
"debug_tape": "node-debug test/tape/index.js",
|
||||
"test": "npm run pre_test && istanbul --config=test/.istanbul.yml cover node_modules/mocha/bin/_mocha -- --check-leaks -t 10000 -b -R spec test/index.js && npm run tape",
|
||||
|
||||
@ -1,29 +0,0 @@
|
||||
var _ = require('lodash');
|
||||
var $Docker = require('dockerode');
|
||||
|
||||
function Docker() {
|
||||
this.dockerAPI = new $Docker({ socketPath: '/var/run/docker.sock' });
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} name
|
||||
* @param {String} image
|
||||
* @param {Object} options
|
||||
* @returns Promise<Object>
|
||||
*/
|
||||
Docker.prototype.createContainer = function (name, image, options) {
|
||||
return this.dockerAPI.createContainer({
|
||||
name: name,
|
||||
Image: image,
|
||||
AttachStdin: _.get(options, 'AttachStdin', false),
|
||||
AttachStdout: _.get(options, 'AttachStdout', true),
|
||||
AttachStderr: _.get(options, 'AttachStderr', true),
|
||||
Tty: _.get(options, 'Tty', true),
|
||||
OpenStdin: _.get(options, 'OpenStdin', false),
|
||||
StdinOnce: _.get(options, 'StdinOnce', false),
|
||||
Env: _.get(options, 'Env'),
|
||||
PortBindings: _.get(options, 'PortBindings')
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = Docker;
|
||||
@ -1,59 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var Promise = require('bluebird');
|
||||
|
||||
function DockerContainer(docker, name, image, options) {
|
||||
this.container = docker.createContainer(name, image, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise}
|
||||
*/
|
||||
DockerContainer.prototype.start = function () {
|
||||
var self = this;
|
||||
return self.container.then(function (c) {
|
||||
return c.start().then(function () {
|
||||
console.log('#~ Started container', c.id);
|
||||
return self.waitReady();
|
||||
})
|
||||
})
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {Promise}
|
||||
*/
|
||||
DockerContainer.prototype.waitReady = function () {
|
||||
return Promise.resolve(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise}
|
||||
*/
|
||||
DockerContainer.prototype.stop = function () {
|
||||
return this.container.then(function (c) {
|
||||
return c.stop().then(function () {
|
||||
console.log('#~ Stopped container', c.id);
|
||||
})
|
||||
.catch(function (err) {
|
||||
if (err.statusCode !== 304) {
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise}
|
||||
*/
|
||||
DockerContainer.prototype.destroy = function () {
|
||||
var self = this;
|
||||
return self.stop().then(function () {
|
||||
return self.container.then(function (c) {
|
||||
return c.remove().then(function () {
|
||||
console.log('#~ Removed container', c.id);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = DockerContainer;
|
||||
@ -1,29 +0,0 @@
|
||||
/*global describe*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const os = require('os');
|
||||
const proc = require('child_process')
|
||||
const config = require('../knexfile');
|
||||
const knex = require('../../knex');
|
||||
|
||||
if (canRunDockerTests()) {
|
||||
for (const dialectName in config) {
|
||||
if (config[dialectName].docker) {
|
||||
describe(`${dialectName} dialect`, function() {
|
||||
require('./reconnect')(config[dialectName], knex);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function canRunDockerTests() {
|
||||
const isLinux = os.platform() === 'linux';
|
||||
const isDarwin = os.platform() === 'darwin'
|
||||
// dont even try on windows / osx for now
|
||||
let hasDockerStarted = false;
|
||||
if (isLinux || isDarwin) {
|
||||
hasDockerStarted = proc.execSync('docker info 1>/dev/null 2>&1 ; echo $?').toString('utf-8') === '0\n';
|
||||
}
|
||||
return hasDockerStarted;
|
||||
}
|
||||
@ -1,56 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var Promise = require('bluebird');
|
||||
var _ = require('lodash');
|
||||
var DockerContainer = require('../dockerContainer');
|
||||
|
||||
function MySQLContainer(docker, options) {
|
||||
var name = _.get(options, 'container');
|
||||
var image = _.get(options, 'image');
|
||||
var username = _.get(options, 'username');
|
||||
var password = _.get(options, 'password');
|
||||
var hostPort = _.get(options, 'hostPort');
|
||||
DockerContainer.call(this, docker, name, image, {
|
||||
Env: [ 'MYSQL_ROOT_PASSWORD=root' ],
|
||||
PortBindings: {
|
||||
'3306/tcp': [{
|
||||
HostPort: hostPort.toString()
|
||||
}]
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
MySQLContainer.prototype = Object.create(DockerContainer.prototype);
|
||||
|
||||
/**
|
||||
* @returns {Promise}
|
||||
*/
|
||||
MySQLContainer.prototype.waitReady = function () {
|
||||
var self = this;
|
||||
return self.container.then(function (c) {
|
||||
return new Promise(function (resolve) {
|
||||
c.exec({
|
||||
AttachStdout: true,
|
||||
Cmd: [
|
||||
'sh',
|
||||
'-c',
|
||||
'until mysqladmin ping -h 127.0.0.1 --silent; do echo "Waiting for mysql readiness" && sleep 2; done'
|
||||
]
|
||||
})
|
||||
.then(function (exec) {
|
||||
return exec.start({ Detach: false, Tty: true });
|
||||
})
|
||||
.then(function (object) {
|
||||
var output = object.output;
|
||||
output.on('data', function (data) {
|
||||
console.log(data.toString('utf-8').trim());
|
||||
});
|
||||
output.on('end', function () {
|
||||
resolve(self);
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = MySQLContainer;
|
||||
@ -1,56 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var Promise = require('bluebird');
|
||||
var _ = require('lodash');
|
||||
var DockerContainer = require('../dockerContainer');
|
||||
|
||||
function PostgresContainer(docker, options) {
|
||||
var name = _.get(options, 'container');
|
||||
var image = _.get(options, 'image');
|
||||
var username = _.get(options, 'username');
|
||||
var password = _.get(options, 'password');
|
||||
var hostPort = _.get(options, 'hostPort');
|
||||
DockerContainer.call(this, docker, name, image, {
|
||||
Env: ['POSTGRES_USER=' + username, 'POSTGRES_PASSWORD=' + password],
|
||||
PortBindings: {
|
||||
'5432/tcp': [{
|
||||
HostPort: hostPort.toString()
|
||||
}]
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
PostgresContainer.prototype = Object.create(DockerContainer.prototype);
|
||||
|
||||
/**
|
||||
* @returns {Promise}
|
||||
*/
|
||||
PostgresContainer.prototype.waitReady = function () {
|
||||
var self = this;
|
||||
return self.container.then(function (c) {
|
||||
return new Promise(function (resolve) {
|
||||
c.exec({
|
||||
AttachStdout: true,
|
||||
Cmd: [
|
||||
'sh',
|
||||
'-c',
|
||||
'until pg_isready; do sleep 1; done'
|
||||
]
|
||||
})
|
||||
.then(function (exec) {
|
||||
return exec.start({ Detach: false, Tty: true });
|
||||
})
|
||||
.then(function (object) {
|
||||
var output = object.output;
|
||||
output.on('data', function (data) {
|
||||
console.log(data.toString('utf-8').trim());
|
||||
});
|
||||
output.on('end', function () {
|
||||
resolve(self);
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = PostgresContainer;
|
||||
@ -1,152 +0,0 @@
|
||||
/*global afterEach, before, expect, describe, it, testPromise*/
|
||||
'use strict';
|
||||
|
||||
var Docker = require('./docker');
|
||||
var Promise = testPromise;
|
||||
|
||||
module.exports = function(config, knex) {
|
||||
|
||||
var dockerConf = config.docker;
|
||||
var ContainerClass = require(dockerConf.factory);
|
||||
|
||||
var IDLE_TIMEOUT_MILLIS = 20 * 1000;
|
||||
var ACQUIRE_CONNECTION_TIMEOUT = 10 * 1000;
|
||||
var ACQUIRE_TIMEOUT_MILLIS = 10 * 1000;
|
||||
|
||||
var docker;
|
||||
var connectionPool;
|
||||
var container;
|
||||
|
||||
|
||||
describe('using database as a docker container', function () {
|
||||
|
||||
this.timeout(process.env.KNEX_TEST_TIMEOUT || 30000);
|
||||
|
||||
before(function () {
|
||||
docker = new Docker();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
return sequencedPromise([
|
||||
function () { console.log('>> Destroying container'); },
|
||||
function () { return container.destroy(); }
|
||||
// function () { console.log('>> Destroying pool'); },
|
||||
// function () { return connectionPool.destroy(); },
|
||||
// function () { console.log('>> Destroyed all'); }
|
||||
]);
|
||||
});
|
||||
|
||||
describe('start container and wait until it is ready', function () {
|
||||
|
||||
beforeEach(function () {
|
||||
container = new ContainerClass(docker, dockerConf);
|
||||
return container.start().then(function () {
|
||||
return waitReadyForQueries();
|
||||
});
|
||||
});
|
||||
|
||||
describe('initialize connection pool', function () {
|
||||
beforeEach(function () {
|
||||
connectionPool = createPool();
|
||||
});
|
||||
|
||||
it('connection pool can query', function () {
|
||||
return testQuery(connectionPool);
|
||||
});
|
||||
|
||||
describe('stop db-container and expect queries to fail', function () {
|
||||
|
||||
beforeEach(function () {
|
||||
return container.stop();
|
||||
});
|
||||
|
||||
it('connection pool can not query x10', function () {
|
||||
var promises = [];
|
||||
for (var i = 0; i < 10; i += 1) {
|
||||
promises.push(
|
||||
testQuery(connectionPool)
|
||||
.then(function () { throw new Error('Failure expected'); })
|
||||
.catch(function (err) {
|
||||
expect(err.message).to.not.equal('Failure expected');
|
||||
})
|
||||
);
|
||||
}
|
||||
return Promise.all(promises);
|
||||
});
|
||||
|
||||
describe('restart db-container and keep using connection pool', function () {
|
||||
beforeEach(function () {
|
||||
return container.start().then(function () {
|
||||
return waitReadyForQueries();
|
||||
});
|
||||
});
|
||||
|
||||
it('connection pool can query x10', function () {
|
||||
var promises = [];
|
||||
for (var i = 0; i < 10; i += 1) {
|
||||
promises.push(testQuery(connectionPool));
|
||||
}
|
||||
return Promise.all(promises);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
function testQuery(pool) {
|
||||
return pool.raw('SELECT 10 as ten').then(function (result) {
|
||||
expect(result.rows || result[0]).to.deep.equal([{ ten: 10 }]);
|
||||
});
|
||||
}
|
||||
|
||||
function sequencedPromise(blocks) {
|
||||
var order = function (prev, block) {
|
||||
return prev.then(block)
|
||||
};
|
||||
var base = Promise.resolve(true);
|
||||
return blocks.reduce(order, base);
|
||||
}
|
||||
|
||||
function createPool() {
|
||||
return knex({
|
||||
// debug: true,
|
||||
client: dockerConf.client,
|
||||
acquireConnectionTimeout: ACQUIRE_CONNECTION_TIMEOUT,
|
||||
pool: {
|
||||
min: 7,
|
||||
max: 7,
|
||||
idleTimeoutMillis: IDLE_TIMEOUT_MILLIS,
|
||||
acquireTimeoutMillis: ACQUIRE_TIMEOUT_MILLIS
|
||||
},
|
||||
connection: {
|
||||
database: dockerConf.database,
|
||||
port: dockerConf.hostPort,
|
||||
user: dockerConf.username,
|
||||
password: dockerConf.password,
|
||||
host: '127.0.0.1'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function waitReadyForQueries(attempt) {
|
||||
attempt = attempt || 0;
|
||||
return new Promise(function (resolve, reject) {
|
||||
console.log('#~ Waiting to be ready for queries #', attempt);
|
||||
var pool = createPool();
|
||||
pool.raw('SELECT 1 as one')
|
||||
.then(function () {
|
||||
return pool.destroy().then(resolve);
|
||||
})
|
||||
.catch(function (a) {
|
||||
return pool.destroy().then(function () {
|
||||
if (attempt < 20) {
|
||||
setTimeout(function () { resolve(waitReadyForQueries(attempt + 1)) }, 1000);
|
||||
} else {
|
||||
reject(attempt);
|
||||
}
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -50,8 +50,3 @@ if (config.oracledb) {
|
||||
if(config.postgres) {
|
||||
require('./unit/dialects/postgres');
|
||||
}
|
||||
|
||||
describe('Docker Integration Tests', function() {
|
||||
this.timeout(process.env.KNEX_TEST_TIMEOUT || 15000);
|
||||
require('./docker')
|
||||
})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user