|
3 | 3 | namespace Tests\Feature; |
4 | 4 |
|
5 | 5 | use App\Enums\DeploymentStatus; |
| 6 | +use App\Enums\WorkerStatus; |
6 | 7 | use App\Facades\SSH; |
7 | 8 | use App\Models\Deployment; |
8 | 9 | use App\Models\GitHook; |
| 10 | +use App\Models\Site; |
| 11 | +use App\Models\Worker; |
9 | 12 | use App\Notifications\DeploymentCompleted; |
10 | 13 | use Exception; |
11 | 14 | use Illuminate\Foundation\Testing\RefreshDatabase; |
@@ -557,4 +560,135 @@ public static function hookData(): array |
557 | 560 | ], |
558 | 561 | ]; |
559 | 562 | } |
| 563 | + |
| 564 | + public function test_deploy_classic_restarts_only_site_workers(): void |
| 565 | + { |
| 566 | + $sshFake = SSH::fake('fake output'); |
| 567 | + Http::fake([ |
| 568 | + 'github.com/*' => Http::response([ |
| 569 | + 'sha' => '123', |
| 570 | + 'commit' => [ |
| 571 | + 'message' => 'test commit message', |
| 572 | + 'name' => 'test commit name', |
| 573 | + 'email' => 'test@example.com', |
| 574 | + 'url' => 'https://github.com/commit-url', |
| 575 | + ], |
| 576 | + ]), |
| 577 | + ]); |
| 578 | + Notification::fake(); |
| 579 | + |
| 580 | + // Create a worker for the site being deployed |
| 581 | + $siteWorker = Worker::factory()->create([ |
| 582 | + 'server_id' => $this->server->id, |
| 583 | + 'site_id' => $this->site->id, |
| 584 | + 'status' => WorkerStatus::RUNNING, |
| 585 | + ]); |
| 586 | + |
| 587 | + // Create another site with workers on the same server |
| 588 | + $otherSite = Site::factory()->create([ |
| 589 | + 'server_id' => $this->server->id, |
| 590 | + ]); |
| 591 | + $otherSiteWorker = Worker::factory()->create([ |
| 592 | + 'server_id' => $this->server->id, |
| 593 | + 'site_id' => $otherSite->id, |
| 594 | + 'status' => WorkerStatus::RUNNING, |
| 595 | + ]); |
| 596 | + |
| 597 | + // Enable restart workers for the deployment script |
| 598 | + $this->site->deploymentScript->update([ |
| 599 | + 'content' => 'git pull', |
| 600 | + 'configs' => ['restart_workers' => true], |
| 601 | + ]); |
| 602 | + |
| 603 | + $this->actingAs($this->user); |
| 604 | + |
| 605 | + $this->post(route('application.deploy', [ |
| 606 | + 'server' => $this->server, |
| 607 | + 'site' => $this->site, |
| 608 | + ])) |
| 609 | + ->assertSessionDoesntHaveErrors(); |
| 610 | + |
| 611 | + // Verify that only the site worker restart command was executed |
| 612 | + SSH::assertExecutedContains('supervisorctl restart '.$siteWorker->id.':*'); |
| 613 | + |
| 614 | + // Verify that other site's worker and "restart all" are not executed |
| 615 | + $this->assertWorkerNotRestarted($otherSiteWorker->id); |
| 616 | + SSH::assertNotExecutedContains('supervisorctl restart all', 'Should not restart all workers'); |
| 617 | + } |
| 618 | + |
| 619 | + public function test_deploy_modern_restarts_only_site_workers(): void |
| 620 | + { |
| 621 | + $sshFake = SSH::fake('fake output'); |
| 622 | + Http::fake([ |
| 623 | + 'github.com/*' => Http::response([ |
| 624 | + 'sha' => '123', |
| 625 | + 'commit' => [ |
| 626 | + 'message' => 'test commit message', |
| 627 | + 'name' => 'test commit name', |
| 628 | + 'email' => 'test@example.com', |
| 629 | + 'url' => 'https://github.com/commit-url', |
| 630 | + ], |
| 631 | + ]), |
| 632 | + ]); |
| 633 | + Notification::fake(); |
| 634 | + |
| 635 | + $this->site->update([ |
| 636 | + 'type_data' => [ |
| 637 | + 'modern_deployment' => true, |
| 638 | + 'modern_deployment_history' => 10, |
| 639 | + 'modern_deployment_shared_resources' => ['.env'], |
| 640 | + ], |
| 641 | + ]); |
| 642 | + $this->site->ensureDeploymentScriptsExist(); |
| 643 | + $this->site->refresh(); |
| 644 | + |
| 645 | + // Create a worker for the site being deployed |
| 646 | + $siteWorker = Worker::factory()->create([ |
| 647 | + 'server_id' => $this->server->id, |
| 648 | + 'site_id' => $this->site->id, |
| 649 | + 'status' => WorkerStatus::RUNNING, |
| 650 | + ]); |
| 651 | + |
| 652 | + // Create another site with workers on the same server |
| 653 | + $otherSite = Site::factory()->create([ |
| 654 | + 'server_id' => $this->server->id, |
| 655 | + ]); |
| 656 | + $otherSiteWorker = Worker::factory()->create([ |
| 657 | + 'server_id' => $this->server->id, |
| 658 | + 'site_id' => $otherSite->id, |
| 659 | + 'status' => WorkerStatus::RUNNING, |
| 660 | + ]); |
| 661 | + |
| 662 | + // Enable restart workers for the pre-flight script |
| 663 | + $this->site->preFlightScript->update([ |
| 664 | + 'content' => 'php artisan migrate --force', |
| 665 | + 'configs' => ['restart_workers' => true], |
| 666 | + ]); |
| 667 | + |
| 668 | + $this->actingAs($this->user); |
| 669 | + |
| 670 | + $this->post(route('application.deploy', [ |
| 671 | + 'server' => $this->server, |
| 672 | + 'site' => $this->site, |
| 673 | + ])) |
| 674 | + ->assertSessionDoesntHaveErrors(); |
| 675 | + |
| 676 | + // Verify that only the site worker restart command was executed |
| 677 | + SSH::assertExecutedContains('supervisorctl restart '.$siteWorker->id.':*'); |
| 678 | + |
| 679 | + // Verify that other site's worker and "restart all" are not executed |
| 680 | + $this->assertWorkerNotRestarted($otherSiteWorker->id); |
| 681 | + SSH::assertNotExecutedContains('supervisorctl restart all', 'Should not restart all workers'); |
| 682 | + } |
| 683 | + |
| 684 | + /** |
| 685 | + * Assert that the given worker's restart command was not executed via SSH. |
| 686 | + */ |
| 687 | + private function assertWorkerNotRestarted(int|string $workerId): void |
| 688 | + { |
| 689 | + SSH::assertNotExecutedContains( |
| 690 | + 'supervisorctl restart '.$workerId.':*', |
| 691 | + "Worker {$workerId} should not be restarted" |
| 692 | + ); |
| 693 | + } |
560 | 694 | } |
0 commit comments