A --parallel eddig két okból nem működött volna: 1. A setUp() a parent::setUp() ELŐTT hívja a refreshApplication()-t, hogy a DB nevét a RefreshDatabase előtt ellenőrizhesse. A Laravel viszont a ParallelTesting::callSetUpTestCaseCallbacks()-ot csak az "if (! $this->app)" ágban futtatja (InteractsWithTestCaseLifecycle), ami így kimaradt - a processzenkénti adatbázis sosem jött létre, minden processz a közös d2dTest-et migrálta volna egyszerre. A callbacket most magunk hívjuk meg; nem párhuzamos futásnál no-op. 2. A névellenőrzés pontos "d2dtest" egyezést várt, és eltérésnél nem hibát dobott, hanem VISSZAÍRTA a configot d2dTest-re - vagyis csendben közös adatbázisra terelte volna a processzeket. A név mostantól a /^d2dtest(_test_\d+)?$/ mintát követi, ami a Laravel TestDatabases::testDatabase() elnevezését fedi le. Szándékosan nem str_starts_with($db, 'd2d'): az átengedné az éles adatbázist is. Az éles d2d elleni azonnali exit(1) változatlan. Ellenőrizve: tiszta lapról a párhuzamos futás létrehozta a d2dtest_test_1..6 adatbázisokat, a sima futás változatlanul működik. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
78 lines
3.2 KiB
PHP
78 lines
3.2 KiB
PHP
<?php
|
|
|
|
namespace Tests;
|
|
|
|
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
|
|
use Illuminate\Support\Facades\ParallelTesting;
|
|
|
|
abstract class TestCase extends BaseTestCase
|
|
{
|
|
protected function setUp(): void
|
|
{
|
|
if (! $this->app) {
|
|
$this->refreshApplication();
|
|
|
|
// A Laravel ezt a saját setUp()-jában csak akkor hívja meg, ha ŐT hozta létre az
|
|
// alkalmazást (InteractsWithTestCaseLifecycle: "if (! $this->app)"). Mi viszont
|
|
// előbb bootolunk - hogy a DB nevét a RefreshDatabase ELŐTT ellenőrizhessük -,
|
|
// ezért ott az az ág kimaradna, és a --parallel processzenkénti adatbázisa sosem
|
|
// jönne létre: minden processz a közös d2dTest-et migrálná egyszerre.
|
|
// Nem párhuzamos futásnál ez no-op (whenRunningInParallel).
|
|
ParallelTesting::callSetUpTestCaseCallbacks($this);
|
|
}
|
|
|
|
$this->guardTestDatabase();
|
|
|
|
parent::setUp();
|
|
}
|
|
|
|
/**
|
|
* Megakadályozza, hogy a tesztek az éles adatbázison fussanak.
|
|
*
|
|
* A parent::setUp() ELŐTT kell lefutnia: a RefreshDatabase feltétel nélkül eldobja
|
|
* a táblákat, tehát utólag ellenőrizni már késő lenne.
|
|
*/
|
|
private function guardTestDatabase(): void
|
|
{
|
|
$database = (string) config('database.connections.mysql.database');
|
|
|
|
// SZIGORÚ ELLENŐRZÉS: A 'd2d' adatbázist SOHA nem szabad teszthez használni!
|
|
// Akkor is védünk, ha a config cache-elve van vagy az APP_ENV nem 'testing'.
|
|
if (strtolower($database) === 'd2d') {
|
|
echo "\n\n!!! KRITIKUS BIZTONSÁGI HIBA !!!\n";
|
|
echo "A tesztek az ÉLŐ (d2d) adatbázishoz kapcsolódnak!\n";
|
|
echo "Ez az adatbázis törléséhez (RefreshDatabase) vezetne.\n";
|
|
echo "A folyamat azonnal leállítva a biztonság érdekében.\n";
|
|
echo "Megoldás: Futtasd a 'php artisan config:clear' parancsot és ellenőrizd a .env.testing fájlt!\n\n";
|
|
exit(1);
|
|
}
|
|
|
|
if (env('APP_ENV') !== 'testing') {
|
|
return;
|
|
}
|
|
|
|
// Kényszerítsük a teszt adatbázist, ha testing környezetben vagyunk és nem d2d
|
|
if (! $this->isTestDatabase($database)) {
|
|
config(['database.connections.mysql.database' => 'd2dTest']);
|
|
$database = (string) config('database.connections.mysql.database');
|
|
}
|
|
|
|
// Általános ellenőrzés, hogy a teszt adatbázis legyen használva
|
|
if (! $this->isTestDatabase($database)) {
|
|
throw new \Exception('HIBA: A teszteknek a d2dTest adatbázison kellene futniuk. Aktuális konfiguráció: '.$database.'. Kérlek futtasd a "php artisan config:clear" parancsot!');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Elfogadható a 'd2dTest', illetve a --parallel processzenkénti 'd2dTest_test_1' alakja
|
|
* (a nevet a Laravel adja: TestDatabases::testDatabase() -> "{$database}_test_{$token}").
|
|
*
|
|
* Szándékosan NEM egyszerű prefix-vizsgálat: a kézenfekvő str_starts_with($db, 'd2d')
|
|
* átengedné az éles 'd2d' nevet is.
|
|
*/
|
|
private function isTestDatabase(string $database): bool
|
|
{
|
|
return preg_match('/^d2dtest(_test_\d+)?$/', strtolower($database)) === 1;
|
|
}
|
|
}
|