github.com/rahart/packer@v0.12.2-0.20161229105310-282bb6ad370f/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/mitchellh/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_BootWait(t *testing.T) {
    98  	var b Builder
    99  	config := testConfig()
   100  
   101  	// Test a default boot_wait
   102  	delete(config, "boot_wait")
   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.RawBootWait != "10s" {
   112  		t.Fatalf("bad value: %s", b.config.RawBootWait)
   113  	}
   114  
   115  	// Test with a bad boot_wait
   116  	config["boot_wait"] = "this is not good"
   117  	warns, err = b.Prepare(config)
   118  	if len(warns) > 0 {
   119  		t.Fatalf("bad: %#v", warns)
   120  	}
   121  	if err == nil {
   122  		t.Fatal("should have error")
   123  	}
   124  
   125  	// Test with a good one
   126  	config["boot_wait"] = "5s"
   127  	b = Builder{}
   128  	warns, err = b.Prepare(config)
   129  	if len(warns) > 0 {
   130  		t.Fatalf("bad: %#v", warns)
   131  	}
   132  	if err != nil {
   133  		t.Fatalf("should not have error: %s", err)
   134  	}
   135  }
   136  
   137  func TestBuilderPrepare_VNCBindAddress(t *testing.T) {
   138  	var b Builder
   139  	config := testConfig()
   140  
   141  	// Test a default boot_wait
   142  	delete(config, "vnc_bind_address")
   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("err: %s", err)
   149  	}
   150  
   151  	if b.config.VNCBindAddress != "127.0.0.1" {
   152  		t.Fatalf("bad value: %s", b.config.VNCBindAddress)
   153  	}
   154  }
   155  
   156  func TestBuilderPrepare_DiskCompaction(t *testing.T) {
   157  	var b Builder
   158  	config := testConfig()
   159  
   160  	// Bad
   161  	config["skip_compaction"] = false
   162  	config["disk_compression"] = true
   163  	config["format"] = "img"
   164  	warns, err := b.Prepare(config)
   165  	if len(warns) > 0 {
   166  		t.Fatalf("bad: %#v", warns)
   167  	}
   168  	if err == nil {
   169  		t.Fatal("should have error")
   170  	}
   171  	if b.config.SkipCompaction != true {
   172  		t.Fatalf("SkipCompaction should be true")
   173  	}
   174  	if b.config.DiskCompression != false {
   175  		t.Fatalf("DiskCompression should be false")
   176  	}
   177  
   178  	// Good
   179  	config["skip_compaction"] = false
   180  	config["disk_compression"] = true
   181  	config["format"] = "qcow2"
   182  	b = Builder{}
   183  	warns, err = b.Prepare(config)
   184  	if len(warns) > 0 {
   185  		t.Fatalf("bad: %#v", warns)
   186  	}
   187  	if err != nil {
   188  		t.Fatalf("should not have error: %s", err)
   189  	}
   190  	if b.config.SkipCompaction != false {
   191  		t.Fatalf("SkipCompaction should be false")
   192  	}
   193  	if b.config.DiskCompression != true {
   194  		t.Fatalf("DiskCompression should be true")
   195  	}
   196  }
   197  
   198  func TestBuilderPrepare_DiskSize(t *testing.T) {
   199  	var b Builder
   200  	config := testConfig()
   201  
   202  	delete(config, "disk_size")
   203  	warns, err := b.Prepare(config)
   204  	if len(warns) > 0 {
   205  		t.Fatalf("bad: %#v", warns)
   206  	}
   207  	if err != nil {
   208  		t.Fatalf("bad err: %s", err)
   209  	}
   210  
   211  	if b.config.DiskSize != 40000 {
   212  		t.Fatalf("bad size: %d", b.config.DiskSize)
   213  	}
   214  
   215  	config["disk_size"] = 60000
   216  	b = Builder{}
   217  	warns, err = b.Prepare(config)
   218  	if len(warns) > 0 {
   219  		t.Fatalf("bad: %#v", warns)
   220  	}
   221  	if err != nil {
   222  		t.Fatalf("should not have error: %s", err)
   223  	}
   224  
   225  	if b.config.DiskSize != 60000 {
   226  		t.Fatalf("bad size: %d", b.config.DiskSize)
   227  	}
   228  }
   229  
   230  func TestBuilderPrepare_Format(t *testing.T) {
   231  	var b Builder
   232  	config := testConfig()
   233  
   234  	// Bad
   235  	config["format"] = "illegal value"
   236  	warns, err := b.Prepare(config)
   237  	if len(warns) > 0 {
   238  		t.Fatalf("bad: %#v", warns)
   239  	}
   240  	if err == nil {
   241  		t.Fatal("should have error")
   242  	}
   243  
   244  	// Good
   245  	config["format"] = "qcow2"
   246  	b = Builder{}
   247  	warns, err = b.Prepare(config)
   248  	if len(warns) > 0 {
   249  		t.Fatalf("bad: %#v", warns)
   250  	}
   251  	if err != nil {
   252  		t.Fatalf("should not have error: %s", err)
   253  	}
   254  
   255  	// Good
   256  	config["format"] = "raw"
   257  	b = Builder{}
   258  	warns, err = b.Prepare(config)
   259  	if len(warns) > 0 {
   260  		t.Fatalf("bad: %#v", warns)
   261  	}
   262  	if err != nil {
   263  		t.Fatalf("should not have error: %s", err)
   264  	}
   265  }
   266  
   267  func TestBuilderPrepare_FloppyFiles(t *testing.T) {
   268  	var b Builder
   269  	config := testConfig()
   270  
   271  	delete(config, "floppy_files")
   272  	warns, err := b.Prepare(config)
   273  	if len(warns) > 0 {
   274  		t.Fatalf("bad: %#v", warns)
   275  	}
   276  	if err != nil {
   277  		t.Fatalf("bad err: %s", err)
   278  	}
   279  
   280  	if len(b.config.FloppyFiles) != 0 {
   281  		t.Fatalf("bad: %#v", b.config.FloppyFiles)
   282  	}
   283  
   284  	floppies_path := "../../common/test-fixtures/floppies"
   285  	config["floppy_files"] = []string{fmt.Sprintf("%s/bar.bat", floppies_path), fmt.Sprintf("%s/foo.ps1", floppies_path)}
   286  	b = Builder{}
   287  	warns, err = b.Prepare(config)
   288  	if len(warns) > 0 {
   289  		t.Fatalf("bad: %#v", warns)
   290  	}
   291  	if err != nil {
   292  		t.Fatalf("should not have error: %s", err)
   293  	}
   294  
   295  	expected := []string{fmt.Sprintf("%s/bar.bat", floppies_path), fmt.Sprintf("%s/foo.ps1", floppies_path)}
   296  	if !reflect.DeepEqual(b.config.FloppyFiles, expected) {
   297  		t.Fatalf("bad: %#v", b.config.FloppyFiles)
   298  	}
   299  }
   300  
   301  func TestBuilderPrepare_InvalidFloppies(t *testing.T) {
   302  	var b Builder
   303  	config := testConfig()
   304  	config["floppy_files"] = []string{"nonexistant.bat", "nonexistant.ps1"}
   305  	b = Builder{}
   306  	_, errs := b.Prepare(config)
   307  	if errs == nil {
   308  		t.Fatalf("Non existant floppies should trigger multierror")
   309  	}
   310  
   311  	if len(errs.(*packer.MultiError).Errors) != 2 {
   312  		t.Fatalf("Multierror should work and report 2 errors")
   313  	}
   314  }
   315  
   316  func TestBuilderPrepare_InvalidKey(t *testing.T) {
   317  	var b Builder
   318  	config := testConfig()
   319  
   320  	// Add a random key
   321  	config["i_should_not_be_valid"] = true
   322  	warns, err := b.Prepare(config)
   323  	if len(warns) > 0 {
   324  		t.Fatalf("bad: %#v", warns)
   325  	}
   326  	if err == nil {
   327  		t.Fatal("should have error")
   328  	}
   329  }
   330  
   331  func TestBuilderPrepare_OutputDir(t *testing.T) {
   332  	var b Builder
   333  	config := testConfig()
   334  
   335  	// Test with existing dir
   336  	dir, err := ioutil.TempDir("", "packer")
   337  	if err != nil {
   338  		t.Fatalf("err: %s", err)
   339  	}
   340  	defer os.RemoveAll(dir)
   341  
   342  	config["output_directory"] = dir
   343  	b = Builder{}
   344  	warns, err := b.Prepare(config)
   345  	if len(warns) > 0 {
   346  		t.Fatalf("bad: %#v", warns)
   347  	}
   348  	if err == nil {
   349  		t.Fatal("should have error")
   350  	}
   351  
   352  	// Test with a good one
   353  	config["output_directory"] = "i-hope-i-dont-exist"
   354  	b = Builder{}
   355  	warns, err = b.Prepare(config)
   356  	if len(warns) > 0 {
   357  		t.Fatalf("bad: %#v", warns)
   358  	}
   359  	if err != nil {
   360  		t.Fatalf("should not have error: %s", err)
   361  	}
   362  }
   363  
   364  func TestBuilderPrepare_ShutdownTimeout(t *testing.T) {
   365  	var b Builder
   366  	config := testConfig()
   367  
   368  	// Test with a bad value
   369  	config["shutdown_timeout"] = "this is not good"
   370  	warns, err := b.Prepare(config)
   371  	if len(warns) > 0 {
   372  		t.Fatalf("bad: %#v", warns)
   373  	}
   374  	if err == nil {
   375  		t.Fatal("should have error")
   376  	}
   377  
   378  	// Test with a good one
   379  	config["shutdown_timeout"] = "5s"
   380  	b = Builder{}
   381  	warns, err = b.Prepare(config)
   382  	if len(warns) > 0 {
   383  		t.Fatalf("bad: %#v", warns)
   384  	}
   385  	if err != nil {
   386  		t.Fatalf("should not have error: %s", err)
   387  	}
   388  }
   389  
   390  func TestBuilderPrepare_SSHHostPort(t *testing.T) {
   391  	var b Builder
   392  	config := testConfig()
   393  
   394  	// Bad
   395  	config["ssh_host_port_min"] = 1000
   396  	config["ssh_host_port_max"] = 500
   397  	b = Builder{}
   398  	warns, err := b.Prepare(config)
   399  	if len(warns) > 0 {
   400  		t.Fatalf("bad: %#v", warns)
   401  	}
   402  	if err == nil {
   403  		t.Fatal("should have error")
   404  	}
   405  
   406  	// Bad
   407  	config["ssh_host_port_min"] = -500
   408  	b = Builder{}
   409  	warns, err = b.Prepare(config)
   410  	if len(warns) > 0 {
   411  		t.Fatalf("bad: %#v", warns)
   412  	}
   413  	if err == nil {
   414  		t.Fatal("should have error")
   415  	}
   416  
   417  	// Good
   418  	config["ssh_host_port_min"] = 500
   419  	config["ssh_host_port_max"] = 1000
   420  	b = Builder{}
   421  	warns, err = b.Prepare(config)
   422  	if len(warns) > 0 {
   423  		t.Fatalf("bad: %#v", warns)
   424  	}
   425  	if err != nil {
   426  		t.Fatalf("should not have error: %s", err)
   427  	}
   428  }
   429  
   430  func TestBuilderPrepare_SSHPrivateKey(t *testing.T) {
   431  	var b Builder
   432  	config := testConfig()
   433  
   434  	config["ssh_private_key_file"] = ""
   435  	b = Builder{}
   436  	warns, err := b.Prepare(config)
   437  	if len(warns) > 0 {
   438  		t.Fatalf("bad: %#v", warns)
   439  	}
   440  	if err != nil {
   441  		t.Fatalf("should not have error: %s", err)
   442  	}
   443  
   444  	config["ssh_private_key_file"] = "/i/dont/exist"
   445  	b = Builder{}
   446  	warns, err = b.Prepare(config)
   447  	if len(warns) > 0 {
   448  		t.Fatalf("bad: %#v", warns)
   449  	}
   450  	if err == nil {
   451  		t.Fatal("should have error")
   452  	}
   453  
   454  	// Test bad contents
   455  	tf, err := ioutil.TempFile("", "packer")
   456  	if err != nil {
   457  		t.Fatalf("err: %s", err)
   458  	}
   459  	defer os.Remove(tf.Name())
   460  	defer tf.Close()
   461  
   462  	if _, err := tf.Write([]byte("HELLO!")); err != nil {
   463  		t.Fatalf("err: %s", err)
   464  	}
   465  
   466  	config["ssh_private_key_file"] = tf.Name()
   467  	b = Builder{}
   468  	warns, err = b.Prepare(config)
   469  	if len(warns) > 0 {
   470  		t.Fatalf("bad: %#v", warns)
   471  	}
   472  	if err == nil {
   473  		t.Fatal("should have error")
   474  	}
   475  
   476  	// Test good contents
   477  	tf.Seek(0, 0)
   478  	tf.Truncate(0)
   479  	tf.Write([]byte(testPem))
   480  	config["ssh_private_key_file"] = tf.Name()
   481  	b = Builder{}
   482  	warns, err = b.Prepare(config)
   483  	if len(warns) > 0 {
   484  		t.Fatalf("bad: %#v", warns)
   485  	}
   486  	if err != nil {
   487  		t.Fatalf("err: %s", err)
   488  	}
   489  }
   490  
   491  func TestBuilderPrepare_SSHWaitTimeout(t *testing.T) {
   492  	var b Builder
   493  	config := testConfig()
   494  
   495  	// Test a default boot_wait
   496  	delete(config, "ssh_wait_timeout")
   497  	warns, err := b.Prepare(config)
   498  	if len(warns) > 0 {
   499  		t.Fatalf("bad: %#v", warns)
   500  	}
   501  	if err != nil {
   502  		t.Fatalf("err: %s", err)
   503  	}
   504  
   505  	// Test with a bad value
   506  	config["ssh_wait_timeout"] = "this is not good"
   507  	b = Builder{}
   508  	warns, err = b.Prepare(config)
   509  	if len(warns) > 0 {
   510  		t.Fatalf("bad: %#v", warns)
   511  	}
   512  	if err == nil {
   513  		t.Fatal("should have error")
   514  	}
   515  
   516  	// Test with a good one
   517  	config["ssh_wait_timeout"] = "5s"
   518  	b = Builder{}
   519  	warns, err = b.Prepare(config)
   520  	if len(warns) > 0 {
   521  		t.Fatalf("bad: %#v", warns)
   522  	}
   523  	if err != nil {
   524  		t.Fatalf("should not have error: %s", err)
   525  	}
   526  }
   527  
   528  func TestBuilderPrepare_QemuArgs(t *testing.T) {
   529  	var b Builder
   530  	config := testConfig()
   531  
   532  	// Test with empty
   533  	delete(config, "qemuargs")
   534  	warns, err := b.Prepare(config)
   535  	if len(warns) > 0 {
   536  		t.Fatalf("bad: %#v", warns)
   537  	}
   538  	if err != nil {
   539  		t.Fatalf("err: %s", err)
   540  	}
   541  
   542  	if !reflect.DeepEqual(b.config.QemuArgs, [][]string{}) {
   543  		t.Fatalf("bad: %#v", b.config.QemuArgs)
   544  	}
   545  
   546  	// Test with a good one
   547  	config["qemuargs"] = [][]interface{}{
   548  		{"foo", "bar", "baz"},
   549  	}
   550  
   551  	b = Builder{}
   552  	warns, err = b.Prepare(config)
   553  	if len(warns) > 0 {
   554  		t.Fatalf("bad: %#v", warns)
   555  	}
   556  	if err != nil {
   557  		t.Fatalf("should not have error: %s", err)
   558  	}
   559  
   560  	expected := [][]string{
   561  		{"foo", "bar", "baz"},
   562  	}
   563  
   564  	if !reflect.DeepEqual(b.config.QemuArgs, expected) {
   565  		t.Fatalf("bad: %#v", b.config.QemuArgs)
   566  	}
   567  }