Files
XC_VM/tests/Unit/StreamDifferRuntimeTest.php
T
obscuremindandClaude Opus 4.8 7583a5be79 fix(cluster): compare runtime in streamDiffer + document it in the DATA contract
Two gaps from adding the runtime directive to the signed stream record:
- ReplicaApply::streamDiffer() ignored `runtime`, so a stored replica whose
  directive is missing or stale (other parts matching) read as matching and
  the shadow drift check missed an incorrect serve-only LB directive. Add
  `runtime` to the compared parts (StreamDifferRuntimeTest).
- The published DATA shape (ReplicaSections docblock + ADR 0004) omitted
  `runtime`, so an agent built to the contract could ignore/reject it. Define
  `runtime {kind, source}` in both.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EheMW763szkH4fnzzkDgT4
2026-10-17 11:07:09 +00:00

37 lines
1.4 KiB
PHP

<?php
use XcVm\Core\Cluster\ReplicaApply;
use PHPUnit\Framework\TestCase;
/**
* @covers \XcVm\Core\Cluster\ReplicaApply
*
* The shadow drift check (ReplicaApply::streamDiffer) must compare the `runtime`
* directive StreamRecords::data() now signs into every stream record. Without
* it, a stored replica whose runtime directive is missing or stale — while the
* other parts match — is reported as matching, so an incorrect serve-only LB
* directive goes undetected by shadow checks and operators.
*/
final class StreamDifferRuntimeTest extends TestCase {
/** @return list<string> */
private function differ(array $rMain, array $rData): array {
$rMethod = new \ReflectionMethod(ReplicaApply::class, 'streamDiffer');
$rMethod->setAccessible(true);
return $rMethod->invoke(null, $rMain, $rData);
}
public function testRuntimeDriftIsReported(): void {
$rBase = ['stream' => ['id' => 1], 'runtime' => ['kind' => 'proxy', 'source' => ['urls' => ['http://a/1']]]];
$this->assertSame([], $this->differ($rBase, $rBase), 'identical records do not differ');
$rChanged = $rBase;
$rChanged['runtime'] = ['kind' => 'other', 'source' => null];
$this->assertContains('runtime', $this->differ($rBase, $rChanged), 'a changed runtime directive is reported');
$rMissing = $rBase;
unset($rMissing['runtime']);
$this->assertContains('runtime', $this->differ($rBase, $rMissing), 'a missing runtime directive is reported');
}
}