github.phpd.cn/hashicorp/packer@v1.3.2/builder/googlecompute/step_create_instance_test.go (about) 1 package googlecompute 2 3 import ( 4 "context" 5 "errors" 6 "strings" 7 "testing" 8 "time" 9 10 "github.com/hashicorp/packer/helper/multistep" 11 "github.com/stretchr/testify/assert" 12 ) 13 14 func TestStepCreateInstance_impl(t *testing.T) { 15 var _ multistep.Step = new(StepCreateInstance) 16 } 17 18 func TestStepCreateInstance(t *testing.T) { 19 state := testState(t) 20 step := new(StepCreateInstance) 21 defer step.Cleanup(state) 22 23 state.Put("ssh_public_key", "key") 24 25 c := state.Get("config").(*Config) 26 d := state.Get("driver").(*DriverMock) 27 d.GetImageResult = StubImage("test-image", "test-project", []string{}, 100) 28 29 // run the step 30 assert.Equal(t, step.Run(context.Background(), state), multistep.ActionContinue, "Step should have passed and continued.") 31 32 // Verify state 33 nameRaw, ok := state.GetOk("instance_name") 34 assert.True(t, ok, "State should have an instance name.") 35 36 // cleanup 37 step.Cleanup(state) 38 39 // Check args passed to the driver. 40 assert.Equal(t, d.DeleteInstanceName, nameRaw.(string), "Incorrect instance name passed to driver.") 41 assert.Equal(t, d.DeleteInstanceZone, c.Zone, "Incorrect instance zone passed to driver.") 42 assert.Equal(t, d.DeleteDiskName, c.InstanceName, "Incorrect disk name passed to driver.") 43 assert.Equal(t, d.DeleteDiskZone, c.Zone, "Incorrect disk zone passed to driver.") 44 } 45 46 func TestStepCreateInstance_fromFamily(t *testing.T) { 47 cases := []struct { 48 Name string 49 Family string 50 Expect bool 51 }{ 52 {"test-image", "", false}, 53 {"test-image", "test-family", false}, // name trumps family 54 {"", "test-family", true}, 55 } 56 57 for _, tc := range cases { 58 state := testState(t) 59 step := new(StepCreateInstance) 60 defer step.Cleanup(state) 61 62 state.Put("ssh_public_key", "key") 63 64 c := state.Get("config").(*Config) 65 c.SourceImage = tc.Name 66 c.SourceImageFamily = tc.Family 67 d := state.Get("driver").(*DriverMock) 68 d.GetImageResult = StubImage("test-image", "test-project", []string{}, 100) 69 70 // run the step 71 assert.Equal(t, step.Run(context.Background(), state), multistep.ActionContinue, "Step should have passed and continued.") 72 73 // cleanup 74 step.Cleanup(state) 75 76 // Check args passed to the driver. 77 if tc.Expect { 78 assert.True(t, d.GetImageFromFamily, "Driver wasn't instructed to use an image family") 79 } else { 80 assert.False(t, d.GetImageFromFamily, "Driver was unexpectedly instructed to use an image family") 81 } 82 } 83 } 84 85 func TestStepCreateInstance_windowsNeedsPassword(t *testing.T) { 86 87 state := testState(t) 88 step := new(StepCreateInstance) 89 defer step.Cleanup(state) 90 91 state.Put("ssh_public_key", "key") 92 c := state.Get("config").(*Config) 93 d := state.Get("driver").(*DriverMock) 94 d.GetImageResult = StubImage("test-image", "test-project", []string{"windows"}, 100) 95 c.Comm.Type = "winrm" 96 // run the step 97 if action := step.Run(context.Background(), state); action != multistep.ActionContinue { 98 t.Fatalf("bad action: %#v", action) 99 } 100 101 // Verify state 102 nameRaw, ok := state.GetOk("instance_name") 103 if !ok { 104 t.Fatal("should have instance name") 105 } 106 107 createPassword, ok := state.GetOk("create_windows_password") 108 109 if !ok || !createPassword.(bool) { 110 t.Fatal("should need to create a windows password") 111 } 112 113 // cleanup 114 step.Cleanup(state) 115 116 if d.DeleteInstanceName != nameRaw.(string) { 117 t.Fatal("should've deleted instance") 118 } 119 if d.DeleteInstanceZone != c.Zone { 120 t.Fatalf("bad instance zone: %#v", d.DeleteInstanceZone) 121 } 122 123 if d.DeleteDiskName != c.InstanceName { 124 t.Fatal("should've deleted disk") 125 } 126 if d.DeleteDiskZone != c.Zone { 127 t.Fatalf("bad disk zone: %#v", d.DeleteDiskZone) 128 } 129 } 130 131 func TestStepCreateInstance_windowsPasswordSet(t *testing.T) { 132 133 state := testState(t) 134 step := new(StepCreateInstance) 135 defer step.Cleanup(state) 136 137 state.Put("ssh_public_key", "key") 138 139 config := state.Get("config").(*Config) 140 driver := state.Get("driver").(*DriverMock) 141 driver.GetImageResult = StubImage("test-image", "test-project", []string{"windows"}, 100) 142 config.Comm.Type = "winrm" 143 config.Comm.WinRMPassword = "password" 144 145 // run the step 146 if action := step.Run(context.Background(), state); action != multistep.ActionContinue { 147 t.Fatalf("bad action: %#v", action) 148 } 149 150 // Verify state 151 nameRaw, ok := state.GetOk("instance_name") 152 if !ok { 153 t.Fatal("should have instance name") 154 } 155 156 _, ok = state.GetOk("create_windows_password") 157 158 if ok { 159 t.Fatal("should not need to create windows password") 160 } 161 162 // cleanup 163 step.Cleanup(state) 164 165 if driver.DeleteInstanceName != nameRaw.(string) { 166 t.Fatal("should've deleted instance") 167 } 168 if driver.DeleteInstanceZone != config.Zone { 169 t.Fatalf("bad instance zone: %#v", driver.DeleteInstanceZone) 170 } 171 172 if driver.DeleteDiskName != config.InstanceName { 173 t.Fatal("should've deleted disk") 174 } 175 if driver.DeleteDiskZone != config.Zone { 176 t.Fatalf("bad disk zone: %#v", driver.DeleteDiskZone) 177 } 178 } 179 180 func TestStepCreateInstance_error(t *testing.T) { 181 state := testState(t) 182 step := new(StepCreateInstance) 183 defer step.Cleanup(state) 184 185 state.Put("ssh_public_key", "key") 186 187 d := state.Get("driver").(*DriverMock) 188 d.RunInstanceErr = errors.New("error") 189 d.GetImageResult = StubImage("test-image", "test-project", []string{}, 100) 190 191 // run the step 192 assert.Equal(t, step.Run(context.Background(), state), multistep.ActionHalt, "Step should have failed and halted.") 193 194 // Verify state 195 _, ok := state.GetOk("error") 196 assert.True(t, ok, "State should have an error.") 197 _, ok = state.GetOk("instance_name") 198 assert.False(t, ok, "State should not have an instance name.") 199 } 200 201 func TestStepCreateInstance_errorOnChannel(t *testing.T) { 202 state := testState(t) 203 step := new(StepCreateInstance) 204 defer step.Cleanup(state) 205 206 state.Put("ssh_public_key", "key") 207 208 errCh := make(chan error, 1) 209 errCh <- errors.New("error") 210 211 d := state.Get("driver").(*DriverMock) 212 d.RunInstanceErrCh = errCh 213 d.GetImageResult = StubImage("test-image", "test-project", []string{}, 100) 214 215 // run the step 216 assert.Equal(t, step.Run(context.Background(), state), multistep.ActionHalt, "Step should have failed and halted.") 217 218 // Verify state 219 _, ok := state.GetOk("error") 220 assert.True(t, ok, "State should have an error.") 221 _, ok = state.GetOk("instance_name") 222 assert.False(t, ok, "State should not have an instance name.") 223 } 224 225 func TestStepCreateInstance_errorTimeout(t *testing.T) { 226 state := testState(t) 227 step := new(StepCreateInstance) 228 defer step.Cleanup(state) 229 230 state.Put("ssh_public_key", "key") 231 232 errCh := make(chan error, 1) 233 234 config := state.Get("config").(*Config) 235 config.stateTimeout = 1 * time.Microsecond 236 237 d := state.Get("driver").(*DriverMock) 238 d.RunInstanceErrCh = errCh 239 d.GetImageResult = StubImage("test-image", "test-project", []string{}, 100) 240 241 // run the step 242 assert.Equal(t, step.Run(context.Background(), state), multistep.ActionHalt, "Step should have failed and halted.") 243 244 // Verify state 245 _, ok := state.GetOk("error") 246 assert.True(t, ok, "State should have an error.") 247 _, ok = state.GetOk("instance_name") 248 assert.False(t, ok, "State should not have an instance name.") 249 } 250 251 func TestStepCreateInstance_noServiceAccount(t *testing.T) { 252 state := testState(t) 253 step := new(StepCreateInstance) 254 defer step.Cleanup(state) 255 256 state.Put("ssh_public_key", "key") 257 258 c := state.Get("config").(*Config) 259 c.DisableDefaultServiceAccount = true 260 c.ServiceAccountEmail = "" 261 d := state.Get("driver").(*DriverMock) 262 d.GetImageResult = StubImage("test-image", "test-project", []string{}, 100) 263 264 // run the step 265 assert.Equal(t, step.Run(context.Background(), state), multistep.ActionContinue, "Step should have passed and continued.") 266 267 // cleanup 268 step.Cleanup(state) 269 270 // Check args passed to the driver. 271 assert.Equal(t, d.RunInstanceConfig.DisableDefaultServiceAccount, c.DisableDefaultServiceAccount, "Incorrect value for DisableDefaultServiceAccount passed to driver.") 272 assert.Equal(t, d.RunInstanceConfig.ServiceAccountEmail, c.ServiceAccountEmail, "Incorrect value for ServiceAccountEmail passed to driver.") 273 } 274 275 func TestStepCreateInstance_customServiceAccount(t *testing.T) { 276 state := testState(t) 277 step := new(StepCreateInstance) 278 defer step.Cleanup(state) 279 280 state.Put("ssh_public_key", "key") 281 282 c := state.Get("config").(*Config) 283 c.DisableDefaultServiceAccount = true 284 c.ServiceAccountEmail = "custom-service-account" 285 d := state.Get("driver").(*DriverMock) 286 d.GetImageResult = StubImage("test-image", "test-project", []string{}, 100) 287 288 // run the step 289 assert.Equal(t, step.Run(context.Background(), state), multistep.ActionContinue, "Step should have passed and continued.") 290 291 // cleanup 292 step.Cleanup(state) 293 294 // Check args passed to the driver. 295 assert.Equal(t, d.RunInstanceConfig.DisableDefaultServiceAccount, c.DisableDefaultServiceAccount, "Incorrect value for DisableDefaultServiceAccount passed to driver.") 296 assert.Equal(t, d.RunInstanceConfig.ServiceAccountEmail, c.ServiceAccountEmail, "Incorrect value for ServiceAccountEmail passed to driver.") 297 } 298 299 func TestCreateInstanceMetadata(t *testing.T) { 300 state := testState(t) 301 c := state.Get("config").(*Config) 302 image := StubImage("test-image", "test-project", []string{}, 100) 303 key := "abcdefgh12345678" 304 305 // create our metadata 306 metadata, err := c.createInstanceMetadata(image, key) 307 308 assert.True(t, err == nil, "Metadata creation should have succeeded.") 309 310 // ensure our key is listed 311 assert.True(t, strings.Contains(metadata["sshKeys"], key), "Instance metadata should contain provided key") 312 } 313 314 func TestCreateInstanceMetadata_noPublicKey(t *testing.T) { 315 state := testState(t) 316 c := state.Get("config").(*Config) 317 image := StubImage("test-image", "test-project", []string{}, 100) 318 sshKeys := c.Metadata["sshKeys"] 319 320 // create our metadata 321 metadata, err := c.createInstanceMetadata(image, "") 322 323 assert.True(t, err == nil, "Metadata creation should have succeeded.") 324 325 // ensure the ssh metadata hasn't changed 326 assert.Equal(t, metadata["sshKeys"], sshKeys, "Instance metadata should not have been modified") 327 }