Ejemplo n.º 1
0
 public Problem(ulong id, Test[] tests, ProblemFile checker, byte checkerCompilerId, DateTime lastUpdate)
 {
     Id                = id;
     Tests             = tests ?? throw new ArgumentNullException(nameof(tests));
     Checker           = checker ?? throw new ArgumentNullException(nameof(checker));
     CheckerCompilerId = checkerCompilerId;
     LastUpdate        = lastUpdate;
 }
Ejemplo n.º 2
0
 public void RemoveFile(ProblemFile file)
 {
     if (file.Content == null && file.id != null)
     {
         File.Delete(Path.Combine(directory, file.id));
     }
     else
     {
         file.Content = null;
     }
 }
Ejemplo n.º 3
0
 public void Copy(ProblemFile file, string path)
 {
     if (file.Content == null)
     {
         File.Copy(Path.Combine(directory, file.id), path, true);
     }
     else
     {
         File.WriteAllBytes(path, file.Content);
     }
 }
Ejemplo n.º 4
0
        public void SaveFile(ProblemFile file)
        {
            if (file.Content != null)
            {
                if (string.IsNullOrEmpty(file.id))
                {
                    file.id = Guid.NewGuid().ToString();
                }

                File.WriteAllBytes(
                    Path.Combine(directory, file.id),
                    file.Content);

                file.Content = null;
            }
        }
Ejemplo n.º 5
0
        private bool compileSolution(string workdir, ProblemFile solution, Compiler compiler)
        {
            string sourceFilename      = $"solution{compiler.FileExt}";
            string sourceFullPath      = Path.Combine(workdir, sourceFilename);
            string compilerLogFullPath = Path.Combine(workdir, Application.Get().Configuration.CompilerLogFileName);

            Application.Get().FileProvider.Copy(solution, sourceFullPath);

            var replacement = GenerateReplacementDictionary(
                sourceFullPath: sourceFullPath,
                sourceFilename: sourceFilename,
                binaryFullPath: Path.Combine(workdir, solutionBinaryFilename),
                binaryFilename: solutionBinaryFilename,
                workDirecrory: workdir,
                compilerLogFilename: Application.Get().Configuration.CompilerLogFileName,
                compilerLogFullPath: compilerLogFullPath
                );

            return(compile(workdir, compiler, replacement, compilerLogFullPath, false));
        }
