private void ProcessSubmission(Submission submission) { // TODO: Check for N+1 queries problem this.logger.InfoFormat("Work on submission №{0} started.", submission.Id); var executionStrategy = this.CreateExecutionStrategy(submission.SubmissionType.ExecutionStrategyType); var context = new ExecutionContext { SubmissionId = submission.Id, AdditionalCompilerArguments = submission.SubmissionType.AdditionalCompilerArguments, CheckerAssemblyName = submission.Problem.Checker.DllFile, CheckerParameter = submission.Problem.Checker.Parameter, CheckerTypeName = submission.Problem.Checker.ClassName, FileContent = submission.Content, AllowedFileExtensions = submission.SubmissionType.AllowedFileExtensions, CompilerType = submission.SubmissionType.CompilerType, MemoryLimit = submission.Problem.MemoryLimit, TimeLimit = submission.Problem.TimeLimit, }; context.Tests = submission.Problem.Tests.ToList().Select(x => new TestContext { Id = x.Id, Input = x.InputDataAsString, Output = x.OutputDataAsString, IsTrialTest = x.IsTrialTest }); ExecutionResult executionResult; try { executionResult = executionStrategy.Execute(context); } catch (Exception exception) { this.logger.ErrorFormat("executionStrategy.Execute on submission №{0} has thrown an exception: {1}", submission.Id, exception); submission.ProcessingComment = string.Format("Exception in executionStrategy.Execute: {0}", exception.Message); return; } submission.IsCompiledSuccessfully = executionResult.IsCompiledSuccessfully; submission.CompilerComment = executionResult.CompilerComment; if (!executionResult.IsCompiledSuccessfully) { return; } foreach (var testResult in executionResult.TestResults) { var testRun = new TestRun { CheckerComment = testResult.CheckerDetails.Comment, ExpectedOutputFragment = testResult.CheckerDetails.ExpectedOutputFragment, UserOutputFragment = testResult.CheckerDetails.UserOutputFragment, ExecutionComment = testResult.ExecutionComment, MemoryUsed = testResult.MemoryUsed, ResultType = testResult.ResultType, TestId = testResult.Id, TimeUsed = testResult.TimeUsed, }; submission.TestRuns.Add(testRun); } this.logger.InfoFormat("Work on submission №{0} ended.", submission.Id); }
public void Copy(OjsDbContext context, TelerikContestSystemEntities oldDb) { var tests = context.Tests.Select(x => new { x.Id, x.ProblemId, x.IsTrialTest, x.OrderBy }).ToList(); var count = oldDb.Submissions.Count(); const int ElementsByIteration = 500; var iterations = Math.Ceiling((decimal)count / ElementsByIteration); for (int i = 0; i < iterations; i++) { GC.Collect(); var newDb = new OjsDbContext(); newDb.Configuration.AutoDetectChangesEnabled = false; newDb.Configuration.ValidateOnSaveEnabled = false; var csharpSubmissionType = newDb.SubmissionTypes.FirstOrDefault(x => x.Name == "C# code"); var cplusPlusSubmissionType = newDb.SubmissionTypes.FirstOrDefault(x => x.Name == "C++ code"); var javaScriptSubmissionType = newDb.SubmissionTypes.FirstOrDefault(x => x.Name == "JavaScript code (NodeJS)"); oldDb = new TelerikContestSystemEntities(); var dataSource = oldDb.Submissions.AsNoTracking() .Where(x => x.Id != 127774) .OrderBy(x => x.Id) .Skip(i * ElementsByIteration) .Take(ElementsByIteration); foreach (var oldSubmission in dataSource) { var problem = newDb.Problems.FirstOrDefault(x => x.OldId == oldSubmission.Task); var participant = newDb.Participants.FirstOrDefault(x => x.OldId == oldSubmission.Participant); var submission = new Submission { Content = oldSubmission.File.ToText().Compress(), PreserveCreatedOn = true, CreatedOn = oldSubmission.SubmittedOn, Problem = problem, Participant = participant, Points = oldSubmission.Points, Processed = true, Processing = false, }; switch (oldSubmission.Language) { case "C# Code": submission.SubmissionType = csharpSubmissionType; break; case "C++ Code": submission.SubmissionType = cplusPlusSubmissionType; break; case "JavaScript Code": submission.SubmissionType = javaScriptSubmissionType; break; case "C + + 觐�": submission.SubmissionType = cplusPlusSubmissionType; break; default: submission.SubmissionType = csharpSubmissionType; break; } var reportFragments = oldSubmission.FullReport.Split( new[] { this.contentHeader }, StringSplitOptions.RemoveEmptyEntries); if (string.IsNullOrWhiteSpace(oldSubmission.FullReport) || !reportFragments.Any()) { continue; } if (reportFragments.Count() == 1) { // Some kind of exception (e.g. "not enough disk space") var errorFragments = reportFragments[0].Split( new[] { this.contentFooter }, StringSplitOptions.RemoveEmptyEntries); submission.IsCompiledSuccessfully = false; submission.CompilerComment = errorFragments[0]; } else if (!reportFragments[1].Trim().StartsWith("Compilation successfull!!!")) { submission.IsCompiledSuccessfully = false; var compilerParts = reportFragments[0].Split( new[] { "\r\n" }, 3, StringSplitOptions.RemoveEmptyEntries); submission.CompilerComment = compilerParts.Count() > 2 ? compilerParts[2].Trim(' ', '\n', '\r', '\t', '-', '=') : null; } else { submission.IsCompiledSuccessfully = true; var compilerParts = reportFragments[0].Split( new[] { "\r\n" }, 3, StringSplitOptions.RemoveEmptyEntries); submission.CompilerComment = compilerParts.Count() > 2 ? compilerParts[2].Trim(' ', '\n', '\r', '\t', '-', '=') : null; for (int j = 2; j < reportFragments.Length - 1; j++) { var testRunText = reportFragments[j].Trim(); var testRunTextParts = testRunText.Split(new[] { this.contentFooter }, StringSplitOptions.None); var testRunTitle = testRunTextParts[0].Trim(); var testRunDescription = testRunTextParts[1].Trim() + Environment.NewLine; var isZeroTest = testRunTitle.StartsWith("Zero"); var testOrderAsString = testRunTitle.GetStringBetween("�", " "); var testOrder = int.Parse(testOrderAsString); var test = tests.FirstOrDefault( x => x.ProblemId == problem.Id && x.IsTrialTest == isZeroTest && x.OrderBy == testOrder); if (test == null) { continue; } var testRun = new TestRun { MemoryUsed = 0, TimeUsed = 0, Submission = submission, TestId = test.Id, }; if (testRunDescription.StartsWith("Answer correct!!!")) { testRun.ResultType = TestRunResultType.CorrectAnswer; testRun.ExecutionComment = null; testRun.CheckerComment = null; var timeUsedAsString = testRunDescription.GetStringBetween("Time used (in milliseconds): ", "Memory used"); if (timeUsedAsString != null) { double timeUsed; if (double.TryParse(timeUsedAsString.Replace(",", ".").Trim(), out timeUsed)) { testRun.TimeUsed = (int)timeUsed; } } var memoryUsedAsString = testRunDescription.GetStringBetween( "Memory used (in bytes): ", Environment.NewLine); if (memoryUsedAsString != null) { testRun.MemoryUsed = int.Parse(memoryUsedAsString.Trim()); } } else if (testRunDescription.StartsWith("Answer incorrect!")) { testRun.ResultType = TestRunResultType.WrongAnswer; testRun.ExecutionComment = null; testRun.CheckerComment = testRunDescription.GetStringBetween( "Answer incorrect!", "Time used"); // Won't work with non-zero tests (will return null) if (testRun.CheckerComment != null) { testRun.CheckerComment = testRun.CheckerComment.Trim(); if (string.IsNullOrWhiteSpace(testRun.CheckerComment)) { testRun.CheckerComment = null; } } var timeUsedAsString = testRunDescription.GetStringBetween("Time used (in milliseconds): ", "Memory used"); if (timeUsedAsString != null) { double timeUsed; if (double.TryParse(timeUsedAsString.Replace(",", ".").Trim(), out timeUsed)) { testRun.TimeUsed = (int)timeUsed; } } var memoryUsedAsString = testRunDescription.GetStringBetween( "Memory used (in bytes): ", Environment.NewLine); if (memoryUsedAsString != null) { testRun.MemoryUsed = int.Parse(memoryUsedAsString.Trim()); } } else if (testRunDescription.StartsWith("Runtime error:")) { testRun.ResultType = TestRunResultType.RunTimeError; testRun.ExecutionComment = testRunDescription.Replace("Runtime error:", string.Empty).Trim(); testRun.CheckerComment = null; testRun.TimeUsed = 0; testRun.MemoryUsed = 0; } else if (testRunDescription.StartsWith("Time limit!")) { testRun.ResultType = TestRunResultType.TimeLimit; testRun.ExecutionComment = null; testRun.CheckerComment = null; testRun.TimeUsed = problem.TimeLimit; testRun.MemoryUsed = 0; } else { testRun.ResultType = TestRunResultType.RunTimeError; testRun.ExecutionComment = testRunDescription.Trim(); testRun.CheckerComment = null; testRun.TimeUsed = 0; testRun.MemoryUsed = 0; } newDb.TestRuns.Add(testRun); } } newDb.Submissions.Add(submission); } newDb.SaveChanges(); Console.Write("."); } }
public TestsControllerBaseTestsClass() { var firstCategory = new ContestCategory() { Id = 1, Name = "Category" }; var secondCategory = new ContestCategory() { Id = 2, Name = "Another category" }; var thirdCategory = new ContestCategory() { Id = 3, Name = "And another category" }; var contest = new Contest { Id = 1, Name = "Contest", CategoryId = 1, Category = firstCategory }; var otherContest = new Contest { Id = 2, Name = "Other contest", CategoryId = 1, Category = firstCategory }; firstCategory.Contests.Add(contest); firstCategory.Contests.Add(otherContest); var selectedProblem = new Problem { Id = 1, Name = "Problem", Contest = contest, ContestId = 1, }; var otherProblem = new Problem { Id = 2, Name = "Other problem", Contest = contest, ContestId = 1, }; var problemWithOnlyTrialTests = new Problem { Id = 3, Name = "OnlyTrialTests", Contest = contest, ContestId = 1, }; var problemWithOnlyNormalTests = new Problem { Id = 4, Name = "OnlyNormalTests", Contest = contest, ContestId = 1, }; var testRun = new TestRun() { Id = 1, TestId = 1, ResultType = TestRunResultType.CorrectAnswer, MemoryUsed = 100, TimeUsed = 100, SubmissionId = 1, ExecutionComment = "Comment execution", CheckerComment = "Comment checker", Submission = new Submission { Id = 1, CreatedOn = DateTime.Now, }, }; var test = new Test { Id = 1, InputDataAsString = "Sample test input", OutputDataAsString = "Sample test output", IsTrialTest = false, TestRuns = new HashSet<TestRun>() { testRun, }, Problem = selectedProblem, ProblemId = 1, OrderBy = 5, }; testRun.Test = test; selectedProblem.Tests.Add(test); selectedProblem.Tests.Add(new Test { InputDataAsString = "Trial input test 1", OutputDataAsString = "Trial output test 1", IsTrialTest = true, Problem = selectedProblem, ProblemId = 1, }); selectedProblem.Tests.Add(new Test { InputDataAsString = "Trial input test 2", OutputDataAsString = "Trial output test 2", IsTrialTest = true, Problem = selectedProblem, ProblemId = 1, }); problemWithOnlyTrialTests.Tests.Add(new Test { InputDataAsString = "Zero test 1\nZero test 1 second line", OutputDataAsString = "Zero test 1\nZero test 1 second lint output", IsTrialTest = true, Problem = selectedProblem, ProblemId = 1, }); for (int i = 0; i < 10; i++) { selectedProblem.Tests.Add(new Test { InputDataAsString = i.ToString(), OutputDataAsString = (i + 1).ToString(), IsTrialTest = false, Problem = selectedProblem, ProblemId = 1, }); } otherProblem.Tests.Add(new Test { InputDataAsString = "Trial input test 1 other", OutputDataAsString = "Trial output test 1 other", IsTrialTest = true, Problem = selectedProblem, ProblemId = 1, }); otherProblem.Tests.Add(new Test { InputDataAsString = "Trial input test 2 other", OutputDataAsString = "Trial output test 2 other", IsTrialTest = true, Problem = selectedProblem, ProblemId = 1, }); for (int i = 0; i < 10; i++) { otherProblem.Tests.Add(new Test { InputDataAsString = i.ToString() + "other", OutputDataAsString = (i + 1).ToString() + "other", IsTrialTest = false, Problem = selectedProblem, ProblemId = 1, }); } for (int i = 0; i < 10; i++) { problemWithOnlyNormalTests.Tests.Add(new Test { InputDataAsString = "Only normal tests " + i.ToString(), OutputDataAsString = "Only normal tests output" + i.ToString(), IsTrialTest = false, Problem = selectedProblem, ProblemId = 1, }); } contest.Problems.Add(selectedProblem); contest.Problems.Add(otherProblem); contest.Problems.Add(problemWithOnlyTrialTests); contest.Problems.Add(problemWithOnlyNormalTests); this.TestViewModel = new TestViewModel { Id = 1, InputFull = "Input test", OutputFull = "Output test", IsTrialTest = false, OrderBy = 1, ProblemId = 1, }; //// TODO: get these mocks in base class for reuse var listsOfTests = new List<Test>(selectedProblem.Tests); this.data = new Mock<IOjsData>(); this.Problems = new Mock<IDeletableEntityRepository<Problem>>(); this.Tests = new Mock<ITestRepository>(); this.TestsRuns = new Mock<ITestRunsRepository>(); this.Categories = new Mock<IDeletableEntityRepository<ContestCategory>>(); this.Contests = new Mock<IContestsRepository>(); this.Submissions = new Mock<ISubmissionsRepository>(); this.Problems.Setup(x => x.All()).Returns((new List<Problem>() { selectedProblem, otherProblem, problemWithOnlyTrialTests, problemWithOnlyNormalTests }).AsQueryable()); this.Tests.Setup(x => x.All()).Returns(listsOfTests.AsQueryable()); this.Tests.Setup(x => x.Add(It.IsAny<Test>())).Callback((Test t) => { listsOfTests.Add(t); }); this.Tests.Setup(x => x.Delete(It.IsAny<int>())).Callback((int id) => { foreach (var currentTest in listsOfTests) { if (currentTest.Id == id) { listsOfTests.Remove(currentTest); break; } } }); this.TestsRuns.Setup(x => x.All()).Returns(new List<TestRun>() { testRun }.AsQueryable()); this.Categories.Setup(x => x.All()).Returns(new List<ContestCategory>() { firstCategory, secondCategory, thirdCategory }.AsQueryable()); this.Contests.Setup(x => x.All()).Returns(new List<Contest>() { contest, otherContest }.AsQueryable()); this.data.SetupGet(x => x.Problems).Returns(this.Problems.Object); this.data.SetupGet(x => x.Tests).Returns(this.Tests.Object); this.data.SetupGet(x => x.TestRuns).Returns(this.TestsRuns.Object); this.data.SetupGet(x => x.ContestCategories).Returns(this.Categories.Object); this.data.SetupGet(x => x.Contests).Returns(this.Contests.Object); this.data.SetupGet(x => x.Submissions).Returns(this.Submissions.Object); this.TestsController = new TestsController(this.data.Object); this.ControllerContext = new ControllerContext(this.MockHttpContestBase(), new RouteData(), this.TestsController); }