Ejemplo n.º 1
0
        public void TestCopy()
        {
            using (NativeRunner runner = new NativeRunner(HOST, PORT))
            {
                runner.PutBlob("blob", new byte[0]);
                Assert.IsTrue(runner.HasBlob("blob"));

                runner.CopyBlob2Blob("blob", "blob2");
                Assert.IsTrue(runner.HasBlob("blob2"));
                Assert.IsTrue(runner.HasBlob("blob"));

                runner.CopyBlob2File("blob2", "file");
                Assert.IsTrue(runner.HasBlob("blob2"));
                Assert.IsTrue(runner.HasFile("file"));

                runner.CopyFile2File("file", "file2");
                Assert.IsTrue(runner.HasFile("file2"));
                Assert.IsTrue(runner.HasFile("file"));

                runner.CopyFile2Blob("file2", "blob3");
                Assert.IsTrue(runner.HasBlob("blob3"));
                Assert.IsTrue(runner.HasFile("file2"));
            }
        }
        bool DealRecord(NativeRunner tester,CHDB db, Guid recID, string desp)
        {
            var rec = (from r in db.RECORDs
                       where r.ID == recID
                       select r).FirstOrDefault();
            if (null == rec)
                return false;
            StringBuilder Detail = new StringBuilder("<h5 style=\"color: red; float: right; text-align: right\">测评机:" + desp + "</h5>");
            try
            {
                ExecuteResult ret = Compile(rec.Code, (Record.LanguageType)rec.Language, tester);
                if (ret.Type != ExecuteResultType.Success)
                {
                    rec.Status = (int)Record.StatusType.Compile_Error;
                    Detail.AppendFormat("<h5>编译失败:</h5>\r\n<pre style=\"padding-left: 10px\">\r\n{0}:<br />{1}</pre>", ret.Type.ToString(), Encoding.UTF8.GetString(tester.GetBlob(ret.ErrorBlob, 0, 10240)) + Encoding.UTF8.GetString(tester.GetBlob(ret.OutputBlob, 0, 10240)));
                    return true;
                }
                tester.MoveFile2File(commands[(Record.LanguageType)rec.Language]["execname"][0], "exec");
                string comparer = rec.PROBLEM1.Comparer == "" ? Resources.DefaultComparer : rec.PROBLEM1.Comparer;
                var comparerLanguage = rec.PROBLEM1.Comparer == "" ? Record.LanguageType.CPP : (Record.LanguageType)rec.PROBLEM1.ComparerLanguage;
                ExecuteResult CompileCMP = Compile(comparer, comparerLanguage, tester);
                if (CompileCMP.Type != ExecuteResultType.Success)
                {
                    rec.Status = (int)Record.StatusType.CMP_Error;
                    Detail.AppendFormat("<h5>比较器编译失败:</h5>\r\n<pre style=\"padding-left: 10px\">\r\n{0}{1}</pre>", ret.Type.ToString(), Encoding.UTF8.GetString(tester.GetBlob(ret.ErrorBlob)));
                    return true;
                }
                tester.MoveFile2File(commands[comparerLanguage]["execname"][0], "comparer");
                Detail.Append("<h5>各测试点详细信息:</h5>\r\n<div style=\"padding-left: 10px\">");
                int totalTests = 0;
                int passedTests = 0;
                rec.MemoryUsed = 0;
                rec.ExecutedTime = 0;
                Guid lastHunt;
                lock (ContestDaemon.HuntLst)
                {
                    string key = rec.User.ToString() + rec.Problem.ToString();
                    lastHunt = ContestDaemon.HuntLst.ContainsKey(key) ? ContestDaemon.HuntLst[key] : Guid.Empty;
                }
                foreach (var test in (from t in db.TESTDATAs
                                      where t.PROBLEM1.ID == rec.PROBLEM1.ID && (t.Available || t.ID == lastHunt)
                                      select new
                                      {
                                          t.ID,
                                          t.MemoryLimit,
                                          t.TimeLimit
                                      }).ToArray())
                {
                    totalTests++;
                    string inputName = test.ID.ToString() + "input";
                    string outputName = test.ID.ToString() + "output";
                    if (!tester.HasBlob(inputName))
                        tester.PutBlob(inputName, (from t in db.TESTDATAs
                                                   where t.ID == test.ID
                                                   select t.Input).Single());
                    if (!tester.HasBlob(outputName))
                        tester.PutBlob(outputName, (from t in db.TESTDATAs
                                                    where t.ID == test.ID
                                                    select t.Data).Single());
                    var result = tester.Execute("./exec", new string[] { }, test.MemoryLimit, test.TimeLimit, -1, RestrictionLevel.Strict, inputName);
                    int Time = result.UserTime;
                    int RealTime = result.RealTime;
                    long Memory_KB = result.Memory / 1024;
                    long Memory = result.Memory;
                    if (result.Type == ExecuteResultType.Success)
                    {
                        tester.CopyBlob2File(outputName, outputName);
                        tester.CopyBlob2File(result.OutputBlob, result.OutputBlob);
                        tester.CopyBlob2File(inputName, inputName);
                        result = tester.Execute("./comparer", new string[] { outputName, result.OutputBlob, inputName }, test.MemoryLimit, test.TimeLimit, 10240, RestrictionLevel.Strict, null);
                        switch (result.Type)
                        {
                            case ExecuteResultType.Success:
                                passedTests++;
                                rec.MemoryUsed = Math.Max((long)rec.MemoryUsed, Memory);
                                rec.ExecutedTime += Time;
                                Detail.AppendFormat("#{0}:<span class=\"score_100\"><b>通过</b></span> ({1} ms / {2} KB)<br />", totalTests, Time, Memory_KB);
                                break;
                            case ExecuteResultType.Failure:
                                switch (result.ExitStatus)
                                {
                                    case 1:
                                        rec.Status = (int)Record.StatusType.Wrong_Answer;
                                        Detail.AppendFormat("#{0}:<span class=\"score_0\"><b>答案错误</b></span> ({1} ms / {2} KB)<br />", totalTests, Time, Memory_KB);
                                        break;
                                    default:
                                        rec.Status = (int)Record.StatusType.CMP_Error;
                                        Detail.AppendFormat("#{0}:<span class=\"score_0\"><b>比较器错误:{1}</b></span> ({2} ms / {3} KB)<br />", totalTests, Encoding.UTF8.GetString(tester.GetBlob(result.OutputBlob)), Time, Memory_KB);
                                        break;
                                }
                                break;
                            default:
                                rec.Status = (int)Record.StatusType.CMP_Error;
                                Detail.AppendFormat("#{0}:<span class=\"score_0\"><b>比较器错误:{1}</b></span> ({2} ms / {3} KB)<br />", totalTests, Encoding.UTF8.GetString(tester.GetBlob(result.OutputBlob)), Time, Memory_KB);
                                break;
                        }
                        if (result.Type != ExecuteResultType.Success)
                            if (rec.PROBLEM1.CONTEST1.Type != (int)Contest.ContestType.OI)
                                break;
                    }
                    else
                    {
                        switch (result.Type)
                        {
                            case ExecuteResultType.MemoryLimitExceeded:
                                rec.Status = (int)Record.StatusType.Memory_Limit_Execeeded;
                                Detail.AppendFormat("#{0}:<span class=\"score_0\"><b>内存超过限定</b></span> ({1} ms / {2} KB)<br />", totalTests, Time, Memory_KB);
                                break;
                            case ExecuteResultType.Crashed:
                                rec.Status = (int)Record.StatusType.Runtime_Error;
                                Detail.AppendFormat("#{0}:<span class=\"score_0\"><b>运行时错误(程序崩溃)</b></span> ({1} ms / {2} KB)<br />", totalTests, Time, Memory_KB);
                                break;
                            case ExecuteResultType.MathError:
                                rec.Status = (int)Record.StatusType.Runtime_Error;
                                Detail.AppendFormat("#{0}:<span class=\"score_0\"><b>运行时错误(数学错误)</b></span> ({1} ms / {2} KB)<br />", totalTests, Time, Memory_KB);
                                break;
                            case ExecuteResultType.Failure:

                                rec.Status = (int)Record.StatusType.Runtime_Error;
                                Detail.AppendFormat("#{0}:<span class=\"score_0\"><b>运行时错误(返回值不为0)</b></span> ({1} ms / {2} KB)<br />", totalTests, Time, Memory_KB);
                                break;
                            case ExecuteResultType.MemoryAccessViolation:
                                rec.Status = (int)Record.StatusType.Runtime_Error;
                                Detail.AppendFormat("#{0}:<span class=\"score_0\"><b>运行时错误(内存不可访问)</b></span> ({1} ms / {2} KB)<br />", totalTests, Time, Memory_KB);
                                break;
                            case ExecuteResultType.Violation:
                                rec.Status = (int)Record.StatusType.Runtime_Error;
                                Detail.AppendFormat("#{0}:<span class=\"score_0\"><b>运行时错误(受限指令)</b></span> ({1} ms / {2} KB)<br />", totalTests, Time, Memory_KB);
                                break;
                            case ExecuteResultType.TimeLimitExceeded:
                                rec.Status = (int)Record.StatusType.Time_Limit_Execeeded;
                                Detail.AppendFormat("#{0}:<span class=\"score_0\"><b>超时</b></span> (Usertime={1} ms, Realtime={3} ms / {2} KB)<br />", totalTests, Time, Memory_KB,RealTime);
                                break;
                            case ExecuteResultType.OutputLimitExceeded:
                                rec.Status = (int)Record.StatusType.Output_Limit_Execeeded;
                                Detail.AppendFormat("#{0}:<span class=\"score_0\"><b>程序吐槽过多</b></span> ({1} ms / {2} KB)<br />", totalTests, Time, Memory_KB);
                                break;
                        }
                        if (rec.PROBLEM1.CONTEST1.Type != (int)Contest.ContestType.OI)
                            break;
                    }
                }
                if (totalTests == passedTests)
                {
                    rec.Status = (int)Record.StatusType.Accept;
                }
                rec.Score = (0 != totalTests ? passedTests * 100 / totalTests : 0);
                Detail.Append("</div>");
                return true;
            }
            finally
            {
                rec.Detail = Detail.ToString();
            }
        }