Ejemplo n.º 6
0
        public WorkerResult Testing(Submission submission, Problem problem, ProblemFile solution)
        {
            string workdir = new DirectoryInfo(Path.Combine(Application.Get().Configuration.TestingWorkDirectory, Guid.NewGuid().ToString())).FullName;

            Directory.CreateDirectory(workdir);
            logger.Info("Slot {0} starting testing at {1}", slotNum, workdir);

            Compiler checkerCompiler  = Application.Get().Compilers.GetCompiler(problem.CheckerCompilerId);
            Compiler solutionCompiler = Application.Get().Compilers.GetCompiler(submission.CompilerId);

            string inputFileFullPath       = Path.Combine(workdir, Application.Get().Configuration.InputFileName);
            string outputFileFullPath      = Path.Combine(workdir, Application.Get().Configuration.OutputFileName);
            string answerFileFullPath      = Path.Combine(workdir, Application.Get().Configuration.AnswerFileName);
            string reportFileFullPath      = Path.Combine(workdir, Application.Get().Configuration.ReportFileName);
            string compilerLogFileFullPath = Path.Combine(workdir, Application.Get().Configuration.CompilerLogFileName);

            if (!compileChecker(workdir, problem.Checker, checkerCompiler))
            {
                SubmissionLog log = new SubmissionLog();
                log.SubmissionId = submission.Id;
                log.Type         = SubmissionLogType.Checker;
                log.Data         = File.ReadAllText(compilerLogFileFullPath);

                Application.Get().RequestMessages.Enqueue(apiClient.GetSendLogRequestMessage(log));
                return(WorkerResult.TestingError);
            }

            {
                bool          st  = compileSolution(workdir, solution, solutionCompiler);
                SubmissionLog log = new SubmissionLog();
                log.SubmissionId = submission.Id;
                log.Type         = SubmissionLogType.Source;
                log.Data         = File.ReadAllText(compilerLogFileFullPath);

                if (!string.IsNullOrWhiteSpace(log.Data))
                {
                    Application.Get().RequestMessages.Enqueue(apiClient.GetSendLogRequestMessage(log));
                }

                if (!st)
                {
                    return(WorkerResult.CompilerError);
                }
            }

            for (uint i = 0; i < problem.Tests.Length; i++)
            {
                logger.Info("Slot {0}: Starting testing test with num {1}", slotNum, problem.Tests[i].Num);

                logger.Info("Slot {0}: Preparion solution start enviroment", slotNum);
                logger.Debug("Slot {0}: Copy input file.", slotNum);
                Application.Get().FileProvider.Copy(problem.Tests[i].Input, inputFileFullPath);

                TestResult testResult = new TestResult();
                testResult.SubmissionId = submission.Id;
                testResult.TestId       = problem.Tests[i].Id;

                {
                    Tester tester = new Tester();

                    var replacement = GenerateReplacementDictionary(
                        binaryFullPath: Path.Combine(workdir, solutionBinaryFilename),
                        binaryFilename: solutionBinaryFilename,
                        workDirecrory: workdir);

                    string program = solutionCompiler.RunCommand.Program.ReplaceByDictionary(re, replacement);
                    string args    = solutionCompiler.RunCommand.Arguments.ReplaceByDictionary(re, replacement);

                    tester.SetProgram(program, $"\"{program}\" {args}");

                    tester.SetWorkDirectory(workdir);
                    tester.SetRealTimeLimit(submission.RealTimeLimit);
                    tester.SetMemoryLimit(submission.MemoryLimit);
                    tester.RedirectIOHandleToFile(IOHandleType.Input, inputFileFullPath);
                    tester.RedirectIOHandleToFile(IOHandleType.Output, outputFileFullPath);
                    tester.RedirectIOHandleToHandle(IOHandleType.Error, tester.GetIORedirectedHandle(IOHandleType.Output));

                    logger.Info("Slot {0}: Run solution", slotNum);
                    if (tester.Run(true))
                    {
                        logger.Info("Slot {0}: Solution run successfully", slotNum);
                    }
                    else
                    {
                        logger.Error("Slot {0}: Can't run solution", slotNum);
                        return(WorkerResult.TestingError);
                    }

                    var waitStatus = tester.Wait();
                    if (waitStatus == WaitingResult.Ok)
                    {
                        logger.Debug("Slot {0}: Waited successfully", slotNum);
                    }
                    else if (waitStatus == WaitingResult.Timeout)
                    {
                        testResult.UsedMemmory = tester.GetUsedResources().PeakMemoryUsageKB;
                        testResult.WorkTime    = tester.GetUsedResources().RealTimeUsageMS;

                        testResult.Result = TestingResult.TimeLimitExceeded;
                        Application.Get().RequestMessages.Enqueue(apiClient.GetSendTestingResultRequestMessage(testResult));

                        logger.Info("Slot {0}: Wait timeouted", slotNum);

                        //Not start checker
                        tester.Destroy();
                        continue;
                    }
                    else
                    {
                        logger.Error("Slot {0}: Wait failed", slotNum);
                        return(WorkerResult.TestingError);
                    }

                    uint exitCode = tester.GetExitCode();
                    if (exitCode == 0)
                    {
                        logger.Info("Slot {0}: Solution exited successfully", slotNum);
                    }
                    else
                    {
                        testResult.UsedMemmory = tester.GetUsedResources().PeakMemoryUsageKB;
                        testResult.WorkTime    = tester.GetUsedResources().CPUWorkTimeMS;

                        testResult.Result = TestingResult.RuntimeError;
                        Application.Get().RequestMessages.Enqueue(apiClient.GetSendTestingResultRequestMessage(testResult));

                        logger.Info("Slot {0}: Solution exit with code {1}", slotNum, exitCode);

                        //Not start checker
                        tester.Destroy();
                        continue;
                    }

                    testResult.UsedMemmory = tester.GetUsedResources().PeakMemoryUsageKB;
                    testResult.WorkTime    = tester.GetUsedResources().CPUWorkTimeMS;

                    tester.Destroy();
                }

                if (testResult.WorkTime > submission.TimeLimit)
                {
                    testResult.Result = TestingResult.TimeLimitExceeded;

                    Application.Get().RequestMessages.Enqueue(apiClient.GetSendTestingResultRequestMessage(testResult));

                    logger.Info("Slot {0}: Solution work {1}ms and time limit {2}ms",
                                slotNum, testResult.WorkTime, submission.TimeLimit);

                    //Not start checker
                    continue;
                }

                if (testResult.UsedMemmory > submission.MemoryLimit)
                {
                    testResult.Result = TestingResult.MemoryLimitExceeded;
                    Application.Get().RequestMessages.Enqueue(apiClient.GetSendTestingResultRequestMessage(testResult));

                    logger.Info("Slot {0}: Solution used {1}kb memory and memory limit {2}kb",
                                slotNum, testResult.UsedMemmory, submission.MemoryLimit);

                    //Not start checker
                    continue;
                }

                logger.Info("Slot {0}: Preparion checker start enviroment", slotNum);
                logger.Info("Slot {0}: Copy answer file.", slotNum);
                Application.Get().FileProvider.Copy(problem.Tests[i].Answer, answerFileFullPath);

                {
                    Tester tester = new Tester();

                    var replacement = GenerateReplacementDictionary(
                        binaryFullPath: Path.Combine(workdir, checkerBinaryFilename),
                        binaryFilename: checkerBinaryFilename,
                        workDirecrory: workdir,
                        inputFilePath: inputFileFullPath,
                        outputFilePath: outputFileFullPath,
                        answerFilePath: answerFileFullPath,
                        reportFilePath: reportFileFullPath);

                    string program = checkerCompiler.RunCommand.Program.ReplaceByDictionary(re, replacement);
                    string args    = $"{checkerCompiler.RunCommand.Arguments} {checkerCompiler.RunCommand.CheckerArguments}".
                                     ReplaceByDictionary(re, replacement);

                    tester.SetProgram(program, $"\"{program}\" {args}");

                    tester.SetWorkDirectory(workdir);
                    tester.SetRealTimeLimit(60 * 1000);
                    //tester.RedirectIOHandleToFile(IOHandleType.Output, reportFileFullPath);
                    //tester.RedirectIOHandleToHandle(IOHandleType.Error, tester.GetIORedirectedHandle(IOHandleType.Output));

                    logger.Info("Slot {0}: Run checker", slotNum);
                    if (tester.Run())
                    {
                        logger.Info("Slot {0}: Checker run successfully", slotNum);
                    }
                    else
                    {
                        logger.Error("Slot {0}: Can't run checker", slotNum);
                        return(WorkerResult.TestingError);
                    }

                    if (tester.Wait() == WaitingResult.Ok)
                    {
                        logger.Debug("Slot {0}: Waited successfully", slotNum);
                    }
                    else
                    {
                        logger.Error("Slot {0}: Wait failed", slotNum);
                        return(WorkerResult.TestingError);
                    }

                    uint exitCode = tester.GetExitCode();
                    logger.Info("Slot {0}: Checker exit with code {1}", slotNum, exitCode);

                    testResult.Result = (TestingResult)exitCode;
                    testResult.Log    = File.ReadAllText(reportFileFullPath);

                    Application.Get().RequestMessages.Enqueue(apiClient.GetSendTestingResultRequestMessage(testResult));

                    tester.Destroy();
                }
            }

            try
            {
                Directory.Delete(workdir, true);
            }
            catch (Exception ex)
            {
                logger.Error(ex, "Slot {0}: Can not delete work directory.", slotNum);
            }

            return(WorkerResult.Ok);
        }
