修复
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
use app\adminapi\service\AssistantSseTiming;
|
||||
|
||||
$checks = 0;
|
||||
function r39TimingExpect(bool $condition, string $message): void
|
||||
{
|
||||
global $checks;
|
||||
++$checks;
|
||||
if (!$condition) {
|
||||
throw new RuntimeException($message);
|
||||
}
|
||||
}
|
||||
|
||||
$timing = new AssistantSseTiming();
|
||||
$codes = [
|
||||
'TCM_FACT_STATE_CONFLICT', 'TCM_REPORT_INCOMPLETE', 'TASK_ANALYSIS_MISSING',
|
||||
'STREAM_CONTENT_MISMATCH', 'UPSTREAM_CLEANUP_PENDING',
|
||||
];
|
||||
foreach (['upstream_done', 'sse_done'] as $phase) {
|
||||
foreach ($codes as $code) {
|
||||
$event = $timing->event($phase, [
|
||||
'status' => 'error', 'error_code' => $code,
|
||||
'patient_id' => 123456, 'patient_name' => 'PRIVATE_PATIENT',
|
||||
'content' => 'PRIVATE_MODEL_BODY',
|
||||
'clinical_fact_state_issues' => ['UNKNOWN_TO_POSITIVE:PRIVATE_SOURCE'],
|
||||
'token' => 'PRIVATE_TOKEN',
|
||||
]);
|
||||
r39TimingExpect(($event['error_code'] ?? null) === $code,
|
||||
'Existing failure code must survive at ' . $phase . ': ' . $code);
|
||||
r39TimingExpect(($event['status'] ?? null) === 'error' && $event['trace_id'] === $timing->id(),
|
||||
'Failure status and request trace must remain paired');
|
||||
r39TimingExpect(array_keys($event) === ['trace_id', 'phase', 'request_elapsed_ms', 'status', 'error_code'],
|
||||
'Diagnostic addition must not retain clinical text, identities or credentials');
|
||||
}
|
||||
}
|
||||
foreach (['TCM_FACT_STATE_CONFLICT PRIVATE_MODEL_BODY', 'UNKNOWN_TO_POSITIVE:PRIVATE_SOURCE',
|
||||
'UNKNOWN_ERROR', 'UPSTREAM_CLEANUP_PENDING\nPRIVATE_TOKEN', [], 123, null] as $bad) {
|
||||
r39TimingExpect(!array_key_exists('error_code', $timing->event('sse_done', ['error_code' => $bad])),
|
||||
'Unlisted or untyped diagnostic values must still be discarded');
|
||||
}
|
||||
|
||||
// Exercise the actual buffered log channel used by the SSE timing writer.
|
||||
$app = new \think\App(dirname(__DIR__) . '/');
|
||||
$directory = sys_get_temp_dir() . '/zyt-r39-timing-' . bin2hex(random_bytes(8));
|
||||
$app->config->set(['default' => 'r39', 'channels' => ['r39' => [
|
||||
'type' => 'File', 'path' => $directory, 'single' => 'timing', 'realtime_write' => false,
|
||||
]]], 'log');
|
||||
$app->make('log');
|
||||
$file = $directory . '/timing.log';
|
||||
try {
|
||||
foreach ($codes as $code) {
|
||||
$timing->log('sse_done', ['status' => 'error', 'error_code' => $code,
|
||||
'content' => 'PRIVATE_MODEL_BODY', 'token' => 'PRIVATE_TOKEN']);
|
||||
}
|
||||
$logged = is_file($file) ? (string) file_get_contents($file) : '';
|
||||
foreach ($codes as $code) {
|
||||
r39TimingExpect(str_contains($logged, '"error_code":"' . $code . '"'),
|
||||
'SSE exit path must persist the concrete safe code: ' . $code);
|
||||
}
|
||||
r39TimingExpect(str_contains($logged, $timing->id())
|
||||
&& !str_contains($logged, 'PRIVATE_MODEL_BODY') && !str_contains($logged, 'PRIVATE_TOKEN'),
|
||||
'Persisted failure remains correlatable and contains no raw payload');
|
||||
} finally {
|
||||
if (is_file($file)) unlink($file);
|
||||
if (is_dir($directory)) rmdir($directory);
|
||||
}
|
||||
|
||||
echo 'R39 timing error code checks: ' . $checks . " passed\n";
|
||||
Reference in New Issue
Block a user