예제 #1
0
        private static RunSolutionResult GetRunResult(ExerciseBlock exercise, string code)
        {
            var buildResult = exercise.BuildSolution(code);

            if (buildResult.HasErrors)
            {
                return new RunSolutionResult {
                           IsCompileError = true, ErrorMessage = buildResult.ErrorMessage, ExecutionServiceName = "uLearn"
                }
            }
            ;
            var result            = SandboxRunner.Run(exercise.CreateSubmission(Utils.NewNormalizedGuid(), code));
            var runSolutionResult = new RunSolutionResult
            {
                IsRightAnswer        = result.Verdict == Verdict.Ok && result.GetOutput().NormalizeEoln() == exercise.ExpectedOutput.NormalizeEoln(),
                ActualOutput         = result.GetOutput().NormalizeEoln(),
                ErrorMessage         = result.CompilationOutput,
                ExecutionServiceName = "this",
                IsCompileError       = result.Verdict == Verdict.CompilationError,
                ExpectedOutput       = exercise.ExpectedOutput.NormalizeEoln(),
                SubmissionId         = 0,
            };

            if (buildResult.HasStyleErrors)
            {
                runSolutionResult.IsStyleViolation = true;

                runSolutionResult.StyleMessage = string.Join("\n", buildResult.StyleErrors.Select(e => e.GetMessageWithPositions()));
            }
            return(runSolutionResult);
        }
예제 #2
0
        private static RunSolutionResult GetRunResult(AbstractExerciseBlock exercise, string code)
        {
            var buildResult = exercise.BuildSolution(code);

            if (buildResult.HasErrors)
            {
                return new RunSolutionResult {
                           IsCompileError = true, ErrorMessage = buildResult.ErrorMessage, ExecutionServiceName = "uLearn"
                }
            }
            ;
            RunSolutionResult runSolutionResult;

            if (exercise is UniversalExerciseBlock)
            {
                var result = new DockerSandboxRunner().Run(exercise.CreateSubmission(Utils.NewNormalizedGuid(), code));

                runSolutionResult = new RunSolutionResult
                {
                    IsRightAnswer        = exercise.IsCorrectRunResult(result),
                    ActualOutput         = result.GetOutput()?.NormalizeEoln() ?? "",
                    ErrorMessage         = result.CompilationOutput,
                    ExecutionServiceName = "course.exe",
                    IsCompileError       = result.Verdict == Verdict.CompilationError,
                    ExpectedOutput       = exercise.ExpectedOutput?.NormalizeEoln() ?? "",
                    SubmissionId         = 0,
                };
            }
            else
            {
                var result = new CsSandboxRunnerClient().Run(exercise.CreateSubmission(Utils.NewNormalizedGuid(), code));
                runSolutionResult = new RunSolutionResult
                {
                    IsRightAnswer        = exercise.IsCorrectRunResult(result),
                    ActualOutput         = result.GetOutput()?.NormalizeEoln() ?? "",
                    ErrorMessage         = result.CompilationOutput,
                    ExecutionServiceName = "course.exe",
                    IsCompileError       = result.Verdict == Verdict.CompilationError,
                    ExpectedOutput       = exercise.ExpectedOutput?.NormalizeEoln() ?? "",
                    SubmissionId         = 0,
                };
            }

            if (buildResult.HasStyleErrors)
            {
                runSolutionResult.IsStyleViolation = true;
                runSolutionResult.StyleMessage     = string.Join("\n", buildResult.StyleErrors.Select(e => e.GetMessageWithPositions()));
            }

            return(runSolutionResult);
        }
