Compare commits
4 commits
master
...
pgavlin/re
Author | SHA1 | Date | |
---|---|---|---|
88f9ca4b51 | |||
87d9be60e1 | |||
e8f3d448db | |||
e07c2c2c21 |
|
@ -1,5 +1,8 @@
|
|||
### Improvements
|
||||
|
||||
- Clear pending operations during `pulumi refresh` or `pulumi up -r`.
|
||||
[#8435](https://github.com/pulumi/pulumi/pull/8435)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- [codegen/typescript] - Respect default values in Pulumi object types.
|
||||
|
|
|
@ -538,6 +538,73 @@ func TestPreviewWithPendingOperations(t *testing.T) {
|
|||
assert.EqualError(t, res.Error(), deploy.PlanPendingOperationsError{}.Error())
|
||||
}
|
||||
|
||||
// Tests that a refresh works for a stack with pending operations.
|
||||
func TestRefreshWithPendingOperations(t *testing.T) {
|
||||
p := &TestPlan{}
|
||||
|
||||
const resType = "pkgA:m:typA"
|
||||
urnA := p.NewURN(resType, "resA", "")
|
||||
|
||||
newResource := func(urn resource.URN, id resource.ID, delete bool, dependencies ...resource.URN) *resource.State {
|
||||
return &resource.State{
|
||||
Type: urn.Type(),
|
||||
URN: urn,
|
||||
Custom: true,
|
||||
Delete: delete,
|
||||
ID: id,
|
||||
Inputs: resource.PropertyMap{},
|
||||
Outputs: resource.PropertyMap{},
|
||||
Dependencies: dependencies,
|
||||
}
|
||||
}
|
||||
|
||||
old := &deploy.Snapshot{
|
||||
PendingOperations: []resource.Operation{{
|
||||
Resource: newResource(urnA, "0", false),
|
||||
Type: resource.OperationTypeUpdating,
|
||||
}},
|
||||
Resources: []*resource.State{
|
||||
newResource(urnA, "0", false),
|
||||
},
|
||||
}
|
||||
|
||||
loaders := []*deploytest.ProviderLoader{
|
||||
deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) {
|
||||
return &deploytest.Provider{}, nil
|
||||
}),
|
||||
}
|
||||
|
||||
program := deploytest.NewLanguageRuntime(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error {
|
||||
_, _, _, err := monitor.RegisterResource("pkgA:m:typA", "resA", true)
|
||||
assert.NoError(t, err)
|
||||
return nil
|
||||
})
|
||||
|
||||
op := TestOp(Update)
|
||||
options := UpdateOptions{Host: deploytest.NewPluginHost(nil, nil, program, loaders...)}
|
||||
project, target := p.GetProject(), p.GetTarget(old)
|
||||
|
||||
// Without refreshing, an update should fail.
|
||||
_, res := op.Run(project, target, options, false, nil, nil)
|
||||
assertIsErrorOrBailResult(t, res)
|
||||
assert.EqualError(t, res.Error(), deploy.PlanPendingOperationsError{}.Error())
|
||||
|
||||
// With a refresh, the update should succeed.
|
||||
withRefresh := options
|
||||
withRefresh.Refresh = true
|
||||
new, res := op.Run(project, target, withRefresh, false, nil, nil)
|
||||
assert.Nil(t, res)
|
||||
assert.Len(t, new.PendingOperations, 0)
|
||||
|
||||
// Similarly, the update should succeed if performed after a separate refresh.
|
||||
new, res = TestOp(Refresh).Run(project, target, options, false, nil, nil)
|
||||
assert.Nil(t, res)
|
||||
assert.Len(t, new.PendingOperations, 0)
|
||||
|
||||
_, res = op.Run(project, p.GetTarget(new), options, false, nil, nil)
|
||||
assert.Nil(t, res)
|
||||
}
|
||||
|
||||
// Tests that a failed partial update causes the engine to persist the resource's old inputs and new outputs.
|
||||
func TestUpdatePartialFailure(t *testing.T) {
|
||||
loaders := []*deploytest.ProviderLoader{
|
||||
|
|
|
@ -270,10 +270,6 @@ func buildResourceMap(prev *Snapshot, preview bool) ([]*resource.State, map[reso
|
|||
return nil, olds, nil
|
||||
}
|
||||
|
||||
if prev.PendingOperations != nil && !preview {
|
||||
return nil, nil, PlanPendingOperationsError{prev.PendingOperations}
|
||||
}
|
||||
|
||||
for _, oldres := range prev.Resources {
|
||||
// Ignore resources that are pending deletion; these should not be recorded in the LUT.
|
||||
if oldres.Delete {
|
||||
|
|
|
@ -146,6 +146,8 @@ func (ex *deploymentExecutor) Execute(callerCtx context.Context, opts Options, p
|
|||
if opts.RefreshOnly {
|
||||
return nil
|
||||
}
|
||||
} else if ex.deployment.prev != nil && len(ex.deployment.prev.PendingOperations) != 0 && !preview {
|
||||
return result.FromError(PlanPendingOperationsError{ex.deployment.prev.PendingOperations})
|
||||
}
|
||||
|
||||
// The set of -t targets provided on the command line. 'nil' means 'update everything'.
|
||||
|
|
|
@ -43,16 +43,5 @@ func TestPendingOperationsDeployment(t *testing.T) {
|
|||
})
|
||||
|
||||
_, err := NewDeployment(&plugin.Context{}, &Target{}, snap, &fixedSource{}, nil, false, nil)
|
||||
if !assert.Error(t, err) {
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
invalidErr, ok := err.(PlanPendingOperationsError)
|
||||
if !assert.True(t, ok) {
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
assert.Len(t, invalidErr.Operations, 1)
|
||||
assert.Equal(t, resourceB.URN, invalidErr.Operations[0].Resource.URN)
|
||||
assert.Equal(t, resource.OperationTypeCreating, invalidErr.Operations[0].Type)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue