github.com/mmcquillan/packer@v1.1.1-0.20171009221028-c85cf0483a5d/builder/googlecompute/config_test.go (about)

     1  package googlecompute
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"strings"
     7  	"testing"
     8  )
     9  
    10  func TestConfigPrepare(t *testing.T) {
    11  	cases := []struct {
    12  		Key   string
    13  		Value interface{}
    14  		Err   bool
    15  	}{
    16  		{
    17  			"unknown_key",
    18  			"bad",
    19  			true,
    20  		},
    21  
    22  		{
    23  			"private_key_file",
    24  			"/tmp/i/should/not/exist",
    25  			true,
    26  		},
    27  
    28  		{
    29  			"project_id",
    30  			nil,
    31  			true,
    32  		},
    33  		{
    34  			"project_id",
    35  			"foo",
    36  			false,
    37  		},
    38  
    39  		{
    40  			"source_image",
    41  			nil,
    42  			true,
    43  		},
    44  		{
    45  			"source_image",
    46  			"foo",
    47  			false,
    48  		},
    49  
    50  		{
    51  			"source_image_family",
    52  			nil,
    53  			false,
    54  		},
    55  		{
    56  			"source_image_family",
    57  			"foo",
    58  			false,
    59  		},
    60  
    61  		{
    62  			"zone",
    63  			nil,
    64  			true,
    65  		},
    66  		{
    67  			"zone",
    68  			"foo",
    69  			false,
    70  		},
    71  
    72  		{
    73  			"ssh_timeout",
    74  			"SO BAD",
    75  			true,
    76  		},
    77  		{
    78  			"ssh_timeout",
    79  			"5s",
    80  			false,
    81  		},
    82  
    83  		{
    84  			"state_timeout",
    85  			"SO BAD",
    86  			true,
    87  		},
    88  		{
    89  			"state_timeout",
    90  			"5s",
    91  			false,
    92  		},
    93  		{
    94  			"use_internal_ip",
    95  			nil,
    96  			false,
    97  		},
    98  		{
    99  			"use_internal_ip",
   100  			false,
   101  			false,
   102  		},
   103  		{
   104  			"use_internal_ip",
   105  			"SO VERY BAD",
   106  			true,
   107  		},
   108  		{
   109  			"on_host_maintenance",
   110  			nil,
   111  			false,
   112  		},
   113  		{
   114  			"on_host_maintenance",
   115  			"TERMINATE",
   116  			false,
   117  		},
   118  		{
   119  			"on_host_maintenance",
   120  			"SO VERY BAD",
   121  			true,
   122  		},
   123  		{
   124  			"preemptible",
   125  			nil,
   126  			false,
   127  		},
   128  		{
   129  			"preemptible",
   130  			false,
   131  			false,
   132  		},
   133  		{
   134  			"preemptible",
   135  			"SO VERY BAD",
   136  			true,
   137  		},
   138  		{
   139  			"image_family",
   140  			nil,
   141  			false,
   142  		},
   143  		{
   144  			"image_family",
   145  			"",
   146  			false,
   147  		},
   148  		{
   149  			"image_family",
   150  			"foo-bar",
   151  			false,
   152  		},
   153  		{
   154  			"image_family",
   155  			"foo bar",
   156  			true,
   157  		},
   158  		{
   159  			"scopes",
   160  			[]string{},
   161  			false,
   162  		},
   163  		{
   164  			"scopes",
   165  			[]string{"https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/compute", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/sqlservice.admin"},
   166  			false,
   167  		},
   168  		{
   169  			"scopes",
   170  			[]string{"https://www.googleapis.com/auth/cloud-platform"},
   171  			false,
   172  		},
   173  	}
   174  
   175  	for _, tc := range cases {
   176  		raw := testConfig(t)
   177  
   178  		if tc.Value == nil {
   179  			delete(raw, tc.Key)
   180  		} else {
   181  			raw[tc.Key] = tc.Value
   182  		}
   183  
   184  		_, warns, errs := NewConfig(raw)
   185  
   186  		if tc.Err {
   187  			testConfigErr(t, warns, errs, tc.Key)
   188  		} else {
   189  			testConfigOk(t, warns, errs)
   190  		}
   191  	}
   192  }
   193  
   194  func TestConfigPrepareAccelerator(t *testing.T) {
   195  	cases := []struct {
   196  		Keys   []string
   197  		Values []interface{}
   198  		Err    bool
   199  	}{
   200  		{
   201  			[]string{"accelerator_count", "on_host_maintenance", "accelerator_type"},
   202  			[]interface{}{1, "MIGRATE", "something_valid"},
   203  			true,
   204  		},
   205  		{
   206  			[]string{"accelerator_count", "on_host_maintenance", "accelerator_type"},
   207  			[]interface{}{1, "TERMINATE", "something_valid"},
   208  			false,
   209  		},
   210  		{
   211  			[]string{"accelerator_count", "on_host_maintenance", "accelerator_type"},
   212  			[]interface{}{1, "TERMINATE", nil},
   213  			true,
   214  		},
   215  		{
   216  			[]string{"accelerator_count", "on_host_maintenance", "accelerator_type"},
   217  			[]interface{}{1, "TERMINATE", ""},
   218  			true,
   219  		},
   220  		{
   221  			[]string{"accelerator_count", "on_host_maintenance", "accelerator_type"},
   222  			[]interface{}{1, "TERMINATE", "something_valid"},
   223  			false,
   224  		},
   225  	}
   226  
   227  	for _, tc := range cases {
   228  		raw := testConfig(t)
   229  
   230  		errStr := ""
   231  		for k := range tc.Keys {
   232  
   233  			// Create the string for error reporting
   234  			// convert value to string if it can be converted
   235  			errStr += fmt.Sprintf("%s:%v, ", tc.Keys[k], tc.Values[k])
   236  			if tc.Values[k] == nil {
   237  				delete(raw, tc.Keys[k])
   238  			} else {
   239  				raw[tc.Keys[k]] = tc.Values[k]
   240  			}
   241  		}
   242  
   243  		_, warns, errs := NewConfig(raw)
   244  
   245  		if tc.Err {
   246  			testConfigErr(t, warns, errs, strings.TrimRight(errStr, ", "))
   247  		} else {
   248  			testConfigOk(t, warns, errs)
   249  		}
   250  	}
   251  }
   252  
   253  func TestConfigDefaults(t *testing.T) {
   254  	cases := []struct {
   255  		Read  func(c *Config) interface{}
   256  		Value interface{}
   257  	}{
   258  		{
   259  			func(c *Config) interface{} { return c.Comm.Type },
   260  			"ssh",
   261  		},
   262  
   263  		{
   264  			func(c *Config) interface{} { return c.Comm.SSHPort },
   265  			22,
   266  		},
   267  	}
   268  
   269  	for _, tc := range cases {
   270  		raw := testConfig(t)
   271  
   272  		c, warns, errs := NewConfig(raw)
   273  		testConfigOk(t, warns, errs)
   274  
   275  		actual := tc.Read(c)
   276  		if actual != tc.Value {
   277  			t.Fatalf("bad: %#v", actual)
   278  		}
   279  	}
   280  }
   281  
   282  func TestImageName(t *testing.T) {
   283  	c, _, _ := NewConfig(testConfig(t))
   284  	if !strings.HasPrefix(c.ImageName, "packer-") {
   285  		t.Fatalf("ImageName should have 'packer-' prefix, found %s", c.ImageName)
   286  	}
   287  	if strings.Contains(c.ImageName, "{{timestamp}}") {
   288  		t.Errorf("ImageName should be interpolated; found %s", c.ImageName)
   289  	}
   290  }
   291  
   292  func TestRegion(t *testing.T) {
   293  	c, _, _ := NewConfig(testConfig(t))
   294  	if c.Region != "us-east1" {
   295  		t.Fatalf("Region should be 'us-east1' given Zone of 'us-east1-a', but is %s", c.Region)
   296  	}
   297  }
   298  
   299  // Helper stuff below
   300  
   301  func testConfig(t *testing.T) map[string]interface{} {
   302  	return map[string]interface{}{
   303  		"account_file": testAccountFile(t),
   304  		"project_id":   "hashicorp",
   305  		"source_image": "foo",
   306  		"ssh_username": "root",
   307  		"image_family": "bar",
   308  		"image_labels": map[string]string{
   309  			"label-1": "value-1",
   310  			"label-2": "value-2",
   311  		},
   312  		"zone": "us-east1-a",
   313  	}
   314  }
   315  
   316  func testConfigStruct(t *testing.T) *Config {
   317  	c, warns, errs := NewConfig(testConfig(t))
   318  	if len(warns) > 0 {
   319  		t.Fatalf("bad: %#v", len(warns))
   320  	}
   321  	if errs != nil {
   322  		t.Fatalf("bad: %#v", errs)
   323  	}
   324  
   325  	return c
   326  }
   327  
   328  func testConfigErr(t *testing.T, warns []string, err error, extra string) {
   329  	if len(warns) > 0 {
   330  		t.Fatalf("bad: %#v", warns)
   331  	}
   332  	if err == nil {
   333  		t.Fatalf("should error: %s", extra)
   334  	}
   335  }
   336  
   337  func testConfigOk(t *testing.T, warns []string, err error) {
   338  	if len(warns) > 0 {
   339  		t.Fatalf("bad: %#v", warns)
   340  	}
   341  	if err != nil {
   342  		t.Fatalf("bad: %s", err)
   343  	}
   344  }
   345  
   346  func testAccountFile(t *testing.T) string {
   347  	tf, err := ioutil.TempFile("", "packer")
   348  	if err != nil {
   349  		t.Fatalf("err: %s", err)
   350  	}
   351  	defer tf.Close()
   352  
   353  	if _, err := tf.Write([]byte(testAccountContent)); err != nil {
   354  		t.Fatalf("err: %s", err)
   355  	}
   356  
   357  	return tf.Name()
   358  }
   359  
   360  // This is just some dummy data that doesn't actually work (it was revoked
   361  // a long time ago).
   362  const testAccountContent = `{}`