private async Task <(bool result, string hint)> IsFailedInCompileStageAsync(StateMachineInstanceOutputDto statemachine, CancellationToken token) { if (statemachine.StartedActors.Count() == 1 && statemachine.StartedActors.Last().Name == "CompileActor") { var actor = statemachine.StartedActors.Last(); if (actor.Status == ManagementService.Model.Enums.ActorStatus.Failed) { return(true, string.Join(Environment.NewLine, string.Join("\r\n", actor.Exceptions), null, null)); } else { var runner = await _mgmt.ReadBlobAsObjectAsync <Runner>(actor.Outputs.Single(x => x.Name == "runner.json").Id, token); var stdout = await _mgmt.ReadBlobAsStringAsync(actor.Outputs.Single(x => x.Name == "stdout.txt").Id, token); var stderr = await _mgmt.ReadBlobAsStringAsync(actor.Outputs.Single(x => x.Name == "stderr.txt").Id, token); return(true, string.Join(Environment.NewLine, runner.Error, stdout, stderr)); } } else { return(false, statemachine.StartedActors.First(x => x.Name == "CompileActor").Outputs.Single(x => x.Name.StartsWith("Main")).Id.ToString()); } }
private async Task HandlePlainHackAsync(StateMachineInstanceOutputDto statemachine, CancellationToken token) { var hack = await _db.HackStatuses .AsNoTracking() .Include(x => x.RelatedStateMachineIds) .Include(x => x.Status) .ThenInclude(x => x.Problem) .FirstOrDefaultAsync(x => x.RelatedStateMachineIds.Any(y => y.StateMachineId == statemachine.Id), token); if (hack != null) { await HandleSingleHackAsync(statemachine.StartedActors, hack, hack.Status, hack.Status.Problem, null, token); // Refresh hack = await _db.HackStatuses .AsNoTracking() .Include(x => x.RelatedStateMachineIds) .Include(x => x.Status) .ThenInclude(x => x.Problem) .FirstOrDefaultAsync(x => x.RelatedStateMachineIds.Any(y => y.StateMachineId == statemachine.Id), token); if (!string.IsNullOrEmpty(hack.ContestId)) { var ce = _cef.Create(hack.ContestId); ce.OnHackCompleted(hack); if (ce.PushNotificationSetting == PushNotificationType.All) { _hub.Clients.All.InvokeAsync("ItemUpdated", "hack", hack.Id, hack.Status.UserId, hack.Result.ToString(), hack.Status.ProblemId); _hub.Clients.All.InvokeAsync("StandingsUpdated", hack.ContestId, hack.UserId, hack.Status.UserId); } } else { _hub.Clients.All.InvokeAsync("ItemUpdated", "hack", hack.Id, hack.Status.UserId); } } }
private async Task HandleContestHackAsync(StateMachineInstanceOutputDto statemachine, CancellationToken token) { var actors = statemachine .StartedActors .GroupBy(x => x.Tag) .ToList(); if (actors.Count > 0) { var judgeStatusId = Guid.Parse(actors.First().Key); var judge = await _db.JudgeStatuses .Include(x => x.Problem) .SingleAsync(x => x.Id == judgeStatusId, token); var problem = judge.Problem; var testCaseId = Guid.Parse(statemachine.InitialBlobs.Single(x => x.Name == "data.txt").Tag); foreach (var x in actors) { await HandleSingleHackAsync(x, null, null, problem, testCaseId, token); } } }
private async Task <IEnumerable <(int subId, JudgeResult result, int time, int memory, string hint)> > HandleRuntimeResultAsync(StateMachineInstanceOutputDto statemachine, int memoryLimit, CancellationToken token) { var runActors = statemachine.StartedActors .Where(x => x.Name == "RunUserProgramActor"); var compareActors = statemachine.StartedActors .Where(x => x.Name == "CompareActor"); var testCaseCount = GetStateMachineTestCaseCount(statemachine); if (runActors.Count() != testCaseCount) { throw new Exception("Missing RunUserProgramActor"); } var ret = new List <(int subId, JudgeResult result, int time, int memory, string hint)>(); for (var i = 0; i < testCaseCount; i++) { var actor = compareActors.SingleOrDefault(x => x.Tag == i.ToString()); if (actor == null) { actor = runActors.Single(x => x.Tag == i.ToString()); var runner = await _mgmt.ReadBlobAsObjectAsync <Runner>(actor.Outputs.Single(x => x.Name == "runner.json").Id, token); if (runner.IsTimeout) { ret.Add(( i, JudgeResult.TimeExceeded, runner.UserTime, runner.PeakMemory, string.Join(Environment.NewLine, actor.Exceptions) + Environment.NewLine + runner.Error)); } else if (runner.ExitCode == 139 || actor.Exceptions.Any(x => x.Contains("May cause by out of memory")) || runner.Error.Contains("std::bad_alloc") || runner.PeakMemory > memoryLimit) { ret.Add(( i, JudgeResult.MemoryExceeded, runner.UserTime, memoryLimit, string.Join(Environment.NewLine, actor.Exceptions) + Environment.NewLine + runner.Error)); } else { ret.Add(( i, JudgeResult.RuntimeError, runner.UserTime, runner.PeakMemory, string.Join(Environment.NewLine, actor.Exceptions) + Environment.NewLine + runner.Error + Environment.NewLine + $"User process exited with code { runner.ExitCode }")); } } else { var runActor = runActors.Single(x => x.Tag == i.ToString()); var compareRunner = await _mgmt.ReadBlobAsObjectAsync <Runner>(actor.Outputs.Single(x => x.Name == "runner.json").Id, token); var runRunner = await _mgmt.ReadBlobAsObjectAsync <Runner>(runActor.Outputs.Single(x => x.Name == "runner.json").Id, token); if (compareRunner.ExitCode == 0) { ret.Add(( i, JudgeResult.Accepted, runRunner.UserTime, runRunner.PeakMemory, "Congratulations!")); } else if (compareRunner.ExitCode == 1) { var validatorStdout = await _mgmt.ReadBlobAsStringAsync(actor.Outputs.Single(x => x.Name == "stdout.txt").Id, token); ret.Add(( i, JudgeResult.PresentationError, runRunner.UserTime, runRunner.PeakMemory, validatorStdout)); } else if (compareRunner.ExitCode == 2) { var validatorStdout = await _mgmt.ReadBlobAsStringAsync(actor.Outputs.Single(x => x.Name == "stdout.txt").Id, token); ret.Add(( i, JudgeResult.WrongAnswer, runRunner.UserTime, runRunner.PeakMemory, validatorStdout)); } else { ret.Add(( i, JudgeResult.SystemError, runRunner.UserTime, runRunner.PeakMemory, string.Join(Environment.NewLine, actor.Exceptions) + Environment.NewLine + compareRunner.Error + Environment.NewLine + $"Validator process exited with code { compareRunner.ExitCode }")); } } } return(ret); }
private int GetStateMachineTestCaseCount(StateMachineInstanceOutputDto statemachine) { return(statemachine.InitialBlobs.Where(x => x.Name.StartsWith("input_")).Count()); }