@@ -30,33 +30,72 @@ func testStepNewConfig(t testing.T, c TestCase, wd *tftest.WorkingDir, step Test
3030 }
3131 }
3232
33- wd .RequireSetConfig (t , step .Config )
33+ err := wd .SetConfig (t , step .Config )
34+ if err != nil {
35+ return fmt .Error ("Error setting config: %w" , err )
36+ }
3437
3538 // require a refresh before applying
3639 // failing to do this will result in data sources not being updated
3740 err := runProviderCommand (t , func () error {
3841 return wd .Refresh ()
3942 }, wd , c .ProviderFactories )
4043 if err != nil {
41- return err
44+ return fmt . Errorf ( "Error running pre-apply refresh: %w" , err )
4245 }
4346
47+ // If this step is a PlanOnly step, skip over this first Plan and
48+ // subsequent Apply, and use the follow-up Plan that checks for
49+ // permadiffs
4450 if ! step .PlanOnly {
51+ // Plan!
4552 err := runProviderCommand (t , func () error {
53+ if step .Destroy {
54+ return wd .CreateDestroyPlan ()
55+ }
56+ return wd .CreatePlan ()
57+ }, wd , c .ProviderFactories )
58+ if err != nil {
59+ return fmt .Errorf ("Error running pre-apply plan: %w" , err )
60+ }
61+
62+ // We need to keep a copy of the state prior to destroying such
63+ // that the destroy steps can verify their behavior in the
64+ // check function
65+ var stateBeforeApplication * terraform.State
66+ err = runProviderCommand (t , func () error {
67+ stateBeforeApplication = getState (t , wd )
68+ return nil
69+ }, wd , c .ProviderFactories )
70+ if err != nil {
71+ return fmt .Errorf ("Error retrieving pre-apply state: %w" , err )
72+ }
73+
74+ // Apply the diff, creating real resources
75+ err = runProviderCommand (t , func () error {
76+ if step .Destroy {
77+ return wd .Destroy ()
78+ }
4679 return wd .Apply ()
4780 }, wd , c .ProviderFactories )
4881 if err != nil {
49- return err
82+ if step .Destroy {
83+ return fmt .Errorf ("Error running destroy: %w" , err )
84+ }
85+ return fmt .Errorf ("Error running apply: %w" , err )
5086 }
5187
88+ // Get the new state
5289 var state * terraform.State
5390 err = runProviderCommand (t , func () error {
5491 state = getState (t , wd )
5592 return nil
5693 }, wd , c .ProviderFactories )
5794 if err != nil {
58- return err
95+ return fmt . Errorf ( "Error retrieving state after apply: %w" , err )
5996 }
97+
98+ // Run any configured checks
6099 if step .Check != nil {
61100 state .IsBinaryDrivenTest = true
62101 if err := step .Check (state ); err != nil {
@@ -69,70 +108,84 @@ func testStepNewConfig(t testing.T, c TestCase, wd *tftest.WorkingDir, step Test
69108
70109 // do a plan
71110 err = runProviderCommand (t , func () error {
111+ if step .Destroy {
112+ return wd .CreateDestroyPlan ()
113+ }
72114 return wd .CreatePlan ()
73115 }, wd , c .ProviderFactories )
74116 if err != nil {
75- return err
117+ return fmt . Errorf ( "Error running post-apply plan: %w" , err )
76118 }
77119
78120 var plan * tfjson.Plan
79121 err = runProviderCommand (t , func () error {
80- plan = wd .RequireSavedPlan (t )
81- return nil
122+ var err error
123+ plan , err = wd .SavedPlan (t )
124+ return err
82125 }, wd , c .ProviderFactories )
83126 if err != nil {
84- return err
127+ return fmt . Errorf ( "Error retrieving post-apply plan: %w" , err )
85128 }
86129
87130 if ! planIsEmpty (plan ) && ! step .ExpectNonEmptyPlan {
88131 var stdout string
89132 err = runProviderCommand (t , func () error {
90- stdout = wd .RequireSavedPlanStdout (t )
91- return nil
133+ var err error
134+ stdout , err = wd .SavedPlanStdout (t )
135+ return err
92136 }, wd , c .ProviderFactories )
93137 if err != nil {
94- return err
138+ return fmt . Errorf ( "Error retrieving formatted plan output: %w" , err )
95139 }
96140 return fmt .Errorf ("After applying this test step, the plan was not empty.\n stdout:\n \n %s" , stdout )
141+ } else if step .ExpectNonEmptyPlan && planIsEmpty (plan ) {
142+ return fmt .Errorf ("Expected a non-empty plan, but got an empty plan!" )
97143 }
98144
99145 // do a refresh
100- if ! c . PreventPostDestroyRefresh {
146+ if ! step . Destroy || ( step . Destroy && ! step . PreventPostDestroyRefresh ) {
101147 err := runProviderCommand (t , func () error {
102148 return wd .Refresh ()
103149 }, wd , c .ProviderFactories )
104150 if err != nil {
105- return err
151+ return fmt . Errorf ( "Error running post-apply refresh: %w" , err )
106152 }
107153 }
108154
109155 // do another plan
110156 err = runProviderCommand (t , func () error {
157+ if step .Destroy {
158+ return wd .CreateDestroyPlan ()
159+ }
111160 return wd .CreatePlan ()
112161 }, wd , c .ProviderFactories )
113162 if err != nil {
114- return err
163+ return fmt . Errorf ( "Error running second post-apply plan: %w" , err )
115164 }
116165
117166 err = runProviderCommand (t , func () error {
118- plan = wd .RequireSavedPlan (t )
119- return nil
167+ var err error
168+ plan , err = wd .SavedPlan (t )
169+ return err
120170 }, wd , c .ProviderFactories )
121171 if err != nil {
122- return err
172+ return fmt . Errorf ( "Error retrieving second post-apply plan: %w" , err )
123173 }
124174
125175 // check if plan is empty
126176 if ! planIsEmpty (plan ) && ! step .ExpectNonEmptyPlan {
127177 var stdout string
128178 err = runProviderCommand (t , func () error {
129- stdout = wd .RequireSavedPlanStdout (t )
130- return nil
179+ var err error
180+ stdout , err = wd .SavedPlanStdout (t )
181+ return err
131182 }, wd , c .ProviderFactories )
132183 if err != nil {
133- return err
184+ return fmt . Errorf ( "Error retrieving formatted second plan output: %w" , err )
134185 }
135186 return fmt .Errorf ("After applying this test step and performing a `terraform refresh`, the plan was not empty.\n stdout\n \n %s" , stdout )
187+ } else if step .ExpectNonEmptyPlan && planIsEmpty (plan ) {
188+ return fmt .Errorf ("Expected a non-empty plan, but got an empty plan!" )
136189 }
137190
138191 // ID-ONLY REFRESH
0 commit comments