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); }); it('zaehlt einen fertigen Lauf in Liste und Karte gleich', function () { // Zwei Zahlen fuer denselben Lauf: in der Liste stand 15/16, in der Karte // daneben „16 von 16 abgeschlossen" — bei Status „Fertig" und 100 %. Die // Liste rechnete `current_step + 1`, also „dieser Schritt laeuft gerade"; // bei einem fertigen Lauf laeuft aber keiner mehr. $host = Host::factory()->create(['status' => 'active']); $total = count(config('provisioning.pipelines.host')); ProvisioningRun::factory()->create([ 'subject_type' => Host::class, 'subject_id' => $host->id, 'pipeline' => 'host', 'status' => ProvisioningRun::STATUS_COMPLETED, // Der letzte ausgefuehrte Schritt, NICHT die Gesamtzahl — genau der // Stand, bei dem die beiden Zahlen auseinanderliefen. 'current_step' => $total - 2, ]); $rows = Livewire::actingAs(admin(), 'operator')->test(Provisioning::class)->viewData('rows'); expect($rows[0]['n'])->toBe($total.'/'.$total) ->and($rows[0]['percent'])->toBe(100); }); it('zeigt bei einem laufenden Lauf weiter den Schritt, der gerade dran ist', function () { // Die Gegenprobe: solange etwas laeuft, ist „dieser Schritt laeuft gerade" // genau richtig, und die Korrektur oben darf das nicht kaputtmachen. $host = Host::factory()->create(['status' => 'onboarding']); $total = count(config('provisioning.pipelines.host')); ProvisioningRun::factory()->create([ 'subject_type' => Host::class, 'subject_id' => $host->id, 'pipeline' => 'host', 'status' => ProvisioningRun::STATUS_RUNNING, 'current_step' => 3, ]); $rows = Livewire::actingAs(admin(), 'operator')->test(Provisioning::class)->viewData('rows'); expect($rows[0]['n'])->toBe('4/'.$total); });