github.phpd.cn/hashicorp/packer@v1.3.2/builder/vmware/common/step_configure_vmx_test.go (about) 1 package common 2 3 import ( 4 "context" 5 "io/ioutil" 6 "os" 7 "testing" 8 9 "github.com/hashicorp/packer/helper/multistep" 10 ) 11 12 func testVMXFile(t *testing.T) string { 13 tf, err := ioutil.TempFile("", "packer") 14 if err != nil { 15 t.Fatalf("err: %s", err) 16 } 17 18 // displayName must always be set 19 err = WriteVMX(tf.Name(), map[string]string{"displayName": "PackerBuild"}) 20 tf.Close() 21 22 return tf.Name() 23 } 24 25 func TestStepConfigureVMX_impl(t *testing.T) { 26 var _ multistep.Step = new(StepConfigureVMX) 27 } 28 29 func TestStepConfigureVMX(t *testing.T) { 30 state := testState(t) 31 step := new(StepConfigureVMX) 32 step.CustomData = map[string]string{ 33 "foo": "bar", 34 } 35 36 vmxPath := testVMXFile(t) 37 defer os.Remove(vmxPath) 38 state.Put("vmx_path", vmxPath) 39 40 // Test the run 41 if action := step.Run(context.Background(), state); action != multistep.ActionContinue { 42 t.Fatalf("bad action: %#v", action) 43 } 44 if _, ok := state.GetOk("error"); ok { 45 t.Fatal("should NOT have error") 46 } 47 48 // Test the resulting data 49 vmxContents, err := ioutil.ReadFile(vmxPath) 50 if err != nil { 51 t.Fatalf("err: %s", err) 52 } 53 vmxData := ParseVMX(string(vmxContents)) 54 55 cases := []struct { 56 Key string 57 Value string 58 }{ 59 // Stuff we set 60 {"msg.autoanswer", "true"}, 61 {"uuid.action", "create"}, 62 63 // Custom data 64 {"foo", "bar"}, 65 66 // Stuff that should NOT exist 67 {"floppy0.present", ""}, 68 } 69 70 for _, tc := range cases { 71 if tc.Value == "" { 72 if _, ok := vmxData[tc.Key]; ok { 73 t.Fatalf("should not have key: %s", tc.Key) 74 } 75 } else { 76 if vmxData[tc.Key] != tc.Value { 77 t.Fatalf("bad: %s %#v", tc.Key, vmxData[tc.Key]) 78 } 79 } 80 } 81 } 82 83 func TestStepConfigureVMX_floppyPath(t *testing.T) { 84 state := testState(t) 85 step := new(StepConfigureVMX) 86 87 vmxPath := testVMXFile(t) 88 defer os.Remove(vmxPath) 89 90 state.Put("floppy_path", "foo") 91 state.Put("vmx_path", vmxPath) 92 93 // Test the run 94 if action := step.Run(context.Background(), state); action != multistep.ActionContinue { 95 t.Fatalf("bad action: %#v", action) 96 } 97 if _, ok := state.GetOk("error"); ok { 98 t.Fatal("should NOT have error") 99 } 100 101 // Test the resulting data 102 vmxContents, err := ioutil.ReadFile(vmxPath) 103 if err != nil { 104 t.Fatalf("err: %s", err) 105 } 106 vmxData := ParseVMX(string(vmxContents)) 107 108 cases := []struct { 109 Key string 110 Value string 111 }{ 112 {"floppy0.present", "TRUE"}, 113 {"floppy0.filetype", "file"}, 114 {"floppy0.filename", "foo"}, 115 } 116 117 for _, tc := range cases { 118 if tc.Value == "" { 119 if _, ok := vmxData[tc.Key]; ok { 120 t.Fatalf("should not have key: %s", tc.Key) 121 } 122 } else { 123 if vmxData[tc.Key] != tc.Value { 124 t.Fatalf("bad: %s %#v", tc.Key, vmxData[tc.Key]) 125 } 126 } 127 } 128 129 } 130 131 func TestStepConfigureVMX_generatedAddresses(t *testing.T) { 132 state := testState(t) 133 step := new(StepConfigureVMX) 134 135 vmxPath := testVMXFile(t) 136 defer os.Remove(vmxPath) 137 138 additionalTestVmxData := []struct { 139 Key string 140 Value string 141 }{ 142 {"foo", "bar"}, 143 {"ethernet0.generatedaddress", "foo"}, 144 {"ethernet1.generatedaddress", "foo"}, 145 {"ethernet1.generatedaddressoffset", "foo"}, 146 } 147 148 // Get any existing VMX data from the VMX file 149 vmxData, err := ReadVMX(vmxPath) 150 if err != nil { 151 t.Fatalf("err %s", err) 152 } 153 154 // Add the additional key/value pairs we need for this test to the existing VMX data 155 for _, data := range additionalTestVmxData { 156 vmxData[data.Key] = data.Value 157 } 158 159 // Recreate the VMX file so it includes all the data needed for this test 160 err = WriteVMX(vmxPath, vmxData) 161 if err != nil { 162 t.Fatalf("err: %s", err) 163 } 164 165 state.Put("vmx_path", vmxPath) 166 167 // Test the run 168 if action := step.Run(context.Background(), state); action != multistep.ActionContinue { 169 t.Fatalf("bad action: %#v", action) 170 } 171 if _, ok := state.GetOk("error"); ok { 172 t.Fatal("should NOT have error") 173 } 174 175 // Test the resulting data 176 vmxContents, err := ioutil.ReadFile(vmxPath) 177 if err != nil { 178 t.Fatalf("err: %s", err) 179 } 180 vmxData = ParseVMX(string(vmxContents)) 181 182 cases := []struct { 183 Key string 184 Value string 185 }{ 186 {"foo", "bar"}, 187 {"ethernet0.generatedaddress", ""}, 188 {"ethernet1.generatedaddress", ""}, 189 {"ethernet1.generatedaddressoffset", ""}, 190 } 191 192 for _, tc := range cases { 193 if tc.Value == "" { 194 if _, ok := vmxData[tc.Key]; ok { 195 t.Fatalf("should not have key: %s", tc.Key) 196 } 197 } else { 198 if vmxData[tc.Key] != tc.Value { 199 t.Fatalf("bad: %s %#v", tc.Key, vmxData[tc.Key]) 200 } 201 } 202 } 203 } 204 205 // Should fail if the displayName key is not found in the VMX 206 func TestStepConfigureVMX_displayNameMissing(t *testing.T) { 207 state := testState(t) 208 step := new(StepConfigureVMX) 209 210 // testVMXFile adds displayName key/value pair to the VMX 211 vmxPath := testVMXFile(t) 212 defer os.Remove(vmxPath) 213 214 // Bad: Delete displayName from the VMX/Create an empty VMX file 215 err := WriteVMX(vmxPath, map[string]string{}) 216 if err != nil { 217 t.Fatalf("err: %s", err) 218 } 219 220 state.Put("vmx_path", vmxPath) 221 222 // Test the run 223 if action := step.Run(context.Background(), state); action != multistep.ActionHalt { 224 t.Fatalf("bad action: %#v. Should halt when displayName key is missing from VMX", action) 225 } 226 if _, ok := state.GetOk("error"); !ok { 227 t.Fatal("should store error in state when displayName key is missing from VMX") 228 } 229 } 230 231 // Should store the value of displayName in the statebag 232 func TestStepConfigureVMX_displayNameStore(t *testing.T) { 233 state := testState(t) 234 step := new(StepConfigureVMX) 235 236 // testVMXFile adds displayName key/value pair to the VMX 237 vmxPath := testVMXFile(t) 238 defer os.Remove(vmxPath) 239 240 state.Put("vmx_path", vmxPath) 241 242 // Test the run 243 if action := step.Run(context.Background(), state); action != multistep.ActionContinue { 244 t.Fatalf("bad action: %#v", action) 245 } 246 if _, ok := state.GetOk("error"); ok { 247 t.Fatal("should NOT have error") 248 } 249 250 // The value of displayName must be stored in the statebag 251 if _, ok := state.GetOk("display_name"); !ok { 252 t.Fatalf("displayName should be stored in the statebag as 'display_name'") 253 } 254 } 255 256 func TestStepConfigureVMX_vmxPathBad(t *testing.T) { 257 state := testState(t) 258 step := new(StepConfigureVMX) 259 260 state.Put("vmx_path", "some_bad_path") 261 262 // Test the run 263 if action := step.Run(context.Background(), state); action != multistep.ActionHalt { 264 t.Fatalf("bad action: %#v. Should halt when vmxPath is bad", action) 265 } 266 if _, ok := state.GetOk("error"); !ok { 267 t.Fatal("should store error in state when vmxPath is bad") 268 } 269 270 }