d2d.emegrendeles.hu/tests/Feature/Deployment/DeploymentPackageGitTest.php
E98Developer 98cf955354 FIX DeploymentPackageTest felbontása hat fájlra a párhuzamos futtatáshoz
A paratest FÁJLONKÉNT osztja szét a munkát, ezért egyetlen 28 tesztes fájlból
nem tudott párhuzamosítani: egy processz vitte a teljes 137 mp-et, a másik öt
üresjáratban állt. A --parallel emiatt korábban egyenesen lassabb volt
(136 -> 143 mp), a teljes suite-on pedig csak 11%-ot hozott.

A felosztás témák szerint történt, de mért időkre kalibrálva, hogy egyik fájl
se domináljon (a leghosszabb a Builder, ~35 mp):

  AccessTest    6 teszt  ~7 mp   jogosultság, feature flag, 403
  GitTest       5 teszt ~18 mp   GitRepository, ChangeSetAnalyzer
  BuilderTest   9 teszt ~35 mp   csomagépítés, _TEENDOK, _torles.sh, verzió
  PageTest      4 teszt ~21 mp   commitlista, keresés, kiválasztás
  CreationTest  2 teszt ~32 mp   felületről indított csomagolás, kirakottnak jelölés
  DownloadTest  2 teszt ~25 mp   naplóbejegyzés, ZIP letöltés, útvonal-ellenőrzés

A két legdrágább teszt (21,7 és 20,4 mp) szándékosan külön fájlba került,
együtt hagyva ők adnák a padlót.

A közös segédfüggvények a DeploymentTestHelpers.php-ba kerültek. Ez nem
*Test.php, ezért a phpunit nem szedi fel teszt-fájlként. A minta-repót takarító
afterAll() helyére register_shutdown_function lépett: az afterAll fájlonként
futna le, és a következő fájl alól húzná ki a mintát.

Mért eredmény (6 mag): ezek a tesztek sorosan 137,00 mp, párhuzamosan
67,88 mp. Teljes suite párhuzamosan 149,78 -> 77,52 mp.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 10:48:31 +02:00

96 lines
3.7 KiB
PHP

<?php
use App\Services\Deployment\ChangeSetAnalyzer;
use App\Services\Deployment\GitRepository;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Http;
use Tests\TestCase;
require_once __DIR__.'/DeploymentTestHelpers.php';
uses(TestCase::class, RefreshDatabase::class);
beforeEach(function () {
Http::fake();
});
test('a commitlista a legfrissebbtől visszafelé, fájlszámmal együtt jön', function () {
$repository = deploymentTestRepository();
$commits = app(GitRepository::class)->commits('main', 10);
expect($commits)->toHaveCount(3)
->and($commits[0]['subject'])->toBe('harmadik commit')
->and($commits[2]['subject'])->toBe('első commit')
->and($commits[0]['hash'])->toHaveLength(40)
->and($commits[0]['file_count'])->toBe(2)
// A törzs a tárgysor nélkül jön, és nem tapad hozzá a --shortstat sora sem.
->and($commits[1]['body'])->toBe('A törzsben említett árlista részlet.')
->and($commits[0]['body'])->toBe('');
deploymentCleanup($repository['path']);
});
test('a diff felismeri az új, módosult, törölt és átnevezett fájlokat', function () {
$repository = deploymentTestRepository();
[$first, , $third] = $repository['commits'];
$files = collect(app(GitRepository::class)->changedFiles($first, $third))->keyBy('path');
expect($files->get('app/Elso.php')['status'])->toBe('M')
->and($files->get('app/Regi.php')['status'])->toBe('D')
->and($files->get('app/Atnevezett.php')['status'])->toBe('R')
->and($files->get('app/Atnevezett.php')['old_path'])->toBe('app/Atnevezendo.php')
// Ékezetes útvonal: core.quotePath=false nélkül "app/\303\201rlista.php" jönne vissza.
->and($files->has('app/Árlista.php'))->toBeTrue();
deploymentCleanup($repository['path']);
});
test('az elemzés kizárja a tiltott fájlokat és külön kezeli a törlendőket', function () {
$repository = deploymentTestRepository();
[$first, , $third] = $repository['commits'];
$changedFiles = app(GitRepository::class)->changedFiles($first, $third);
$changeSet = app(ChangeSetAnalyzer::class)->analyze($changedFiles);
expect($changeSet['copied'])->toContain('app/Árlista.php', 'app/Atnevezett.php', 'app/Elso.php')
->and($changeSet['copied'])->not->toContain('.env')
->and($changeSet['counts']['excluded'])->toBe(1)
// A törölt fájl mellett az átnevezés régi útvonala is törlendő a célgépen.
->and($changeSet['deleted'])->toContain('app/Regi.php', 'app/Atnevezendo.php');
$titles = collect($changeSet['warnings'])->pluck('title')->implode(' | ');
expect($titles)->toContain('Migráció')
->and($titles)->toContain('Seeder')
->and($titles)->toContain('Törlendő fájl');
deploymentCleanup($repository['path']);
});
test('az érvénytelen commit azonosítót nem adja tovább a gitnek', function () {
$repository = deploymentTestRepository();
$git = app(GitRepository::class);
expect($git->resolveCommit('../../etc/passwd'))->toBeNull()
->and($git->resolveCommit('main; rm -rf /'))->toBeNull()
->and($git->resolveCommit('HEAD'))->toBeNull()
->and($git->resolveCommit($repository['commits'][0]))->toBe($repository['commits'][0]);
deploymentCleanup($repository['path']);
});
test('a fordított tartomány felismerhető', function () {
$repository = deploymentTestRepository();
[$first, , $third] = $repository['commits'];
$git = app(GitRepository::class);
expect($git->isAncestor($first, $third))->toBeTrue()
->and($git->isAncestor($third, $first))->toBeFalse();
deploymentCleanup($repository['path']);
});