pulumi/tests/integration/partial_state/partial_state_test.go
Alex Clemmer f037c7d143 Checkpoint resource initialization errors
When a resource fails to initialize (i.e., it is successfully created,
but fails to transition to a fully-initialized state), and a user
subsequently runs `pulumi update` without changing that resource, our
CLI will fail to warn the user that this resource is not initialized.

This commit begins the process of allowing our CLI to report this by
storing a list of initialization errors in the checkpoint.
2018-07-20 17:59:06 -07:00

86 lines
3.3 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))
assert.Equal(t, []string{"state can't be 4"}, a.InitErrors)
},
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))
assert.Nil(t, nil)
},
},
{
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))
assert.Equal(t, []string{"state can't be 4"}, a.InitErrors)
},
},
},
})
}