github.com/wikibal01/hashicorp-terraform@v0.11.12-beta1/terraform/upgrade_state_v1_test.go (about) 1 package terraform 2 3 import ( 4 "bytes" 5 "reflect" 6 "strings" 7 "testing" 8 9 "github.com/davecgh/go-spew/spew" 10 ) 11 12 // TestReadUpgradeStateV1toV3 tests the state upgrade process from the V1 state 13 // to the current version, and needs editing each time. This means it tests the 14 // entire pipeline of upgrades (which migrate version to version). 15 func TestReadUpgradeStateV1toV3(t *testing.T) { 16 // ReadState should transparently detect the old version but will upgrade 17 // it on Write. 18 actual, err := ReadState(strings.NewReader(testV1State)) 19 if err != nil { 20 t.Fatalf("err: %s", err) 21 } 22 23 buf := new(bytes.Buffer) 24 if err := WriteState(actual, buf); err != nil { 25 t.Fatalf("err: %s", err) 26 } 27 28 if actual.Version != 3 { 29 t.Fatalf("bad: State version not incremented; is %d", actual.Version) 30 } 31 32 roundTripped, err := ReadState(buf) 33 if err != nil { 34 t.Fatalf("err: %s", err) 35 } 36 37 if !reflect.DeepEqual(actual, roundTripped) { 38 t.Logf("actual:\n%#v", actual) 39 t.Fatalf("roundTripped:\n%#v", roundTripped) 40 } 41 } 42 43 func TestReadUpgradeStateV1toV3_outputs(t *testing.T) { 44 // ReadState should transparently detect the old version but will upgrade 45 // it on Write. 46 actual, err := ReadState(strings.NewReader(testV1StateWithOutputs)) 47 if err != nil { 48 t.Fatalf("err: %s", err) 49 } 50 51 buf := new(bytes.Buffer) 52 if err := WriteState(actual, buf); err != nil { 53 t.Fatalf("err: %s", err) 54 } 55 56 if actual.Version != 3 { 57 t.Fatalf("bad: State version not incremented; is %d", actual.Version) 58 } 59 60 roundTripped, err := ReadState(buf) 61 if err != nil { 62 t.Fatalf("err: %s", err) 63 } 64 65 if !reflect.DeepEqual(actual, roundTripped) { 66 spew.Config.DisableMethods = true 67 t.Fatalf("bad:\n%s\n\nround tripped:\n%s\n", spew.Sdump(actual), spew.Sdump(roundTripped)) 68 spew.Config.DisableMethods = false 69 } 70 } 71 72 // Upgrading the state should not lose empty module Outputs and Resources maps 73 // during upgrade. The init for a new module initializes new maps, so we may not 74 // be expecting to check for a nil map. 75 func TestReadUpgradeStateV1toV3_emptyState(t *testing.T) { 76 // ReadState should transparently detect the old version but will upgrade 77 // it on Write. 78 orig, err := ReadStateV1([]byte(testV1EmptyState)) 79 if err != nil { 80 t.Fatalf("err: %s", err) 81 } 82 83 stateV2, err := upgradeStateV1ToV2(orig) 84 if err != nil { 85 t.Fatalf("error attempting upgradeStateV1ToV2: %s", err) 86 } 87 88 for _, m := range stateV2.Modules { 89 if m.Resources == nil { 90 t.Fatal("V1 to V2 upgrade lost module.Resources") 91 } 92 if m.Outputs == nil { 93 t.Fatal("V1 to V2 upgrade lost module.Outputs") 94 } 95 } 96 97 stateV3, err := upgradeStateV2ToV3(stateV2) 98 if err != nil { 99 t.Fatalf("error attempting to upgradeStateV2ToV3: %s", err) 100 } 101 for _, m := range stateV3.Modules { 102 if m.Resources == nil { 103 t.Fatal("V2 to V3 upgrade lost module.Resources") 104 } 105 if m.Outputs == nil { 106 t.Fatal("V2 to V3 upgrade lost module.Outputs") 107 } 108 } 109 110 } 111 112 const testV1EmptyState = `{ 113 "version": 1, 114 "serial": 0, 115 "modules": [ 116 { 117 "path": [ 118 "root" 119 ], 120 "outputs": {}, 121 "resources": {} 122 } 123 ] 124 } 125 ` 126 127 const testV1State = `{ 128 "version": 1, 129 "serial": 9, 130 "remote": { 131 "type": "http", 132 "config": { 133 "url": "http://my-cool-server.com/" 134 } 135 }, 136 "modules": [ 137 { 138 "path": [ 139 "root" 140 ], 141 "outputs": null, 142 "resources": { 143 "foo": { 144 "type": "", 145 "primary": { 146 "id": "bar" 147 } 148 } 149 }, 150 "depends_on": [ 151 "aws_instance.bar" 152 ] 153 } 154 ] 155 } 156 ` 157 158 const testV1StateWithOutputs = `{ 159 "version": 1, 160 "serial": 9, 161 "remote": { 162 "type": "http", 163 "config": { 164 "url": "http://my-cool-server.com/" 165 } 166 }, 167 "modules": [ 168 { 169 "path": [ 170 "root" 171 ], 172 "outputs": { 173 "foo": "bar", 174 "baz": "foo" 175 }, 176 "resources": { 177 "foo": { 178 "type": "", 179 "primary": { 180 "id": "bar" 181 } 182 } 183 }, 184 "depends_on": [ 185 "aws_instance.bar" 186 ] 187 } 188 ] 189 } 190 `