diff --git a/helpers/Dojo/ExerciceResultsValidation.ts b/helpers/Dojo/ExerciceResultsValidation.ts new file mode 100644 index 0000000000000000000000000000000000000000..9b91ceed6716ecce08e94d3ca25c0e83451f1f1d --- /dev/null +++ b/helpers/Dojo/ExerciceResultsValidation.ts @@ -0,0 +1,74 @@ +import { TypedEmitter } from 'tiny-typed-emitter'; +import ExerciceRunningEvents from '../../types/Dojo/ExerciceRunningEvents'; +import ExerciceCheckerError from '../../../shared/types/Dojo/ExerciceCheckerError'; +import path from 'node:path'; +import SharedExerciceHelper from '../../../shared/helpers/Dojo/SharedExerciceHelper'; +import ClientsSharedConfig from '../../config/ClientsSharedConfig'; +import Toolbox from '../../../shared/helpers/Toolbox'; +import * as fs from 'fs-extra'; +import ExerciceResultsFile from '../../../shared/types/Dojo/ExerciceResultsFile'; + + +class ExerciceResultsValidation { + readonly events: TypedEmitter<ExerciceRunningEvents> = new TypedEmitter<ExerciceRunningEvents>(); + + public exerciceResults: ExerciceResultsFile | undefined = undefined; + + constructor(private folderResultsDojo: string, private folderResultsExercice: string) { } + + run() { + (async () => { + let resultsFilePath: string; + + + // Results file existence + { + this.events.emit('step', 'CHECK_RESULTS_FILE_EXIST', 'Checking if results file exists'); + const resultsFileOriginPath = path.join(this.folderResultsExercice, ClientsSharedConfig.filenames.results); + resultsFilePath = path.join(this.folderResultsDojo, ClientsSharedConfig.filenames.results); + + if ( !fs.existsSync(resultsFileOriginPath) ) { + this.events.emit('endStep', 'CHECK_RESULTS_FILE_EXIST', `Results file not found`, true); + this.events.emit('finished', false, ExerciceCheckerError.EXERCICE_RESULTS_FILE_NOT_FOUND); + return; + } + this.events.emit('endStep', 'CHECK_RESULTS_FILE_EXIST', 'Results file found', false); + + fs.moveSync(resultsFileOriginPath, resultsFilePath, { overwrite: true }); + } + + + // Results file schema validation + { + this.events.emit('step', 'VALIDATE_RESULTS_FILE', 'Validating results file schema'); + const validationResults = SharedExerciceHelper.validateResultFile(resultsFilePath); + if ( !validationResults.isValid ) { + this.events.emit('endStep', 'VALIDATE_RESULTS_FILE', `Results file is not valid. Here are the errors :\n${ JSON.stringify(validationResults.errors) }`, true); + this.events.emit('finished', false, ExerciceCheckerError.EXERCICE_RESULTS_FILE_SCHEMA_NOT_VALID); + return; + } + this.exerciceResults = validationResults.results; + this.events.emit('endStep', 'VALIDATE_RESULTS_FILE', 'Results file found', false); + } + + + // Results folder size + // ATTENTION: This test is at the end because even if it fail the local execution will continue and we need the other test above to be done + { + this.events.emit('step', 'CHECK_SIZE', 'Validating results folder size'); + const resultsFolderSize = await Toolbox.fs.getTotalSize(this.folderResultsExercice); + if ( resultsFolderSize > ClientsSharedConfig.exerciceResultsFolderMaxSizeInBytes ) { + this.events.emit('endStep', 'CHECK_SIZE', `Results folder size is too big (bigger than ${ ClientsSharedConfig.exerciceResultsFolderMaxSizeInBytes / 1000000 } MB)`, true); + this.events.emit('finished', false, ExerciceCheckerError.EXERCICE_RESULTS_FOLDER_TOO_BIG); + return; + } + this.events.emit('endStep', 'CHECK_SIZE', 'Validating results folder size', false); + } + + this.events.emit('finished', true, 0); + })(); + } +} + + +export default ExerciceResultsValidation; \ No newline at end of file