Fix same resource test

This commit is contained in:
Fraser Waters 2021-11-18 11:39:41 +00:00
parent 598f2c7213
commit 4fa395b03d
4 changed files with 47 additions and 8 deletions

View file

@ -3210,11 +3210,11 @@ func TestResoucesWithSames(t *testing.T) {
expected = resource.NewPropertyMapFromMap(map[string]interface{}{
"X": "Y",
})
assert.Equal(t, expected, snap.Resources[1].Outputs)
assert.Equal(t, expected, snap.Resources[2].Outputs)
expected = resource.NewPropertyMapFromMap(map[string]interface{}{
"foo": "bar",
"zed": 24,
})
assert.Equal(t, expected, snap.Resources[2].Outputs)
assert.Equal(t, expected, snap.Resources[1].Outputs)
}

View file

@ -163,6 +163,37 @@ func (rp *ResourcePlan) diffPropertyDependencies(a, b map[resource.PropertyKey][
return nil
}
// This is similar to ResourcePlan.checkGoal but for the case we're we don't have a goal saved. This simple checks that we're not changing anything.
func checkMissingPlan(
oldState *resource.State,
newInputs resource.PropertyMap,
programGoal *resource.Goal) error {
// We new up a fake ResourcePlan that matches the old state and then simply call checkGoal on it.
goal := &GoalPlan{
Type: oldState.Type,
Name: oldState.URN.Name(),
Custom: oldState.Custom,
Adds: nil,
Deletes: nil,
Updates: nil,
Parent: oldState.Parent,
Protect: oldState.Protect,
Dependencies: oldState.Dependencies,
Provider: oldState.Provider,
PropertyDependencies: oldState.PropertyDependencies,
DeleteBeforeReplace: nil,
IgnoreChanges: nil,
AdditionalSecretOutputs: oldState.AdditionalSecretOutputs,
Aliases: oldState.Aliases,
ID: "",
CustomTimeouts: oldState.CustomTimeouts,
}
rp := ResourcePlan{Goal: goal}
return rp.checkGoal(oldState.Outputs, newInputs, programGoal)
}
func (rp *ResourcePlan) checkGoal(
oldOutputs resource.PropertyMap,
newInputs resource.PropertyMap,

View file

@ -1170,9 +1170,11 @@ func (op StepOp) Suffix() string {
func (op StepOp) ConstrainedTo(constraint StepOp) bool {
var allowed []StepOp
switch constraint {
case OpSame, OpCreate, OpDelete, OpRead, OpReadReplacement, OpRefresh, OpReadDiscard, OpDiscardReplaced,
case OpSame, OpDelete, OpRead, OpReadReplacement, OpRefresh, OpReadDiscard, OpDiscardReplaced,
OpRemovePendingReplace, OpImport, OpImportReplacement:
allowed = []StepOp{constraint}
case OpCreate:
allowed = []StepOp{OpSame, OpCreate}
case OpUpdate:
allowed = []StepOp{OpSame, OpUpdate}
case OpReplace, OpCreateReplacement, OpDeleteReplaced:

View file

@ -194,7 +194,9 @@ func (sg *stepGenerator) GenerateSteps(event RegisterResourceEvent) ([]Step, res
}
resourcePlan.Ops = resourcePlan.Ops[1:]
} else {
return nil, result.Errorf("%v is not allowed by the plan: no steps were expected for this resource", s.Op())
if !s.Op().ConstrainedTo(OpSame) {
return nil, result.Errorf("%v is not allowed by the plan: no steps were expected for this resource", s.Op())
}
}
}
@ -310,13 +312,17 @@ func (sg *stepGenerator) generateSteps(event RegisterResourceEvent) ([]Step, res
sg.deployment.newPlans.set(urn, newResourcePlan)
// If there is a plan for this resource, validate that the program goal conforms to the plan.
// If theres no plan for this resource check that nothing has been changed.
if sg.deployment.plan != nil {
resourcePlan, ok := sg.deployment.plan[urn]
if !ok {
return nil, result.Errorf("resource not found in plan")
}
if err := resourcePlan.checkGoal(oldOutputs, inputs, goal); err != nil {
return nil, result.FromError(fmt.Errorf("resource violates plan: %w", err))
if err := checkMissingPlan(old, inputs, goal); err != nil {
return nil, result.FromError(fmt.Errorf("resource violates plan: %w", err))
}
} else {
if err := resourcePlan.checkGoal(oldOutputs, inputs, goal); err != nil {
return nil, result.FromError(fmt.Errorf("resource violates plan: %w", err))
}
}
}