예제 #3
0
        protected async Task <RunSolutionResult> CheckSolution(string courseId, ExerciseSlide exerciseSlide, string userCode, string userId, string userName, bool waitUntilChecked, bool saveSubmissionOnCompileErrors)
        {
            var exerciseMetricId = GetExerciseMetricId(courseId, exerciseSlide);

            metricSender.SendCount("exercise.try");
            metricSender.SendCount($"exercise.{courseId.ToLower(CultureInfo.InvariantCulture)}.try");
            metricSender.SendCount($"exercise.{exerciseMetricId}.try");

            var course        = courseManager.GetCourse(courseId);
            var exerciseBlock = exerciseSlide.Exercise;
            var buildResult   = exerciseBlock.BuildSolution(userCode);

            if (buildResult.HasErrors)
            {
                metricSender.SendCount($"exercise.{exerciseMetricId}.CompilationError");
            }
            if (buildResult.HasStyleErrors)
            {
                metricSender.SendCount($"exercise.{exerciseMetricId}.StyleViolation");
            }

            if (!saveSubmissionOnCompileErrors)
            {
                if (buildResult.HasErrors)
                {
                    return new RunSolutionResult {
                               IsCompileError = true, ErrorMessage = buildResult.ErrorMessage, ExecutionServiceName = "uLearn"
                    }
                }
                ;
            }

            var compilationErrorMessage = buildResult.HasErrors ? buildResult.ErrorMessage : null;
            var dontRunSubmission       = buildResult.HasErrors;
            var submissionLanguage      = exerciseBlock.Language.Value;
            var submissionSandbox       = (exerciseBlock as UniversalExerciseBlock)?.DockerImageName;
            var submission = await userSolutionsRepo.AddUserExerciseSubmission(
                courseId, exerciseSlide.Id,
                userCode, compilationErrorMessage, null,
                userId, "uLearn", GenerateSubmissionName(exerciseSlide, userName),
                submissionLanguage,
                submissionSandbox,
                dontRunSubmission?AutomaticExerciseCheckingStatus.Done : AutomaticExerciseCheckingStatus.Waiting
                );

            if (buildResult.HasErrors)
            {
                return new RunSolutionResult {
                           IsCompileError = true, ErrorMessage = buildResult.ErrorMessage, SubmissionId = submission.Id, ExecutionServiceName = "uLearn"
                }
            }
            ;

            var hasAutomaticChecking = exerciseBlock.HasAutomaticChecking();
            var executionTimeout     = TimeSpan.FromSeconds(exerciseBlock.TimeLimit * 2 + 5);

            try
            {
                if (hasAutomaticChecking)
                {
                    await userSolutionsRepo.RunAutomaticChecking(submission, executionTimeout, waitUntilChecked);
                }
            }
            catch (SubmissionCheckingTimeout)
            {
                log.Error($"Не смог запустить проверку решения, никто не взял его на проверку за {executionTimeout.TotalSeconds} секунд.\nКурс «{course.Title}», слайд «{exerciseSlide.Title}» ({exerciseSlide.Id})");

                errorsBot.PostToChannel($"Не смог запустить проверку решения, никто не взял его на проверку за {executionTimeout.TotalSeconds} секунд.\nКурс «{course.Title}», слайд «{exerciseSlide.Title}» ({exerciseSlide.Id})\n\nhttps://ulearn.me/Sandbox");
                return(new RunSolutionResult
                {
                    IsCompillerFailure = true,
                    ErrorMessage = "К сожалению, из-за большой нагрузки мы не смогли оперативно проверить ваше решение. " +
                                   "Мы попробуем проверить его позже, просто подождите и обновите страницу. ",
                    ExecutionServiceName = "ulearn"
                });
            }

            if (!waitUntilChecked)
            {
                metricSender.SendCount($"exercise.{exerciseMetricId}.dont_wait_result");
                return(new RunSolutionResult {
                    SubmissionId = submission.Id
                });
            }

            /* Update the submission */
            submission = userSolutionsRepo.FindNoTrackingSubmission(submission.Id);

            if (submission.AutomaticCheckingIsRightAnswer)
            {
                await CreateStyleErrorsReviewsForSubmission(submission, buildResult.StyleErrors, exerciseMetricId);
            }

            var  automaticChecking = submission.AutomaticChecking;
            bool sentToReview;

            if (!hasAutomaticChecking)
            {
                sentToReview = await SendToReviewAndUpdateScore(submission, courseManager, slideCheckingsRepo, groupsRepo, visitsRepo, metricSender, true).ConfigureAwait(false);
            }
            else
            {
                sentToReview = slideCheckingsRepo.HasManualExerciseChecking(courseId, exerciseSlide.Id, userId, submission.Id);
            }

            var result = new RunSolutionResult
            {
                IsCompileError       = automaticChecking?.IsCompilationError ?? false,
                ErrorMessage         = automaticChecking?.CompilationError.Text ?? "",
                IsRightAnswer        = submission.AutomaticCheckingIsRightAnswer,
                ExpectedOutput       = exerciseBlock.HideExpectedOutputOnError ? null : exerciseSlide.Exercise.ExpectedOutput?.NormalizeEoln(),
                ActualOutput         = automaticChecking?.Output.Text ?? "",
                ExecutionServiceName = automaticChecking?.ExecutionServiceName ?? "ulearn",
                SentToReview         = sentToReview,
                SubmissionId         = submission.Id,
            };

            if (buildResult.HasStyleErrors)
            {
                result.IsStyleViolation = true;
                result.StyleMessage     = string.Join("\n", buildResult.StyleErrors.Select(e => e.GetMessageWithPositions()));
            }

            return(result);
        }
