CluPilotCloud/tests/Feature/Admin/ProvisioningActionsTest.php

89 lines
3.8 KiB
PHP

<?php
use App\Livewire\Admin\Provisioning;
use App\Models\Host;
use App\Models\Instance;
use App\Models\Order;
use App\Models\ProvisioningRun;
use App\Provisioning\Jobs\AdvanceRunJob;
use Illuminate\Support\Facades\Queue;
use Livewire\Livewire;
// admin() helper defined in HostManagementTest.
it('retries a failed run from the provisioning console', function () {
Queue::fake();
$host = Host::factory()->create(['status' => 'error']);
$run = ProvisioningRun::factory()->create([
'subject_type' => Host::class, 'subject_id' => $host->id, 'pipeline' => 'host',
'status' => ProvisioningRun::STATUS_FAILED, 'attempt' => 3, 'current_step' => 4, 'error' => 'boom',
]);
Livewire::actingAs(admin(), 'operator')->test(Provisioning::class)->call('retry', $run->uuid);
$run->refresh();
expect($run->status)->toBe(ProvisioningRun::STATUS_RUNNING)
->and($run->attempt)->toBe(0)
->and($run->error)->toBeNull()
->and($host->fresh()->status)->toBe('onboarding');
Queue::assertPushed(AdvanceRunJob::class);
});
it('leaves a live customer alone when the run being retried is a maintenance one', function () {
// The retry set the order to `provisioning` for ANY pipeline, and only the
// `customer` pipeline ever puts it back to `active` (CompleteProvisioning).
// So retrying a failed address, restart, storage, quota or plan-change run
// left a paying customer's order reading `provisioning` for ever: nothing in
// the product would move it again, the customer saw nothing wrong, and the
// console's view of them was simply false. Same reasoning as RunRunner's
// failRun() on the way down — a maintenance run must not condemn what it
// maintains.
Queue::fake();
$order = Order::factory()->create(['status' => 'active']);
$instance = Instance::factory()->create([
'order_id' => $order->id, 'customer_id' => $order->customer_id, 'status' => 'active',
]);
$run = ProvisioningRun::factory()->create([
'subject_type' => Order::class, 'subject_id' => $order->id, 'pipeline' => 'address',
'status' => ProvisioningRun::STATUS_FAILED, 'error' => 'boom',
]);
Livewire::actingAs(admin(), 'operator')->test(Provisioning::class)->call('retry', $run->uuid);
expect($run->fresh()->status)->toBe(ProvisioningRun::STATUS_RUNNING)
->and($order->fresh()->status)->toBe('active')
->and($instance->fresh()->status)->toBe('active');
Queue::assertPushed(AdvanceRunJob::class);
});
it('does put a customer build back into provisioning when that is the run being retried', function () {
Queue::fake();
$order = Order::factory()->create(['status' => 'failed']);
$instance = Instance::factory()->create([
'order_id' => $order->id, 'customer_id' => $order->customer_id, 'status' => 'failed',
]);
$run = ProvisioningRun::factory()->create([
'subject_type' => Order::class, 'subject_id' => $order->id, 'pipeline' => 'customer',
'status' => ProvisioningRun::STATUS_FAILED, 'error' => 'boom',
]);
Livewire::actingAs(admin(), 'operator')->test(Provisioning::class)->call('retry', $run->uuid);
expect($order->fresh()->status)->toBe('provisioning')
->and($instance->fresh()->status)->toBe('provisioning');
});
it('ignores retry on a run that is not failed', function () {
Queue::fake();
$host = Host::factory()->active()->create();
$run = ProvisioningRun::factory()->create([
'subject_type' => Host::class, 'subject_id' => $host->id, 'pipeline' => 'host',
'status' => ProvisioningRun::STATUS_RUNNING,
]);
Livewire::actingAs(admin(), 'operator')->test(Provisioning::class)->call('retry', $run->uuid);
expect($run->fresh()->status)->toBe(ProvisioningRun::STATUS_RUNNING);
Queue::assertNotPushed(AdvanceRunJob::class);
});