github.com/kimor79/packer@v0.8.7-0.20151221212622-d507b18eb4cf/builder/qemu/builder_test.go (about)

     1  package qemu
     2  
     3  import (
     4  	"github.com/mitchellh/packer/packer"
     5  	"io/ioutil"
     6  	"os"
     7  	"reflect"
     8  	"testing"
     9  )
    10  
    11  var testPem = `
    12  -----BEGIN RSA PRIVATE KEY-----
    13  MIIEpQIBAAKCAQEAxd4iamvrwRJvtNDGQSIbNvvIQN8imXTRWlRY62EvKov60vqu
    14  hh+rDzFYAIIzlmrJopvOe0clqmi3mIP9dtkjPFrYflq52a2CF5q+BdwsJXuRHbJW
    15  LmStZUwW1khSz93DhvhmK50nIaczW63u4EO/jJb3xj+wxR1Nkk9bxi3DDsYFt8SN
    16  AzYx9kjlEYQ/+sI4/ATfmdV9h78SVotjScupd9KFzzi76gWq9gwyCBLRynTUWlyD
    17  2UOfJRkOvhN6/jKzvYfVVwjPSfA9IMuooHdScmC4F6KBKJl/zf/zETM0XyzIDNmH
    18  uOPbCiljq2WoRM+rY6ET84EO0kVXbfx8uxUsqQIDAQABAoIBAQCkPj9TF0IagbM3
    19  5BSs/CKbAWS4dH/D4bPlxx4IRCNirc8GUg+MRb04Xz0tLuajdQDqeWpr6iLZ0RKV
    20  BvreLF+TOdV7DNQ4XE4gSdJyCtCaTHeort/aordL3l0WgfI7mVk0L/yfN1PEG4YG
    21  E9q1TYcyrB3/8d5JwIkjabxERLglCcP+geOEJp+QijbvFIaZR/n2irlKW4gSy6ko
    22  9B0fgUnhkHysSg49ChHQBPQ+o5BbpuLrPDFMiTPTPhdfsvGGcyCGeqfBA56oHcSF
    23  K02Fg8OM+Bd1lb48LAN9nWWY4WbwV+9bkN3Ym8hO4c3a/Dxf2N7LtAQqWZzFjvM3
    24  /AaDvAgBAoGBAPLD+Xn1IYQPMB2XXCXfOuJewRY7RzoVWvMffJPDfm16O7wOiW5+
    25  2FmvxUDayk4PZy6wQMzGeGKnhcMMZTyaq2g/QtGfrvy7q1Lw2fB1VFlVblvqhoJa
    26  nMJojjC4zgjBkXMHsRLeTmgUKyGs+fdFbfI6uejBnnf+eMVUMIdJ+6I9AoGBANCn
    27  kWO9640dttyXURxNJ3lBr2H3dJOkmD6XS+u+LWqCSKQe691Y/fZ/ZL0Oc4Mhy7I6
    28  hsy3kDQ5k2V0fkaNODQIFJvUqXw2pMewUk8hHc9403f4fe9cPrL12rQ8WlQw4yoC
    29  v2B61vNczCCUDtGxlAaw8jzSRaSI5s6ax3K7enbdAoGBAJB1WYDfA2CoAQO6y9Sl
    30  b07A/7kQ8SN5DbPaqrDrBdJziBQxukoMJQXJeGFNUFD/DXFU5Fp2R7C86vXT7HIR
    31  v6m66zH+CYzOx/YE6EsUJms6UP9VIVF0Rg/RU7teXQwM01ZV32LQ8mswhTH20o/3
    32  uqMHmxUMEhZpUMhrfq0isyApAoGAe1UxGTXfj9AqkIVYylPIq2HqGww7+jFmVEj1
    33  9Wi6S6Sq72ffnzzFEPkIQL/UA4TsdHMnzsYKFPSbbXLIWUeMGyVTmTDA5c0e5XIR
    34  lPhMOKCAzv8w4VUzMnEkTzkFY5JqFCD/ojW57KvDdNZPVB+VEcdxyAW6aKELXMAc
    35  eHLc1nkCgYEApm/motCTPN32nINZ+Vvywbv64ZD+gtpeMNP3CLrbe1X9O+H52AXa
    36  1jCoOldWR8i2bs2NVPcKZgdo6fFULqE4dBX7Te/uYEIuuZhYLNzRO1IKU/YaqsXG
    37  3bfQ8hKYcSnTfE0gPtLDnqCIxTocaGLSHeG3TH9fTw+dA8FvWpUztI4=
    38  -----END RSA PRIVATE KEY-----
    39  `
    40  
    41  func testConfig() map[string]interface{} {
    42  	return map[string]interface{}{
    43  		"iso_checksum":            "foo",
    44  		"iso_checksum_type":       "md5",
    45  		"iso_url":                 "http://www.google.com/",
    46  		"ssh_username":            "foo",
    47  		packer.BuildNameConfigKey: "foo",
    48  	}
    49  }
    50  
    51  func TestBuilder_ImplementsBuilder(t *testing.T) {
    52  	var raw interface{}
    53  	raw = &Builder{}
    54  	if _, ok := raw.(packer.Builder); !ok {
    55  		t.Error("Builder must implement builder.")
    56  	}
    57  }
    58  
    59  func TestBuilderPrepare_Defaults(t *testing.T) {
    60  	var b Builder
    61  	config := testConfig()
    62  	warns, err := b.Prepare(config)
    63  	if len(warns) > 0 {
    64  		t.Fatalf("bad: %#v", warns)
    65  	}
    66  	if err != nil {
    67  		t.Fatalf("should not have error: %s", err)
    68  	}
    69  
    70  	if b.config.OutputDir != "output-foo" {
    71  		t.Errorf("bad output dir: %s", b.config.OutputDir)
    72  	}
    73  
    74  	if b.config.SSHHostPortMin != 2222 {
    75  		t.Errorf("bad min ssh host port: %d", b.config.SSHHostPortMin)
    76  	}
    77  
    78  	if b.config.SSHHostPortMax != 4444 {
    79  		t.Errorf("bad max ssh host port: %d", b.config.SSHHostPortMax)
    80  	}
    81  
    82  	if b.config.Comm.SSHPort != 22 {
    83  		t.Errorf("bad ssh port: %d", b.config.Comm.SSHPort)
    84  	}
    85  
    86  	if b.config.VMName != "packer-foo" {
    87  		t.Errorf("bad vm name: %s", b.config.VMName)
    88  	}
    89  
    90  	if b.config.Format != "qcow2" {
    91  		t.Errorf("bad format: %s", b.config.Format)
    92  	}
    93  }
    94  
    95  func TestBuilderPrepare_BootWait(t *testing.T) {
    96  	var b Builder
    97  	config := testConfig()
    98  
    99  	// Test a default boot_wait
   100  	delete(config, "boot_wait")
   101  	warns, err := b.Prepare(config)
   102  	if len(warns) > 0 {
   103  		t.Fatalf("bad: %#v", warns)
   104  	}
   105  	if err != nil {
   106  		t.Fatalf("err: %s", err)
   107  	}
   108  
   109  	if b.config.RawBootWait != "10s" {
   110  		t.Fatalf("bad value: %s", b.config.RawBootWait)
   111  	}
   112  
   113  	// Test with a bad boot_wait
   114  	config["boot_wait"] = "this is not good"
   115  	warns, err = b.Prepare(config)
   116  	if len(warns) > 0 {
   117  		t.Fatalf("bad: %#v", warns)
   118  	}
   119  	if err == nil {
   120  		t.Fatal("should have error")
   121  	}
   122  
   123  	// Test with a good one
   124  	config["boot_wait"] = "5s"
   125  	b = Builder{}
   126  	warns, err = b.Prepare(config)
   127  	if len(warns) > 0 {
   128  		t.Fatalf("bad: %#v", warns)
   129  	}
   130  	if err != nil {
   131  		t.Fatalf("should not have error: %s", err)
   132  	}
   133  }
   134  
   135  func TestBuilderPrepare_DiskCompaction(t *testing.T) {
   136  	var b Builder
   137  	config := testConfig()
   138  
   139  	// Bad
   140  	config["skip_compaction"] = false
   141  	config["disk_compression"] = true
   142  	config["format"] = "img"
   143  	warns, err := b.Prepare(config)
   144  	if len(warns) > 0 {
   145  		t.Fatalf("bad: %#v", warns)
   146  	}
   147  	if err == nil {
   148  		t.Fatal("should have error")
   149  	}
   150  	if b.config.SkipCompaction != true {
   151  		t.Fatalf("SkipCompaction should be true")
   152  	}
   153  	if b.config.DiskCompression != false {
   154  		t.Fatalf("DiskCompression should be false")
   155  	}
   156  
   157  	// Good
   158  	config["skip_compaction"] = false
   159  	config["disk_compression"] = true
   160  	config["format"] = "qcow2"
   161  	b = Builder{}
   162  	warns, err = b.Prepare(config)
   163  	if len(warns) > 0 {
   164  		t.Fatalf("bad: %#v", warns)
   165  	}
   166  	if err != nil {
   167  		t.Fatalf("should not have error: %s", err)
   168  	}
   169  	if b.config.SkipCompaction != false {
   170  		t.Fatalf("SkipCompaction should be false")
   171  	}
   172  	if b.config.DiskCompression != true {
   173  		t.Fatalf("DiskCompression should be true")
   174  	}
   175  }
   176  
   177  func TestBuilderPrepare_DiskSize(t *testing.T) {
   178  	var b Builder
   179  	config := testConfig()
   180  
   181  	delete(config, "disk_size")
   182  	warns, err := b.Prepare(config)
   183  	if len(warns) > 0 {
   184  		t.Fatalf("bad: %#v", warns)
   185  	}
   186  	if err != nil {
   187  		t.Fatalf("bad err: %s", err)
   188  	}
   189  
   190  	if b.config.DiskSize != 40000 {
   191  		t.Fatalf("bad size: %d", b.config.DiskSize)
   192  	}
   193  
   194  	config["disk_size"] = 60000
   195  	b = Builder{}
   196  	warns, err = b.Prepare(config)
   197  	if len(warns) > 0 {
   198  		t.Fatalf("bad: %#v", warns)
   199  	}
   200  	if err != nil {
   201  		t.Fatalf("should not have error: %s", err)
   202  	}
   203  
   204  	if b.config.DiskSize != 60000 {
   205  		t.Fatalf("bad size: %d", b.config.DiskSize)
   206  	}
   207  }
   208  
   209  func TestBuilderPrepare_HTTPPort(t *testing.T) {
   210  	var b Builder
   211  	config := testConfig()
   212  
   213  	// Bad
   214  	config["http_port_min"] = 1000
   215  	config["http_port_max"] = 500
   216  	warns, err := b.Prepare(config)
   217  	if len(warns) > 0 {
   218  		t.Fatalf("bad: %#v", warns)
   219  	}
   220  	if err == nil {
   221  		t.Fatal("should have error")
   222  	}
   223  
   224  	// Bad
   225  	config["http_port_min"] = -500
   226  	b = Builder{}
   227  	warns, err = b.Prepare(config)
   228  	if len(warns) > 0 {
   229  		t.Fatalf("bad: %#v", warns)
   230  	}
   231  	if err == nil {
   232  		t.Fatal("should have error")
   233  	}
   234  
   235  	// Good
   236  	config["http_port_min"] = 500
   237  	config["http_port_max"] = 1000
   238  	b = Builder{}
   239  	warns, err = b.Prepare(config)
   240  	if len(warns) > 0 {
   241  		t.Fatalf("bad: %#v", warns)
   242  	}
   243  	if err != nil {
   244  		t.Fatalf("should not have error: %s", err)
   245  	}
   246  }
   247  
   248  func TestBuilderPrepare_Format(t *testing.T) {
   249  	var b Builder
   250  	config := testConfig()
   251  
   252  	// Bad
   253  	config["format"] = "illegal value"
   254  	warns, err := b.Prepare(config)
   255  	if len(warns) > 0 {
   256  		t.Fatalf("bad: %#v", warns)
   257  	}
   258  	if err == nil {
   259  		t.Fatal("should have error")
   260  	}
   261  
   262  	// Good
   263  	config["format"] = "qcow2"
   264  	b = Builder{}
   265  	warns, err = b.Prepare(config)
   266  	if len(warns) > 0 {
   267  		t.Fatalf("bad: %#v", warns)
   268  	}
   269  	if err != nil {
   270  		t.Fatalf("should not have error: %s", err)
   271  	}
   272  
   273  	// Good
   274  	config["format"] = "raw"
   275  	b = Builder{}
   276  	warns, err = b.Prepare(config)
   277  	if len(warns) > 0 {
   278  		t.Fatalf("bad: %#v", warns)
   279  	}
   280  	if err != nil {
   281  		t.Fatalf("should not have error: %s", err)
   282  	}
   283  }
   284  
   285  func TestBuilderPrepare_InvalidKey(t *testing.T) {
   286  	var b Builder
   287  	config := testConfig()
   288  
   289  	// Add a random key
   290  	config["i_should_not_be_valid"] = true
   291  	warns, err := b.Prepare(config)
   292  	if len(warns) > 0 {
   293  		t.Fatalf("bad: %#v", warns)
   294  	}
   295  	if err == nil {
   296  		t.Fatal("should have error")
   297  	}
   298  }
   299  
   300  func TestBuilderPrepare_OutputDir(t *testing.T) {
   301  	var b Builder
   302  	config := testConfig()
   303  
   304  	// Test with existing dir
   305  	dir, err := ioutil.TempDir("", "packer")
   306  	if err != nil {
   307  		t.Fatalf("err: %s", err)
   308  	}
   309  	defer os.RemoveAll(dir)
   310  
   311  	config["output_directory"] = dir
   312  	b = Builder{}
   313  	warns, err := b.Prepare(config)
   314  	if len(warns) > 0 {
   315  		t.Fatalf("bad: %#v", warns)
   316  	}
   317  	if err == nil {
   318  		t.Fatal("should have error")
   319  	}
   320  
   321  	// Test with a good one
   322  	config["output_directory"] = "i-hope-i-dont-exist"
   323  	b = Builder{}
   324  	warns, err = b.Prepare(config)
   325  	if len(warns) > 0 {
   326  		t.Fatalf("bad: %#v", warns)
   327  	}
   328  	if err != nil {
   329  		t.Fatalf("should not have error: %s", err)
   330  	}
   331  }
   332  
   333  func TestBuilderPrepare_ShutdownTimeout(t *testing.T) {
   334  	var b Builder
   335  	config := testConfig()
   336  
   337  	// Test with a bad value
   338  	config["shutdown_timeout"] = "this is not good"
   339  	warns, err := b.Prepare(config)
   340  	if len(warns) > 0 {
   341  		t.Fatalf("bad: %#v", warns)
   342  	}
   343  	if err == nil {
   344  		t.Fatal("should have error")
   345  	}
   346  
   347  	// Test with a good one
   348  	config["shutdown_timeout"] = "5s"
   349  	b = Builder{}
   350  	warns, err = b.Prepare(config)
   351  	if len(warns) > 0 {
   352  		t.Fatalf("bad: %#v", warns)
   353  	}
   354  	if err != nil {
   355  		t.Fatalf("should not have error: %s", err)
   356  	}
   357  }
   358  
   359  func TestBuilderPrepare_SSHHostPort(t *testing.T) {
   360  	var b Builder
   361  	config := testConfig()
   362  
   363  	// Bad
   364  	config["ssh_host_port_min"] = 1000
   365  	config["ssh_host_port_max"] = 500
   366  	b = Builder{}
   367  	warns, err := b.Prepare(config)
   368  	if len(warns) > 0 {
   369  		t.Fatalf("bad: %#v", warns)
   370  	}
   371  	if err == nil {
   372  		t.Fatal("should have error")
   373  	}
   374  
   375  	// Bad
   376  	config["ssh_host_port_min"] = -500
   377  	b = Builder{}
   378  	warns, err = b.Prepare(config)
   379  	if len(warns) > 0 {
   380  		t.Fatalf("bad: %#v", warns)
   381  	}
   382  	if err == nil {
   383  		t.Fatal("should have error")
   384  	}
   385  
   386  	// Good
   387  	config["ssh_host_port_min"] = 500
   388  	config["ssh_host_port_max"] = 1000
   389  	b = Builder{}
   390  	warns, err = b.Prepare(config)
   391  	if len(warns) > 0 {
   392  		t.Fatalf("bad: %#v", warns)
   393  	}
   394  	if err != nil {
   395  		t.Fatalf("should not have error: %s", err)
   396  	}
   397  }
   398  
   399  func TestBuilderPrepare_sshKeyPath(t *testing.T) {
   400  	var b Builder
   401  	config := testConfig()
   402  
   403  	config["ssh_key_path"] = ""
   404  	b = Builder{}
   405  	warns, err := b.Prepare(config)
   406  	if len(warns) > 0 {
   407  		t.Fatalf("bad: %#v", warns)
   408  	}
   409  	if err != nil {
   410  		t.Fatalf("should not have error: %s", err)
   411  	}
   412  
   413  	config["ssh_key_path"] = "/i/dont/exist"
   414  	b = Builder{}
   415  	warns, err = b.Prepare(config)
   416  	if len(warns) > 0 {
   417  		t.Fatalf("bad: %#v", warns)
   418  	}
   419  	if err == nil {
   420  		t.Fatal("should have error")
   421  	}
   422  
   423  	// Test bad contents
   424  	tf, err := ioutil.TempFile("", "packer")
   425  	if err != nil {
   426  		t.Fatalf("err: %s", err)
   427  	}
   428  	defer os.Remove(tf.Name())
   429  	defer tf.Close()
   430  
   431  	if _, err := tf.Write([]byte("HELLO!")); err != nil {
   432  		t.Fatalf("err: %s", err)
   433  	}
   434  
   435  	config["ssh_key_path"] = tf.Name()
   436  	b = Builder{}
   437  	warns, err = b.Prepare(config)
   438  	if len(warns) > 0 {
   439  		t.Fatalf("bad: %#v", warns)
   440  	}
   441  	if err == nil {
   442  		t.Fatal("should have error")
   443  	}
   444  
   445  	// Test good contents
   446  	tf.Seek(0, 0)
   447  	tf.Truncate(0)
   448  	tf.Write([]byte(testPem))
   449  	config["ssh_key_path"] = tf.Name()
   450  	b = Builder{}
   451  	warns, err = b.Prepare(config)
   452  	if len(warns) > 0 {
   453  		t.Fatalf("bad: %#v", warns)
   454  	}
   455  	if err != nil {
   456  		t.Fatalf("err: %s", err)
   457  	}
   458  }
   459  
   460  func TestBuilderPrepare_SSHUser(t *testing.T) {
   461  	var b Builder
   462  	config := testConfig()
   463  
   464  	config["ssh_username"] = ""
   465  	b = Builder{}
   466  	warns, err := b.Prepare(config)
   467  	if len(warns) > 0 {
   468  		t.Fatalf("bad: %#v", warns)
   469  	}
   470  	if err == nil {
   471  		t.Fatal("should have error")
   472  	}
   473  
   474  	config["ssh_username"] = "exists"
   475  	b = Builder{}
   476  	warns, err = b.Prepare(config)
   477  	if len(warns) > 0 {
   478  		t.Fatalf("bad: %#v", warns)
   479  	}
   480  	if err != nil {
   481  		t.Fatalf("should not have error: %s", err)
   482  	}
   483  }
   484  
   485  func TestBuilderPrepare_SSHWaitTimeout(t *testing.T) {
   486  	var b Builder
   487  	config := testConfig()
   488  
   489  	// Test a default boot_wait
   490  	delete(config, "ssh_wait_timeout")
   491  	warns, err := b.Prepare(config)
   492  	if len(warns) > 0 {
   493  		t.Fatalf("bad: %#v", warns)
   494  	}
   495  	if err != nil {
   496  		t.Fatalf("err: %s", err)
   497  	}
   498  
   499  	// Test with a bad value
   500  	config["ssh_wait_timeout"] = "this is not good"
   501  	b = Builder{}
   502  	warns, err = b.Prepare(config)
   503  	if len(warns) > 0 {
   504  		t.Fatalf("bad: %#v", warns)
   505  	}
   506  	if err == nil {
   507  		t.Fatal("should have error")
   508  	}
   509  
   510  	// Test with a good one
   511  	config["ssh_wait_timeout"] = "5s"
   512  	b = Builder{}
   513  	warns, err = b.Prepare(config)
   514  	if len(warns) > 0 {
   515  		t.Fatalf("bad: %#v", warns)
   516  	}
   517  	if err != nil {
   518  		t.Fatalf("should not have error: %s", err)
   519  	}
   520  }
   521  
   522  func TestBuilderPrepare_QemuArgs(t *testing.T) {
   523  	var b Builder
   524  	config := testConfig()
   525  
   526  	// Test with empty
   527  	delete(config, "qemuargs")
   528  	warns, err := b.Prepare(config)
   529  	if len(warns) > 0 {
   530  		t.Fatalf("bad: %#v", warns)
   531  	}
   532  	if err != nil {
   533  		t.Fatalf("err: %s", err)
   534  	}
   535  
   536  	if !reflect.DeepEqual(b.config.QemuArgs, [][]string{}) {
   537  		t.Fatalf("bad: %#v", b.config.QemuArgs)
   538  	}
   539  
   540  	// Test with a good one
   541  	config["qemuargs"] = [][]interface{}{
   542  		[]interface{}{"foo", "bar", "baz"},
   543  	}
   544  
   545  	b = Builder{}
   546  	warns, err = b.Prepare(config)
   547  	if len(warns) > 0 {
   548  		t.Fatalf("bad: %#v", warns)
   549  	}
   550  	if err != nil {
   551  		t.Fatalf("should not have error: %s", err)
   552  	}
   553  
   554  	expected := [][]string{
   555  		[]string{"foo", "bar", "baz"},
   556  	}
   557  
   558  	if !reflect.DeepEqual(b.config.QemuArgs, expected) {
   559  		t.Fatalf("bad: %#v", b.config.QemuArgs)
   560  	}
   561  }