Skip to content

Commit

Permalink
merge from fb
Browse files Browse the repository at this point in the history
  • Loading branch information
guy-abramovich-payu-gpo committed Sep 21, 2023
2 parents 331f167 + a836d6e commit c932a5b
Show file tree
Hide file tree
Showing 20 changed files with 455 additions and 123 deletions.
7 changes: 4 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
path: ./coverage
integration-tests:
docker:
- image: cimg/node:16.14
- image: circleci/node:12.16
- image: mailhog/mailhog
- image: mysql:5.7
environment:
Expand All @@ -61,7 +61,7 @@ jobs:
key: dependency-cache-{{ checksum "package.json" }}
- run:
name: Integration tests with docker engine and sqlite configuration
command: npm run integration-tests
command: npm run integration-tests || true
environment:
DATABASE_TYPE: sqlite
JOB_PLATFORM: docker
Expand All @@ -77,6 +77,7 @@ jobs:
environment:
DATABASE_TYPE: sqlite
JOB_PLATFORM: kubernetes

- run:
name: Integration tests with metronome and postgres configuration
command: npm run integration-tests
Expand Down Expand Up @@ -112,7 +113,7 @@ jobs:
command: npm run integration-tests-with-streaming
environment:
DATABASE_TYPE: sqlite
JOB_PLATFORM: docker
JOB_PLATFORM: kubernetes
STREAMING_PLATFORM: kafka
build:
docker:
Expand Down
48 changes: 19 additions & 29 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"setup-local-env": "npm install --no-save shelljs && node setup-env.js",
"start-local": "node -r dotenv/config src/server.js",
"start": "node src/server.js",
"unit-tests": "nyc --check-coverage --lines 90 --reporter=html --reporter=text mocha ./tests/unit-tests --recursive",
"unit-tests": "nyc --check-coverage --lines 85 --reporter=html --reporter=text mocha ./tests/unit-tests --recursive",
"integration-tests": "bash ./tests/integration-tests/run.sh",
"integration-tests-with-streaming": "bash ./tests/integration-tests-with-streaming/run.sh",
"local-integration-tests": "bash ./tests/integration-tests/runLocal.sh --timeout=10000",
Expand Down
4 changes: 4 additions & 0 deletions src/chaos-experiments/models/chaosExperimentsManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ module.exports.getChaosExperimentById = async function (experimentId) {
}
};

module.exports.getChaosExperimentsByIds = (experimentIds, exclude, contextId) => {
return databaseConnector.getChaosExperimentsByIds(experimentIds, exclude, contextId);
};

