github.com/mitchellh/packer@v1.3.2/builder/qemu/builder_test.go (about)

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