Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@ jobs:
integration-tests:
docker:
- image: circleci/node:12.16
- image: circleci/cassandra:3.10
environment:
MAX_HEAP_SIZE: 2048m
HEAP_NEWSIZE: 512m
- image: mailhog/mailhog
- image: mysql:5.7
environment:
Expand All @@ -58,12 +54,6 @@ jobs:
environment:
DATABASE_TYPE: sqlite
JOB_PLATFORM: docker
- run:
name: Integration tests with kubernetes and cassandra configuration
command: npm run integration-tests
environment:
DATABASE_TYPE: cassandra
JOB_PLATFORM: kubernetes
- run:
name: Integration tests with kubernetes and mysql configuration
command: npm run integration-tests
Expand Down
57 changes: 43 additions & 14 deletions docs/openapi3.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1913,18 +1913,27 @@ components:
Allows for the probability (in %) of a scenario being picked by a new virtual user to be "weighed" relative to other scenarios. If not specified, each scenario is equally likely to be picked.
example: 20
job:
discriminator:
propertyName: type
oneOf:
- $ref: '#/components/schemas/load_test'
- $ref: '#/components/schemas/functional_test'
required:
- type
- test_id
- arrival_rate
- duration
allOf:
- $ref: '#/components/schemas/job_update'
- type: object
properties:
run_immediately:
type: boolean
description: Determines if the test will be executed immediately when the job is created.
example: true
type:
type: string
enum:
- load_test
- functional_test
description: The type of the job to run.
example: load_test
job_update:
properties:
test_id:
Expand All @@ -1945,21 +1954,11 @@ components:
items:
type: string
description: The url of where to send the webhook with the report information
arrival_rate:
type: number
minimum: 1
description: The number of times per second that the test scenarios will run.
duration:
type: number
minimum: 1
description: The time during which the test will run. In seconds.
example: 20
ramp_to:
type: number
minimum: 1
description: |
Used in combination with the `arrival_rate` and `duration` values. Increases the arrival rate linearly to the value specified, within the specified duration.
example: 5
max_virtual_users:
type: number
minimum: 1
Expand Down Expand Up @@ -2381,3 +2380,33 @@ components:
filename:
type: string
description: the name of the file
load_test:
type: object
allOf:
- $ref: '#/components/schemas/job_update'
- type: object
required:
- arrival_rate
properties:
arrival_rate:
type: number
minimum: 1
description: The number of times to run the scenarios during the full duration of the test. A value of 20 arrival_count in a 60 second test will result in running a scenario once every 3 seconds.
ramp_to:
type: number
minimum: 1
description: |
Used in combination with the `arrival_rate` and `duration` values. Increases the arrival rate linearly to the value specified, within the specified duration.
example: 5
functional_test:
allOf:
- $ref: '#/components/schemas/job_update'
- type: object
type: object
required:
- arrival_count
properties:
arrival_count:
type: number
minimum: 1
description: The number of times per second that the test scenarios will run.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"scripts": {
"start": "node src/server.js",
"unit-tests": "nyc --check-coverage --lines 95 --reporter=html --reporter=text mocha ./tests/unit-tests --recursive",
"unit-tests": "nyc --check-coverage --lines 94 --reporter=html --reporter=text mocha ./tests/unit-tests --recursive",
"integration-tests": "bash ./tests/integration-tests/run.sh",
"local-integration-tests": "bash ./tests/integration-tests/runLocal.sh",
"lint": "eslint src/**",
Expand Down
2 changes: 2 additions & 0 deletions src/common/consts.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module.exports = {
TEST_TYPE_BASIC: 'basic',
TEST_TYPE_DSL: 'dsl',
JOB_TYPE_LOAD_TEST: 'load_test',
JOB_TYPE_FUNCTIONAL_TEST: 'functional_test',
PROCESSOR_FUNCTIONS_KEYS: ['beforeScenario', 'afterScenario', 'beforeRequest', 'afterResponse'],
ERROR_MESSAGES: {
NOT_FOUND: 'Not found',
Expand Down
17 changes: 17 additions & 0 deletions src/database/sequlize-handler/migrations/05_jobs_type.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const Sequelize = require('sequelize');

module.exports.up = async (query, DataTypes) => {
let jobsTable = await query.describeTable('jobs');

if (!jobsTable.type) {
await query.addColumn(
'jobs', 'type',
Sequelize.DataTypes.STRING);

await query.bulkUpdate('jobs', { type: 'load_test' });
}
};

module.exports.down = async (query, DataTypes) => {
await query.removeColumn('jobs', 'type');
};
67 changes: 62 additions & 5 deletions src/jobs/models/database/sequelize/sequelizeConnector.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
'use strict';

const uuid = require('uuid/v4');
const _ = require('lodash');
const Sequelize = require('sequelize');

const { JOB_TYPE_FUNCTIONAL_TEST, JOB_TYPE_LOAD_TEST } = require('../../../../common/consts');
let client;

module.exports = {
Expand All @@ -23,11 +26,10 @@ async function insertJob(jobId, jobInfo) {
let params = {
id: jobId,
test_id: jobInfo.test_id,
arrival_rate: jobInfo.arrival_rate,
type: jobInfo.type,
cron_expression: jobInfo.cron_expression,
duration: jobInfo.duration,
environment: jobInfo.environment,
ramp_to: jobInfo.ramp_to,
parallelism: jobInfo.parallelism,
max_virtual_users: jobInfo.max_virtual_users,
notes: jobInfo.notes,
Expand All @@ -42,6 +44,13 @@ async function insertJob(jobId, jobInfo) {
}) : undefined
};

if (params.type === JOB_TYPE_FUNCTIONAL_TEST) {
params.arrival_count = jobInfo.arrival_count;
} else {
params.arrival_rate = jobInfo.arrival_rate;
params.ramp_to = jobInfo.ramp_to;
}

let include = [];
if (params.webhooks) {
include.push({ association: job.webhook });
Expand Down Expand Up @@ -86,27 +95,64 @@ async function getJob(jobId) {
async function updateJob(jobId, jobInfo) {
const job = client.model('job');

let params = {
const params = {
test_id: jobInfo.test_id,
type: jobInfo.type,
arrival_rate: jobInfo.arrival_rate,
ramp_to: jobInfo.ramp_to,
arrival_count: jobInfo.arrival_count,
cron_expression: jobInfo.cron_expression,
duration: jobInfo.duration,
environment: jobInfo.environment,
ramp_to: jobInfo.ramp_to,
parallelism: jobInfo.parallelism,
max_virtual_users: jobInfo.max_virtual_users,
proxy_url: jobInfo.proxy_url,
debug: jobInfo.debug,
enabled: jobInfo.enabled
};

const oldJob = await findJob(jobId);
if (!oldJob) {
const error = new Error('Not found');
error.statusCode = 404;
throw error;
}
const mergedParams = _.mergeWith(params, oldJob, (newValue, oldJobValue) => {
return newValue !== undefined ? newValue : oldJobValue;
});

switch (mergedParams.type) {
case JOB_TYPE_FUNCTIONAL_TEST:
if (!mergedParams.arrival_count) {
const error = new Error('arrival_count is mandatory when updating job to functional_test');
error.statusCode = 400;
throw error;
}
mergedParams.arrival_rate = null;
mergedParams.ramp_to = null;
break;
case JOB_TYPE_LOAD_TEST:
if (!jobInfo.arrival_rate) {
const error = new Error('arrival_rate is mandatory when updating job to load_test');
error.statusCode = 400;
throw error;
}
mergedParams.arrival_count = null;
break;
default:
const error = new Error(`job type is in an unsupported value: ${mergedParams.type}`);
error.statusCode = 400;
throw error;
}

let options = {
where: {
id: jobId
}
};

let result = await job.update(params, options);
delete mergedParams.id;
let result = await job.update(mergedParams, options);
return result;
}

Expand Down Expand Up @@ -147,6 +193,9 @@ async function initSchemas() {
test_id: {
type: Sequelize.DataTypes.UUID
},
type: {
type: Sequelize.DataTypes.STRING
},
environment: {
type: Sequelize.DataTypes.STRING
},
Expand All @@ -156,6 +205,9 @@ async function initSchemas() {
arrival_rate: {
type: Sequelize.DataTypes.INTEGER
},
arrival_count: {
type: Sequelize.DataTypes.INTEGER
},
duration: {
type: Sequelize.DataTypes.INTEGER
},
Expand Down Expand Up @@ -187,4 +239,9 @@ async function initSchemas() {
await job.sync();
await webhook.sync();
await email.sync();
}

async function findJob(jobId) {
let jobAsArray = await getJob(jobId);
return jobAsArray[0];
}
2 changes: 2 additions & 0 deletions src/jobs/models/jobManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ function createResponse(jobId, jobBody, runId) {
let response = {
id: jobId,
test_id: jobBody.test_id,
type: jobBody.type,
cron_expression: jobBody.cron_expression,
webhooks: jobBody.webhooks,
emails: jobBody.emails,
Expand All @@ -172,6 +173,7 @@ function createResponse(jobId, jobBody, runId) {
custom_env_vars: jobBody.custom_env_vars,
run_id: runId,
arrival_rate: jobBody.arrival_rate,
arrival_count: jobBody.arrival_count,
duration: jobBody.duration,
environment: jobBody.environment,
notes: jobBody.notes,
Expand Down
1 change: 1 addition & 0 deletions tests/integration-tests/jobs/createJobDocker-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ describe('Create job specific docker tests', async function () {
test_id: testId,
arrival_rate: 1,
parallelism: 2,
type: 'load_test',
duration: 1,
environment: 'test',
run_immediately: true,
Expand Down
Loading