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  }