github.com/adrian-bl/terraform@v0.7.0-rc2.0.20160705220747-de0a34fc3517/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.Fatalf("bad: %#v", actual) 39 } 40 } 41 42 func TestReadUpgradeStateV1toV3_outputs(t *testing.T) { 43 // ReadState should transparently detect the old version but will upgrade 44 // it on Write. 45 actual, err := ReadState(strings.NewReader(testV1StateWithOutputs)) 46 if err != nil { 47 t.Fatalf("err: %s", err) 48 } 49 50 buf := new(bytes.Buffer) 51 if err := WriteState(actual, buf); err != nil { 52 t.Fatalf("err: %s", err) 53 } 54 55 if actual.Version != 3 { 56 t.Fatalf("bad: State version not incremented; is %d", actual.Version) 57 } 58 59 roundTripped, err := ReadState(buf) 60 if err != nil { 61 t.Fatalf("err: %s", err) 62 } 63 64 if !reflect.DeepEqual(actual, roundTripped) { 65 spew.Config.DisableMethods = true 66 t.Fatalf("bad:\n%s\n\nround tripped:\n%s\n", spew.Sdump(actual), spew.Sdump(roundTripped)) 67 spew.Config.DisableMethods = false 68 } 69 } 70 71 // Upgrading the state should not lose empty module Outputs and Resources maps 72 // during upgrade. The init for a new module initializes new maps, so we may not 73 // be expecting to check for a nil map. 74 func TestReadUpgradeStateV1toV3_emptyState(t *testing.T) { 75 // ReadState should transparently detect the old version but will upgrade 76 // it on Write. 77 orig, err := ReadStateV1([]byte(testV1EmptyState)) 78 if err != nil { 79 t.Fatalf("err: %s", err) 80 } 81 82 stateV2, err := upgradeStateV1ToV2(orig) 83 for _, m := range stateV2.Modules { 84 if m.Resources == nil { 85 t.Fatal("V1 to V2 upgrade lost module.Resources") 86 } 87 if m.Outputs == nil { 88 t.Fatal("V1 to V2 upgrade lost module.Outputs") 89 } 90 } 91 92 stateV3, err := upgradeStateV2ToV3(stateV2) 93 for _, m := range stateV3.Modules { 94 if m.Resources == nil { 95 t.Fatal("V2 to V3 upgrade lost module.Resources") 96 } 97 if m.Outputs == nil { 98 t.Fatal("V2 to V3 upgrade lost module.Outputs") 99 } 100 } 101 102 } 103 104 const testV1EmptyState = `{ 105 "version": 1, 106 "serial": 0, 107 "modules": [ 108 { 109 "path": [ 110 "root" 111 ], 112 "outputs": {}, 113 "resources": {} 114 } 115 ] 116 } 117 ` 118 119 const testV1State = `{ 120 "version": 1, 121 "serial": 9, 122 "remote": { 123 "type": "http", 124 "config": { 125 "url": "http://my-cool-server.com/" 126 } 127 }, 128 "modules": [ 129 { 130 "path": [ 131 "root" 132 ], 133 "outputs": null, 134 "resources": { 135 "foo": { 136 "type": "", 137 "primary": { 138 "id": "bar" 139 } 140 } 141 }, 142 "depends_on": [ 143 "aws_instance.bar" 144 ] 145 } 146 ] 147 } 148 ` 149 150 const testV1StateWithOutputs = `{ 151 "version": 1, 152 "serial": 9, 153 "remote": { 154 "type": "http", 155 "config": { 156 "url": "http://my-cool-server.com/" 157 } 158 }, 159 "modules": [ 160 { 161 "path": [ 162 "root" 163 ], 164 "outputs": { 165 "foo": "bar", 166 "baz": "foo" 167 }, 168 "resources": { 169 "foo": { 170 "type": "", 171 "primary": { 172 "id": "bar" 173 } 174 } 175 }, 176 "depends_on": [ 177 "aws_instance.bar" 178 ] 179 } 180 ] 181 } 182 `