private async Task <bool> Compile(int lr, int var) { string name = ProcessCompiler.CreatePath(lr, var); ProcessCompiler pc = new ProcessCompiler(PathToSoulution(name), PathExecuteModel(name)); return(await Task.Run(() => pc.Execute(60000))); }
public async Task <IActionResult> Check(IFormFileCollection uploadedSources, [FromHeader] int variantId) { //Получим идентификатор юзера из его сессии var userIdentifier = int.Parse(User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value); //Проверим что вариант назначен пользователю var assignedVar = await _db.AssignedVariants.Include(aw => aw.Variant).ThenInclude(var => var.LaboratoryWork).FirstOrDefaultAsync(av => av.UserId == userIdentifier && av.VariantId == variantId); if (assignedVar != null) { //Возможно пользователь уже решил вариант var solution = await _db.Solutions.FirstOrDefaultAsync(sol => sol.AssignedVariant == assignedVar && sol.IsSolved); if (solution == null) { //Получим метод оценки var evaluation = assignedVar.Variant.LaboratoryWork.Evaluation; //Если не решил, то создадим нужные директории var solutionDirectory = CreateDirectoriesSources(assignedVar.Variant.VariantId, variantId, userIdentifier); //Cохраним его код в директорию пользователя await SaveSources(solutionDirectory, uploadedSources); //Создаём новое решение solution = new Solution { AssignedVariant = assignedVar, IsSolved = true, SendDate = DateTime.Now, SourceCode = solutionDirectory, IsCompile = true }; //Возьмём пути для исполняемых файлов var programFileUser = CreateExecuteDirectories(assignedVar.Variant.VariantId, variantId, userIdentifier); var programFileModel = new Uri((await _db.Variants.FirstOrDefaultAsync(var => var.VariantId == variantId)).LinkToModel).AbsolutePath; //Создадим директорию для запуска эталонной программы программы var moveModelProgram = Path.Combine(Environment.CurrentDirectory, "modelTestingFiled", $"{userIdentifier}_{variantId}"); Directory.CreateDirectory(moveModelProgram); //Новая файл в директории var newPathProgram = Path.Combine(moveModelProgram, Path.GetFileName(programFileModel)); System.IO.File.Copy(programFileModel, newPathProgram, true); //Скомпилируем программу пользователя var compiler = new ProcessCompiler(solutionDirectory, programFileUser); var isCompile = await compiler.Execute(10000); var extractUserDirectory = new DirectoryInfo(programFileUser).Parent.FullName; //Если не скомпилировалась заносим, то в последнее решение добавим информацию что программа пользователя не была скомпилированна if (isCompile != true) { solution.IsCompile = false; solution.IsSolved = false; await _db.Solutions.AddAsync(solution); DeleteProgramsDirectories(extractUserDirectory, moveModelProgram); await _db.SaveChangesAsync(); var result = compiler.CompileState; //Удалим показанный путь программы return(BadRequest(result.Replace(solutionDirectory, null))); } //Прогоним по тестам List <ResultRun> resultTests; string[] testNames; double[] weights; try { //Получим входные данные для задачи var gen = new Gen(); // testData: класс Test с полями Name, Data, Weight // имя вес данные | если нужные еще какие-либо данные // test [30] : #случайноеЦелое(10,20,10) | n; var testData = gen.GetTestsFromJson(assignedVar.Variant.InputDataRuns); testNames = testData.Select(td => td.Name).ToArray(); weights = testData.Select(td => td.Weight).ToArray(); //Получим ограничения лабы var constrainsLab = JsonConvert.DeserializeObject <Constrains>( assignedVar.Variant.LaboratoryWork.Constraints, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Populate }); var variantConstrainsJson = assignedVar.Variant.Constraints; if (variantConstrainsJson != null) { //Получим ограничения варианта var constrainsVar = JsonConvert.DeserializeObject <Constrains>( assignedVar.Variant.Constraints, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Populate }); //Перезапишем ограничениями лабы ограничениями варианта(которые доступны) constrainsLab = OverridingConstrains(constrainsLab, constrainsVar); } var verification = new Verification(programFileUser, newPathProgram, constrainsLab); resultTests = await verification.RunTests(testData.Select(t => t.Data).ToList()); } catch (Exception e) { //Если произошло что-то не хорошее, то не будем понапрасну тратить драгоценные байты хранилища и удали исходные коды пользователя Directory.Delete(solutionDirectory, true); return(BadRequest(e.Message)); } finally { //В любом случае удалим директорию пользователя с исполняемым файлом и директорию с моделью DeleteProgramsDirectories(extractUserDirectory, moveModelProgram); } //Сохраним сейчас чтобы добавить тестовые прогоны в БД await _db.Solutions.AddAsync(solution); await _db.SaveChangesAsync(); var counterName = 0; foreach (var result in resultTests) { var testRun = new TestRun { Name = testNames[counterName++], InputData = result.Input.ToArray(), OutputData = result.Output.ToArray(), ResultRun = JsonConvert.SerializeObject(new { result.Time, result.Memory, result.IsCorrect, result.Comment }), SolutionId = solution.SolutionId }; await _db.TestRuns.AddAsync(testRun); } var countCompleteTest = resultTests.Count(rt => rt.IsCorrect); solution.IsSolved = Rate(evaluation, resultTests, weights, out var currMark); assignedVar.Mark = currMark; await _db.SaveChangesAsync(); //Выведем количество верных тестовых прогонов и комментарии к ним return(Ok($"{countCompleteTest} / {resultTests.Count} тестов пройдено.{FormattingResultLog(resultTests, testNames)}")); } return(Ok("Задача уже решена")); } return(BadRequest("Нет доступа")); }