2026-07-16 14:19:29 +03:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
use App\Services\External\SelfRenderLivenessProbe;
|
|
|
|
|
use Illuminate\Support\Facades\Http;
|
|
|
|
|
use Tests\TestCase;
|
|
|
|
|
|
2026-08-03 14:56:28 +03:00
|
|
|
/**
|
|
|
|
|
* Сторож живости своей рендер-виртуалки.
|
|
|
|
|
*
|
|
|
|
|
* 🔴 03.08.2026 виртуалка стала ЕДИНСТВЕННОЙ точкой отказа «Поиска клиентов»:
|
|
|
|
|
* чужой xf4.ru умер и снят. А сторож у неё был болен ровно тем же, чем сторож
|
|
|
|
|
* xf4: считал сервис живым по «ответ меньше 500». Поле `ok`, которое виртуалка
|
|
|
|
|
* честно отдаёт в `/health`, не читалось вовсе — значит зелёный не мог означать
|
|
|
|
|
* ничего, а прежний тест «зелёный при 404» этот изъян ещё и ОХРАНЯЛ.
|
|
|
|
|
*
|
|
|
|
|
* Новое правило: зелёный только когда виртуалка сама сказала `ok: true`.
|
|
|
|
|
* Молчание про `ok` — это красный, а не зелёный: раз ручка перестала отвечать
|
|
|
|
|
* так, как договаривались, мы про неё больше ничего не знаем.
|
|
|
|
|
*
|
|
|
|
|
* 🪤 Чего этот сторож НЕ доказывает: что виртуалка отрисует страницу. `ok` — её
|
|
|
|
|
* рассказ о себе. Настоящая проверка рендера стоит живой отрисовки на каждый
|
|
|
|
|
* показ плитки, и такого решения владелец не принимал.
|
|
|
|
|
*/
|
2026-07-16 14:19:29 +03:00
|
|
|
uses(TestCase::class);
|
|
|
|
|
|
2026-08-03 14:56:28 +03:00
|
|
|
/** Ответ health-ручки виртуалки — тот же вид, что она отдаёт на бою. */
|
|
|
|
|
function vmHealth(array $body, int $status = 200): void
|
|
|
|
|
{
|
|
|
|
|
config()->set('services.self_render.health_url', 'https://vm.local/health');
|
|
|
|
|
Http::fake(['vm.local/health' => Http::response($body, $status)]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
it('серый, когда адрес проверки не задан', function () {
|
|
|
|
|
config()->set('services.self_render.endpoint', 'https://vm.local/render');
|
2026-07-16 14:19:29 +03:00
|
|
|
config()->set('services.self_render.health_url', '');
|
2026-08-03 14:56:28 +03:00
|
|
|
|
|
|
|
|
// 🪤 Раньше при пустом адресе проверки сторож пинговал саму ручку рендера.
|
|
|
|
|
// Она принимает только POST и на GET отдаёт 404/405 — то есть сторож был
|
|
|
|
|
// ЗЕЛЁНЫМ навсегда. Честный ответ здесь — «проверить нечем».
|
2026-07-16 14:19:29 +03:00
|
|
|
expect((new SelfRenderLivenessProbe)->check()->light)->toBe('grey');
|
|
|
|
|
});
|
|
|
|
|
|
2026-08-03 14:56:28 +03:00
|
|
|
it('зелёный, когда виртуалка сказала ok', function () {
|
|
|
|
|
vmHealth(['ok' => true, 'active' => 0, 'max' => 8, 'proxies' => 1]);
|
|
|
|
|
|
|
|
|
|
$r = (new SelfRenderLivenessProbe)->check();
|
|
|
|
|
|
|
|
|
|
expect($r->light)->toBe('green')
|
|
|
|
|
// Числа показываем человеку: занятость и наличие прокси видно сразу,
|
|
|
|
|
// без похода на виртуалку руками.
|
|
|
|
|
->and($r->detail)->toContain('0 из 8')
|
|
|
|
|
->and($r->detail)->toContain('прокси 1');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('КРАСНЫЙ, когда виртуалка сказала ok: false', function () {
|
|
|
|
|
// Ради этого прогона всё и затевалось: раньше такой ответ был бы зелёным,
|
|
|
|
|
// потому что 200 меньше 500.
|
|
|
|
|
vmHealth(['ok' => false, 'active' => 8, 'max' => 8, 'proxies' => 0]);
|
|
|
|
|
|
|
|
|
|
expect((new SelfRenderLivenessProbe)->check()->light)->toBe('red');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('КРАСНЫЙ, когда про ok в ответе не сказано ничего', function () {
|
|
|
|
|
// Ручка ответила 200, но не тем, о чём договаривались, — значит мы про
|
|
|
|
|
// виртуалку ничего не знаем. Молчание засчитывать за «жива» нельзя.
|
2026-07-16 14:19:29 +03:00
|
|
|
config()->set('services.self_render.health_url', 'https://vm.local/health');
|
|
|
|
|
Http::fake(['vm.local/health' => Http::response('ok', 200)]);
|
2026-08-03 14:56:28 +03:00
|
|
|
|
|
|
|
|
expect((new SelfRenderLivenessProbe)->check()->light)->toBe('red');
|
2026-07-16 14:19:29 +03:00
|
|
|
});
|
|
|
|
|
|
2026-08-03 14:56:28 +03:00
|
|
|
it('КРАСНЫЙ на 404 и 405 — это GET к ручке, которая их не принимает', function () {
|
|
|
|
|
// Прежний тест требовал здесь ЗЕЛЁНЫЙ. Именно это правило сделало сторожа
|
|
|
|
|
// xf4 слепым навсегда, и его нельзя повторять.
|
|
|
|
|
vmHealth(['ok' => true], 404);
|
2026-07-16 14:19:29 +03:00
|
|
|
expect((new SelfRenderLivenessProbe)->check()->light)->toBe('red');
|
2026-08-03 14:56:28 +03:00
|
|
|
|
|
|
|
|
vmHealth(['ok' => true], 405);
|
2026-07-16 14:19:29 +03:00
|
|
|
expect((new SelfRenderLivenessProbe)->check()->light)->toBe('red');
|
|
|
|
|
});
|
2026-07-16 15:29:07 +03:00
|
|
|
|
2026-08-03 14:56:28 +03:00
|
|
|
it('красный при 500 и при сетевой ошибке', function () {
|
|
|
|
|
vmHealth(['ok' => false], 500);
|
|
|
|
|
expect((new SelfRenderLivenessProbe)->check()->light)->toBe('red');
|
|
|
|
|
|
|
|
|
|
config()->set('services.self_render.health_url', 'https://vm.local/health');
|
|
|
|
|
Http::fake(fn () => throw new RuntimeException('down'));
|
|
|
|
|
expect((new SelfRenderLivenessProbe)->check()->light)->toBe('red');
|
2026-07-16 15:29:07 +03:00
|
|
|
});
|