7.0.9 → 7.0.10 sudo 업데이트 실측 후 점검에서 드러난 3건.
- 정리 단계가 소스 경로(core_{ts}/extracted/{루트}) 안쪽만 지워 껍데기가
업데이트마다 남던 것을 격리 디렉토리 루트째 삭제로 바꾼다. 부모는 구버전
클래스로 돌아 다음 업데이트부터 효력이 있으므로, 신버전 코드로 도는 두 자식
(execute-upgrade-steps / execute-bundled-updates)이 파일이 없는 core_* 만
골라 치운다 — 구버전 부모에서 올라오는 업데이트도 껍데기 없이 끝난다.
- 항목별 소유권 스냅샷이 격리 디렉토리 생성 뒤에 찍혀 root 가 만든 추출본을
원본으로 기록하고 복원이 다시 root 로 되돌리던 것을, 이번 실행의 격리
디렉토리를 스냅샷에서 제외해 닫는다.
- 완료 안내문이 성공 경로에서는 동작하지 않는 hotfix:rollback-stale-files 를
가리키던 것을 --prune 재실행 안내만 남기도록 정정한다(ko/en/ja).
부수: ExecuteUpgradeStepsStandaloneTest 가 앞선 core:update 실행이 남긴
프로세스 env 플래그에 따라 결과가 갈리던 순서 의존을 setUp/tearDown 에서 제거.
121 lines
4.7 KiB
PHP
121 lines
4.7 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature\Console;
|
|
|
|
use App\Console\Commands\Core\ExecuteBundledUpdatesCommand;
|
|
use Illuminate\Support\Facades\Artisan;
|
|
use Illuminate\Support\Facades\File;
|
|
use Tests\TestCase;
|
|
|
|
/**
|
|
* `core:execute-bundled-updates` 커맨드 회귀.
|
|
*
|
|
* 본 커맨드는 `core:update` 의 BundledExtensionUpdatePrompt 가 사용자 선택을 매니페스트로
|
|
* 직렬화한 후 별도 PHP 프로세스에서 호출하는 진입점. fresh 코드 로드 보장으로 부모 stale
|
|
* memory 결함을 회피.
|
|
*
|
|
* 검증:
|
|
* - 매니페스트 누락 / 부재 시 INVALID 반환
|
|
* - 매니페스트 JSON 파싱 실패 시 FAILURE 반환
|
|
* - 빈 매니페스트 처리 시 RESULT_PREFIX 페이로드 (성공 0/실패 0) 출력
|
|
*/
|
|
class ExecuteBundledUpdatesCommandTest extends TestCase
|
|
{
|
|
private array $tempFiles = [];
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
foreach ($this->tempFiles as $f) {
|
|
if (File::exists($f)) {
|
|
File::delete($f);
|
|
}
|
|
}
|
|
parent::tearDown();
|
|
}
|
|
|
|
public function test_missing_manifest_option_returns_invalid(): void
|
|
{
|
|
$exit = Artisan::call('core:execute-bundled-updates');
|
|
$this->assertSame(2, $exit, 'Command::INVALID 반환 (option 부재)');
|
|
}
|
|
|
|
public function test_nonexistent_manifest_path_returns_invalid(): void
|
|
{
|
|
$exit = Artisan::call('core:execute-bundled-updates', [
|
|
'--manifest' => storage_path('app/__no_such_manifest__.json'),
|
|
]);
|
|
$this->assertSame(2, $exit, 'Command::INVALID 반환 (파일 부재)');
|
|
}
|
|
|
|
public function test_malformed_json_returns_failure(): void
|
|
{
|
|
$path = storage_path('app/test_bundled_manifest_'.uniqid().'.json');
|
|
File::put($path, 'not-valid-json{{{');
|
|
$this->tempFiles[] = $path;
|
|
|
|
$exit = Artisan::call('core:execute-bundled-updates', [
|
|
'--manifest' => $path,
|
|
]);
|
|
|
|
$this->assertSame(1, $exit, 'Command::FAILURE 반환 (JSON 파싱 실패)');
|
|
}
|
|
|
|
public function test_empty_manifest_outputs_result_prefix_with_zero_counts(): void
|
|
{
|
|
$path = storage_path('app/test_bundled_manifest_'.uniqid().'.json');
|
|
File::put($path, json_encode([
|
|
'modules' => [],
|
|
'plugins' => [],
|
|
'templates' => [],
|
|
'lang_packs' => [],
|
|
]));
|
|
$this->tempFiles[] = $path;
|
|
|
|
$exit = Artisan::call('core:execute-bundled-updates', [
|
|
'--manifest' => $path,
|
|
]);
|
|
$this->assertSame(0, $exit, '빈 매니페스트는 SUCCESS');
|
|
|
|
$output = Artisan::output();
|
|
$this->assertStringContainsString(
|
|
ExecuteBundledUpdatesCommand::RESULT_PREFIX,
|
|
$output,
|
|
'결과 표식 라인 출력 (부모 spawn 파싱 대상)',
|
|
);
|
|
$this->assertStringContainsString('"success":0', $output);
|
|
$this->assertStringContainsString('"failed":0', $output);
|
|
}
|
|
|
|
/**
|
|
* 이 자식은 부모의 정리 단계가 끝난 **뒤에** 돈다. 구버전 부모(7.0.0~7.0.9)의 정리는
|
|
* 소스 경로 안쪽만 지워 `core_{ts}/extracted` 껍데기를 남기므로, 그 껍데기를 여기서
|
|
* 치워야 구버전에서 올라오는 업데이트도 잔존물 없이 끝난다. 파일이 있는 격리
|
|
* 디렉토리는 건드리지 않는다.
|
|
*
|
|
* @effects execute_bundled_updates_child_sweeps_empty_staging_directories_left_by_parent
|
|
*/
|
|
public function test_빈_매니페스트_처리_후_부모가_남긴_빈_격리_디렉토리를_치운다(): void
|
|
{
|
|
$base = storage_path('framework/testing/bundled-sweep-'.uniqid());
|
|
File::ensureDirectoryExists($base.DIRECTORY_SEPARATOR.'core_20260906_095309'.DIRECTORY_SEPARATOR.'extracted');
|
|
$live = $base.DIRECTORY_SEPARATOR.'core_20260906_120000'.DIRECTORY_SEPARATOR.'extracted';
|
|
File::ensureDirectoryExists($live);
|
|
File::put($live.DIRECTORY_SEPARATOR.'composer.json', '{}');
|
|
config(['app.update.pending_path' => $base]);
|
|
|
|
$path = storage_path('app/test_bundled_manifest_'.uniqid().'.json');
|
|
File::put($path, json_encode(['modules' => [], 'plugins' => [], 'templates' => [], 'lang_packs' => []]));
|
|
$this->tempFiles[] = $path;
|
|
|
|
try {
|
|
$exit = Artisan::call('core:execute-bundled-updates', ['--manifest' => $path]);
|
|
|
|
$this->assertSame(0, $exit);
|
|
$this->assertDirectoryDoesNotExist($base.DIRECTORY_SEPARATOR.'core_20260906_095309', '빈 껍데기는 치운다');
|
|
$this->assertFileExists($live.DIRECTORY_SEPARATOR.'composer.json', '파일이 있는 격리 디렉토리는 남긴다');
|
|
} finally {
|
|
File::deleteDirectory($base);
|
|
}
|
|
}
|
|
}
|