Skip to content
Snippets Groups Projects
Commit bef7705e authored by michael.minelli's avatar michael.minelli
Browse files

ExerciseResultsSanAndVal => Adapt class for optional results file

parent 4ff3846e
No related branches found
No related tags found
No related merge requests found
import { TypedEmitter } from 'tiny-typed-emitter';
import ExerciseRunningEvents from '../../types/Dojo/ExerciseRunningEvents';
import ExerciseCheckerError from '../../../shared/types/Dojo/ExerciseCheckerError';
import path from 'node:path';
import SharedExerciseHelper from '../../../shared/helpers/Dojo/SharedExerciseHelper';
import ClientsSharedConfig from '../../config/ClientsSharedConfig';
import Toolbox from '../../../shared/helpers/Toolbox';
import * as fs from 'fs-extra';
import ExerciseResultsFile from '../../../shared/types/Dojo/ExerciseResultsFile';
import JSON5 from 'json5';
class ExerciseResultsSanitizerAndValidator {
readonly events: TypedEmitter<ExerciseRunningEvents> = new TypedEmitter<ExerciseRunningEvents>();
public exerciseResults: ExerciseResultsFile = {};
private resultsFilePath: string = '';
constructor(private folderResultsDojo: string, private folderResultsExercise: string, private containerExitCode: number) { }
private async resultsFileSanitization() {
this.events.emit('step', 'RESULTS_FILE_SANITIZATION', 'Sanitizing results file');
if ( this.exerciseResults.success === undefined ) {
this.exerciseResults.success = this.containerExitCode === 0;
}
if ( this.exerciseResults.containerExitCode === undefined ) {
this.exerciseResults.containerExitCode = this.containerExitCode;
}
this.events.emit('endStep', 'RESULTS_FILE_SANITIZATION', 'Results file sanitized', false);
}
private async resultsFileProvided(): Promise<boolean> {
// Results file schema validation
{
this.events.emit('step', 'VALIDATE_RESULTS_FILE', 'Validating results file schema');
const validationResults = SharedExerciseHelper.validateResultFile(this.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, ExerciseCheckerError.EXERCISE_RESULTS_FILE_SCHEMA_NOT_VALID);
return false;
}
this.exerciseResults = validationResults.results ?? {};
this.events.emit('endStep', 'VALIDATE_RESULTS_FILE', 'Results file is valid', false);
}
// Results file content sanitization
await this.resultsFileSanitization();
// 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.folderResultsExercise);
if ( resultsFolderSize > ClientsSharedConfig.exerciseResultsFolderMaxSizeInBytes ) {
this.events.emit('endStep', 'CHECK_SIZE', `Results folder size is too big (bigger than ${ ClientsSharedConfig.exerciseResultsFolderMaxSizeInBytes / 1000000 } MB)`, true);
this.events.emit('finished', false, ExerciseCheckerError.EXERCISE_RESULTS_FOLDER_TOO_BIG);
return false;
}
this.events.emit('endStep', 'CHECK_SIZE', 'Results folder size is in bounds', false);
}
return true;
}
private async resultsFileNotProvided(): Promise<boolean> {
await this.resultsFileSanitization();
return true;
}
run() {
(async () => {
// Results file existence
this.events.emit('step', 'CHECK_RESULTS_FILE_EXIST', 'Checking if results file exists');
const resultsFileOriginPath = path.join(this.folderResultsExercise, ClientsSharedConfig.filenames.results);
this.resultsFilePath = path.join(this.folderResultsDojo, ClientsSharedConfig.filenames.results);
let result: boolean;
if ( fs.existsSync(resultsFileOriginPath) ) {
this.events.emit('endStep', 'CHECK_RESULTS_FILE_EXIST', 'Results file found', false);
result = await this.resultsFileProvided();
if ( result ) {
fs.rmSync(resultsFileOriginPath, { force: true });
} else {
fs.moveSync(resultsFileOriginPath, this.resultsFilePath, { overwrite: true });
}
} else {
this.events.emit('endStep', 'CHECK_RESULTS_FILE_EXIST', 'Results file not found', false);
result = await this.resultsFileNotProvided();
}
if ( result ) {
fs.writeFileSync(this.resultsFilePath, JSON5.stringify(this.exerciseResults), 'utf8');
this.events.emit('finished', true, 0);
}
})();
}
}
export default ExerciseResultsSanitizerAndValidator;
\ No newline at end of file
import { TypedEmitter } from 'tiny-typed-emitter';
import ExerciseRunningEvents from '../../types/Dojo/ExerciseRunningEvents';
import ExerciseCheckerError from '../../../shared/types/Dojo/ExerciseCheckerError';
import path from 'node:path';
import SharedExerciseHelper from '../../../shared/helpers/Dojo/SharedExerciseHelper';
import ClientsSharedConfig from '../../config/ClientsSharedConfig';
import Toolbox from '../../../shared/helpers/Toolbox';
import * as fs from 'fs-extra';
import ExerciseResultsFile from '../../../shared/types/Dojo/ExerciseResultsFile';
class ExerciseResultsValidation {
readonly events: TypedEmitter<ExerciseRunningEvents> = new TypedEmitter<ExerciseRunningEvents>();
public exerciseResults: ExerciseResultsFile | undefined = undefined;
constructor(private folderResultsDojo: string, private folderResultsExercise: 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.folderResultsExercise, 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, ExerciseCheckerError.EXERCISE_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 = SharedExerciseHelper.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, ExerciseCheckerError.EXERCISE_RESULTS_FILE_SCHEMA_NOT_VALID);
return;
}
this.exerciseResults = validationResults.results;
this.events.emit('endStep', 'VALIDATE_RESULTS_FILE', 'Results file is valid', 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.folderResultsExercise);
if ( resultsFolderSize > ClientsSharedConfig.exerciseResultsFolderMaxSizeInBytes ) {
this.events.emit('endStep', 'CHECK_SIZE', `Results folder size is too big (bigger than ${ ClientsSharedConfig.exerciseResultsFolderMaxSizeInBytes / 1000000 } MB)`, true);
this.events.emit('finished', false, ExerciseCheckerError.EXERCISE_RESULTS_FOLDER_TOO_BIG);
return;
}
this.events.emit('endStep', 'CHECK_SIZE', 'Results folder size is in bounds', false);
}
this.events.emit('finished', true, 0);
})();
}
}
export default ExerciseResultsValidation;
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment