Exemple #1
0
 public void GradeAll()
 {
     if (IsGrading)
     {
         throw new JudgeIsGradingException();
     }
     new Thread(new ThreadStart(() =>
     {
         IsGrading              = true;
         List <string> users    = userModel.GetListUsernames();
         List <string> problems = problemModel.GetListProblemnames();
         Totaltestcases         = TestcasesGraded = 0;
         for (int i = 0; i < problems.Count; ++i)
         {
             Totaltestcases += problemModel[problems[i]].Testcases.Count;
         }
         Totaltestcases *= users.Count;
         for (int i = 0; i < users.Count; ++i)
         {
             for (int j = 0; j < problems.Count; ++j)
             {
                 double totalScore = GradeOneSubmission(problems[j], users[i], out JudgeUpdateScoreType status);
                 if (!IsGrading)
                 {
                     i = users.Count;
                     j = problems.Count;
                     ///break all
                 }
                 else
                 {
                     OnUpdateScore?.Invoke(this, new JudgeUpdateScoreSubmissionEvent()
                     {
                         Points      = totalScore,
                         ProblemName = problems[j],
                         UserName    = users[i],
                         Status      = status
                     });
                 }
             }
         }
         IsGrading = false;
         OnGradeStatusChanged?.Invoke(this, new JudgeGradingEvent()
         {
             Event = JudgeGradingEventType.Complete
         });
     })).Start();
 }
Exemple #2
0
 public void GradeUser(string userName)
 {
     if (!userModel.Contains(userName))
     {
         throw new JudgeUserNotFoundException(userName);
     }
     userName = userModel[userName].UserName; //exactly name
     if (IsGrading)
     {
         throw new JudgeIsGradingException();
     }
     new Thread(new ThreadStart(() =>
     {
         IsGrading = true;
         List <string> listProblems = problemModel.GetListProblemnames();
         Totaltestcases             = TestcasesGraded = 0;
         foreach (Problem p in problemModel.GetProblems())
         {
             Totaltestcases += p.Testcases.Count;
         }
         foreach (string problemName in listProblems)
         {
             double totalScore = GradeOneSubmission(problemName, userName, out JudgeUpdateScoreType status);
             if (!IsGrading)
             {
                 break;
             }
             else
             {
                 OnUpdateScore?.Invoke(this, new JudgeUpdateScoreSubmissionEvent()
                 {
                     Points      = totalScore,
                     ProblemName = problemName,
                     UserName    = userName,
                     Status      = status
                 });
             }
         }
         IsGrading = false;
         OnGradeStatusChanged?.Invoke(this, new JudgeGradingEvent()
         {
             Event = JudgeGradingEventType.Complete
         });
     })).Start();
 }
Exemple #3
0
 public void GradeSubmission(string problemName, string userName)
 {
     if (!problemModel.Contains(problemName))
     {
         throw new JudgeProblemNotFoundExpcetion(problemName);
     }
     if (!userModel.Contains(userName))
     {
         throw new JudgeUserNotFoundException(userName);
     }
     Totaltestcases = TestcasesGraded = 0;
     Totaltestcases = problemModel[problemName].Testcases.Count;
     problemName    = problemModel[problemName].ProblemName;
     userName       = userModel[userName].UserName; //exactly name
     if (IsGrading)
     {
         throw new JudgeIsGradingException();
     }
     new Thread(new ThreadStart(() =>
     {
         IsGrading         = true;
         double totalScore = GradeOneSubmission(problemName, userName, out JudgeUpdateScoreType status);
         if (IsGrading)
         {
             OnUpdateScore?.Invoke(this, new JudgeUpdateScoreSubmissionEvent()
             {
                 Points      = totalScore,
                 ProblemName = problemName,
                 UserName    = userName,
                 Status      = status
             });
         }
         IsGrading = false;
         OnGradeStatusChanged?.Invoke(this, new JudgeGradingEvent()
         {
             Event = JudgeGradingEventType.Complete
         });
     })).Start();
 }
Exemple #4
0
        private double GradeOneSubmission(string problemName, string userName, out JudgeUpdateScoreType status)
        {
            status = JudgeUpdateScoreType.OK;
            int total = problemModel[problemName].Testcases.Count;

            //Remove old submission
            judgeModel.RemoveSubmission(problemName, userName);
            OnUpdateScore?.Invoke(this, new JudgeUpdateScoreSubmissionEvent()
            {
                ProblemName = problemName,
                UserName    = userName,
                Status      = JudgeUpdateScoreType.RemoveSubmission,
                Points      = 0,
            });

            OnGradeStatusChanged?.Invoke(this, new JudgeGradingEvent()
            {
                Event       = JudgeGradingEventType.BeginGradingSubmission,
                ProblemName = problemName,
                UserName    = userName
            });
            //--------------- check submission existed & get user, problem object
            User    user    = userModel[userName];
            Problem problem = problemModel[problemName];
            List <UserSubmission> submissions = user.GetSubmission(problemName);

            if (submissions.Count == 0)
            {
                //Submission not found
                OnGradeStatusChanged?.Invoke(this, new JudgeGradingEvent()
                {
                    Event       = JudgeGradingEventType.SubmissionNotFound,
                    UserName    = userName,
                    ProblemName = problemName
                });
                TestcasesGraded += total;
                judgeModel.CreateNewSubmission(problemName, userName, "Not found submission!", "MS", "(null)");
                status = JudgeUpdateScoreType.SubmissionNotFound;
                return(0);
            }

            //--------------- make directory
            string currentDir        = FS.Combine(workSpace, DateTime.Now.Ticks.ToString());
            string currentUserDir    = FS.Combine(currentDir, user.UserName);
            string currentProblemDir = FS.Combine(currentDir, problem.ProblemName);
            string inputRun          = FS.Combine(currentProblemDir, "input.txt");

            FS.CreateDirectory(currentDir);
            FS.CreateDirectory(currentUserDir);
            FS.CreateDirectory(currentProblemDir);
            FS.CreateEmptyFile(inputRun);

            Compiler       compiler      = null;
            UserSubmission submission    = null;
            CompileStatus  compileResult = null;

            //--------------- compile
            foreach (UserSubmission sub in submissions)
            {
                submission = sub;
                string userSourceCode = FS.Combine(userModel.UserDirectory, userName, sub.ToString());

                string newSource = FS.Combine(currentUserDir, sub.ToString());
                FS.CopyFile(userSourceCode, newSource);

                if (!compilerManager.Contains(sub.Extension))
                {
                    continue;
                }
                List <Compiler> compilers = compilerManager[sub.Extension];
                bool            found     = false;
                foreach (Compiler com in compilers)
                {
                    compiler = com;

                    OnGradeStatusChanged.Invoke(this, new JudgeGradingEvent()
                    {
                        Event       = JudgeGradingEventType.Compiling,
                        Status      = com.Name,
                        UserName    = userName,
                        ProblemName = problemName
                    });

                    compileResult = com.Compile(sandbox, sub.ToString(), currentUserDir);

                    if (!IsGrading) //cancel
                    {
                        FS.DeleteDirectory(currentDir);
                        TestcasesGraded += total;
                        return(0);
                    }

                    if (compileResult.Success)
                    {
                        found = true;
                        break;
                    }
                }
                if (found)
                {
                    break;
                }
            }
            if (compiler == null)
            {
                //Submission not found
                OnGradeStatusChanged?.Invoke(this, new JudgeGradingEvent()
                {
                    Event       = JudgeGradingEventType.CompilerNotFound,
                    UserName    = userName,
                    ProblemName = problemName
                });
                TestcasesGraded += total;
                judgeModel.CreateNewSubmission(problemName, userName, "Not found submission!", "MS", "(null)");
                status = JudgeUpdateScoreType.CompilerNotFound;
                return(0);
            }

            if (!compileResult.Success)
            {
                //Compile error
                OnGradeStatusChanged?.Invoke(this, new JudgeGradingEvent()
                {
                    Status      = compileResult.Message,
                    UserName    = userName,
                    ProblemName = problemName,
                    Event       = JudgeGradingEventType.CompileError
                });
                TestcasesGraded += total;
                FS.DeleteDirectory(currentDir);
                judgeModel.CreateNewSubmission(problemName, userName, compileResult.Message, "CE", compiler.Name);
                status = JudgeUpdateScoreType.CompileError;
                return(0);
            }

            //OK
            OnGradeStatusChanged.Invoke(this, new JudgeGradingEvent()
            {
                Event       = JudgeGradingEventType.CompileSuccessfully,
                UserName    = userName,
                ProblemName = problemName,
                Status      = compiler.Name
            });

            //Check execute exist
            if (!FS.FileExist(FS.Combine(currentUserDir, compileResult.OutputFileName)))
            {
                OnGradeStatusChanged?.Invoke(this, new JudgeGradingEvent()
                {
                    ProblemName = problemName,
                    UserName    = userName,
                    Event       = JudgeGradingEventType.SubmissionNotFound
                });
                OnGradeStatusChanged?.Invoke(this, new JudgeGradingEvent()
                {
                    ProblemName = problemName,
                    UserName    = userName,
                    Event       = JudgeGradingEventType.NotFoundExecute
                });
                judgeModel.CreateNewSubmission(problemName, userName, "Not found execute", "NFE", compiler.Name);
                status = JudgeUpdateScoreType.ExecuteNotFound;
                return(0);
            }

            //3. Run testcase
            List <SubmissionTestcaseResult> gradingTestcaseResult = new List <SubmissionTestcaseResult>();

            foreach (Testcase test in problem.Testcases)
            {
                OnGradeStatusChanged?.Invoke(this, new JudgeGradingEvent()
                {
                    Event = JudgeGradingEventType.BeginRunTest
                });
                string currentTestDir = FS.Combine(currentProblemDir, test.TestcaseName);
                string sourceInput    = FS.Combine(problem.ParentDirectory, problem.ProblemName, test.TestcaseName, problem.Input);
                string sourceOutput   = FS.Combine(problem.ParentDirectory, problem.ProblemName, test.TestcaseName, problem.Output);
                string destOutput     = FS.Combine(currentTestDir, problem.Output);

                //create testcase directory
                FS.CreateDirectory(currentTestDir);

                //copy execute
                FS.CopyFile(FS.Combine(currentUserDir, compileResult.OutputFileName),
                            FS.Combine(currentTestDir, compileResult.OutputFileName));

                //copy input
                if (!problem.UseStdin)
                {
                    string destInput = FS.Combine(currentTestDir, problem.Input);
                    FS.CopyFile(sourceInput, destInput);
                }

                //run
                var running_status = sandbox.StartRun(-1,
                                                      ('"' + compiler.RunProgram + '"' + " " + compiler.RunArgs).Replace("$NAME$", submission.Name),
                                                      currentTestDir,
                                                      problem.Timelimit,
                                                      problem.Memorylimit * 1024,
                                                      problem.UseStdin ? sourceInput : inputRun,
                                                      problem.UseStdout ? destOutput : null,
                                                      TreatExitCodeNonZeroAsRTE
                                                      );

                if (!IsGrading) //cancel
                {
                    TestcasesGraded += total;
                    FS.DeleteDirectory(currentDir);
                    return(0);
                }
                TestcasesGraded++;
                total--;

                string grading_status = running_status.Status.ToString();
                double points         = 0.0;
                int    timeExecute    = running_status.TimeExecuted;
                int    memUsed        = running_status.MemoryUsed;

                //check
                if (running_status.ExitCode != 0)
                {
                    if (running_status.Status == SandBoxStatusType.TLE)
                    {
                        OnGradeStatusChanged?.Invoke(this, new JudgeGradingEvent()
                        {
                            Event        = JudgeGradingEventType.EndRunTest,
                            ProblemName  = problemName,
                            UserName     = userName,
                            TestCaseName = test.TestcaseName,
                            TimeExecuted = timeExecute,
                            Status       = "TLE"
                        });
                    }
                    else if (running_status.Status == SandBoxStatusType.MLE)
                    {
                        OnGradeStatusChanged?.Invoke(this, new JudgeGradingEvent()
                        {
                            Event        = JudgeGradingEventType.EndRunTest,
                            ProblemName  = problemName,
                            UserName     = userName,
                            TestCaseName = test.TestcaseName,
                            Status       = "MLE"
                        });
                    }
                    else if (running_status.Status == SandBoxStatusType.RTE)
                    {
                        OnGradeStatusChanged?.Invoke(this, new JudgeGradingEvent()
                        {
                            Event        = JudgeGradingEventType.EndRunTest,
                            ProblemName  = problemName,
                            UserName     = userName,
                            TestCaseName = test.TestcaseName,
                            Status       = "RTE"
                        });
                    }
                    else if (running_status.Status == SandBoxStatusType.UnknownError)
                    {
                        OnGradeStatusChanged?.Invoke(this, new JudgeGradingEvent()
                        {
                            Event        = JudgeGradingEventType.EndRunTest,
                            ProblemName  = problemName,
                            UserName     = userName,
                            TestCaseName = test.TestcaseName,
                            Status       = "Unknown"
                        });
                    }
                    else
                    {
                        throw new Exception("JUDGER ERROR");
                    }
                }
                else
                {
                    //if run ok -> copy output & rename
                    FS.CopyFile(sourceOutput, destOutput + "$");

                    //check result
                    bool checker_result = checker.Compare(problem.Checker, problem.Output, problem.Output + "$", currentTestDir);

                    if (checker_result)
                    {
                        grading_status = "AC";
                        points         = test.Point;
                    }
                    else
                    {
                        grading_status = "WA";
                    }
                    OnGradeStatusChanged?.Invoke(this, new JudgeGradingEvent()
                    {
                        Event        = JudgeGradingEventType.EndRunTest,
                        MemoryUsed   = memUsed,
                        TimeExecuted = timeExecute,
                        Status       = grading_status,
                        Points       = points,
                        TestCaseName = test.TestcaseName,
                        ProblemName  = problemName,
                        UserName     = userName,
                    });
                }

                gradingTestcaseResult.Add(new SubmissionTestcaseResult()
                {
                    ProblemName  = problemName,
                    UserName     = userName,
                    TestcaseName = test.TestcaseName,
                    Points       = points,
                    MemoryUsed   = memUsed,
                    TimeExecuted = timeExecute,
                    Status       = grading_status
                });
            }

            //update status to database & calc score
            double totalScore    = 0;
            int    submission_id = judgeModel.CreateNewSubmission(problemName, userName, compileResult.Message, "OK", compiler.Name);

            foreach (SubmissionTestcaseResult r in gradingTestcaseResult)
            {
                if (r.Status == "AC")
                {
                    judgeModel.UpdateLanguageTimeGrading(compiler.Name, r.TimeExecuted);
                }
                judgeModel.UpdateStatus(submission_id, r.TestcaseName,
                                        r.Points, r.Status, r.TimeExecuted, r.MemoryUsed);
                totalScore += r.Points;
            }

            //4. Clean
            FS.DeleteDirectory(currentDir);
            OnGradeStatusChanged?.Invoke(this, new JudgeGradingEvent()
            {
                Event = JudgeGradingEventType.EndGradingSubmission
            });
            status = JudgeUpdateScoreType.OK;
            return(totalScore);
        }