public void TestPutGetFile()
 {
     using (NativeRunner runner = new NativeRunner(HOST, PORT))
     {
         string data = "Hello AK";
         runner.PutFile("data", Encoding.ASCII.GetBytes(data));
         Assert.IsTrue(runner.HasFile("data"));
         Assert.AreEqual(data, Encoding.ASCII.GetString(runner.GetFile("data")));
     }
 }
 public void TestLongFile()
 {
     using (NativeRunner runner = new NativeRunner(HOST, PORT))
     {
         string longFile = "Linus大婶在slashdot上回答一些编程爱好者的提问,其中一个人问他什么样的代码是他所喜好的,大婶表述了自己一些观点之后,举了一个指针的例子,解释了什么才是core low-level coding。下面是Linus的教学原文及翻译——"
             + "“At the opposite end of the spectrum, I actually wish more people understood the really core low-level kind of coding. Not big, complex stuff like the lockless name lookup, but simply good use of pointers-to-pointers etc. For example, I’ve seen too many people who delete a singly-linked list entry by keeping track of the “prev” entry, and then to delete the entry, doing something like。(在这段话的最后,我实际上希望更多的人了解什么是真正的核心底层代码。这并不像无锁文件名查询(注:可能是git源码里的设计)那样庞大、复杂,只是仅仅像诸如使用二级指针那样简单的技术。例如,我见过很多人在删除一个单项链表的时候,维护了一个”prev”表项指针,然后删除当前表项,就像这样)”"
             + "and whenever I see code like that, I just go “This person doesn’t understand pointers”. And it’s sadly quite common.(当我看到这样的代码时,我就会想“这个人不了解指针”。令人难过的是这太常见了。)"
             + "People who understand pointers just use a “pointer to the entry pointer”, and initialize that with the address of the list_head. And then as they traverse the list, they can remove the entry without using any conditionals, by just doing a “*pp = entry->next”. (了解指针的人会使用链表头的地址来初始化一个“指向节点指针的指针”。当遍历链表的时候,可以不用任何条件判断(注:指prev是否为链表头)就能移除某个节点,只要写)"
             + "So there’s lots of pride in doing the small details right. It may not be big and important code, but I do like seeing code where people really thought about the details, and clearly also were thinking about the compiler being able to generate efficient code (rather than hoping that the compiler is so smart that it can make efficient code *despite* the state of the original source code). (纠正细节是令人自豪的事。也许这段代码并非庞大和重要,但我喜欢看那些注重代码细节的人写的代码,也就是清楚地了解如何才能编译出有效代码(而不是寄望于聪明的编译器来产生有效代码,即使是那些原始的汇编代码))。"
             + "Linus举了一个单向链表的例子,但给出的代码太短了,一般的人很难搞明白这两个代码后面的含义。正好,有个编程爱好者阅读了这段话,并给出了一个比较完整的代码。他的话我就不翻译了,下面给出代码说明。";
         runner.PutFile("code.cpp", Encoding.UTF8.GetBytes(longFile));
         Assert.AreEqual(longFile, Encoding.UTF8.GetString(runner.GetFile("code.cpp")));
     }
 }
        public void TestHas()
        {
            using (NativeRunner runner = new NativeRunner(HOST, PORT))
            {
                runner.PutBlob("blob", Encoding.ASCII.GetBytes("Hello"));
                Assert.IsTrue(runner.HasBlob("blob"));
                Assert.AreEqual("Hello", Encoding.ASCII.GetString(runner.GetBlob("blob")));

                runner.PutFile("file", Encoding.ASCII.GetBytes("Hello2"));
                Assert.IsTrue(runner.HasFile("file"));
                Assert.AreEqual("Hello2", Encoding.ASCII.GetString(runner.GetFile("file")));
            }
        }
 public void TestKeepAlive()
 {
     using (NativeRunner runner = new NativeRunner(HOST, PORT))
     {
         Thread.Sleep(6000);
         runner.PutFile("file1", new byte[3]);
         Thread.Sleep(6000);
         Assert.AreEqual(3, runner.GetFile("file1").Length);
         Thread.Sleep(6000);
     }
 }
 bool DealHunt(NativeRunner tester,CHDB db, Guid huntID, string desp)
 {
     var rec = (from h in db.HUNTs
                where h.ID == huntID
                select h).FirstOrDefault();
     if (null == rec)
         return false;
     int TimeLimit = (from t in db.TESTDATAs
                      where t.PROBLEM1.ID == rec.RECORD1.PROBLEM1.ID
                      select t).Max(x => x.TimeLimit);
     long MemoryLimit = (from t in db.TESTDATAs
                         where t.PROBLEM1.ID == rec.RECORD1.PROBLEM1.ID
                         select t).Max(x => x.MemoryLimit);
     StringBuilder Detail = new StringBuilder("<h5 style=\"color: red; float: right; text-align: right\">测评机:" + desp + "</h5>");
     try
     {
         string HuntData = null;
         ExecuteResult result;
         switch ((Record.LanguageType)rec.DataType)
         {
             default:
                 result = Compile(rec.HuntData, (Record.LanguageType)rec.DataType, tester);
                 if (result.Type != ExecuteResultType.Success)
                 {
                     rec.Status = (int)Hunt.StatusType.CompileError;
                     Detail.Append(Encoding.UTF8.GetString(tester.GetBlob(result.ErrorBlob, 0, 10240)));
                     break;
                 }
                 result = tester.Execute("./" + commands[(Record.LanguageType)rec.DataType]["execname"][0], new string[] { }, MemoryLimit, TimeLimit, 100 * 1024 * 1024, RestrictionLevel.Strict, null);
                 if (result.Type != ExecuteResultType.Success)
                 {
                     rec.Status = (int)Hunt.StatusType.BadData;
                     Detail.Append(Encoding.UTF8.GetString(tester.GetBlob(result.OutputBlob)));
                     break;
                 }
                 HuntData = result.OutputBlob;
                 break;
             case Record.LanguageType.Data:
                 tester.PutBlob(HuntData = tester.RandomString(), Encoding.UTF8.GetBytes(rec.HuntData));
                 break;
         }
         if (null == HuntData)
             return true;
         string DataChecker = rec.RECORD1.PROBLEM1.DataChecker;
         result = Compile(DataChecker, (Record.LanguageType)rec.RECORD1.PROBLEM1.DataCheckerLanguage, tester);
         if (result.Type != ExecuteResultType.Success)
         {
             rec.Status = (int)Hunt.StatusType.DataCheckerError;
             Detail.Append(Encoding.UTF8.GetString(tester.GetBlob(result.ErrorBlob)));
             return true;
         }
         result = tester.Execute("./" + commands[(Record.LanguageType)rec.RECORD1.PROBLEM1.DataCheckerLanguage]["execname"][0], new string[] { }, MemoryLimit, TimeLimit, 100 * 1024 * 1024, RestrictionLevel.Strict, HuntData);
         if (result.Type != ExecuteResultType.Success)
         {
             if (result.Type == ExecuteResultType.Failure && result.ExitStatus == 1)
                 rec.Status = (int)Hunt.StatusType.BadData;
             else
                 rec.Status = (int)Hunt.StatusType.DataCheckerError;
             Detail.Append(result.Type.ToString() + Encoding.UTF8.GetString(tester.GetBlob(result.OutputBlob)));
             return true;
         }
         string stdout = result.OutputBlob;
         result = Compile(rec.RECORD1.Code, (Record.LanguageType)rec.RECORD1.Language, tester);
         if (result.Type != ExecuteResultType.Success)
         {
             rec.Status = (int)Hunt.StatusType.OtherError;
             Detail.Append("原记录编译失败");
             return true;
         }
         result = tester.Execute("./" + commands[(Record.LanguageType)rec.RECORD1.Language]["execname"][0], new string[] { }, MemoryLimit, TimeLimit, 100 * 1024 * 1024, RestrictionLevel.Strict, HuntData);
         tester.MoveBlob2File(stdout, stdout);
         tester.MoveBlob2File(HuntData, HuntData);
         if (result.Type == ExecuteResultType.Success)
         {
             string userout = result.OutputBlob;
             string comparer = rec.RECORD1.PROBLEM1.Comparer == "" ? Resources.DefaultComparer : rec.RECORD1.PROBLEM1.Comparer;
             var comparerLanguage = rec.RECORD1.PROBLEM1.Comparer == "" ? Record.LanguageType.CPP : (Record.LanguageType)rec.RECORD1.PROBLEM1.ComparerLanguage;
             result = Compile(comparer, comparerLanguage, tester);
             if (result.Type != ExecuteResultType.Success)
             {
                 rec.Status = (int)Hunt.StatusType.OtherError;
                 Detail.Append("比较器编译失败");
                 return true;
             }
             tester.MoveBlob2File(userout, userout);
             result = tester.Execute("./" + commands[comparerLanguage]["execname"][0], new string[] { stdout, userout, HuntData }, MemoryLimit, TimeLimit, 10 * 1024, RestrictionLevel.Strict, null);
             if (result.Type == ExecuteResultType.Failure && result.ExitStatus == 1)
             {
                 var newid = Guid.NewGuid();
                 rec.RECORD1.PROBLEM1.TESTDATAs.Add(new TESTDATA()
                 {
                     ID = newid,
                     Available = false,
                     MemoryLimit = MemoryLimit,
                     TimeLimit = TimeLimit,
                     Data = tester.GetFile(stdout),
                     Input = tester.GetFile(HuntData)
                 });
                 rec.RECORD1.Status = (int)Record.StatusType.Hacked;
                 rec.Status = (int)Hunt.StatusType.Success;
                 lock (ContestDaemon.HuntLst)
                 {
                     string key = rec.RECORD1.User.ToString() + rec.RECORD1.Problem.ToString();
                     if (!ContestDaemon.HuntLst.ContainsKey(key))
                         ContestDaemon.HuntLst.Add(key, newid);
                     else
                         ContestDaemon.HuntLst[key] = newid;
                 }
                 return true;
             }
             else if (result.Type == ExecuteResultType.Success)
             {
                 rec.Status = (int)Hunt.StatusType.Fail;
                 return true;
             }
             else
             {
                 rec.Status = (int)Hunt.StatusType.OtherError;
                 Detail.Append("比较器错误");
                 return true;
             }
         }
         else
         {
             Guid newid = Guid.NewGuid();
             rec.RECORD1.PROBLEM1.TESTDATAs.Add(new TESTDATA()
             {
                 ID = newid,
                 Available = false,
                 MemoryLimit = MemoryLimit,
                 TimeLimit = TimeLimit,
                 Data = tester.GetFile(stdout),
                 Input = tester.GetFile(HuntData)
             });
             rec.RECORD1.Status = (int)Record.StatusType.Hacked;
             rec.Status = (int)Hunt.StatusType.Success;
             lock (ContestDaemon.HuntLst)
             {
                 string key = rec.RECORD1.User.ToString() + rec.RECORD1.Problem.ToString();
                 if (!ContestDaemon.HuntLst.ContainsKey(key))
                     ContestDaemon.HuntLst.Add(key, newid);
                 else
                     ContestDaemon.HuntLst[key] = newid;
             }
             return true;
         }
     }
     finally
     {
         rec.Detail = Detail.ToString();
     }
 }