github.com/miquella/terraform@v0.6.17-0.20160517195040-40db82f25ec0/helper/resource/testing_import_state.go (about) 1 package resource 2 3 import ( 4 "fmt" 5 "log" 6 "reflect" 7 8 "github.com/davecgh/go-spew/spew" 9 "github.com/hashicorp/terraform/terraform" 10 ) 11 12 // testStepImportState runs an imort state test step 13 func testStepImportState( 14 opts terraform.ContextOpts, 15 state *terraform.State, 16 step TestStep) (*terraform.State, error) { 17 // Determine the ID to import 18 importId := step.ImportStateId 19 if importId == "" { 20 resource, err := testResource(step, state) 21 if err != nil { 22 return state, err 23 } 24 25 importId = resource.Primary.ID 26 } 27 28 // Setup the context. We initialize with an empty state. We use the 29 // full config for provider configurations. 30 mod, err := testModule(opts, step) 31 if err != nil { 32 return state, err 33 } 34 35 opts.Module = mod 36 opts.State = terraform.NewState() 37 ctx, err := terraform.NewContext(&opts) 38 if err != nil { 39 return state, err 40 } 41 42 // Do the import! 43 newState, err := ctx.Import(&terraform.ImportOpts{ 44 // Set the module so that any provider config is loaded 45 Module: mod, 46 47 Targets: []*terraform.ImportTarget{ 48 &terraform.ImportTarget{ 49 Addr: step.ResourceName, 50 ID: importId, 51 }, 52 }, 53 }) 54 if err != nil { 55 log.Printf("[ERROR] Test: ImportState failure: %s", err) 56 return state, err 57 } 58 59 // Go through the new state and verify 60 if step.ImportStateCheck != nil { 61 var states []*terraform.InstanceState 62 for _, r := range newState.RootModule().Resources { 63 if r.Primary != nil { 64 states = append(states, r.Primary) 65 } 66 } 67 if err := step.ImportStateCheck(states); err != nil { 68 return state, err 69 } 70 } 71 72 // Verify that all the states match 73 if step.ImportStateVerify { 74 new := newState.RootModule().Resources 75 old := state.RootModule().Resources 76 for _, r := range new { 77 // Find the existing resource 78 var oldR *terraform.ResourceState 79 for _, r2 := range old { 80 if r2.Primary != nil && r2.Primary.ID == r.Primary.ID { 81 oldR = r2 82 break 83 } 84 } 85 if oldR == nil { 86 return state, fmt.Errorf( 87 "Failed state verification, resource with ID %s not found", 88 r.Primary.ID) 89 } 90 91 // Compare their attributes 92 actual := r.Primary.Attributes 93 expected := oldR.Primary.Attributes 94 if !reflect.DeepEqual(actual, expected) { 95 // Determine only the different attributes 96 for k, v := range expected { 97 if av, ok := actual[k]; ok && v == av { 98 delete(expected, k) 99 delete(actual, k) 100 } 101 } 102 103 spewConf := spew.NewDefaultConfig() 104 spewConf.SortKeys = true 105 return state, fmt.Errorf( 106 "Attributes not equivalent. Difference is shown below. Top is actual, bottom is expected."+ 107 "\n\n%s\n\n%s", 108 spewConf.Sdump(actual), spewConf.Sdump(expected)) 109 } 110 } 111 } 112 113 // Return the old state (non-imported) so we don't change anything. 114 return state, nil 115 }