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

     1  package vmcx
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"reflect"
     7  	"testing"
     8  
     9  	"io/ioutil"
    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  		"guest_additions_mode":    "none",
    26  		"clone_from_vmxc_path":    "generated",
    27  		packer.BuildNameConfigKey: "foo",
    28  	}
    29  }
    30  
    31  func TestBuilder_ImplementsBuilder(t *testing.T) {
    32  	var raw interface{}
    33  	raw = &Builder{}
    34  	if _, ok := raw.(packer.Builder); !ok {
    35  		t.Error("Builder must implement builder.")
    36  	}
    37  }
    38  
    39  func TestBuilderPrepare_Defaults(t *testing.T) {
    40  	var b Builder
    41  	config := testConfig()
    42  
    43  	//Create vmxc folder
    44  	td, err := ioutil.TempDir("", "packer")
    45  	if err != nil {
    46  		t.Fatalf("err: %s", err)
    47  	}
    48  	defer os.RemoveAll(td)
    49  	config["clone_from_vmxc_path"] = td
    50  
    51  	warns, err := b.Prepare(config)
    52  	if len(warns) > 0 {
    53  		t.Fatalf("bad: %#v", warns)
    54  	}
    55  	if err != nil {
    56  		t.Fatalf("should not have error: %s", err)
    57  	}
    58  
    59  	if b.config.VMName != "packer-foo" {
    60  		t.Errorf("bad vm name: %s", b.config.VMName)
    61  	}
    62  }
    63  
    64  func TestBuilderPrepare_InvalidKey(t *testing.T) {
    65  	var b Builder
    66  	config := testConfig()
    67  
    68  	//Create vmxc folder
    69  	td, err := ioutil.TempDir("", "packer")
    70  	if err != nil {
    71  		t.Fatalf("err: %s", err)
    72  	}
    73  	defer os.RemoveAll(td)
    74  	config["clone_from_vmxc_path"] = td
    75  
    76  	// Add a random key
    77  	config["i_should_not_be_valid"] = true
    78  	warns, err := b.Prepare(config)
    79  	if len(warns) > 0 {
    80  		t.Fatalf("bad: %#v", warns)
    81  	}
    82  	if err == nil {
    83  		t.Fatal("should have error")
    84  	}
    85  }
    86  
    87  func TestBuilderPrepare_CloneFromExistingMachineOrImportFromExportedMachineSettingsRequired(t *testing.T) {
    88  	var b Builder
    89  	config := testConfig()
    90  	delete(config, "clone_from_vmxc_path")
    91  
    92  	warns, err := b.Prepare(config)
    93  	if len(warns) > 0 {
    94  		t.Fatalf("bad: %#v", warns)
    95  	}
    96  	if err == nil {
    97  		t.Fatal("should have error")
    98  	}
    99  }
   100  
   101  func TestBuilderPrepare_ExportedMachinePathDoesNotExist(t *testing.T) {
   102  	var b Builder
   103  	config := testConfig()
   104  
   105  	//Create vmxc folder
   106  	td, err := ioutil.TempDir("", "packer")
   107  	if err != nil {
   108  		t.Fatalf("err: %s", err)
   109  	}
   110  
   111  	//Delete the folder immediately
   112  	os.RemoveAll(td)
   113  
   114  	config["clone_from_vmxc_path"] = td
   115  
   116  	warns, err := b.Prepare(config)
   117  	if len(warns) > 0 {
   118  		t.Fatalf("bad: %#v", warns)
   119  	}
   120  	if err == nil {
   121  		t.Fatal("should have error")
   122  	}
   123  }
   124  
   125  func TestBuilderPrepare_ExportedMachinePathExists(t *testing.T) {
   126  	var b Builder
   127  	config := testConfig()
   128  
   129  	//Create vmxc folder
   130  	td, err := ioutil.TempDir("", "packer")
   131  	if err != nil {
   132  		t.Fatalf("err: %s", err)
   133  	}
   134  
   135  	//Only delete afterwards
   136  	defer os.RemoveAll(td)
   137  
   138  	config["clone_from_vmxc_path"] = td
   139  
   140  	warns, err := b.Prepare(config)
   141  	if len(warns) > 0 {
   142  		t.Fatalf("bad: %#v", warns)
   143  	}
   144  	if err != nil {
   145  		t.Fatalf("should not have error: %s", err)
   146  	}
   147  }
   148  
   149  func disabled_TestBuilderPrepare_CloneFromVmSettingUsedSoNoCloneFromVmxcPathRequired(t *testing.T) {
   150  	var b Builder
   151  	config := testConfig()
   152  	delete(config, "clone_from_vmxc_path")
   153  
   154  	config["clone_from_vm_name"] = "test_machine_name_that_does_not_exist"
   155  
   156  	warns, err := b.Prepare(config)
   157  	if len(warns) > 0 {
   158  		t.Fatalf("bad: %#v", warns)
   159  	}
   160  
   161  	if err == nil {
   162  		t.Fatal("should have error")
   163  	} else {
   164  		errorMessage := err.Error()
   165  		if errorMessage != "1 error(s) occurred:\n\n* Virtual machine 'test_machine_name_that_does_not_exist' to clone from does not exist." {
   166  			t.Fatalf("should not have error: %s", err)
   167  		}
   168  	}
   169  }
   170  
   171  func TestBuilderPrepare_ISOChecksum(t *testing.T) {
   172  	var b Builder
   173  	config := testConfig()
   174  
   175  	//Create vmxc folder
   176  	td, err := ioutil.TempDir("", "packer")
   177  	if err != nil {
   178  		t.Fatalf("err: %s", err)
   179  	}
   180  	defer os.RemoveAll(td)
   181  	config["clone_from_vmxc_path"] = td
   182  
   183  	// Test bad
   184  	config["iso_checksum"] = ""
   185  	warns, err := b.Prepare(config)
   186  	if len(warns) > 0 {
   187  		t.Fatalf("bad: %#v", warns)
   188  	}
   189  	if err == nil {
   190  		t.Fatal("should have error")
   191  	}
   192  
   193  	// Test good
   194  	config["iso_checksum"] = "FOo"
   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.ISOChecksum != "foo" {
   205  		t.Fatalf("should've lowercased: %s", b.config.ISOChecksum)
   206  	}
   207  }
   208  
   209  func TestBuilderPrepare_ISOChecksumType(t *testing.T) {
   210  	var b Builder
   211  	config := testConfig()
   212  
   213  	//Create vmxc folder
   214  	td, err := ioutil.TempDir("", "packer")
   215  	if err != nil {
   216  		t.Fatalf("err: %s", err)
   217  	}
   218  	defer os.RemoveAll(td)
   219  	config["clone_from_vmxc_path"] = td
   220  
   221  	// Test bad
   222  	config["iso_checksum_type"] = ""
   223  	warns, err := b.Prepare(config)
   224  	if len(warns) > 0 {
   225  		t.Fatalf("bad: %#v", warns)
   226  	}
   227  	if err == nil {
   228  		t.Fatal("should have error")
   229  	}
   230  
   231  	// Test good
   232  	config["iso_checksum_type"] = "mD5"
   233  	b = Builder{}
   234  	warns, err = b.Prepare(config)
   235  	if len(warns) > 0 {
   236  		t.Fatalf("bad: %#v", warns)
   237  	}
   238  	if err != nil {
   239  		t.Fatalf("should not have error: %s", err)
   240  	}
   241  
   242  	if b.config.ISOChecksumType != "md5" {
   243  		t.Fatalf("should've lowercased: %s", b.config.ISOChecksumType)
   244  	}
   245  
   246  	// Test unknown
   247  	config["iso_checksum_type"] = "fake"
   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  	// Test none
   258  	config["iso_checksum_type"] = "none"
   259  	b = Builder{}
   260  	warns, err = b.Prepare(config)
   261  	if len(warns) == 0 {
   262  		t.Fatalf("bad: %#v", warns)
   263  	}
   264  	if err != nil {
   265  		t.Fatalf("should not have error: %s", err)
   266  	}
   267  
   268  	if b.config.ISOChecksumType != "none" {
   269  		t.Fatalf("should've lowercased: %s", b.config.ISOChecksumType)
   270  	}
   271  }
   272  
   273  func TestBuilderPrepare_ISOUrl(t *testing.T) {
   274  	var b Builder
   275  	config := testConfig()
   276  
   277  	//Create vmxc folder
   278  	td, err := ioutil.TempDir("", "packer")
   279  	if err != nil {
   280  		t.Fatalf("err: %s", err)
   281  	}
   282  	defer os.RemoveAll(td)
   283  	config["clone_from_vmxc_path"] = td
   284  
   285  	delete(config, "iso_url")
   286  	delete(config, "iso_urls")
   287  
   288  	// Test both empty (should be allowed, as we cloning a vm so we probably don't need an ISO file)
   289  	config["iso_url"] = ""
   290  	b = Builder{}
   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 not have an error")
   297  	}
   298  
   299  	// Test iso_url set
   300  	config["iso_url"] = "http://www.packer.io"
   301  	b = Builder{}
   302  	warns, err = b.Prepare(config)
   303  	if len(warns) > 0 {
   304  		t.Fatalf("bad: %#v", warns)
   305  	}
   306  	if err != nil {
   307  		t.Errorf("should not have error: %s", err)
   308  	}
   309  
   310  	expected := []string{"http://www.packer.io"}
   311  	if !reflect.DeepEqual(b.config.ISOUrls, expected) {
   312  		t.Fatalf("bad: %#v", b.config.ISOUrls)
   313  	}
   314  
   315  	// Test both set
   316  	config["iso_url"] = "http://www.packer.io"
   317  	config["iso_urls"] = []string{"http://www.packer.io"}
   318  	b = Builder{}
   319  	warns, err = b.Prepare(config)
   320  	if len(warns) > 0 {
   321  		t.Fatalf("bad: %#v", warns)
   322  	}
   323  	if err == nil {
   324  		t.Fatal("should have error")
   325  	}
   326  
   327  	// Test just iso_urls set
   328  	delete(config, "iso_url")
   329  	config["iso_urls"] = []string{
   330  		"http://www.packer.io",
   331  		"http://www.hashicorp.com",
   332  	}
   333  
   334  	b = Builder{}
   335  	warns, err = b.Prepare(config)
   336  	if len(warns) > 0 {
   337  		t.Fatalf("bad: %#v", warns)
   338  	}
   339  	if err != nil {
   340  		t.Errorf("should not have error: %s", err)
   341  	}
   342  
   343  	expected = []string{
   344  		"http://www.packer.io",
   345  		"http://www.hashicorp.com",
   346  	}
   347  	if !reflect.DeepEqual(b.config.ISOUrls, expected) {
   348  		t.Fatalf("bad: %#v", b.config.ISOUrls)
   349  	}
   350  }
   351  
   352  func TestBuilderPrepare_FloppyFiles(t *testing.T) {
   353  	var b Builder
   354  	config := testConfig()
   355  
   356  	//Create vmxc folder
   357  	td, err := ioutil.TempDir("", "packer")
   358  	if err != nil {
   359  		t.Fatalf("err: %s", err)
   360  	}
   361  	defer os.RemoveAll(td)
   362  	config["clone_from_vmxc_path"] = td
   363  
   364  	delete(config, "floppy_files")
   365  	warns, err := b.Prepare(config)
   366  	if len(warns) > 0 {
   367  		t.Fatalf("bad: %#v", warns)
   368  	}
   369  	if err != nil {
   370  		t.Fatalf("bad err: %s", err)
   371  	}
   372  
   373  	if len(b.config.FloppyFiles) != 0 {
   374  		t.Fatalf("bad: %#v", b.config.FloppyFiles)
   375  	}
   376  
   377  	floppies_path := "../../../common/test-fixtures/floppies"
   378  	config["floppy_files"] = []string{fmt.Sprintf("%s/bar.bat", floppies_path), fmt.Sprintf("%s/foo.ps1", floppies_path)}
   379  	b = Builder{}
   380  	warns, err = b.Prepare(config)
   381  	if len(warns) > 0 {
   382  		t.Fatalf("bad: %#v", warns)
   383  	}
   384  	if err != nil {
   385  		t.Fatalf("should not have error: %s", err)
   386  	}
   387  
   388  	expected := []string{fmt.Sprintf("%s/bar.bat", floppies_path), fmt.Sprintf("%s/foo.ps1", floppies_path)}
   389  	if !reflect.DeepEqual(b.config.FloppyFiles, expected) {
   390  		t.Fatalf("bad: %#v", b.config.FloppyFiles)
   391  	}
   392  }
   393  
   394  func TestBuilderPrepare_InvalidFloppies(t *testing.T) {
   395  	var b Builder
   396  	config := testConfig()
   397  
   398  	//Create vmxc folder
   399  	td, err := ioutil.TempDir("", "packer")
   400  	if err != nil {
   401  		t.Fatalf("err: %s", err)
   402  	}
   403  	defer os.RemoveAll(td)
   404  	config["clone_from_vmxc_path"] = td
   405  
   406  	config["floppy_files"] = []string{"nonexistent.bat", "nonexistent.ps1"}
   407  	b = Builder{}
   408  	_, errs := b.Prepare(config)
   409  	if errs == nil {
   410  		t.Fatalf("Nonexistent floppies should trigger multierror")
   411  	}
   412  
   413  	if len(errs.(*packer.MultiError).Errors) != 2 {
   414  		t.Fatalf("Multierror should work and report 2 errors")
   415  	}
   416  }
   417  
   418  func TestBuilderPrepare_CommConfig(t *testing.T) {
   419  	// Test Winrm
   420  	{
   421  		config := testConfig()
   422  
   423  		//Create vmxc folder
   424  		td, err := ioutil.TempDir("", "packer")
   425  		if err != nil {
   426  			t.Fatalf("err: %s", err)
   427  		}
   428  		defer os.RemoveAll(td)
   429  		config["clone_from_vmxc_path"] = td
   430  
   431  		config["communicator"] = "winrm"
   432  		config["winrm_username"] = "username"
   433  		config["winrm_password"] = "password"
   434  		config["winrm_host"] = "1.2.3.4"
   435  
   436  		var 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.Fatalf("should not have error: %s", err)
   443  		}
   444  
   445  		if b.config.Comm.WinRMUser != "username" {
   446  			t.Errorf("bad winrm_username: %s", b.config.Comm.WinRMUser)
   447  		}
   448  		if b.config.Comm.WinRMPassword != "password" {
   449  			t.Errorf("bad winrm_password: %s", b.config.Comm.WinRMPassword)
   450  		}
   451  		if host := b.config.Comm.Host(); host != "1.2.3.4" {
   452  			t.Errorf("bad host: %s", host)
   453  		}
   454  	}
   455  
   456  	// Test SSH
   457  	{
   458  		config := testConfig()
   459  
   460  		//Create vmxc folder
   461  		td, err := ioutil.TempDir("", "packer")
   462  		if err != nil {
   463  			t.Fatalf("err: %s", err)
   464  		}
   465  		defer os.RemoveAll(td)
   466  		config["clone_from_vmxc_path"] = td
   467  
   468  		config["communicator"] = "ssh"
   469  		config["ssh_username"] = "username"
   470  		config["ssh_password"] = "password"
   471  		config["ssh_host"] = "1.2.3.4"
   472  
   473  		var b Builder
   474  		warns, err := b.Prepare(config)
   475  		if len(warns) > 0 {
   476  			t.Fatalf("bad: %#v", warns)
   477  		}
   478  		if err != nil {
   479  			t.Fatalf("should not have error: %s", err)
   480  		}
   481  
   482  		if b.config.Comm.SSHUsername != "username" {
   483  			t.Errorf("bad ssh_username: %s", b.config.Comm.SSHUsername)
   484  		}
   485  		if b.config.Comm.SSHPassword != "password" {
   486  			t.Errorf("bad ssh_password: %s", b.config.Comm.SSHPassword)
   487  		}
   488  		if host := b.config.Comm.Host(); host != "1.2.3.4" {
   489  			t.Errorf("bad host: %s", host)
   490  		}
   491  	}
   492  }
   493  
   494  func TestUserVariablesInBootCommand(t *testing.T) {
   495  	var b Builder
   496  	config := testConfig()
   497  
   498  	//Create vmxc folder
   499  	td, err := ioutil.TempDir("", "packer")
   500  	if err != nil {
   501  		t.Fatalf("err: %s", err)
   502  	}
   503  	defer os.RemoveAll(td)
   504  	config["clone_from_vmxc_path"] = td
   505  
   506  	config[packer.UserVariablesConfigKey] = map[string]string{"test-variable": "test"}
   507  	config["boot_command"] = []string{"blah {{user `test-variable`}} blah"}
   508  
   509  	warns, err := b.Prepare(config)
   510  	if len(warns) > 0 {
   511  		t.Fatalf("bad: %#v", warns)
   512  	}
   513  	if err != nil {
   514  		t.Fatalf("should not have error: %s", err)
   515  	}
   516  
   517  	ui := packer.TestUi(t)
   518  	cache := &packer.FileCache{CacheDir: os.TempDir()}
   519  	hook := &packer.MockHook{}
   520  	driver := &hypervcommon.DriverMock{}
   521  
   522  	// Set up the state.
   523  	state := new(multistep.BasicStateBag)
   524  	state.Put("cache", cache)
   525  	state.Put("config", &b.config)
   526  	state.Put("driver", driver)
   527  	state.Put("hook", hook)
   528  	state.Put("http_port", uint(0))
   529  	state.Put("ui", ui)
   530  	state.Put("vmName", "packer-foo")
   531  
   532  	step := &hypervcommon.StepTypeBootCommand{
   533  		BootCommand: b.config.FlatBootCommand(),
   534  		SwitchName:  b.config.SwitchName,
   535  		Ctx:         b.config.ctx,
   536  	}
   537  
   538  	ret := step.Run(context.Background(), state)
   539  	if ret != multistep.ActionContinue {
   540  		t.Fatalf("should not have error: %#v", ret)
   541  	}
   542  }