Isolate invalid nodes using native error indices before bisection
This commit is contained in:
parent
3d20330ee3
commit
7f657cb017
@ -13,6 +13,7 @@ final class NativeValidator
|
||||
public array $rejected = [];
|
||||
private string $dir;
|
||||
private float $startedAt;
|
||||
private ?int $failureIndex = null;
|
||||
|
||||
public function __construct(private string $singbox, private string $mihomo, private ?array $clashTemplate = null, ?string $dataDirectory = null)
|
||||
{
|
||||
@ -47,6 +48,13 @@ final class NativeValidator
|
||||
try {
|
||||
$process->run();
|
||||
$this->checks++;
|
||||
$this->failureIndex = null;
|
||||
// Native diagnostics stay in memory. Extract only the structured node index.
|
||||
$diagnostic = $process->getErrorOutput().$process->getOutput();
|
||||
$pattern = $format === 'singbox' ? '/outbound(?:s)?\[(\d+)\]/' : '/proxy (\d+):/';
|
||||
if (!$process->isSuccessful() && preg_match($pattern, $diagnostic, $match)) {
|
||||
$this->failureIndex = (int) $match[1] - ($format === 'singbox' ? 2 : 0);
|
||||
}
|
||||
return $process->isSuccessful();
|
||||
} finally {
|
||||
@unlink($file);
|
||||
@ -67,7 +75,16 @@ final class NativeValidator
|
||||
|
||||
private function partition(string $format, array $nodes, callable $render): array
|
||||
{
|
||||
if (!$nodes || $this->check($format, $render($nodes))) return $nodes;
|
||||
if (!$nodes) return [];
|
||||
while ($nodes) {
|
||||
if ($this->check($format, $render($nodes))) return $nodes;
|
||||
$keys = array_keys($nodes);
|
||||
if ($this->failureIndex === null || !isset($keys[$this->failureIndex])) break;
|
||||
$key = $keys[$this->failureIndex];
|
||||
$this->rejected[$format][] = $key;
|
||||
unset($nodes[$key]);
|
||||
}
|
||||
if (!$nodes) return [];
|
||||
if (count($nodes) === 1) {
|
||||
$this->rejected[$format][] = array_key_first($nodes);
|
||||
return [];
|
||||
|
||||
22
tests/Unit/Freenode/NativeValidatorTest.php
Normal file
22
tests/Unit/Freenode/NativeValidatorTest.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace Tests\Unit\Freenode;
|
||||
use App\Services\Freenode\NativeValidator;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class NativeValidatorTest extends TestCase
|
||||
{
|
||||
public function testNativeErrorIndexAvoidsCheckingEveryNodeSeparately(): void
|
||||
{
|
||||
$mh = getenv('TEST_MIHOMO');
|
||||
if (!$mh) self::markTestSkipped('Set TEST_MIHOMO for native validation');
|
||||
$rows = [];
|
||||
for ($i = 0; $i < 32; $i++) {
|
||||
$rows[hash('sha256', (string) $i)] = ['name' => 'synthetic-'.$i, 'type' => 'ss', 'server' => 'example.invalid', 'port' => 443, 'cipher' => $i % 4 === 0 ? 'invalid-synthetic' : 'aes-128-gcm', 'password' => 'synthetic'];
|
||||
}
|
||||
$validator = new NativeValidator('', $mh);
|
||||
$good = $validator->filter('clash', $rows);
|
||||
self::assertCount(24, $good);
|
||||
self::assertCount(8, $validator->rejected['clash']);
|
||||
self::assertLessThanOrEqual(10, $validator->checks);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user