Пример #1
0
Файл: Gen.cs Проект: xguppy/ALS
        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)));
        }
Пример #2
0
        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("Нет доступа"));
        }