Skip to content

Commit 14ffcb1

Browse files
committed
Extract verifyImportState()
1 parent f9c8a54 commit 14ffcb1

File tree

1 file changed

+105
-97
lines changed

1 file changed

+105
-97
lines changed

helper/resource/testing_new_import_state.go

Lines changed: 105 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -296,138 +296,146 @@ func runImportTestStep(ctx context.Context, t testing.T, helper *plugintest.Help
296296
if step.ImportStateVerify {
297297
logging.HelperResourceTrace(ctx, "Using TestStep ImportStateVerify")
298298

299-
// Ensure that we do not match against data sources as they
300-
// cannot be imported and are not what we want to verify.
301-
// Mode is not present in ResourceState so we use the
302-
// stringified ResourceStateKey for comparison.
303-
newResources := make(map[string]*terraform.ResourceState)
304-
for k, v := range importState.RootModule().Resources {
305-
if !strings.HasPrefix(k, "data.") {
306-
newResources[k] = v
307-
}
308-
}
309-
oldResources := make(map[string]*terraform.ResourceState)
310-
for k, v := range state.RootModule().Resources {
311-
if !strings.HasPrefix(k, "data.") {
312-
oldResources[k] = v
313-
}
314-
}
315-
316299
identifierAttribute := step.ImportStateVerifyIdentifierAttribute
300+
importStateVerifyIgnore := step.ImportStateVerifyIgnore
317301

318-
if identifierAttribute == "" {
319-
identifierAttribute = "id"
302+
if outcome, err := verifyImportState(state, importState, identifierAttribute, importStateVerifyIgnore); !outcome.ok {
303+
return outcome, err
320304
}
305+
}
321306

322-
for _, r := range newResources {
323-
rIdentifier, ok := r.Primary.Attributes[identifierAttribute]
307+
return testOK()
308+
}
324309

325-
if !ok {
326-
return testFatal(fmt.Errorf("ImportStateVerify: New resource missing identifier attribute %q, ensure attribute value is properly set or use ImportStateVerifyIdentifierAttribute to choose different attribute", identifierAttribute))
327-
}
310+
func verifyImportState(state *terraform.State, importState *terraform.State, identifierAttribute string, importStateVerifyIgnore []string) (testOutcome, error) {
311+
// Ensure that we do not match against data sources as they
312+
// cannot be imported and are not what we want to verify.
313+
// Mode is not present in ResourceState so we use the
314+
// stringified ResourceStateKey for comparison.
315+
newResources := make(map[string]*terraform.ResourceState)
316+
for k, v := range importState.RootModule().Resources {
317+
if !strings.HasPrefix(k, "data.") {
318+
newResources[k] = v
319+
}
320+
}
321+
oldResources := make(map[string]*terraform.ResourceState)
322+
for k, v := range state.RootModule().Resources {
323+
if !strings.HasPrefix(k, "data.") {
324+
oldResources[k] = v
325+
}
326+
}
328327

329-
// Find the existing resource
330-
var oldR *terraform.ResourceState
331-
for _, r2 := range oldResources {
332-
if r2.Primary == nil || r2.Type != r.Type || r2.Provider != r.Provider {
333-
continue
334-
}
328+
if identifierAttribute == "" {
329+
identifierAttribute = "id"
330+
}
335331

336-
r2Identifier, ok := r2.Primary.Attributes[identifierAttribute]
332+
for _, r := range newResources {
333+
rIdentifier, ok := r.Primary.Attributes[identifierAttribute]
337334

338-
if !ok {
339-
return testFatal(fmt.Errorf("ImportStateVerify: Old resource missing identifier attribute %q, ensure attribute value is properly set or use ImportStateVerifyIdentifierAttribute to choose different attribute", identifierAttribute))
340-
}
335+
if !ok {
336+
return testFatal(fmt.Errorf("ImportStateVerify: New resource missing identifier attribute %q, ensure attribute value is properly set or use ImportStateVerifyIdentifierAttribute to choose different attribute", identifierAttribute))
337+
}
341338

342-
if r2Identifier == rIdentifier {
343-
oldR = r2
344-
break
345-
}
339+
// Find the existing resource
340+
var oldR *terraform.ResourceState
341+
for _, r2 := range oldResources {
342+
if r2.Primary == nil || r2.Type != r.Type || r2.Provider != r.Provider {
343+
continue
346344
}
347-
if oldR == nil || oldR.Primary == nil {
348-
return testFatal(fmt.Errorf("Failed state verification, resource with ID %s not found", rIdentifier))
345+
346+
r2Identifier, ok := r2.Primary.Attributes[identifierAttribute]
347+
348+
if !ok {
349+
return testFatal(fmt.Errorf("ImportStateVerify: Old resource missing identifier attribute %q, ensure attribute value is properly set or use ImportStateVerifyIdentifierAttribute to choose different attribute", identifierAttribute))
349350
}
350351

351-
// don't add empty flatmapped containers, so we can more easily
352-
// compare the attributes
353-
skipEmpty := func(k, v string) bool {
354-
if strings.HasSuffix(k, ".#") || strings.HasSuffix(k, ".%") {
355-
if v == "0" {
356-
return true
357-
}
358-
}
359-
return false
352+
if r2Identifier == rIdentifier {
353+
oldR = r2
354+
break
360355
}
356+
}
357+
if oldR == nil || oldR.Primary == nil {
358+
return testFatal(fmt.Errorf("Failed state verification, resource with ID %s not found", rIdentifier))
359+
}
361360

362-
// Compare their attributes
363-
actual := make(map[string]string)
364-
for k, v := range r.Primary.Attributes {
365-
if skipEmpty(k, v) {
366-
continue
361+
// don't add empty flatmapped containers, so we can more easily
362+
// compare the attributes
363+
skipEmpty := func(k, v string) bool {
364+
if strings.HasSuffix(k, ".#") || strings.HasSuffix(k, ".%") {
365+
if v == "0" {
366+
return true
367367
}
368-
actual[k] = v
369368
}
369+
return false
370+
}
370371

371-
expected := make(map[string]string)
372-
for k, v := range oldR.Primary.Attributes {
373-
if skipEmpty(k, v) {
374-
continue
375-
}
376-
expected[k] = v
372+
// Compare their attributes
373+
actual := make(map[string]string)
374+
for k, v := range r.Primary.Attributes {
375+
if skipEmpty(k, v) {
376+
continue
377377
}
378+
actual[k] = v
379+
}
378380

379-
// Remove fields we're ignoring
380-
for _, v := range step.ImportStateVerifyIgnore {
381-
for k := range actual {
382-
if strings.HasPrefix(k, v) {
383-
delete(actual, k)
384-
}
385-
}
386-
for k := range expected {
387-
if strings.HasPrefix(k, v) {
388-
delete(expected, k)
389-
}
390-
}
381+
expected := make(map[string]string)
382+
for k, v := range oldR.Primary.Attributes {
383+
if skipEmpty(k, v) {
384+
continue
391385
}
386+
expected[k] = v
387+
}
392388

393-
// timeouts are only _sometimes_ added to state. To
394-
// account for this, just don't compare timeouts at
395-
// all.
389+
// Remove fields we're ignoring
390+
for _, v := range importStateVerifyIgnore {
396391
for k := range actual {
397-
if strings.HasPrefix(k, "timeouts.") {
398-
delete(actual, k)
399-
}
400-
if k == "timeouts" {
392+
if strings.HasPrefix(k, v) {
401393
delete(actual, k)
402394
}
403395
}
404396
for k := range expected {
405-
if strings.HasPrefix(k, "timeouts.") {
406-
delete(expected, k)
407-
}
408-
if k == "timeouts" {
397+
if strings.HasPrefix(k, v) {
409398
delete(expected, k)
410399
}
411400
}
401+
}
412402

413-
if !reflect.DeepEqual(actual, expected) {
414-
// Determine only the different attributes
415-
// go-cmp tries to show surrounding identical map key/value for
416-
// context of differences, which may be confusing.
417-
for k, v := range expected {
418-
if av, ok := actual[k]; ok && v == av {
419-
delete(expected, k)
420-
delete(actual, k)
421-
}
422-
}
403+
// timeouts are only _sometimes_ added to state. To
404+
// account for this, just don't compare timeouts at
405+
// all.
406+
for k := range actual {
407+
if strings.HasPrefix(k, "timeouts.") {
408+
delete(actual, k)
409+
}
410+
if k == "timeouts" {
411+
delete(actual, k)
412+
}
413+
}
414+
for k := range expected {
415+
if strings.HasPrefix(k, "timeouts.") {
416+
delete(expected, k)
417+
}
418+
if k == "timeouts" {
419+
delete(expected, k)
420+
}
421+
}
423422

424-
if diff := cmp.Diff(expected, actual); diff != "" {
425-
return testFail("ImportStateVerify attributes not equivalent. Difference is shown below. The - symbol indicates attributes missing after import.\n\n%s", diff)
423+
if !reflect.DeepEqual(actual, expected) {
424+
// Determine only the different attributes
425+
// go-cmp tries to show surrounding identical map key/value for
426+
// context of differences, which may be confusing.
427+
for k, v := range expected {
428+
if av, ok := actual[k]; ok && v == av {
429+
delete(expected, k)
430+
delete(actual, k)
426431
}
427432
}
433+
434+
if diff := cmp.Diff(expected, actual); diff != "" {
435+
return testFail("ImportStateVerify attributes not equivalent. Difference is shown below. The - symbol indicates attributes missing after import.\n\n%s", diff)
436+
}
428437
}
429438
}
430-
431439
return testOK()
432440
}
433441

0 commit comments

Comments
 (0)