Ejemplo n.º 7
0
 public void LoadContent(ProblemFile file)
 {
     file.Content = null;
     file.Content = File.ReadAllBytes(
         Path.Combine(directory, file.id));
 }
Ejemplo n.º 8
0
        public void Do(CancellationToken token)
        {
            Application app = Application.Get();

            while (!token.IsCancellationRequested)
            {
                var submissions = client.GetSuitableSubmissions(app.Compilers.GetCompilers());
                if (!submissions.Any())
                {
                    Thread.Sleep(app.Configuration.GetSubmissionDelayMs);
                    continue;
                }

                var submission = submissions.First();
                if (!client.SendRequest(client.GetTakeSubmissionsRequestMessage(submission.Id)))
                {
                    continue;
                }

                logger.Info("Testing slot {0} taken submission with id {1}", slotNumber, submission.Id);
                logger.Debug("Submission: {0}", submission);

                WorkerResult result = WorkerResult.Ok;

                ProblemFile solution = client.DownloadSolution(submission);
                app.FileProvider.SaveFile(solution);

                Problem problem = app.Problems.FetchProblem(
                    submission.ProblemId, submission.ProblemUpdatedAt,
                    () =>
                {
                    logger.Debug("Need download problem with id {0}", submission.ProblemId);
                    var downloadedProblem = client.DownloadProblem(submission.ProblemId);
                    if (downloadedProblem is null)
                    {
                        logger.Error("Failed to download problem with id {0}", submission.ProblemId);
                        result = WorkerResult.TestingError;
                    }

                    return(downloadedProblem);
                }
                    );

                Worker worker = new Worker(slotNumber, client);

                if (result != WorkerResult.TestingError)
                {
                    try
                    {
                        result = worker.Testing(submission, problem, solution);
                    }
                    catch (Exception ex)
                    {
                        logger.Error("Slot {0} worker testing failed with exception {1}. Error {2}", slotNumber, ex.GetType().Name, ex);
                        result = WorkerResult.TestingError;
                    }
                }

                switch (result)
                {
                case WorkerResult.Ok:
                case WorkerResult.CompilerError:
                    app.RequestMessages.Enqueue(client.GetReleaseSubmissionsRequestMessage(submission.Id, result));
                    break;

                case WorkerResult.TestingError:
                    app.RequestMessages.Enqueue(client.GetFailSubmissionsRequestMessage(submission.Id));
                    break;
                }
            }

            token.ThrowIfCancellationRequested();
        }