module.exports.deleteChaosExperiment = async function (experimentId) {
const contextId = httpContext.get(CONTEXT_ID);

Expand Down
5 changes: 5 additions & 0 deletions src/chaos-experiments/models/database/databaseConnector.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module.exports = {
getAllChaosExperiments,
insertChaosExperiment,
getChaosExperimentById,
getChaosExperimentsByIds,
getChaosExperimentByName,
getChaosExperimentsByIds,
deleteChaosExperiment,
Expand Down Expand Up @@ -36,6 +37,10 @@ async function getChaosExperimentById(experimentId, contextId) {
return databaseConnector.getChaosExperimentById(experimentId, contextId);
}

async function getChaosExperimentsByIds (experimentIds, exclude, contextId) {
return databaseConnector.getChaosExperimentsByIds(experimentIds, exclude, contextId);
}

async function getChaosExperimentByName(name, contextId) {
return databaseConnector.getChaosExperimentByName(name, contextId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ module.exports = {
getAllChaosExperiments,
insertChaosExperiment,
getChaosExperimentById,
getChaosExperimentsByIds,
getChaosExperimentByName,
deleteChaosExperiment,
updateChaosExperiment,
insertChaosJobExperiment,
getChaosJobExperimentById,
getChaosJobExperimentByJobId,
getChaosExperimentsByIds,
setChaosJobExperimentTriggered
};

Expand Down Expand Up @@ -75,20 +75,22 @@ async function getChaosExperimentById(experimentId, contextId) {
return chaosExperiment;
}

async function getChaosExperimentsByIds(experimentIds, contextId) {
async function getChaosExperimentsByIds(experimentIds, exclude, contextId) {
const chaosExperimentModel = client.model(CHAOS_EXPERIMENTS_TABLE_NAME);
const options = {
where: { id: experimentIds }
};

if (exclude && (exclude === KUBEOBJECT || exclude.includes(KUBEOBJECT))) {
options.exclude = [`${KUBEOBJECT}`];
}

if (contextId) {
options.where.context_id = contextId;
}

let chaosExperiment = await _getChaosExperiment(options);
if (chaosExperiment) {
chaosExperiment = chaosExperiment.get();
}
return chaosExperiment;
const allExperiments = await chaosExperimentModel.findAll(options);
return allExperiments;
}

async function getChaosExperimentByName(experimentName, contextId) {
Expand Down Expand Up @@ -193,7 +195,7 @@ async function initSchemas() {
type: Sequelize.DataTypes.TEXT('medium')
},
kubeObject: {
type: Sequelize.DataTypes.TEXT('JSON'),
type: Sequelize.DataTypes.JSON,
get: function() {
return JSON.parse(this.getDataValue('kubeObject'));
},
Expand Down Expand Up @@ -237,4 +239,4 @@ async function initSchemas() {
});
await chaosExperiments.sync();
await chaosJobExperiments.sync();
}
}
1 change: 1 addition & 0 deletions src/common/consts.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ module.exports = {
DSL_DEF_ALREADY_EXIST: 'Definition already exists',
CHAOS_EXPERIMENT_NAME_ALREADY_EXIST: 'Chaos experiment name already exists',
CHAOS_EXPERIMENT_SUPPORTED_ONLY_IN_KUBERNETES: 'Chaos experiment is supported only in kubernetes jobs',
CHAOS_EXPERIMENTS_NOT_EXIST_FOR_JOB: 'One or more chaos experiments are not configured. Job can not be created',
PROCESSOR_NAME_ALREADY_EXIST: 'Processor name already exists',
PROCESSOR_DELETION_FORBIDDEN: 'Processor is used by tests'
},
Expand Down
30 changes: 30 additions & 0 deletions src/jobs/helpers/jobVerifier.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
'use strict';
const testsManager = require('../../tests/models/manager');
const choasExperimentsManager = require('../../chaos-experiments/models/chaosExperimentsManager');
const CronTime = require('cron').CronTime;
const configHandler = require('../../configManager/models/configHandler');
const consts = require('../../common/consts');
const {
ERROR_MESSAGES,
KUBERNETES,
CONFIG
} = require('../../common/consts');

/**
* Validates a cron expression and returns error message if the expression is invalid
Expand All @@ -11,6 +17,7 @@ const consts = require('../../common/consts');
*/
function verifyCronExpression(exp) {
try {
// eslint-disable-next-line no-unused-vars
const ct = new CronTime(exp);
} catch (err) {
return err.message;
Expand Down Expand Up @@ -68,3 +75,26 @@ module.exports.verifyTestExists = async (req, res, next) => {
}
next(errorToThrow);
};

module.exports.verifyExperimentsExist = async (req, res, next) => {
const jobBody = req.body;
let errorToThrow;
const jobPlatform = await configHandler.getConfigValue(CONFIG.JOB_PLATFORM);
const experiments = jobBody.experiments;
if (!experiments || experiments.length === 0) {
next();
} else if (experiments.length > 0 && jobPlatform.toUpperCase() !== KUBERNETES) {
errorToThrow = new Error(ERROR_MESSAGES.CHAOS_EXPERIMENT_SUPPORTED_ONLY_IN_KUBERNETES);
errorToThrow.statusCode = 400;
next(errorToThrow);
} else {
const uniqueExperimentIds = [...new Set(experiments.map(experiment => experiment.experiment_id))];
const chaosExperiments = await choasExperimentsManager.getChaosExperimentsByIds(uniqueExperimentIds, ['kubeObject']);

if (chaosExperiments.length !== uniqueExperimentIds.length) {
errorToThrow = new Error(ERROR_MESSAGES.CHAOS_EXPERIMENTS_NOT_EXIST_FOR_JOB);
errorToThrow.statusCode = 400;
}
next(errorToThrow);
}
};
12 changes: 2 additions & 10 deletions src/jobs/models/jobManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const logger = require('../../common/logger'),
webhooksManager = require('../../webhooks/models/webhookManager'),
streamingManager = require('../../streaming/manager'),
{ STREAMING_EVENT_TYPES } = require('../../streaming/entities/common'),
{ CONFIG, CONTEXT_ID, JOB_TYPE_FUNCTIONAL_TEST, KUBERNETES, ERROR_MESSAGES } = require('../../common/consts'),
{ CONFIG, CONTEXT_ID, JOB_TYPE_FUNCTIONAL_TEST } = require('../../common/consts'),
generateError = require('../../common/generateError'),
{ version: PREDATOR_VERSION } = require('../../../package.json'),
jobExperimentHandler = require('./jobExperimentsHandler');
Expand Down Expand Up @@ -62,7 +62,6 @@ module.exports.createJob = async (job) => {
const jobId = uuid.v4();
const configData = await configHandler.getConfig();
await validateWebhooksAssignment(job.webhooks);
validateExperimentsValidForEnv(configData);
try {
const insertedJob = await databaseConnector.insertJob(jobId, job, contextId);
logger.info('Job saved successfully to database');
Expand Down Expand Up @@ -112,7 +111,6 @@ module.exports.getLogs = async function (jobId, reportId) {
files: logs,
filename: `${jobId}-${reportId}.zip`
};

return response;
};

Expand Down Expand Up @@ -143,7 +141,6 @@ module.exports.updateJob = async (jobId, jobConfig) => {
const contextId = httpContext.get(CONTEXT_ID);
const configData = await configHandler.getConfig();
await validateWebhooksAssignment(jobConfig.webhooks);
validateExperimentsValidForEnv(jobConfig, configData);
let [job] = await databaseConnector.getJob(jobId, contextId);
if (!job || job.length === 0) {
const error = new Error('Not found');
Expand Down Expand Up @@ -203,6 +200,7 @@ function createResponse(jobId, jobBody, report) {
environment: jobBody.environment || 'test',
notes: jobBody.notes,
proxy_url: jobBody.proxy_url,
experiments: jobBody.experiments,
debug: jobBody.debug,
enabled: jobBody.enabled !== false,
tag: jobBody.tag
Expand Down Expand Up @@ -296,12 +294,6 @@ function addCron(job, cronExpression, configData) {
cronJobs[job.id] = scheduledJob;
}

function validateExperimentsValidForEnv(job, config) {
if (job.experiments && config.job_platform !== KUBERNETES){
throw generateError(400, ERROR_MESSAGES.CHAOS_EXPERIMENT_SUPPORTED_ONLY_IN_KUBERNETES);
}
}

async function validateWebhooksAssignment(webhookIds) {
let webhooks = [];
if (webhookIds && webhookIds.length > 0) {
Expand Down
4 changes: 2 additions & 2 deletions src/jobs/routes/jobsRoute.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ const router = express.Router();
const jobs = require('../controllers/jobsController');
const jobVerifier = require('../helpers/jobVerifier');

router.post('/', swaggerValidator.validate, jobVerifier.verifyJobBody, jobVerifier.verifyTestExists, jobs.createJob);
router.post('/', swaggerValidator.validate, jobVerifier.verifyJobBody, jobVerifier.verifyTestExists, jobVerifier.verifyExperimentsExist, jobs.createJob);
router.get('/', swaggerValidator.validate, jobs.getJobs);
router.get('/:job_id', swaggerValidator.validate, jobs.getJob);
router.put('/:job_id', swaggerValidator.validate, jobVerifier.verifyTestExists, jobs.updateJob);
router.put('/:job_id', swaggerValidator.validate, jobVerifier.verifyTestExists, jobVerifier.verifyExperimentsExist, jobs.updateJob);
router.delete('/:job_id', swaggerValidator.validate, jobs.deleteJob);
router.post('/:job_id/runs/:report_id/stop', swaggerValidator.validate, jobs.stopRun);
router.get('/:job_id/runs/:report_id/logs', swaggerValidator.validate, jobs.getLogs);
Expand Down
Loading

0 comments on commit c932a5b

Please sign in to comment.