コード例 #1
0
        public void Run(int runId)
        {
            FudgeDataContext db = new FudgeDataContext();
            var run             = db.Runs.SingleOrDefault(r => r.RunId == runId);

            Console.WriteLine("[judge] Received run " + runId);

            long totalTime      = 0;
            long peakWorkingSet = 0;

            if (run != null)
            {
                run.Status = RunStatus.Compiling;
                db.SubmitChanges();

                int sourceCodeHandle = Host.CreateFile(run.Code);
                int executableHandle = 0;

                try {
                    executableHandle = Host.Compile(run.Language, sourceCodeHandle);
                }
                catch (CompilationErrorException ex) {
                    run.Error  = ex.Message;
                    run.Status = RunStatus.CompilationError;

                    Host.DeleteFile(sourceCodeHandle);
                    db.SubmitChanges();

                    Console.WriteLine("[judge] Judged run " + runId);

                    return;
                }

                run.Status = RunStatus.Running;
                db.SubmitChanges();

                run.ExecutionTime = 0;
                run.Memory        = 0;

                var            testCases = run.Problem.TestCases;
                List <TestRun> testRuns  = new List <TestRun>();
                bool           stop      = false;

                foreach (var testCase in testCases)
                {
                    if (stop)
                    {
                        break;
                    }

                    TestRun testRun = new TestRun();

                    testRun.TestCaseId = testCase.TestCaseId;
                    testRun.RunId      = run.RunId;
                    testRun.Output     = String.Empty;

                    try {
                        ProcessResult result = Host.Execute(executableHandle, MemoryLimit, TimeLimit, OutputLimit, String.Concat(testCase.Input.TrimEnd(null), Environment.NewLine));

                        totalTime     += result.ExecutionTime;
                        peakWorkingSet = Math.Max(peakWorkingSet, result.WorkingSet);

                        testRun.Output = result.Output.TrimEnd(null);

                        if (totalTime > TimeLimit)
                        {
                            throw new TimeLimitExceededException();
                        }

                        if (FixNewLines(testRun.Output) == FixNewLines(testCase.Output))
                        {
                            testRun.Status = TestRunStatus.Accepted;
                        }
                        else
                        {
                            testRun.Status = TestRunStatus.WrongAnswer;
                        }
                    }
                    catch (RuntimeErrorException ex) {
                        testRun.Error  = ex.Message;
                        testRun.Status = TestRunStatus.RuntimeError;
                    }
                    catch (TimeLimitExceededException) {
                        testRun.Status = TestRunStatus.TimeLimitExceeded;
                    }
                    catch (MemoryLimitExceededException) {
                        testRun.Status = TestRunStatus.MemoryLimitExceeded;
                    }
                    catch (OutputLimitExceededException) {
                        testRun.Status = TestRunStatus.OutputLimitExceeded;
                    }
                    finally {
                        if (testRun.Status == TestRunStatus.Accepted)
                        {
                            run.ExecutionTime = (int)totalTime;
                            run.Memory        = (int)peakWorkingSet;
                        }
                        else
                        {
                            testRuns.Add(testRun);

                            if (run.Type == RunType.RunUntilFail)
                            {
                                stop = true;
                            }
                        }
                    }
                }

                Host.DeleteFile(sourceCodeHandle);

                run.Status = RunStatus.Done;

                db.TestRuns.InsertAllOnSubmit(testRuns);
                db.SubmitChanges();

                if (testRuns.Count == 0 || run.Type == RunType.RunAll)
                {
                    db.sp_SubmitAcceptedRun(run.RunId);
                }

                Console.WriteLine("[judge] Judged run " + runId);
            }
            else
            {
                throw new Exception("Not a valid run");
            }
        }