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{}{ expected = resource.NewPropertyMapFromMap(map[string]interface{}{
"X": "Y", "X": "Y",
}) })
assert.Equal(t, expected, snap.Resources[1].Outputs) assert.Equal(t, expected, snap.Resources[2].Outputs)
expected = resource.NewPropertyMapFromMap(map[string]interface{}{ expected = resource.NewPropertyMapFromMap(map[string]interface{}{
"foo": "bar", "foo": "bar",
"zed": 24, "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 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( func (rp *ResourcePlan) checkGoal(
oldOutputs resource.PropertyMap, oldOutputs resource.PropertyMap,
newInputs resource.PropertyMap, newInputs resource.PropertyMap,

View file

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

View file

@ -194,7 +194,9 @@ func (sg *stepGenerator) GenerateSteps(event RegisterResourceEvent) ([]Step, res
} }
resourcePlan.Ops = resourcePlan.Ops[1:] resourcePlan.Ops = resourcePlan.Ops[1:]
} else { } 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) sg.deployment.newPlans.set(urn, newResourcePlan)
// If there is a plan for this resource, validate that the program goal conforms to the plan. // 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 { if sg.deployment.plan != nil {
resourcePlan, ok := sg.deployment.plan[urn] resourcePlan, ok := sg.deployment.plan[urn]
if !ok { if !ok {
return nil, result.Errorf("resource not found in plan") if err := checkMissingPlan(old, inputs, goal); err != nil {
} return nil, result.FromError(fmt.Errorf("resource violates plan: %w", err))
if err := resourcePlan.checkGoal(oldOutputs, 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))
}
} }
} }