github.com/rahart/packer@v0.12.2-0.20161229105310-282bb6ad370f/builder/azure/arm/config_test.go (about)

     1  // Copyright (c) Microsoft Corporation. All rights reserved.
     2  // Licensed under the MIT License. See the LICENSE file in builder/azure for license information.
     3  
     4  package arm
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/mitchellh/packer/builder/azure/common/constants"
    13  	"github.com/mitchellh/packer/packer"
    14  )
    15  
    16  // List of configuration parameters that are required by the ARM builder.
    17  var requiredConfigValues = []string{
    18  	"capture_name_prefix",
    19  	"capture_container_name",
    20  	"client_id",
    21  	"client_secret",
    22  	"image_offer",
    23  	"image_publisher",
    24  	"image_sku",
    25  	"location",
    26  	"os_type",
    27  	"storage_account",
    28  	"resource_group_name",
    29  	"subscription_id",
    30  }
    31  
    32  func TestConfigShouldProvideReasonableDefaultValues(t *testing.T) {
    33  	c, _, err := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
    34  
    35  	if err != nil {
    36  		t.Error("Expected configuration creation to succeed, but it failed!\n")
    37  		t.Fatalf(" errors: %s\n", err)
    38  	}
    39  
    40  	if c.UserName == "" {
    41  		t.Error("Expected 'UserName' to be populated, but it was empty!")
    42  	}
    43  
    44  	if c.VMSize == "" {
    45  		t.Error("Expected 'VMSize' to be populated, but it was empty!")
    46  	}
    47  
    48  	if c.ObjectID != "" {
    49  		t.Errorf("Expected 'ObjectID' to be nil, but it was '%s'!", c.ObjectID)
    50  	}
    51  }
    52  
    53  func TestConfigShouldBeAbleToOverrideDefaultedValues(t *testing.T) {
    54  	builderValues := getArmBuilderConfiguration()
    55  	builderValues["ssh_password"] = "override_password"
    56  	builderValues["ssh_username"] = "override_username"
    57  	builderValues["vm_size"] = "override_vm_size"
    58  	builderValues["communicator"] = "ssh"
    59  
    60  	c, _, err := newConfig(builderValues, getPackerConfiguration())
    61  
    62  	if err != nil {
    63  		t.Fatalf("newConfig failed: %s", err)
    64  	}
    65  
    66  	if c.Password != "override_password" {
    67  		t.Errorf("Expected 'Password' to be set to 'override_password', but found '%s'!", c.Password)
    68  	}
    69  
    70  	if c.Comm.SSHPassword != "override_password" {
    71  		t.Errorf("Expected 'c.Comm.SSHPassword' to be set to 'override_password', but found '%s'!", c.Comm.SSHPassword)
    72  	}
    73  
    74  	if c.UserName != "override_username" {
    75  		t.Errorf("Expected 'UserName' to be set to 'override_username', but found '%s'!", c.UserName)
    76  	}
    77  
    78  	if c.Comm.SSHUsername != "override_username" {
    79  		t.Errorf("Expected 'c.Comm.SSHUsername' to be set to 'override_username', but found '%s'!", c.Comm.SSHUsername)
    80  	}
    81  
    82  	if c.VMSize != "override_vm_size" {
    83  		t.Errorf("Expected 'vm_size' to be set to 'override_vm_size', but found '%s'!", c.VMSize)
    84  	}
    85  }
    86  
    87  func TestConfigShouldDefaultVMSizeToStandardA1(t *testing.T) {
    88  	c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
    89  
    90  	if c.VMSize != "Standard_A1" {
    91  		t.Errorf("Expected 'VMSize' to default to 'Standard_A1', but got '%s'.", c.VMSize)
    92  	}
    93  }
    94  
    95  func TestConfigShouldDefaultImageVersionToLatest(t *testing.T) {
    96  	c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
    97  
    98  	if c.ImageVersion != "latest" {
    99  		t.Errorf("Expected 'ImageVersion' to default to 'latest', but got '%s'.", c.ImageVersion)
   100  	}
   101  }
   102  
   103  func TestConfigShouldNotDefaultImageVersionIfCustomImage(t *testing.T) {
   104  	config := map[string]string{
   105  		"capture_name_prefix":    "ignore",
   106  		"capture_container_name": "ignore",
   107  		"location":               "ignore",
   108  		"image_url":              "ignore",
   109  		"storage_account":        "ignore",
   110  		"resource_group_name":    "ignore",
   111  		"subscription_id":        "ignore",
   112  		"os_type":                constants.Target_Linux,
   113  		"communicator":           "none",
   114  	}
   115  
   116  	c, _, _ := newConfig(config, getPackerConfiguration())
   117  	if c.ImageVersion != "" {
   118  		t.Errorf("Expected 'ImageVersion' to empty, but got '%s'.", c.ImageVersion)
   119  	}
   120  }
   121  
   122  func TestConfigShouldNormalizeOSTypeCase(t *testing.T) {
   123  	config := map[string]string{
   124  		"capture_name_prefix":    "ignore",
   125  		"capture_container_name": "ignore",
   126  		"location":               "ignore",
   127  		"image_url":              "ignore",
   128  		"storage_account":        "ignore",
   129  		"resource_group_name":    "ignore",
   130  		"subscription_id":        "ignore",
   131  		"communicator":           "none",
   132  	}
   133  
   134  	os_types := map[string][]string{
   135  		constants.Target_Linux:   {"linux", "LiNuX"},
   136  		constants.Target_Windows: {"windows", "WiNdOWs"},
   137  	}
   138  
   139  	for k, v := range os_types {
   140  		for _, os_type := range v {
   141  			config["os_type"] = os_type
   142  			c, _, err := newConfig(config, getPackerConfiguration())
   143  			if err != nil {
   144  				t.Fatalf("Expected config to accept the value %q, but it did not", os_type)
   145  			}
   146  
   147  			if c.OSType != k {
   148  				t.Fatalf("Expected config to normalize the value %q to %q, but it did not", os_type, constants.Target_Linux)
   149  			}
   150  		}
   151  	}
   152  
   153  	bad_os_types := []string{"", "does-not-exist"}
   154  	for _, os_type := range bad_os_types {
   155  		config["os_type"] = os_type
   156  		_, _, err := newConfig(config, getPackerConfiguration())
   157  		if err == nil {
   158  			t.Fatalf("Expected config to not accept the value %q, but it did", os_type)
   159  		}
   160  	}
   161  }
   162  
   163  func TestConfigShouldRejectCustomImageAndMarketPlace(t *testing.T) {
   164  	config := map[string]string{
   165  		"capture_name_prefix":    "ignore",
   166  		"capture_container_name": "ignore",
   167  		"location":               "ignore",
   168  		"image_url":              "ignore",
   169  		"resource_group_name":    "ignore",
   170  		"storage_account":        "ignore",
   171  		"subscription_id":        "ignore",
   172  		"os_type":                constants.Target_Linux,
   173  		"communicator":           "none",
   174  	}
   175  	packerConfiguration := getPackerConfiguration()
   176  	marketPlace := []string{"image_publisher", "image_offer", "image_sku"}
   177  
   178  	for _, x := range marketPlace {
   179  		config[x] = "ignore"
   180  		_, _, err := newConfig(config, packerConfiguration)
   181  		if err == nil {
   182  			t.Errorf("Expected Config to reject image_url and %s, but it did not", x)
   183  		}
   184  	}
   185  }
   186  
   187  func TestConfigVirtualNetworkNameIsOptional(t *testing.T) {
   188  	config := map[string]string{
   189  		"capture_name_prefix":    "ignore",
   190  		"capture_container_name": "ignore",
   191  		"location":               "ignore",
   192  		"image_url":              "ignore",
   193  		"storage_account":        "ignore",
   194  		"resource_group_name":    "ignore",
   195  		"subscription_id":        "ignore",
   196  		"os_type":                constants.Target_Linux,
   197  		"communicator":           "none",
   198  		"virtual_network_name":   "MyVirtualNetwork",
   199  	}
   200  
   201  	c, _, _ := newConfig(config, getPackerConfiguration())
   202  	if c.VirtualNetworkName != "MyVirtualNetwork" {
   203  		t.Errorf("Expected Config to set virtual_network_name to MyVirtualNetwork, but got %q", c.VirtualNetworkName)
   204  	}
   205  	if c.VirtualNetworkResourceGroupName != "" {
   206  		t.Errorf("Expected Config to leave virtual_network_resource_group_name to '', but got %q", c.VirtualNetworkResourceGroupName)
   207  	}
   208  	if c.VirtualNetworkSubnetName != "" {
   209  		t.Errorf("Expected Config to leave virtual_network_subnet_name to '', but got %q", c.VirtualNetworkSubnetName)
   210  	}
   211  }
   212  
   213  // The user can pass the value virtual_network_resource_group_name to avoid the lookup of
   214  // a virtual network's resource group, or to help with disambiguation.  The value should
   215  // only be set if virtual_network_name was set.
   216  func TestConfigVirtualNetworkResourceGroupNameMustBeSetWithVirtualNetworkName(t *testing.T) {
   217  	config := map[string]string{
   218  		"capture_name_prefix":                 "ignore",
   219  		"capture_container_name":              "ignore",
   220  		"location":                            "ignore",
   221  		"image_url":                           "ignore",
   222  		"storage_account":                     "ignore",
   223  		"resource_group_name":                 "ignore",
   224  		"subscription_id":                     "ignore",
   225  		"os_type":                             constants.Target_Linux,
   226  		"communicator":                        "none",
   227  		"virtual_network_resource_group_name": "MyVirtualNetworkRG",
   228  	}
   229  
   230  	_, _, err := newConfig(config, getPackerConfiguration())
   231  	if err == nil {
   232  		t.Error("Expected Config to reject virtual_network_resource_group_name, if virtual_network_name is not set.")
   233  	}
   234  }
   235  
   236  // The user can pass the value virtual_network_subnet_name to avoid the lookup of
   237  // a virtual network subnet's name, or to help with disambiguation.  The value should
   238  // only be set if virtual_network_name was set.
   239  func TestConfigVirtualNetworkSubnetNameMustBeSetWithVirtualNetworkName(t *testing.T) {
   240  	config := map[string]string{
   241  		"capture_name_prefix":         "ignore",
   242  		"capture_container_name":      "ignore",
   243  		"location":                    "ignore",
   244  		"image_url":                   "ignore",
   245  		"storage_account":             "ignore",
   246  		"resource_group_name":         "ignore",
   247  		"subscription_id":             "ignore",
   248  		"os_type":                     constants.Target_Linux,
   249  		"communicator":                "none",
   250  		"virtual_network_subnet_name": "MyVirtualNetworkRG",
   251  	}
   252  
   253  	_, _, err := newConfig(config, getPackerConfiguration())
   254  	if err == nil {
   255  		t.Error("Expected Config to reject virtual_network_subnet_name, if virtual_network_name is not set.")
   256  	}
   257  }
   258  
   259  func TestConfigShouldDefaultToPublicCloud(t *testing.T) {
   260  	c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
   261  
   262  	if c.CloudEnvironmentName != "Public" {
   263  		t.Errorf("Expected 'CloudEnvironmentName' to default to 'Public', but got '%s'.", c.CloudEnvironmentName)
   264  	}
   265  
   266  	if c.cloudEnvironment == nil || c.cloudEnvironment.Name != "AzurePublicCloud" {
   267  		t.Errorf("Expected 'cloudEnvironment' to be set to 'AzurePublicCloud', but got '%s'.", c.cloudEnvironment)
   268  	}
   269  }
   270  
   271  func TestConfigInstantiatesCorrectAzureEnvironment(t *testing.T) {
   272  	config := map[string]string{
   273  		"capture_name_prefix":    "ignore",
   274  		"capture_container_name": "ignore",
   275  		"image_offer":            "ignore",
   276  		"image_publisher":        "ignore",
   277  		"image_sku":              "ignore",
   278  		"location":               "ignore",
   279  		"storage_account":        "ignore",
   280  		"resource_group_name":    "ignore",
   281  		"subscription_id":        "ignore",
   282  		"os_type":                constants.Target_Linux,
   283  		"communicator":           "none",
   284  	}
   285  
   286  	// user input is fun :)
   287  	var table = []struct {
   288  		name            string
   289  		environmentName string
   290  	}{
   291  		{"China", "AzureChinaCloud"},
   292  		{"ChinaCloud", "AzureChinaCloud"},
   293  		{"AzureChinaCloud", "AzureChinaCloud"},
   294  		{"aZuReChInAcLoUd", "AzureChinaCloud"},
   295  
   296  		{"USGovernment", "AzureUSGovernmentCloud"},
   297  		{"USGovernmentCloud", "AzureUSGovernmentCloud"},
   298  		{"AzureUSGovernmentCloud", "AzureUSGovernmentCloud"},
   299  		{"aZuReUsGoVeRnMeNtClOuD", "AzureUSGovernmentCloud"},
   300  
   301  		{"Public", "AzurePublicCloud"},
   302  		{"PublicCloud", "AzurePublicCloud"},
   303  		{"AzurePublicCloud", "AzurePublicCloud"},
   304  		{"aZuRePuBlIcClOuD", "AzurePublicCloud"},
   305  	}
   306  
   307  	packerConfiguration := getPackerConfiguration()
   308  
   309  	for _, x := range table {
   310  		config["cloud_environment_name"] = x.name
   311  		c, _, err := newConfig(config, packerConfiguration)
   312  		if err != nil {
   313  			t.Fatal(err)
   314  		}
   315  
   316  		if c.cloudEnvironment == nil || c.cloudEnvironment.Name != x.environmentName {
   317  			t.Errorf("Expected 'cloudEnvironment' to be set to '%s', but got '%s'.", x.environmentName, c.cloudEnvironment)
   318  		}
   319  	}
   320  }
   321  
   322  func TestUserShouldProvideRequiredValues(t *testing.T) {
   323  	builderValues := getArmBuilderConfiguration()
   324  
   325  	// Ensure we can successfully create a config.
   326  	_, _, err := newConfig(builderValues, getPackerConfiguration())
   327  	if err != nil {
   328  		t.Error("Expected configuration creation to succeed, but it failed!\n")
   329  		t.Fatalf(" -> %+v\n", builderValues)
   330  	}
   331  
   332  	// Take away a required element, and ensure construction fails.
   333  	for _, v := range requiredConfigValues {
   334  		originalValue := builderValues[v]
   335  		delete(builderValues, v)
   336  
   337  		_, _, err := newConfig(builderValues, getPackerConfiguration())
   338  		if err == nil {
   339  			t.Error("Expected configuration creation to fail, but it succeeded!\n")
   340  			t.Fatalf(" -> %+v\n", builderValues)
   341  		}
   342  
   343  		builderValues[v] = originalValue
   344  	}
   345  }
   346  
   347  func TestSystemShouldDefineRuntimeValues(t *testing.T) {
   348  	c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
   349  
   350  	if c.Password == "" {
   351  		t.Errorf("Expected Password to not be empty, but it was '%s'!", c.Password)
   352  	}
   353  
   354  	if c.tmpComputeName == "" {
   355  		t.Errorf("Expected tmpComputeName to not be empty, but it was '%s'!", c.tmpComputeName)
   356  	}
   357  
   358  	if c.tmpDeploymentName == "" {
   359  		t.Errorf("Expected tmpDeploymentName to not be empty, but it was '%s'!", c.tmpDeploymentName)
   360  	}
   361  
   362  	if c.tmpResourceGroupName == "" {
   363  		t.Errorf("Expected tmpResourceGroupName to not be empty, but it was '%s'!", c.tmpResourceGroupName)
   364  	}
   365  
   366  	if c.tmpOSDiskName == "" {
   367  		t.Errorf("Expected tmpOSDiskName to not be empty, but it was '%s'!", c.tmpOSDiskName)
   368  	}
   369  }
   370  
   371  func TestConfigShouldTransformToVirtualMachineCaptureParameters(t *testing.T) {
   372  	c, _, _ := newConfig(getArmBuilderConfiguration(), getPackerConfiguration())
   373  	parameters := c.toVirtualMachineCaptureParameters()
   374  
   375  	if *parameters.DestinationContainerName != c.CaptureContainerName {
   376  		t.Errorf("Expected DestinationContainerName to be equal to config's CaptureContainerName, but they were '%s' and '%s' respectively.", *parameters.DestinationContainerName, c.CaptureContainerName)
   377  	}
   378  
   379  	if *parameters.VhdPrefix != c.CaptureNamePrefix {
   380  		t.Errorf("Expected DestinationContainerName to be equal to config's CaptureContainerName, but they were '%s' and '%s' respectively.", *parameters.VhdPrefix, c.CaptureNamePrefix)
   381  	}
   382  
   383  	if *parameters.OverwriteVhds != false {
   384  		t.Error("Expected OverwriteVhds to be false, but it was not.")
   385  	}
   386  }
   387  
   388  func TestConfigShouldSupportPackersConfigElements(t *testing.T) {
   389  	c, _, err := newConfig(
   390  		getArmBuilderConfiguration(),
   391  		getPackerConfiguration(),
   392  		getPackerCommunicatorConfiguration())
   393  
   394  	if err != nil {
   395  		t.Fatal(err)
   396  	}
   397  
   398  	if c.Comm.SSHTimeout != 1*time.Hour {
   399  		t.Errorf("Expected Comm.SSHTimeout to be a duration of an hour, but got '%s' instead.", c.Comm.SSHTimeout)
   400  	}
   401  
   402  	if c.Comm.WinRMTimeout != 2*time.Hour {
   403  		t.Errorf("Expected Comm.WinRMTimeout to be a durationof two hours, but got '%s' instead.", c.Comm.WinRMTimeout)
   404  	}
   405  }
   406  
   407  func TestWinRMConfigShouldSetRoundTripDecorator(t *testing.T) {
   408  	config := getArmBuilderConfiguration()
   409  	config["communicator"] = "winrm"
   410  	config["winrm_username"] = "username"
   411  	config["winrm_password"] = "password"
   412  
   413  	c, _, err := newConfig(config, getPackerConfiguration())
   414  	if err != nil {
   415  		t.Fatal(err)
   416  	}
   417  
   418  	if c.Comm.WinRMTransportDecorator == nil {
   419  		t.Error("Expected WinRMTransportDecorator to be set, but it was nil")
   420  	}
   421  }
   422  
   423  func TestUserDeviceLoginIsEnabledForLinux(t *testing.T) {
   424  	config := map[string]string{
   425  		"capture_name_prefix":    "ignore",
   426  		"capture_container_name": "ignore",
   427  		"image_offer":            "ignore",
   428  		"image_publisher":        "ignore",
   429  		"image_sku":              "ignore",
   430  		"location":               "ignore",
   431  		"storage_account":        "ignore",
   432  		"resource_group_name":    "ignore",
   433  		"subscription_id":        "ignore",
   434  		"os_type":                constants.Target_Linux,
   435  		"communicator":           "none",
   436  	}
   437  
   438  	_, _, err := newConfig(config, getPackerConfiguration())
   439  	if err != nil {
   440  		t.Fatalf("failed to use device login for Linux: %s", err)
   441  	}
   442  }
   443  
   444  func TestUseDeviceLoginIsDisabledForWindows(t *testing.T) {
   445  	config := map[string]string{
   446  		"capture_name_prefix":    "ignore",
   447  		"capture_container_name": "ignore",
   448  		"image_offer":            "ignore",
   449  		"image_publisher":        "ignore",
   450  		"image_sku":              "ignore",
   451  		"location":               "ignore",
   452  		"storage_account":        "ignore",
   453  		"resource_group_name":    "ignore",
   454  		"subscription_id":        "ignore",
   455  		"os_type":                constants.Target_Windows,
   456  		"communicator":           "none",
   457  	}
   458  
   459  	_, _, err := newConfig(config, getPackerConfiguration())
   460  	if err == nil {
   461  		t.Fatal("Expected test to fail, but it succeeded")
   462  	}
   463  
   464  	multiError, _ := err.(*packer.MultiError)
   465  	if len(multiError.Errors) != 2 {
   466  		t.Errorf("Expected to find 2 errors, but found %d errors", len(multiError.Errors))
   467  	}
   468  
   469  	if !strings.Contains(err.Error(), "client_id must be specified") {
   470  		t.Error("Expected to find error for 'client_id must be specified")
   471  	}
   472  	if !strings.Contains(err.Error(), "client_secret must be specified") {
   473  		t.Error("Expected to find error for 'client_secret must be specified")
   474  	}
   475  }
   476  
   477  func TestConfigShouldRejectMalformedCaptureNamePrefix(t *testing.T) {
   478  	config := map[string]string{
   479  		"capture_container_name": "ignore",
   480  		"image_offer":            "ignore",
   481  		"image_publisher":        "ignore",
   482  		"image_sku":              "ignore",
   483  		"location":               "ignore",
   484  		"storage_account":        "ignore",
   485  		"resource_group_name":    "ignore",
   486  		"subscription_id":        "ignore",
   487  		"communicator":           "none",
   488  		// Does not matter for this test case, just pick one.
   489  		"os_type": constants.Target_Linux,
   490  	}
   491  
   492  	wellFormedCaptureNamePrefix := []string{
   493  		"packer",
   494  		"AbcdefghijklmnopqrstuvwX",
   495  		"hypen-hypen",
   496  		"0leading-number",
   497  		"v1.core.local",
   498  	}
   499  
   500  	for _, x := range wellFormedCaptureNamePrefix {
   501  		config["capture_name_prefix"] = x
   502  		_, _, err := newConfig(config, getPackerConfiguration())
   503  
   504  		if err != nil {
   505  			t.Errorf("Expected test to pass, but it failed with the well-formed capture_name_prefix set to %q.", x)
   506  		}
   507  	}
   508  
   509  	malformedCaptureNamePrefix := []string{
   510  		"-leading-hypen",
   511  		"trailing-hypen-",
   512  		"trailing-period.",
   513  		"_leading-underscore",
   514  		"punc-!@#$%^&*()_+-=-punc",
   515  		"There-are-too-many-characters-in-the-name-and-the-limit-is-twenty-four",
   516  	}
   517  
   518  	for _, x := range malformedCaptureNamePrefix {
   519  		config["capture_name_prefix"] = x
   520  		_, _, err := newConfig(config, getPackerConfiguration())
   521  
   522  		if err == nil {
   523  			t.Errorf("Expected test to fail, but it succeeded with the malformed capture_name_prefix set to %q.", x)
   524  		}
   525  	}
   526  }
   527  
   528  func TestConfigShouldRejectMalformedCaptureContainerName(t *testing.T) {
   529  	config := map[string]string{
   530  		"capture_name_prefix": "ignore",
   531  		"image_offer":         "ignore",
   532  		"image_publisher":     "ignore",
   533  		"image_sku":           "ignore",
   534  		"location":            "ignore",
   535  		"storage_account":     "ignore",
   536  		"resource_group_name": "ignore",
   537  		"subscription_id":     "ignore",
   538  		"communicator":        "none",
   539  		// Does not matter for this test case, just pick one.
   540  		"os_type": constants.Target_Linux,
   541  	}
   542  
   543  	wellFormedCaptureContainerName := []string{
   544  		"0leading",
   545  		"aleading",
   546  		"hype-hypen",
   547  		"abcdefghijklmnopqrstuvwxyz0123456789-abcdefghijklmnopqrstuvwxyz", // 63 characters
   548  	}
   549  
   550  	for _, x := range wellFormedCaptureContainerName {
   551  		config["capture_container_name"] = x
   552  		_, _, err := newConfig(config, getPackerConfiguration())
   553  
   554  		if err != nil {
   555  			t.Errorf("Expected test to pass, but it failed with the well-formed capture_container_name set to %q.", x)
   556  		}
   557  	}
   558  
   559  	malformedCaptureContainerName := []string{
   560  		"No-Capitals",
   561  		"double--hypens",
   562  		"-leading-hypen",
   563  		"trailing-hypen-",
   564  		"punc-!@#$%^&*()_+-=-punc",
   565  		"there-are-over-63-characters-in-this-string-and-that-is-a-bad-container-name",
   566  	}
   567  
   568  	for _, x := range malformedCaptureContainerName {
   569  		config["capture_container_name"] = x
   570  		_, _, err := newConfig(config, getPackerConfiguration())
   571  
   572  		if err == nil {
   573  			t.Errorf("Expected test to fail, but it succeeded with the malformed capture_container_name set to %q.", x)
   574  		}
   575  	}
   576  }
   577  
   578  func TestConfigShouldAcceptTags(t *testing.T) {
   579  	config := map[string]interface{}{
   580  		"capture_name_prefix":    "ignore",
   581  		"capture_container_name": "ignore",
   582  		"image_offer":            "ignore",
   583  		"image_publisher":        "ignore",
   584  		"image_sku":              "ignore",
   585  		"location":               "ignore",
   586  		"storage_account":        "ignore",
   587  		"resource_group_name":    "ignore",
   588  		"subscription_id":        "ignore",
   589  		"communicator":           "none",
   590  		// Does not matter for this test case, just pick one.
   591  		"os_type": constants.Target_Linux,
   592  		"azure_tags": map[string]string{
   593  			"tag01": "value01",
   594  			"tag02": "value02",
   595  		},
   596  	}
   597  
   598  	c, _, err := newConfig(config, getPackerConfiguration())
   599  
   600  	if err != nil {
   601  		t.Fatal(err)
   602  	}
   603  
   604  	if len(c.AzureTags) != 2 {
   605  		t.Fatalf("expected to find 2 tags, but got %d", len(c.AzureTags))
   606  	}
   607  
   608  	if _, ok := c.AzureTags["tag01"]; !ok {
   609  		t.Error("expected to find key=\"tag01\", but did not")
   610  	}
   611  	if _, ok := c.AzureTags["tag02"]; !ok {
   612  		t.Error("expected to find key=\"tag02\", but did not")
   613  	}
   614  
   615  	value := c.AzureTags["tag01"]
   616  	if *value != "value01" {
   617  		t.Errorf("expected AzureTags[\"tag01\"] to have value \"value01\", but got %q", value)
   618  	}
   619  
   620  	value = c.AzureTags["tag02"]
   621  	if *value != "value02" {
   622  		t.Errorf("expected AzureTags[\"tag02\"] to have value \"value02\", but got %q", value)
   623  	}
   624  }
   625  
   626  func TestConfigShouldRejectTagsInExcessOf15AcceptTags(t *testing.T) {
   627  	tooManyTags := map[string]string{}
   628  	for i := 0; i < 16; i++ {
   629  		tooManyTags[fmt.Sprintf("tag%.2d", i)] = "ignored"
   630  	}
   631  
   632  	config := map[string]interface{}{
   633  		"capture_name_prefix":    "ignore",
   634  		"capture_container_name": "ignore",
   635  		"image_offer":            "ignore",
   636  		"image_publisher":        "ignore",
   637  		"image_sku":              "ignore",
   638  		"location":               "ignore",
   639  		"storage_account":        "ignore",
   640  		"resource_group_name":    "ignore",
   641  		"subscription_id":        "ignore",
   642  		"communicator":           "none",
   643  		// Does not matter for this test case, just pick one.
   644  		"os_type":    constants.Target_Linux,
   645  		"azure_tags": tooManyTags,
   646  	}
   647  
   648  	_, _, err := newConfig(config, getPackerConfiguration())
   649  
   650  	if err == nil {
   651  		t.Fatal("expected config to reject based on an excessive amount of tags (> 15)")
   652  	}
   653  }
   654  
   655  func TestConfigShouldRejectExcessiveTagNameLength(t *testing.T) {
   656  	nameTooLong := make([]byte, 513)
   657  	for i := range nameTooLong {
   658  		nameTooLong[i] = 'a'
   659  	}
   660  
   661  	tags := map[string]string{}
   662  	tags[string(nameTooLong)] = "ignored"
   663  
   664  	config := map[string]interface{}{
   665  		"capture_name_prefix":    "ignore",
   666  		"capture_container_name": "ignore",
   667  		"image_offer":            "ignore",
   668  		"image_publisher":        "ignore",
   669  		"image_sku":              "ignore",
   670  		"location":               "ignore",
   671  		"storage_account":        "ignore",
   672  		"resource_group_name":    "ignore",
   673  		"subscription_id":        "ignore",
   674  		"communicator":           "none",
   675  		// Does not matter for this test case, just pick one.
   676  		"os_type":    constants.Target_Linux,
   677  		"azure_tags": tags,
   678  	}
   679  
   680  	_, _, err := newConfig(config, getPackerConfiguration())
   681  	if err == nil {
   682  		t.Fatal("expected config to reject tag name based on length (> 512)")
   683  	}
   684  }
   685  
   686  func TestConfigShouldRejectExcessiveTagValueLength(t *testing.T) {
   687  	valueTooLong := make([]byte, 257)
   688  	for i := range valueTooLong {
   689  		valueTooLong[i] = 'a'
   690  	}
   691  
   692  	tags := map[string]string{}
   693  	tags["tag01"] = string(valueTooLong)
   694  
   695  	config := map[string]interface{}{
   696  		"capture_name_prefix":    "ignore",
   697  		"capture_container_name": "ignore",
   698  		"image_offer":            "ignore",
   699  		"image_publisher":        "ignore",
   700  		"image_sku":              "ignore",
   701  		"location":               "ignore",
   702  		"storage_account":        "ignore",
   703  		"resource_group_name":    "ignore",
   704  		"subscription_id":        "ignore",
   705  		"communicator":           "none",
   706  		// Does not matter for this test case, just pick one.
   707  		"os_type":    constants.Target_Linux,
   708  		"azure_tags": tags,
   709  	}
   710  
   711  	_, _, err := newConfig(config, getPackerConfiguration())
   712  	if err == nil {
   713  		t.Fatal("expected config to reject tag value based on length (> 256)")
   714  	}
   715  }
   716  
   717  func TestConfigShouldRejectMissingCustomDataFile(t *testing.T) {
   718  	config := map[string]interface{}{
   719  		"capture_name_prefix":    "ignore",
   720  		"capture_container_name": "ignore",
   721  		"image_offer":            "ignore",
   722  		"image_publisher":        "ignore",
   723  		"image_sku":              "ignore",
   724  		"location":               "ignore",
   725  		"storage_account":        "ignore",
   726  		"resource_group_name":    "ignore",
   727  		"subscription_id":        "ignore",
   728  		"communicator":           "none",
   729  		// Does not matter for this test case, just pick one.
   730  		"os_type":          constants.Target_Linux,
   731  		"custom_data_file": "/this/file/does/not/exist",
   732  	}
   733  
   734  	_, _, err := newConfig(config, getPackerConfiguration())
   735  	if err == nil {
   736  		t.Fatal("expected config to reject missing custom data file")
   737  	}
   738  }
   739  
   740  func getArmBuilderConfiguration() map[string]string {
   741  	m := make(map[string]string)
   742  	for _, v := range requiredConfigValues {
   743  		m[v] = "ignored00"
   744  	}
   745  
   746  	m["communicator"] = "none"
   747  	m["os_type"] = constants.Target_Linux
   748  	return m
   749  }
   750  
   751  func getArmBuilderConfigurationWithWindows() map[string]string {
   752  	m := make(map[string]string)
   753  	for _, v := range requiredConfigValues {
   754  		m[v] = "ignored00"
   755  	}
   756  
   757  	m["object_id"] = "ignored00"
   758  	m["tenant_id"] = "ignored00"
   759  	m["winrm_username"] = "ignored00"
   760  	m["communicator"] = "winrm"
   761  	m["os_type"] = constants.Target_Windows
   762  	return m
   763  }
   764  
   765  func getPackerConfiguration() interface{} {
   766  	config := map[string]interface{}{
   767  		"packer_build_name":    "azure-arm-vm",
   768  		"packer_builder_type":  "azure-arm-vm",
   769  		"packer_debug":         "false",
   770  		"packer_force":         "false",
   771  		"packer_template_path": "/home/jenkins/azure-arm-vm/template.json",
   772  	}
   773  
   774  	return config
   775  }
   776  
   777  func getPackerCommunicatorConfiguration() map[string]string {
   778  	config := map[string]string{
   779  		"ssh_timeout":   "1h",
   780  		"winrm_timeout": "2h",
   781  	}
   782  
   783  	return config
   784  }