diff --git a/judge/judgedaemon.main.php b/judge/judgedaemon.main.php index c8f13f427d..fa2beda90d 100644 --- a/judge/judgedaemon.main.php +++ b/judge/judgedaemon.main.php @@ -1489,6 +1489,7 @@ function judge(array $judgeTask): bool 'output_diff' => rest_encode_file($passdir . '/feedback/judgemessage.txt', $output_storage_limit), 'hostname' => $myhost, 'testcasedir' => $testcasedir, + 'compare_metadata' => rest_encode_file($passdir . '/compare.meta', false), ]; if (file_exists($passdir . '/feedback/teammessage.txt')) { diff --git a/webapp/migrations/Version20250302070928.php b/webapp/migrations/Version20250302070928.php new file mode 100644 index 0000000000..a201c5fcc5 --- /dev/null +++ b/webapp/migrations/Version20250302070928.php @@ -0,0 +1,36 @@ +addSql('ALTER TABLE judging_run_output ADD validator_metadata LONGBLOB DEFAULT NULL COMMENT \'Judging metadata of the validator(DC2Type:blobtext)\', CHANGE metadata metadata LONGBLOB DEFAULT NULL COMMENT \'Judging metadata of the run(DC2Type:blobtext)\''); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE judging_run_output DROP validator_metadata, CHANGE metadata metadata LONGBLOB DEFAULT NULL COMMENT \'Judging metadata(DC2Type:blobtext)\''); + } + + public function isTransactional(): bool + { + return false; + } +} diff --git a/webapp/src/Controller/API/JudgehostController.php b/webapp/src/Controller/API/JudgehostController.php index 705a08542d..e26ed64ad2 100644 --- a/webapp/src/Controller/API/JudgehostController.php +++ b/webapp/src/Controller/API/JudgehostController.php @@ -608,7 +608,12 @@ public function addDebugInfo( ), new OA\Property( property: 'metadata', - description: 'The (base64-encoded) metadata', + description: 'The (base64-encoded) metadata of the run', + type: 'string' + ), + new OA\Property( + property: 'compare_metadata', + description: 'The (base64-encoded) metadata of the validator', type: 'string' ), ] @@ -647,6 +652,7 @@ public function addJudgingRunAction( $teamMessage = $request->request->get('team_message'); $metadata = $request->request->get('metadata'); $testcasedir = $request->request->get('testcasedir'); + $compareMeta = $request->request->get('compare_metadata'); $judgehost = $this->em->getRepository(Judgehost::class)->findOneBy(['hostname' => $hostname]); if (!$judgehost) { @@ -654,7 +660,7 @@ public function addJudgingRunAction( } $hasFinalResult = $this->addSingleJudgingRun($judgeTaskId, $hostname, $runResult, $runTime, - $outputSystem, $outputError, $outputDiff, $outputRun, $teamMessage, $metadata, $testcasedir); + $outputSystem, $outputError, $outputDiff, $outputRun, $teamMessage, $metadata, $testcasedir, $compareMeta); $judgehost = $this->em->getRepository(Judgehost::class)->findOneBy(['hostname' => $hostname]); $judgehost->setPolltime(Utils::now()); $this->em->flush(); @@ -910,16 +916,17 @@ protected function giveBackJudging(int $judgingId, ?Judgehost $judgehost): void */ private function addSingleJudgingRun( int $judgeTaskId, - string $hostname, - string $runResult, - string $runTime, - string $outputSystem, - string $outputError, - string $outputDiff, - string $outputRun, + string $hostname, + string $runResult, + string $runTime, + string $outputSystem, + string $outputError, + string $outputDiff, + string $outputRun, ?string $teamMessage, - string $metadata, - ?string $testcasedir + string $metadata, + ?string $testcasedir, + ?string $compareMeta, ): bool { $resultsRemap = $this->config->get('results_remap'); $resultsPrio = $this->config->get('results_prio'); @@ -940,7 +947,8 @@ private function addSingleJudgingRun( $outputRun, $teamMessage, $metadata, - $testcasedir + $testcasedir, + $compareMeta ) { $judgingRun = $this->em->getRepository(JudgingRun::class)->findOneBy( ['judgetaskid' => $judgeTaskId]); @@ -962,6 +970,10 @@ private function addSingleJudgingRun( ->setOutputSystem(base64_decode($outputSystem)) ->setMetadata(base64_decode($metadata)); + if ($compareMeta) { + $judgingRunOutput->setValidatorMetadata(base64_decode($compareMeta)); + } + if ($teamMessage) { $judgingRunOutput->setTeamMessage(base64_decode($teamMessage)); } diff --git a/webapp/src/Controller/Jury/SubmissionController.php b/webapp/src/Controller/Jury/SubmissionController.php index 0927fdce0c..ee0fb74dbf 100644 --- a/webapp/src/Controller/Jury/SubmissionController.php +++ b/webapp/src/Controller/Jury/SubmissionController.php @@ -383,7 +383,7 @@ public function viewAction( ->join('t.content', 'tc') ->leftJoin('t.judging_runs', 'jr', Join::WITH, 'jr.judging = :judging') ->leftJoin('jr.output', 'jro') - ->select('t', 'jr', 'tc.image_thumb AS image_thumb', 'jro.metadata') + ->select('t', 'jr', 'tc.image_thumb AS image_thumb', 'jro.metadata', 'jro.validatorMetadata') ->andWhere('t.problem = :problem') ->setParameter('judging', $selectedJudging) ->setParameter('problem', $submission->getProblem()) diff --git a/webapp/src/Entity/JudgingRunOutput.php b/webapp/src/Entity/JudgingRunOutput.php index ac312e9565..c253a14982 100644 --- a/webapp/src/Entity/JudgingRunOutput.php +++ b/webapp/src/Entity/JudgingRunOutput.php @@ -64,10 +64,17 @@ class JudgingRunOutput #[ORM\Column( type: 'blobtext', nullable: true, - options: ['comment' => 'Judging metadata'] + options: ['comment' => 'Judging metadata of the run'] )] private ?string $metadata = null; + #[ORM\Column( + type: 'blobtext', + nullable: true, + options: ['comment' => 'Judging metadata of the validator'] + )] + private ?string $validatorMetadata = null; + public function setRun(JudgingRun $run): JudgingRunOutput { $this->run = $run; @@ -144,4 +151,15 @@ public function setMetadata(?string $metadata): self $this->metadata = $metadata; return $this; } + + public function getValidatorMetadata(): string + { + return $this->validatorMetadata; + } + + public function setValidatorMetadata(?string $validatorMetadata): self + { + $this->validatorMetadata = $validatorMetadata; + return $this; + } } diff --git a/webapp/src/Twig/TwigExtension.php b/webapp/src/Twig/TwigExtension.php index 178bd9f369..bb36469615 100644 --- a/webapp/src/Twig/TwigExtension.php +++ b/webapp/src/Twig/TwigExtension.php @@ -1228,16 +1228,31 @@ public function printMetadata(?string $metadata): string return ''; } $metadata = Utils::parseMetadata($metadata); - return '' - . ' ' - . $metadata['cpu-time'] . 's CPU, ' - . $metadata['wall-time'] . 's wall, ' - . ' ' - . Utils::printsize((int)($metadata['memory-bytes'])) . ', ' - . ' ' - . 'exit-code: ' . $metadata['exitcode'] - . (($metadata['signal'] ?? -1) > 0 ? ' signal: ' . $metadata['signal'] : '') - . ''; + $result = ''; + + if (isset($metadata['cpu-time']) || isset($metadata['wall-time'])) { + $result .= ' '; + } + + if (isset($metadata['cpu-time'])) { + $result .= $metadata['cpu-time'] . 's CPU, '; + } + if (isset($metadata['wall-time'])) { + $result .= $metadata['wall-time'] . 's wall, '; + } + if (isset($metadata['memory-bytes'])) { + $result .= ' ' + . Utils::printsize((int)($metadata['memory-bytes'])) . ', '; + } + if (isset($metadata['exitcode'])) { + $result .= ' ' + . 'exit-code: ' . $metadata['exitcode']; + } + if (isset($metadata['signal'])) { + $result .= ' signal: ' . $metadata['signal']; + } + $result .= ''; + return $result; } public function printWarningContent(ExternalSourceWarning $warning): string diff --git a/webapp/templates/jury/submission.html.twig b/webapp/templates/jury/submission.html.twig index 9a17bc6ff9..528386fff8 100644 --- a/webapp/templates/jury/submission.html.twig +++ b/webapp/templates/jury/submission.html.twig @@ -822,6 +822,21 @@ {{ runsOutput[runIdx].team_message }} {% endif %} {% endif %} + + {% if runsOutput[runIdx].validatorMetadata is not empty %} +
+
Validator metadata
+ {{ runsOutput[runIdx].validatorMetadata | printMetadata }} + +
+
{{ runsOutput[runIdx].validatorMetadata }}
+
+ + {% endif %} {% endif %}