pulumi/tests/integration/partial_state/partial_state_test.go
Sean Gillespie 1cbf8bdc40 Partial status for resource providers
This commit adds CLI support for resource providers to provide partial
state upon failure. For resource providers that model resource
operations across multiple API calls, the Provider RPC interface can now
accomodate saving bags of state for resource operations that failed.
This is a common pattern for Terraform-backed providers that try to do
post-creation steps on resource as part of Create or Update resource
operations.
2018-07-02 13:32:23 -07:00

82 lines
3.2 KiB
Go

// Copyright 2016-2018, Pulumi Corporation. All rights reserved.
package ints
import (
"testing"
"github.com/pulumi/pulumi/pkg/resource"
"github.com/pulumi/pulumi/pkg/testing/integration"
"github.com/stretchr/testify/assert"
)
// TestPartialState tests that the engine persists partial state of a resource if a provider
// provides partial state alongside a resource creation or update error.
//
// The setup of this test uses a dynamic provider that will partially fail if a resource's state
// value is the number 4.
func TestPartialState(t *testing.T) {
integration.ProgramTest(t, &integration.ProgramTestOptions{
Dir: "step1",
Dependencies: []string{"@pulumi/pulumi"},
Quick: true,
ExpectFailure: true,
ExtraRuntimeValidation: func(t *testing.T, stackInfo integration.RuntimeValidationStackInfo) {
// The first update tries to create a resource with state 4. This fails partially.
assert.NotNil(t, stackInfo.Deployment)
assert.Equal(t, 2, len(stackInfo.Deployment.Resources))
stackRes := stackInfo.Deployment.Resources[0]
assert.Equal(t, resource.RootStackType, stackRes.URN.Type())
a := stackInfo.Deployment.Resources[1]
// We should still have persisted the resource and its outputs to the snapshot.
assert.Equal(t, "doomed", string(a.URN.Name()))
assert.Equal(t, 4.0, a.Outputs["state"].(float64))
},
EditDirs: []integration.EditDir{
{
Dir: "step2",
Additive: true,
ExtraRuntimeValidation: func(t *testing.T, stackInfo integration.RuntimeValidationStackInfo) {
// The next update deletes the resource. We should successfully delete it.
assert.NotNil(t, stackInfo.Deployment)
assert.Equal(t, 1, len(stackInfo.Deployment.Resources))
stackRes := stackInfo.Deployment.Resources[0]
assert.Equal(t, resource.RootStackType, stackRes.URN.Type())
},
},
{
Dir: "step3",
Additive: true,
ExtraRuntimeValidation: func(t *testing.T, stackInfo integration.RuntimeValidationStackInfo) {
// Step 3 creates a resource with state 5, which succeeds.
assert.NotNil(t, stackInfo.Deployment)
assert.Equal(t, 2, len(stackInfo.Deployment.Resources))
stackRes := stackInfo.Deployment.Resources[0]
assert.Equal(t, resource.RootStackType, stackRes.URN.Type())
a := stackInfo.Deployment.Resources[1]
assert.Equal(t, "not-doomed", string(a.URN.Name()))
assert.Equal(t, 5.0, a.Outputs["state"].(float64))
},
},
{
Dir: "step4",
Additive: true,
ExpectFailure: true,
ExtraRuntimeValidation: func(t *testing.T, stackInfo integration.RuntimeValidationStackInfo) {
// Step 4 updates the resource to have state 4, which fails partially.
assert.NotNil(t, stackInfo.Deployment)
assert.Equal(t, 2, len(stackInfo.Deployment.Resources))
stackRes := stackInfo.Deployment.Resources[0]
assert.Equal(t, resource.RootStackType, stackRes.URN.Type())
a := stackInfo.Deployment.Resources[1]
// We should have persisted the updated resource's new outputs
// to the snapshot.
assert.Equal(t, "not-doomed", string(a.URN.Name()))
assert.Equal(t, 4.0, a.Outputs["state"].(float64))
},
},
},
})
}