github.com/StackPointCloud/packer@v0.10.2-0.20180716202532-b28098e0f79b/builder/hyperv/iso/builder_test.go (about)

     1  package iso
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"reflect"
     7  	"strconv"
     8  	"testing"
     9  
    10  	"os"
    11  
    12  	hypervcommon "github.com/hashicorp/packer/builder/hyperv/common"
    13  	"github.com/hashicorp/packer/helper/multistep"
    14  	"github.com/hashicorp/packer/packer"
    15  )
    16  
    17  func testConfig() map[string]interface{} {
    18  	return map[string]interface{}{
    19  		"iso_checksum":            "foo",
    20  		"iso_checksum_type":       "md5",
    21  		"iso_url":                 "http://www.packer.io",
    22  		"shutdown_command":        "yes",
    23  		"ssh_username":            "foo",
    24  		"ram_size":                64,
    25  		"disk_size":               256,
    26  		"disk_block_size":         1,
    27  		"guest_additions_mode":    "none",
    28  		"disk_additional_size":    "50000,40000,30000",
    29  		packer.BuildNameConfigKey: "foo",
    30  	}
    31  }
    32  
    33  func TestBuilder_ImplementsBuilder(t *testing.T) {
    34  	var raw interface{}
    35  	raw = &Builder{}
    36  	if _, ok := raw.(packer.Builder); !ok {
    37  		t.Error("Builder must implement builder.")
    38  	}
    39  }
    40  
    41  func TestBuilderPrepare_Defaults(t *testing.T) {
    42  	var b Builder
    43  	config := testConfig()
    44  
    45  	warns, err := b.Prepare(config)
    46  	if len(warns) > 0 {
    47  		t.Fatalf("bad: %#v", warns)
    48  	}
    49  	if err != nil {
    50  		t.Fatalf("should not have error: %s", err)
    51  	}
    52  
    53  	if b.config.VMName != "packer-foo" {
    54  		t.Errorf("bad vm name: %s", b.config.VMName)
    55  	}
    56  }
    57  
    58  func TestBuilderPrepare_DiskSize(t *testing.T) {
    59  	var b Builder
    60  	config := testConfig()
    61  
    62  	delete(config, "disk_size")
    63  	warns, err := b.Prepare(config)
    64  	if len(warns) > 0 {
    65  		t.Fatalf("bad: %#v", warns)
    66  	}
    67  	if err != nil {
    68  		t.Fatalf("bad err: %s", err)
    69  	}
    70  
    71  	if b.config.DiskSize != 40*1024 {
    72  		t.Fatalf("bad size: %d", b.config.DiskSize)
    73  	}
    74  
    75  	config["disk_size"] = 256
    76  	b = Builder{}
    77  	warns, err = b.Prepare(config)
    78  	if len(warns) > 0 {
    79  		t.Fatalf("bad: %#v", warns)
    80  	}
    81  	if err != nil {
    82  		t.Fatalf("should not have error: %s", err)
    83  	}
    84  
    85  	if b.config.DiskSize != 256 {
    86  		t.Fatalf("bad size: %d", b.config.DiskSize)
    87  	}
    88  }
    89  
    90  func TestBuilderPrepare_DiskBlockSize(t *testing.T) {
    91  	var b Builder
    92  	config := testConfig()
    93  	expected_default_block_size := uint(32)
    94  	expected_min_block_size := uint(0)
    95  	expected_max_block_size := uint(256)
    96  
    97  	// Test default with empty disk_block_size
    98  	delete(config, "disk_block_size")
    99  	warns, err := b.Prepare(config)
   100  	if len(warns) > 0 {
   101  		t.Fatalf("bad: %#v", warns)
   102  	}
   103  	if err != nil {
   104  		t.Fatalf("bad err: %s", err)
   105  	}
   106  	if b.config.DiskBlockSize != expected_default_block_size {
   107  		t.Fatalf("bad default block size with empty config: %d. Expected %d", b.config.DiskBlockSize, expected_default_block_size)
   108  	}
   109  
   110  	test_sizes := []uint{0, 1, 32, 256, 512, 1 * 1024, 32 * 1024}
   111  	for _, test_size := range test_sizes {
   112  		config["disk_block_size"] = test_size
   113  		b = Builder{}
   114  		warns, err = b.Prepare(config)
   115  		if test_size > expected_max_block_size || test_size < expected_min_block_size {
   116  			if len(warns) > 0 {
   117  				t.Fatalf("bad, should have no warns: %#v", warns)
   118  			}
   119  			if err == nil {
   120  				t.Fatalf("bad, should have error but didn't. disk_block_size=%d outside expected valid range [%d,%d]", test_size, expected_min_block_size, expected_max_block_size)
   121  			}
   122  		} else {
   123  			if len(warns) > 0 {
   124  				t.Fatalf("bad: %#v", warns)
   125  			}
   126  			if err != nil {
   127  				t.Fatalf("bad, should not have error: %s", err)
   128  			}
   129  			if test_size == 0 {
   130  				if b.config.DiskBlockSize != expected_default_block_size {
   131  					t.Fatalf("bad default block size with 0 value config: %d. Expected: %d", b.config.DiskBlockSize, expected_default_block_size)
   132  				}
   133  			} else {
   134  				if b.config.DiskBlockSize != test_size {
   135  					t.Fatalf("bad block size with 0 value config: %d. Expected: %d", b.config.DiskBlockSize, expected_default_block_size)
   136  				}
   137  			}
   138  		}
   139  	}
   140  }
   141  
   142  func TestBuilderPrepare_FixedVHDFormat(t *testing.T) {
   143  	var b Builder
   144  	config := testConfig()
   145  	config["use_fixed_vhd_format"] = true
   146  	config["generation"] = 1
   147  	config["skip_compaction"] = true
   148  	config["differencing_disk"] = false
   149  
   150  	//use_fixed_vhd_format should work with generation = 1, skip_compaction = true, and differencing_disk = false
   151  	warns, err := b.Prepare(config)
   152  	if len(warns) > 0 {
   153  		t.Fatalf("bad: %#v", warns)
   154  	}
   155  	if err != nil {
   156  		t.Fatalf("bad err: %s", err)
   157  	}
   158  
   159  	//use_fixed_vhd_format should not work with differencing_disk = true
   160  	config["differencing_disk"] = true
   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.Fatal("should have error")
   168  	}
   169  	config["differencing_disk"] = false
   170  
   171  	//use_fixed_vhd_format should not work with skip_compaction = false
   172  	config["skip_compaction"] = false
   173  	b = Builder{}
   174  	warns, err = b.Prepare(config)
   175  	if len(warns) > 0 {
   176  		t.Fatalf("bad: %#v", warns)
   177  	}
   178  	if err == nil {
   179  		t.Fatal("should have error")
   180  	}
   181  	config["skip_compaction"] = true
   182  
   183  	//use_fixed_vhd_format should not work with generation = 2
   184  	config["generation"] = 2
   185  	b = Builder{}
   186  	warns, err = b.Prepare(config)
   187  	if len(warns) > 0 {
   188  		t.Fatalf("bad: %#v", warns)
   189  	}
   190  	if err == nil {
   191  		t.Fatal("should have error")
   192  	}
   193  }
   194  
   195  func TestBuilderPrepare_FloppyFiles(t *testing.T) {
   196  	var b Builder
   197  	config := testConfig()
   198  
   199  	delete(config, "floppy_files")
   200  	warns, err := b.Prepare(config)
   201  	if len(warns) > 0 {
   202  		t.Fatalf("bad: %#v", warns)
   203  	}
   204  	if err != nil {
   205  		t.Fatalf("bad err: %s", err)
   206  	}
   207  
   208  	if len(b.config.FloppyFiles) != 0 {
   209  		t.Fatalf("bad: %#v", b.config.FloppyFiles)
   210  	}
   211  
   212  	floppiesPath := "../../../common/test-fixtures/floppies"
   213  	config["floppy_files"] = []string{fmt.Sprintf("%s/bar.bat", floppiesPath), fmt.Sprintf("%s/foo.ps1", floppiesPath)}
   214  	b = Builder{}
   215  	warns, err = b.Prepare(config)
   216  	if len(warns) > 0 {
   217  		t.Fatalf("bad: %#v", warns)
   218  	}
   219  	if err != nil {
   220  		t.Fatalf("should not have error: %s", err)
   221  	}
   222  
   223  	expected := []string{fmt.Sprintf("%s/bar.bat", floppiesPath), fmt.Sprintf("%s/foo.ps1", floppiesPath)}
   224  	if !reflect.DeepEqual(b.config.FloppyFiles, expected) {
   225  		t.Fatalf("bad: %#v", b.config.FloppyFiles)
   226  	}
   227  }
   228  
   229  func TestBuilderPrepare_InvalidFloppies(t *testing.T) {
   230  	var b Builder
   231  	config := testConfig()
   232  	config["floppy_files"] = []string{"nonexistent.bat", "nonexistent.ps1"}
   233  	b = Builder{}
   234  	_, errs := b.Prepare(config)
   235  	if errs == nil {
   236  		t.Fatalf("Nonexistent floppies should trigger multierror")
   237  	}
   238  
   239  	if len(errs.(*packer.MultiError).Errors) != 2 {
   240  		t.Fatalf("Multierror should work and report 2 errors")
   241  	}
   242  }
   243  
   244  func TestBuilderPrepare_InvalidKey(t *testing.T) {
   245  	var b Builder
   246  	config := testConfig()
   247  
   248  	// Add a random key
   249  	config["i_should_not_be_valid"] = true
   250  	warns, err := b.Prepare(config)
   251  	if len(warns) > 0 {
   252  		t.Fatalf("bad: %#v", warns)
   253  	}
   254  	if err == nil {
   255  		t.Fatal("should have error")
   256  	}
   257  }
   258  
   259  func TestBuilderPrepare_ISOChecksum(t *testing.T) {
   260  	var b Builder
   261  	config := testConfig()
   262  
   263  	// Test bad
   264  	config["iso_checksum"] = ""
   265  	warns, err := b.Prepare(config)
   266  	if len(warns) > 0 {
   267  		t.Fatalf("bad: %#v", warns)
   268  	}
   269  	if err == nil {
   270  		t.Fatal("should have error")
   271  	}
   272  
   273  	// Test good
   274  	config["iso_checksum"] = "FOo"
   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  	if b.config.ISOChecksum != "foo" {
   285  		t.Fatalf("should've lowercased: %s", b.config.ISOChecksum)
   286  	}
   287  }
   288  
   289  func TestBuilderPrepare_ISOChecksumType(t *testing.T) {
   290  	var b Builder
   291  	config := testConfig()
   292  
   293  	// Test bad
   294  	config["iso_checksum_type"] = ""
   295  	warns, err := b.Prepare(config)
   296  	if len(warns) > 0 {
   297  		t.Fatalf("bad: %#v", warns)
   298  	}
   299  	if err == nil {
   300  		t.Fatal("should have error")
   301  	}
   302  
   303  	// Test good
   304  	config["iso_checksum_type"] = "mD5"
   305  	b = Builder{}
   306  	warns, err = b.Prepare(config)
   307  	if len(warns) > 0 {
   308  		t.Fatalf("bad: %#v", warns)
   309  	}
   310  	if err != nil {
   311  		t.Fatalf("should not have error: %s", err)
   312  	}
   313  
   314  	if b.config.ISOChecksumType != "md5" {
   315  		t.Fatalf("should've lowercased: %s", b.config.ISOChecksumType)
   316  	}
   317  
   318  	// Test unknown
   319  	config["iso_checksum_type"] = "fake"
   320  	b = Builder{}
   321  	warns, err = b.Prepare(config)
   322  	if len(warns) > 0 {
   323  		t.Fatalf("bad: %#v", warns)
   324  	}
   325  	if err == nil {
   326  		t.Fatal("should have error")
   327  	}
   328  
   329  	// Test none
   330  	config["iso_checksum_type"] = "none"
   331  	b = Builder{}
   332  	warns, err = b.Prepare(config)
   333  	if len(warns) == 0 {
   334  		t.Fatalf("bad: %#v", warns)
   335  	}
   336  	if err != nil {
   337  		t.Fatalf("should not have error: %s", err)
   338  	}
   339  
   340  	if b.config.ISOChecksumType != "none" {
   341  		t.Fatalf("should've lowercased: %s", b.config.ISOChecksumType)
   342  	}
   343  }
   344  
   345  func TestBuilderPrepare_ISOUrl(t *testing.T) {
   346  	var b Builder
   347  	config := testConfig()
   348  	delete(config, "iso_url")
   349  	delete(config, "iso_urls")
   350  
   351  	// Test both empty
   352  	config["iso_url"] = ""
   353  	b = Builder{}
   354  	warns, err := b.Prepare(config)
   355  	if len(warns) > 0 {
   356  		t.Fatalf("bad: %#v", warns)
   357  	}
   358  	if err == nil {
   359  		t.Fatal("should have error")
   360  	}
   361  
   362  	// Test iso_url set
   363  	config["iso_url"] = "http://www.packer.io"
   364  	b = Builder{}
   365  	warns, err = b.Prepare(config)
   366  	if len(warns) > 0 {
   367  		t.Fatalf("bad: %#v", warns)
   368  	}
   369  	if err != nil {
   370  		t.Errorf("should not have error: %s", err)
   371  	}
   372  
   373  	expected := []string{"http://www.packer.io"}
   374  	if !reflect.DeepEqual(b.config.ISOUrls, expected) {
   375  		t.Fatalf("bad: %#v", b.config.ISOUrls)
   376  	}
   377  
   378  	// Test both set
   379  	config["iso_url"] = "http://www.packer.io"
   380  	config["iso_urls"] = []string{"http://www.packer.io"}
   381  	b = Builder{}
   382  	warns, err = b.Prepare(config)
   383  	if len(warns) > 0 {
   384  		t.Fatalf("bad: %#v", warns)
   385  	}
   386  	if err == nil {
   387  		t.Fatal("should have error")
   388  	}
   389  
   390  	// Test just iso_urls set
   391  	delete(config, "iso_url")
   392  	config["iso_urls"] = []string{
   393  		"http://www.packer.io",
   394  		"http://www.hashicorp.com",
   395  	}
   396  
   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.Errorf("should not have error: %s", err)
   404  	}
   405  
   406  	expected = []string{
   407  		"http://www.packer.io",
   408  		"http://www.hashicorp.com",
   409  	}
   410  	if !reflect.DeepEqual(b.config.ISOUrls, expected) {
   411  		t.Fatalf("bad: %#v", b.config.ISOUrls)
   412  	}
   413  }
   414  
   415  func TestBuilderPrepare_SizeNotRequiredWhenUsingExistingHarddrive(t *testing.T) {
   416  	var b Builder
   417  	config := testConfig()
   418  	delete(config, "iso_url")
   419  	delete(config, "iso_urls")
   420  	delete(config, "disk_size")
   421  
   422  	config["disk_size"] = 1
   423  
   424  	// Test just iso_urls set but with vhdx
   425  	delete(config, "iso_url")
   426  	config["iso_urls"] = []string{
   427  		"http://www.packer.io/hdd.vhdx",
   428  		"http://www.hashicorp.com/dvd.iso",
   429  	}
   430  
   431  	b = Builder{}
   432  	warns, err := b.Prepare(config)
   433  	if len(warns) > 0 {
   434  		t.Fatalf("bad: %#v", warns)
   435  	}
   436  	if err != nil {
   437  		t.Errorf("should not have error: %s", err)
   438  	}
   439  
   440  	expected := []string{
   441  		"http://www.packer.io/hdd.vhdx",
   442  		"http://www.hashicorp.com/dvd.iso",
   443  	}
   444  	if !reflect.DeepEqual(b.config.ISOUrls, expected) {
   445  		t.Fatalf("bad: %#v", b.config.ISOUrls)
   446  	}
   447  
   448  	// Test just iso_urls set but with vhd
   449  	delete(config, "iso_url")
   450  	config["iso_urls"] = []string{
   451  		"http://www.packer.io/hdd.vhd",
   452  		"http://www.hashicorp.com/dvd.iso",
   453  	}
   454  
   455  	b = Builder{}
   456  	warns, err = b.Prepare(config)
   457  	if len(warns) > 0 {
   458  		t.Fatalf("bad: %#v", warns)
   459  	}
   460  	if err != nil {
   461  		t.Errorf("should not have error: %s", err)
   462  	}
   463  
   464  	expected = []string{
   465  		"http://www.packer.io/hdd.vhd",
   466  		"http://www.hashicorp.com/dvd.iso",
   467  	}
   468  	if !reflect.DeepEqual(b.config.ISOUrls, expected) {
   469  		t.Fatalf("bad: %#v", b.config.ISOUrls)
   470  	}
   471  }
   472  
   473  func TestBuilderPrepare_SizeIsRequiredWhenNotUsingExistingHarddrive(t *testing.T) {
   474  	var b Builder
   475  	config := testConfig()
   476  	delete(config, "iso_url")
   477  	delete(config, "iso_urls")
   478  	delete(config, "disk_size")
   479  
   480  	config["disk_size"] = 1
   481  
   482  	// Test just iso_urls set but with vhdx
   483  	delete(config, "iso_url")
   484  	config["iso_urls"] = []string{
   485  		"http://www.packer.io/os.iso",
   486  		"http://www.hashicorp.com/dvd.iso",
   487  	}
   488  
   489  	b = Builder{}
   490  	warns, err := b.Prepare(config)
   491  	if len(warns) > 0 {
   492  		t.Fatalf("bad: %#v", warns)
   493  	}
   494  	if err == nil {
   495  		t.Errorf("should have error")
   496  	}
   497  
   498  	expected := []string{
   499  		"http://www.packer.io/os.iso",
   500  		"http://www.hashicorp.com/dvd.iso",
   501  	}
   502  	if !reflect.DeepEqual(b.config.ISOUrls, expected) {
   503  		t.Fatalf("bad: %#v", b.config.ISOUrls)
   504  	}
   505  }
   506  
   507  func TestBuilderPrepare_MaximumOfSixtyFourAdditionalDisks(t *testing.T) {
   508  	var b Builder
   509  	config := testConfig()
   510  
   511  	disks := make([]string, 65)
   512  	for i := range disks {
   513  		disks[i] = strconv.Itoa(i)
   514  	}
   515  	config["disk_additional_size"] = disks
   516  
   517  	b = Builder{}
   518  	warns, err := b.Prepare(config)
   519  	if len(warns) > 0 {
   520  		t.Fatalf("bad: %#v", warns)
   521  	}
   522  	if err == nil {
   523  		t.Errorf("should have error")
   524  	}
   525  
   526  }
   527  
   528  func TestBuilderPrepare_CommConfig(t *testing.T) {
   529  	// Test Winrm
   530  	{
   531  		config := testConfig()
   532  		config["communicator"] = "winrm"
   533  		config["winrm_username"] = "username"
   534  		config["winrm_password"] = "password"
   535  		config["winrm_host"] = "1.2.3.4"
   536  
   537  		var b Builder
   538  		warns, err := b.Prepare(config)
   539  		if len(warns) > 0 {
   540  			t.Fatalf("bad: %#v", warns)
   541  		}
   542  		if err != nil {
   543  			t.Fatalf("should not have error: %s", err)
   544  		}
   545  
   546  		if b.config.Comm.WinRMUser != "username" {
   547  			t.Errorf("bad winrm_username: %s", b.config.Comm.WinRMUser)
   548  		}
   549  		if b.config.Comm.WinRMPassword != "password" {
   550  			t.Errorf("bad winrm_password: %s", b.config.Comm.WinRMPassword)
   551  		}
   552  		if host := b.config.Comm.Host(); host != "1.2.3.4" {
   553  			t.Errorf("bad host: %s", host)
   554  		}
   555  	}
   556  
   557  	// Test SSH
   558  	{
   559  		config := testConfig()
   560  		config["communicator"] = "ssh"
   561  		config["ssh_username"] = "username"
   562  		config["ssh_password"] = "password"
   563  		config["ssh_host"] = "1.2.3.4"
   564  
   565  		var b Builder
   566  		warns, err := b.Prepare(config)
   567  		if len(warns) > 0 {
   568  			t.Fatalf("bad: %#v", warns)
   569  		}
   570  		if err != nil {
   571  			t.Fatalf("should not have error: %s", err)
   572  		}
   573  
   574  		if b.config.Comm.SSHUsername != "username" {
   575  			t.Errorf("bad ssh_username: %s", b.config.Comm.SSHUsername)
   576  		}
   577  		if b.config.Comm.SSHPassword != "password" {
   578  			t.Errorf("bad ssh_password: %s", b.config.Comm.SSHPassword)
   579  		}
   580  		if host := b.config.Comm.Host(); host != "1.2.3.4" {
   581  			t.Errorf("bad host: %s", host)
   582  		}
   583  	}
   584  
   585  }
   586  
   587  func TestUserVariablesInBootCommand(t *testing.T) {
   588  	var b Builder
   589  	config := testConfig()
   590  
   591  	config[packer.UserVariablesConfigKey] = map[string]string{"test-variable": "test"}
   592  	config["boot_command"] = []string{"blah {{user `test-variable`}} blah"}
   593  
   594  	warns, err := b.Prepare(config)
   595  	if len(warns) > 0 {
   596  		t.Fatalf("bad: %#v", warns)
   597  	}
   598  	if err != nil {
   599  		t.Fatalf("should not have error: %s", err)
   600  	}
   601  
   602  	ui := packer.TestUi(t)
   603  	cache := &packer.FileCache{CacheDir: os.TempDir()}
   604  	hook := &packer.MockHook{}
   605  	driver := &hypervcommon.DriverMock{}
   606  
   607  	// Set up the state.
   608  	state := new(multistep.BasicStateBag)
   609  	state.Put("cache", cache)
   610  	state.Put("config", &b.config)
   611  	state.Put("driver", driver)
   612  	state.Put("hook", hook)
   613  	state.Put("http_port", uint(0))
   614  	state.Put("ui", ui)
   615  	state.Put("vmName", "packer-foo")
   616  
   617  	step := &hypervcommon.StepTypeBootCommand{
   618  		BootCommand: b.config.FlatBootCommand(),
   619  		SwitchName:  b.config.SwitchName,
   620  		Ctx:         b.config.ctx,
   621  	}
   622  
   623  	ret := step.Run(context.Background(), state)
   624  	if ret != multistep.ActionContinue {
   625  		t.Fatalf("should not have error: %#v", ret)
   626  	}
   627  }