예제 #4
0
        protected async Task <RunSolutionResult> CheckSolution(string courseId, ExerciseSlide exerciseSlide, string userCode, string userId, string userName, bool waitUntilChecked, bool saveSubmissionOnCompileErrors)
        {
            var slideTitleForMetric = exerciseSlide.LatinTitle.Replace(".", "_").ToLower(CultureInfo.InvariantCulture);

            if (slideTitleForMetric.Length > 25)
            {
                slideTitleForMetric = slideTitleForMetric.Substring(0, 25);
            }
            var exerciseMetricId = $"{courseId.ToLower(CultureInfo.InvariantCulture)}.{exerciseSlide.Id.ToString("N").Substring(32 - 25)}.{slideTitleForMetric}";

            metricSender.SendCount("exercise.try");
            metricSender.SendCount($"exercise.{courseId.ToLower(CultureInfo.InvariantCulture)}.try");
            metricSender.SendCount($"exercise.{exerciseMetricId}.try");

            var course        = courseManager.GetCourse(courseId);
            var exerciseBlock = exerciseSlide.Exercise;
            var buildResult   = exerciseBlock.BuildSolution(userCode);

            if (buildResult.HasErrors)
            {
                metricSender.SendCount($"exercise.{exerciseMetricId}.CompilationError");
            }
            if (buildResult.HasStyleErrors)
            {
                metricSender.SendCount($"exercise.{exerciseMetricId}.StyleViolation");
            }

            if (!saveSubmissionOnCompileErrors)
            {
                if (buildResult.HasErrors)
                {
                    return new RunSolutionResult {
                               IsCompileError = true, ErrorMessage = buildResult.ErrorMessage, ExecutionServiceName = "uLearn"
                    }
                }
                ;
            }

            var compilationErrorMessage = buildResult.HasErrors ? buildResult.ErrorMessage : null;
            var dontRunSubmission       = buildResult.HasErrors;
            var submissionLanguage      = SubmissionLanguageHelpers.ByLangId(exerciseSlide.Exercise.LangId);
            var submission = await userSolutionsRepo.AddUserExerciseSubmission(
                courseId, exerciseSlide.Id,
                userCode, compilationErrorMessage, null,
                userId, "uLearn", GenerateSubmissionName(exerciseSlide, userName),
                submissionLanguage,
                dontRunSubmission?AutomaticExerciseCheckingStatus.Done : AutomaticExerciseCheckingStatus.Waiting
                );

            if (buildResult.HasErrors)
            {
                return new RunSolutionResult {
                           IsCompileError = true, ErrorMessage = buildResult.ErrorMessage, SubmissionId = submission.Id, ExecutionServiceName = "uLearn"
                }
            }
            ;

            try
            {
                if (submissionLanguage.HasAutomaticChecking())
                {
                    await userSolutionsRepo.RunAutomaticChecking(submission, executionTimeout, waitUntilChecked);
                }
            }
            catch (SubmissionCheckingTimeout)
            {
                log.Error($"Не смог запустить проверку решения, никто не взял его на проверку за {executionTimeout.TotalSeconds} секунд.\nКурс «{course.Title}», слайд «{exerciseSlide.Title}» ({exerciseSlide.Id})");

                errorsBot.PostToChannel($"Не смог запустить проверку решения, никто не взял его на проверку за {executionTimeout.TotalSeconds} секунд.\nКурс «{course.Title}», слайд «{exerciseSlide.Title}» ({exerciseSlide.Id})\n\nhttps://ulearn.me/Sandbox");
                return(new RunSolutionResult
                {
                    IsCompillerFailure = true,
                    ErrorMessage = "К сожалению, из-за большой нагрузки мы не смогли оперативно проверить ваше решение. " +
                                   "Мы попробуем проверить его позже, просто подождите и обновите страницу. ",
                    ExecutionServiceName = "uLearn"
                });
            }

            if (!waitUntilChecked)
            {
                metricSender.SendCount($"exercise.{exerciseMetricId}.dont_wait_result");
                return(new RunSolutionResult {
                    SubmissionId = submission.Id
                });
            }

            /* Update the submission */
            submission = userSolutionsRepo.FindNoTrackingSubmission(submission.Id);

            var automaticChecking = submission.AutomaticChecking;
            var isProhibitedUserToSendForReview = slideCheckingsRepo.IsProhibitedToSendExerciseToManualChecking(courseId, exerciseSlide.Id, userId);
            var sendToReview = exerciseBlock.RequireReview &&
                               submission.AutomaticCheckingIsRightAnswer &&
                               !isProhibitedUserToSendForReview &&
                               groupsRepo.IsManualCheckingEnabledForUser(course, userId);

            if (sendToReview)
            {
                await slideCheckingsRepo.RemoveWaitingManualExerciseCheckings(courseId, exerciseSlide.Id, userId);

                await slideCheckingsRepo.AddManualExerciseChecking(courseId, exerciseSlide.Id, userId, submission);

                await visitsRepo.MarkVisitsAsWithManualChecking(courseId, exerciseSlide.Id, userId);

                metricSender.SendCount($"exercise.{exerciseMetricId}.sent_to_review");
                metricSender.SendCount("exercise.sent_to_review");
            }
            await visitsRepo.UpdateScoreForVisit(courseId, exerciseSlide.Id, userId);

            if (automaticChecking != null)
            {
                var verdictForMetric = automaticChecking.GetVerdict().Replace(" ", "");
                metricSender.SendCount($"exercise.{exerciseMetricId}.{verdictForMetric}");
            }

            if (submission.AutomaticCheckingIsRightAnswer)
            {
                await CreateStyleErrorsReviewsForSubmission(submission, buildResult.StyleErrors, exerciseMetricId);
            }

            var result = new RunSolutionResult
            {
                IsCompileError       = automaticChecking?.IsCompilationError ?? false,
                ErrorMessage         = automaticChecking?.CompilationError.Text ?? "",
                IsRightAnswer        = submission.AutomaticCheckingIsRightAnswer,
                ExpectedOutput       = exerciseBlock.HideExpectedOutputOnError ? null : exerciseSlide.Exercise.ExpectedOutput.NormalizeEoln(),
                ActualOutput         = automaticChecking?.Output.Text ?? "",
                ExecutionServiceName = automaticChecking?.ExecutionServiceName ?? "ulearn",
                SentToReview         = sendToReview,
                SubmissionId         = submission.Id,
            };

            if (buildResult.HasStyleErrors)
            {
                result.IsStyleViolation = true;
                result.StyleMessage     = string.Join("\n", buildResult.StyleErrors.Select(e => e.GetMessageWithPositions()));
            }
            return(result);
        }