diff --git a/.gitignore b/.gitignore index 199855319..8dd382f2a 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,6 @@ website/.bundle website/vendor packer-test*.log + +*.received.txt +*.received.json diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 548b82018..1d18273b0 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -66,6 +66,18 @@ "ImportPath": "github.com/armon/go-radix", "Rev": "4239b77079c7b5d1243b7b4736304ce8ddb6f0f2" }, + { + "ImportPath": "github.com/approvals/go-approval-tests", + "Rev": "ad96e53bea43a905c17beeb983a0f9ce087dc48d" + }, + { + "ImportPath": "github.com/approvals/go-approval-tests/reporters", + "Rev": "ad96e53bea43a905c17beeb983a0f9ce087dc48d" + }, + { + "ImportPath": "github.com/approvals/go-approval-tests/utils", + "Rev": "ad96e53bea43a905c17beeb983a0f9ce087dc48d" + }, { "ImportPath": "github.com/aws/aws-sdk-go/aws", "Comment": "v1.1.2", diff --git a/builder/azure/arm/TestKeyVaultDeployment03.approved.txt b/builder/azure/arm/template_factory_test.TestKeyVaultDeployment03.approved.json similarity index 96% rename from builder/azure/arm/TestKeyVaultDeployment03.approved.txt rename to builder/azure/arm/template_factory_test.TestKeyVaultDeployment03.approved.json index fa683ce8c..6d4049800 100644 --- a/builder/azure/arm/TestKeyVaultDeployment03.approved.txt +++ b/builder/azure/arm/template_factory_test.TestKeyVaultDeployment03.approved.json @@ -1,67 +1,67 @@ -{ - "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json", - "contentVersion": "1.0.0.0", - "parameters": { - "keyVaultName": { - "type": "string" - }, - "keyVaultSecretValue": { - "type": "securestring" - }, - "objectId": { - "type": "string" - }, - "tenantId": { - "type": "string" - } - }, - "resources": [ - { - "apiVersion": "[variables('apiVersion')]", - "location": "[variables('location')]", - "name": "[parameters('keyVaultName')]", - "properties": { - "accessPolicies": [ - { - "objectId": "[parameters('objectId')]", - "permissions": { - "keys": [ - "all" - ], - "secrets": [ - "all" - ] - }, - "tenantId": "[parameters('tenantId')]" - } - ], - "enabledForDeployment": "true", - "enabledForTemplateDeployment": "true", - "sku": { - "family": "A", - "name": "standard" - }, - "tenantId": "[parameters('tenantId')]" - }, - "resources": [ - { - "apiVersion": "[variables('apiVersion')]", - "dependsOn": [ - "[concat('Microsoft.KeyVault/vaults/', parameters('keyVaultName'))]" - ], - "name": "[variables('keyVaultSecretName')]", - "properties": { - "value": "[parameters('keyVaultSecretValue')]" - }, - "type": "secrets" - } - ], - "type": "Microsoft.KeyVault/vaults" - } - ], - "variables": { - "apiVersion": "2015-06-01", - "keyVaultSecretName": "packerKeyVaultSecret", - "location": "[resourceGroup().location]" - } +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json", + "contentVersion": "1.0.0.0", + "parameters": { + "keyVaultName": { + "type": "string" + }, + "keyVaultSecretValue": { + "type": "securestring" + }, + "objectId": { + "type": "string" + }, + "tenantId": { + "type": "string" + } + }, + "resources": [ + { + "apiVersion": "[variables('apiVersion')]", + "location": "[variables('location')]", + "name": "[parameters('keyVaultName')]", + "properties": { + "accessPolicies": [ + { + "objectId": "[parameters('objectId')]", + "permissions": { + "keys": [ + "all" + ], + "secrets": [ + "all" + ] + }, + "tenantId": "[parameters('tenantId')]" + } + ], + "enabledForDeployment": "true", + "enabledForTemplateDeployment": "true", + "sku": { + "family": "A", + "name": "standard" + }, + "tenantId": "[parameters('tenantId')]" + }, + "resources": [ + { + "apiVersion": "[variables('apiVersion')]", + "dependsOn": [ + "[concat('Microsoft.KeyVault/vaults/', parameters('keyVaultName'))]" + ], + "name": "[variables('keyVaultSecretName')]", + "properties": { + "value": "[parameters('keyVaultSecretValue')]" + }, + "type": "secrets" + } + ], + "type": "Microsoft.KeyVault/vaults" + } + ], + "variables": { + "apiVersion": "2015-06-01", + "keyVaultSecretName": "packerKeyVaultSecret", + "location": "[resourceGroup().location]" + } } \ No newline at end of file diff --git a/builder/azure/arm/TestVirtualMachineDeployment03.approved.txt b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment03.approved.json similarity index 96% rename from builder/azure/arm/TestVirtualMachineDeployment03.approved.txt rename to builder/azure/arm/template_factory_test.TestVirtualMachineDeployment03.approved.json index 8cd4ae5c6..a6fce9d67 100644 --- a/builder/azure/arm/TestVirtualMachineDeployment03.approved.txt +++ b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment03.approved.json @@ -1,160 +1,160 @@ -{ - "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json", - "contentVersion": "1.0.0.0", - "parameters": { - "adminPassword": { - "type": "string" - }, - "adminUsername": { - "type": "string" - }, - "dnsNameForPublicIP": { - "type": "string" - }, - "osDiskName": { - "type": "string" - }, - "storageAccountBlobEndpoint": { - "type": "string" - }, - "vmName": { - "type": "string" - }, - "vmSize": { - "type": "string" - } - }, - "resources": [ - { - "apiVersion": "[variables('apiVersion')]", - "location": "[variables('location')]", - "name": "[variables('publicIPAddressName')]", - "properties": { - "dnsSettings": { - "domainNameLabel": "[parameters('dnsNameForPublicIP')]" - }, - "publicIPAllocationMethod": "[variables('publicIPAddressType')]" - }, - "type": "Microsoft.Network/publicIPAddresses" - }, - { - "apiVersion": "[variables('apiVersion')]", - "location": "[variables('location')]", - "name": "[variables('virtualNetworkName')]", - "properties": { - "addressSpace": { - "addressPrefixes": [ - "[variables('addressPrefix')]" - ] - }, - "subnets": [ - { - "name": "[variables('subnetName')]", - "properties": { - "addressPrefix": "[variables('subnetAddressPrefix')]" - } - } - ] - }, - "type": "Microsoft.Network/virtualNetworks" - }, - { - "apiVersion": "[variables('apiVersion')]", - "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", - "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" - ], - "location": "[variables('location')]", - "name": "[variables('nicName')]", - "properties": { - "ipConfigurations": [ - { - "name": "ipconfig", - "properties": { - "privateIPAllocationMethod": "Dynamic", - "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" - }, - "subnet": { - "id": "[variables('subnetRef')]" - } - } - } - ] - }, - "type": "Microsoft.Network/networkInterfaces" - }, - { - "apiVersion": "[variables('apiVersion')]", - "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" - ], - "location": "[variables('location')]", - "name": "[parameters('vmName')]", - "properties": { - "diagnosticsProfile": { - "bootDiagnostics": { - "enabled": false - } - }, - "hardwareProfile": { - "vmSize": "[parameters('vmSize')]" - }, - "networkProfile": { - "networkInterfaces": [ - { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" - } - ] - }, - "osProfile": { - "adminPassword": "[parameters('adminPassword')]", - "adminUsername": "[parameters('adminUsername')]", - "computerName": "[parameters('vmName')]", - "linuxConfiguration": { - "ssh": { - "publicKeys": [ - { - "keyData": "", - "path": "[variables('sshKeyPath')]" - } - ] - } - } - }, - "storageProfile": { - "imageReference": { - "offer": "ImageOffer", - "publisher": "ImagePublisher", - "sku": "ImageSku", - "version": "ImageVersion" - }, - "osDisk": { - "caching": "ReadWrite", - "createOption": "FromImage", - "name": "osdisk", - "vhd": { - "uri": "[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),'/', parameters('osDiskName'),'.vhd')]" - } - } - } - }, - "type": "Microsoft.Compute/virtualMachines" - } - ], - "variables": { - "addressPrefix": "10.0.0.0/16", - "apiVersion": "2015-06-15", - "location": "[resourceGroup().location]", - "nicName": "packerNic", - "publicIPAddressName": "packerPublicIP", - "publicIPAddressType": "Dynamic", - "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", - "subnetAddressPrefix": "10.0.0.0/24", - "subnetName": "packerSubnet", - "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", - "virtualNetworkName": "packerNetwork", - "vmStorageAccountContainerName": "images", - "vnetID": "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" - } +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json", + "contentVersion": "1.0.0.0", + "parameters": { + "adminPassword": { + "type": "string" + }, + "adminUsername": { + "type": "string" + }, + "dnsNameForPublicIP": { + "type": "string" + }, + "osDiskName": { + "type": "string" + }, + "storageAccountBlobEndpoint": { + "type": "string" + }, + "vmName": { + "type": "string" + }, + "vmSize": { + "type": "string" + } + }, + "resources": [ + { + "apiVersion": "[variables('apiVersion')]", + "location": "[variables('location')]", + "name": "[variables('publicIPAddressName')]", + "properties": { + "dnsSettings": { + "domainNameLabel": "[parameters('dnsNameForPublicIP')]" + }, + "publicIPAllocationMethod": "[variables('publicIPAddressType')]" + }, + "type": "Microsoft.Network/publicIPAddresses" + }, + { + "apiVersion": "[variables('apiVersion')]", + "location": "[variables('location')]", + "name": "[variables('virtualNetworkName')]", + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[variables('addressPrefix')]" + ] + }, + "subnets": [ + { + "name": "[variables('subnetName')]", + "properties": { + "addressPrefix": "[variables('subnetAddressPrefix')]" + } + } + ] + }, + "type": "Microsoft.Network/virtualNetworks" + }, + { + "apiVersion": "[variables('apiVersion')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" + ], + "location": "[variables('location')]", + "name": "[variables('nicName')]", + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + }, + "subnet": { + "id": "[variables('subnetRef')]" + } + } + } + ] + }, + "type": "Microsoft.Network/networkInterfaces" + }, + { + "apiVersion": "[variables('apiVersion')]", + "dependsOn": [ + "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + ], + "location": "[variables('location')]", + "name": "[parameters('vmName')]", + "properties": { + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": false + } + }, + "hardwareProfile": { + "vmSize": "[parameters('vmSize')]" + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + } + ] + }, + "osProfile": { + "adminPassword": "[parameters('adminPassword')]", + "adminUsername": "[parameters('adminUsername')]", + "computerName": "[parameters('vmName')]", + "linuxConfiguration": { + "ssh": { + "publicKeys": [ + { + "keyData": "", + "path": "[variables('sshKeyPath')]" + } + ] + } + } + }, + "storageProfile": { + "imageReference": { + "offer": "ImageOffer", + "publisher": "ImagePublisher", + "sku": "ImageSku", + "version": "ImageVersion" + }, + "osDisk": { + "caching": "ReadWrite", + "createOption": "FromImage", + "name": "osdisk", + "vhd": { + "uri": "[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),'/', parameters('osDiskName'),'.vhd')]" + } + } + } + }, + "type": "Microsoft.Compute/virtualMachines" + } + ], + "variables": { + "addressPrefix": "10.0.0.0/16", + "apiVersion": "2015-06-15", + "location": "[resourceGroup().location]", + "nicName": "packerNic", + "publicIPAddressName": "packerPublicIP", + "publicIPAddressType": "Dynamic", + "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", + "subnetAddressPrefix": "10.0.0.0/24", + "subnetName": "packerSubnet", + "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", + "virtualNetworkName": "packerNetwork", + "vmStorageAccountContainerName": "images", + "vnetID": "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" + } } \ No newline at end of file diff --git a/builder/azure/arm/TestVirtualMachineDeployment04.approved.txt b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment04.approved.json similarity index 96% rename from builder/azure/arm/TestVirtualMachineDeployment04.approved.txt rename to builder/azure/arm/template_factory_test.TestVirtualMachineDeployment04.approved.json index 9aa27815c..74a4b767f 100644 --- a/builder/azure/arm/TestVirtualMachineDeployment04.approved.txt +++ b/builder/azure/arm/template_factory_test.TestVirtualMachineDeployment04.approved.json @@ -1,158 +1,158 @@ -{ - "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json", - "contentVersion": "1.0.0.0", - "parameters": { - "adminPassword": { - "type": "string" - }, - "adminUsername": { - "type": "string" - }, - "dnsNameForPublicIP": { - "type": "string" - }, - "osDiskName": { - "type": "string" - }, - "storageAccountBlobEndpoint": { - "type": "string" - }, - "vmName": { - "type": "string" - }, - "vmSize": { - "type": "string" - } - }, - "resources": [ - { - "apiVersion": "[variables('apiVersion')]", - "location": "[variables('location')]", - "name": "[variables('publicIPAddressName')]", - "properties": { - "dnsSettings": { - "domainNameLabel": "[parameters('dnsNameForPublicIP')]" - }, - "publicIPAllocationMethod": "[variables('publicIPAddressType')]" - }, - "type": "Microsoft.Network/publicIPAddresses" - }, - { - "apiVersion": "[variables('apiVersion')]", - "location": "[variables('location')]", - "name": "[variables('virtualNetworkName')]", - "properties": { - "addressSpace": { - "addressPrefixes": [ - "[variables('addressPrefix')]" - ] - }, - "subnets": [ - { - "name": "[variables('subnetName')]", - "properties": { - "addressPrefix": "[variables('subnetAddressPrefix')]" - } - } - ] - }, - "type": "Microsoft.Network/virtualNetworks" - }, - { - "apiVersion": "[variables('apiVersion')]", - "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", - "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" - ], - "location": "[variables('location')]", - "name": "[variables('nicName')]", - "properties": { - "ipConfigurations": [ - { - "name": "ipconfig", - "properties": { - "privateIPAllocationMethod": "Dynamic", - "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" - }, - "subnet": { - "id": "[variables('subnetRef')]" - } - } - } - ] - }, - "type": "Microsoft.Network/networkInterfaces" - }, - { - "apiVersion": "[variables('apiVersion')]", - "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" - ], - "location": "[variables('location')]", - "name": "[parameters('vmName')]", - "properties": { - "diagnosticsProfile": { - "bootDiagnostics": { - "enabled": false - } - }, - "hardwareProfile": { - "vmSize": "[parameters('vmSize')]" - }, - "networkProfile": { - "networkInterfaces": [ - { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" - } - ] - }, - "osProfile": { - "adminPassword": "[parameters('adminPassword')]", - "adminUsername": "[parameters('adminUsername')]", - "computerName": "[parameters('vmName')]", - "linuxConfiguration": { - "ssh": { - "publicKeys": [ - { - "keyData": "", - "path": "[variables('sshKeyPath')]" - } - ] - } - } - }, - "storageProfile": { - "osDisk": { - "caching": "ReadWrite", - "createOption": "FromImage", - "image": { - "uri": "https://localhost/custom.vhd" - }, - "name": "osdisk", - "osType": "Linux", - "vhd": { - "uri": "[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),'/', parameters('osDiskName'),'.vhd')]" - } - } - } - }, - "type": "Microsoft.Compute/virtualMachines" - } - ], - "variables": { - "addressPrefix": "10.0.0.0/16", - "apiVersion": "2015-06-15", - "location": "[resourceGroup().location]", - "nicName": "packerNic", - "publicIPAddressName": "packerPublicIP", - "publicIPAddressType": "Dynamic", - "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", - "subnetAddressPrefix": "10.0.0.0/24", - "subnetName": "packerSubnet", - "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", - "virtualNetworkName": "packerNetwork", - "vmStorageAccountContainerName": "images", - "vnetID": "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" - } +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json", + "contentVersion": "1.0.0.0", + "parameters": { + "adminPassword": { + "type": "string" + }, + "adminUsername": { + "type": "string" + }, + "dnsNameForPublicIP": { + "type": "string" + }, + "osDiskName": { + "type": "string" + }, + "storageAccountBlobEndpoint": { + "type": "string" + }, + "vmName": { + "type": "string" + }, + "vmSize": { + "type": "string" + } + }, + "resources": [ + { + "apiVersion": "[variables('apiVersion')]", + "location": "[variables('location')]", + "name": "[variables('publicIPAddressName')]", + "properties": { + "dnsSettings": { + "domainNameLabel": "[parameters('dnsNameForPublicIP')]" + }, + "publicIPAllocationMethod": "[variables('publicIPAddressType')]" + }, + "type": "Microsoft.Network/publicIPAddresses" + }, + { + "apiVersion": "[variables('apiVersion')]", + "location": "[variables('location')]", + "name": "[variables('virtualNetworkName')]", + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[variables('addressPrefix')]" + ] + }, + "subnets": [ + { + "name": "[variables('subnetName')]", + "properties": { + "addressPrefix": "[variables('subnetAddressPrefix')]" + } + } + ] + }, + "type": "Microsoft.Network/virtualNetworks" + }, + { + "apiVersion": "[variables('apiVersion')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" + ], + "location": "[variables('location')]", + "name": "[variables('nicName')]", + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + }, + "subnet": { + "id": "[variables('subnetRef')]" + } + } + } + ] + }, + "type": "Microsoft.Network/networkInterfaces" + }, + { + "apiVersion": "[variables('apiVersion')]", + "dependsOn": [ + "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + ], + "location": "[variables('location')]", + "name": "[parameters('vmName')]", + "properties": { + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": false + } + }, + "hardwareProfile": { + "vmSize": "[parameters('vmSize')]" + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + } + ] + }, + "osProfile": { + "adminPassword": "[parameters('adminPassword')]", + "adminUsername": "[parameters('adminUsername')]", + "computerName": "[parameters('vmName')]", + "linuxConfiguration": { + "ssh": { + "publicKeys": [ + { + "keyData": "", + "path": "[variables('sshKeyPath')]" + } + ] + } + } + }, + "storageProfile": { + "osDisk": { + "caching": "ReadWrite", + "createOption": "FromImage", + "image": { + "uri": "https://localhost/custom.vhd" + }, + "name": "osdisk", + "osType": "Linux", + "vhd": { + "uri": "[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),'/', parameters('osDiskName'),'.vhd')]" + } + } + } + }, + "type": "Microsoft.Compute/virtualMachines" + } + ], + "variables": { + "addressPrefix": "10.0.0.0/16", + "apiVersion": "2015-06-15", + "location": "[resourceGroup().location]", + "nicName": "packerNic", + "publicIPAddressName": "packerPublicIP", + "publicIPAddressType": "Dynamic", + "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", + "subnetAddressPrefix": "10.0.0.0/24", + "subnetName": "packerSubnet", + "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", + "virtualNetworkName": "packerNetwork", + "vmStorageAccountContainerName": "images", + "vnetID": "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" + } } \ No newline at end of file diff --git a/builder/azure/arm/template_factory_test.go b/builder/azure/arm/template_factory_test.go index b098ec37f..4ab976f9c 100644 --- a/builder/azure/arm/template_factory_test.go +++ b/builder/azure/arm/template_factory_test.go @@ -2,11 +2,10 @@ package arm import ( "encoding/json" - "strings" "testing" "github.com/Azure/azure-sdk-for-go/arm/resources/resources" - "github.com/mitchellh/packer/builder/azure/common/approvals" + "github.com/approvals/go-approval-tests" "github.com/mitchellh/packer/builder/azure/common/constants" "github.com/mitchellh/packer/builder/azure/common/template" ) @@ -110,13 +109,7 @@ func TestVirtualMachineDeployment03(t *testing.T) { t.Fatal(err) } - bs, err := json.MarshalIndent(deployment.Properties.Template, "", " ") - if err != nil { - t.Fatal(err) - } - - reader := strings.NewReader(string(bs)) - err = approvals.Verify(t, reader) + err = approvaltests.VerifyJSONStruct(t, deployment.Properties.Template) if err != nil { t.Fatal(err) } @@ -146,13 +139,7 @@ func TestVirtualMachineDeployment04(t *testing.T) { t.Fatal(err) } - bs, err := json.MarshalIndent(deployment.Properties.Template, "", " ") - if err != nil { - t.Fatal(err) - } - - reader := strings.NewReader(string(bs)) - err = approvals.Verify(t, reader) + err = approvaltests.VerifyJSONStruct(t, deployment.Properties.Template) if err != nil { t.Fatal(err) } @@ -243,13 +230,7 @@ func TestKeyVaultDeployment03(t *testing.T) { t.Fatal(err) } - bs, err := json.MarshalIndent(deployment.Properties.Template, "", " ") - if err != nil { - t.Fatal(err) - } - - reader := strings.NewReader(string(bs)) - err = approvals.Verify(t, reader) + err = approvaltests.VerifyJSONStruct(t, deployment.Properties.Template) if err != nil { t.Fatal(err) } diff --git a/builder/azure/common/template/TestBuildLinux00.approved.txt b/builder/azure/common/template/template_builder_test.TestBuildLinux00.approved.json similarity index 86% rename from builder/azure/common/template/TestBuildLinux00.approved.txt rename to builder/azure/common/template/template_builder_test.TestBuildLinux00.approved.json index ebba273b8..a8ecfc0be 100644 --- a/builder/azure/common/template/TestBuildLinux00.approved.txt +++ b/builder/azure/common/template/template_builder_test.TestBuildLinux00.approved.json @@ -1,160 +1,160 @@ -{ - "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json", - "contentVersion": "1.0.0.0", - "parameters": { - "adminPassword": { - "type": "string" - }, - "adminUsername": { - "type": "string" - }, - "dnsNameForPublicIP": { - "type": "string" - }, - "osDiskName": { - "type": "string" - }, - "storageAccountBlobEndpoint": { - "type": "string" - }, - "vmName": { - "type": "string" - }, - "vmSize": { - "type": "string" - } - }, - "variables": { - "addressPrefix": "10.0.0.0/16", - "apiVersion": "2015-06-15", - "location": "[resourceGroup().location]", - "nicName": "packerNic", - "publicIPAddressName": "packerPublicIP", - "publicIPAddressType": "Dynamic", - "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", - "subnetAddressPrefix": "10.0.0.0/24", - "subnetName": "packerSubnet", - "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", - "virtualNetworkName": "packerNetwork", - "vmStorageAccountContainerName": "images", - "vnetID": "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" - }, - "resources": [ - { - "apiVersion": "[variables('apiVersion')]", - "name": "[variables('publicIPAddressName')]", - "type": "Microsoft.Network/publicIPAddresses", - "location": "[variables('location')]", - "properties": { - "dnsSettings": { - "domainNameLabel": "[parameters('dnsNameForPublicIP')]" - }, - "publicIPAllocationMethod": "[variables('publicIPAddressType')]" - } - }, - { - "apiVersion": "[variables('apiVersion')]", - "name": "[variables('virtualNetworkName')]", - "type": "Microsoft.Network/virtualNetworks", - "location": "[variables('location')]", - "properties": { - "addressSpace": { - "addressPrefixes": [ - "[variables('addressPrefix')]" - ] - }, - "subnets": [ - { - "properties": { - "addressPrefix": "[variables('subnetAddressPrefix')]" - }, - "name": "[variables('subnetName')]" - } - ] - } - }, - { - "apiVersion": "[variables('apiVersion')]", - "name": "[variables('nicName')]", - "type": "Microsoft.Network/networkInterfaces", - "location": "[variables('location')]", - "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", - "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" - ], - "properties": { - "ipConfigurations": [ - { - "properties": { - "privateIPAllocationMethod": "Dynamic", - "subnet": { - "id": "[variables('subnetRef')]" - }, - "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" - } - }, - "name": "ipconfig" - } - ] - } - }, - { - "apiVersion": "[variables('apiVersion')]", - "name": "[parameters('vmName')]", - "type": "Microsoft.Compute/virtualMachines", - "location": "[variables('location')]", - "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" - ], - "properties": { - "diagnosticsProfile": { - "bootDiagnostics": { - "enabled": false - } - }, - "hardwareProfile": { - "vmSize": "[parameters('vmSize')]" - }, - "networkProfile": { - "networkInterfaces": [ - { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" - } - ] - }, - "osProfile": { - "computerName": "[parameters('vmName')]", - "adminUsername": "[parameters('adminUsername')]", - "adminPassword": "[parameters('adminPassword')]", - "linuxConfiguration": { - "ssh": { - "publicKeys": [ - { - "path": "[variables('sshKeyPath')]", - "keyData": "--test-ssh-authorized-key--" - } - ] - } - } - }, - "storageProfile": { - "imageReference": { - "publisher": "Canonical", - "offer": "UbuntuServer", - "sku": "16.04", - "version": "latest" - }, - "osDisk": { - "name": "osdisk", - "vhd": { - "uri": "[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),'/', parameters('osDiskName'),'.vhd')]" - }, - "caching": "ReadWrite", - "createOption": "FromImage" - } - } - } - } - ] +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json", + "contentVersion": "1.0.0.0", + "parameters": { + "adminPassword": { + "type": "string" + }, + "adminUsername": { + "type": "string" + }, + "dnsNameForPublicIP": { + "type": "string" + }, + "osDiskName": { + "type": "string" + }, + "storageAccountBlobEndpoint": { + "type": "string" + }, + "vmName": { + "type": "string" + }, + "vmSize": { + "type": "string" + } + }, + "resources": [ + { + "apiVersion": "[variables('apiVersion')]", + "location": "[variables('location')]", + "name": "[variables('publicIPAddressName')]", + "properties": { + "dnsSettings": { + "domainNameLabel": "[parameters('dnsNameForPublicIP')]" + }, + "publicIPAllocationMethod": "[variables('publicIPAddressType')]" + }, + "type": "Microsoft.Network/publicIPAddresses" + }, + { + "apiVersion": "[variables('apiVersion')]", + "location": "[variables('location')]", + "name": "[variables('virtualNetworkName')]", + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[variables('addressPrefix')]" + ] + }, + "subnets": [ + { + "name": "[variables('subnetName')]", + "properties": { + "addressPrefix": "[variables('subnetAddressPrefix')]" + } + } + ] + }, + "type": "Microsoft.Network/virtualNetworks" + }, + { + "apiVersion": "[variables('apiVersion')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" + ], + "location": "[variables('location')]", + "name": "[variables('nicName')]", + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + }, + "subnet": { + "id": "[variables('subnetRef')]" + } + } + } + ] + }, + "type": "Microsoft.Network/networkInterfaces" + }, + { + "apiVersion": "[variables('apiVersion')]", + "dependsOn": [ + "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + ], + "location": "[variables('location')]", + "name": "[parameters('vmName')]", + "properties": { + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": false + } + }, + "hardwareProfile": { + "vmSize": "[parameters('vmSize')]" + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + } + ] + }, + "osProfile": { + "adminPassword": "[parameters('adminPassword')]", + "adminUsername": "[parameters('adminUsername')]", + "computerName": "[parameters('vmName')]", + "linuxConfiguration": { + "ssh": { + "publicKeys": [ + { + "keyData": "--test-ssh-authorized-key--", + "path": "[variables('sshKeyPath')]" + } + ] + } + } + }, + "storageProfile": { + "imageReference": { + "offer": "UbuntuServer", + "publisher": "Canonical", + "sku": "16.04", + "version": "latest" + }, + "osDisk": { + "caching": "ReadWrite", + "createOption": "FromImage", + "name": "osdisk", + "vhd": { + "uri": "[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),'/', parameters('osDiskName'),'.vhd')]" + } + } + } + }, + "type": "Microsoft.Compute/virtualMachines" + } + ], + "variables": { + "addressPrefix": "10.0.0.0/16", + "apiVersion": "2015-06-15", + "location": "[resourceGroup().location]", + "nicName": "packerNic", + "publicIPAddressName": "packerPublicIP", + "publicIPAddressType": "Dynamic", + "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", + "subnetAddressPrefix": "10.0.0.0/24", + "subnetName": "packerSubnet", + "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", + "virtualNetworkName": "packerNetwork", + "vmStorageAccountContainerName": "images", + "vnetID": "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" + } } \ No newline at end of file diff --git a/builder/azure/common/template/TestBuildLinux01.approved.txt b/builder/azure/common/template/template_builder_test.TestBuildLinux01.approved.json similarity index 86% rename from builder/azure/common/template/TestBuildLinux01.approved.txt rename to builder/azure/common/template/template_builder_test.TestBuildLinux01.approved.json index 0f7799013..45bf5b271 100644 --- a/builder/azure/common/template/TestBuildLinux01.approved.txt +++ b/builder/azure/common/template/template_builder_test.TestBuildLinux01.approved.json @@ -1,158 +1,158 @@ -{ - "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json", - "contentVersion": "1.0.0.0", - "parameters": { - "adminPassword": { - "type": "string" - }, - "adminUsername": { - "type": "string" - }, - "dnsNameForPublicIP": { - "type": "string" - }, - "osDiskName": { - "type": "string" - }, - "storageAccountBlobEndpoint": { - "type": "string" - }, - "vmName": { - "type": "string" - }, - "vmSize": { - "type": "string" - } - }, - "variables": { - "addressPrefix": "10.0.0.0/16", - "apiVersion": "2015-06-15", - "location": "[resourceGroup().location]", - "nicName": "packerNic", - "publicIPAddressName": "packerPublicIP", - "publicIPAddressType": "Dynamic", - "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", - "subnetAddressPrefix": "10.0.0.0/24", - "subnetName": "packerSubnet", - "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", - "virtualNetworkName": "packerNetwork", - "vmStorageAccountContainerName": "images", - "vnetID": "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" - }, - "resources": [ - { - "apiVersion": "[variables('apiVersion')]", - "name": "[variables('publicIPAddressName')]", - "type": "Microsoft.Network/publicIPAddresses", - "location": "[variables('location')]", - "properties": { - "dnsSettings": { - "domainNameLabel": "[parameters('dnsNameForPublicIP')]" - }, - "publicIPAllocationMethod": "[variables('publicIPAddressType')]" - } - }, - { - "apiVersion": "[variables('apiVersion')]", - "name": "[variables('virtualNetworkName')]", - "type": "Microsoft.Network/virtualNetworks", - "location": "[variables('location')]", - "properties": { - "addressSpace": { - "addressPrefixes": [ - "[variables('addressPrefix')]" - ] - }, - "subnets": [ - { - "properties": { - "addressPrefix": "[variables('subnetAddressPrefix')]" - }, - "name": "[variables('subnetName')]" - } - ] - } - }, - { - "apiVersion": "[variables('apiVersion')]", - "name": "[variables('nicName')]", - "type": "Microsoft.Network/networkInterfaces", - "location": "[variables('location')]", - "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", - "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" - ], - "properties": { - "ipConfigurations": [ - { - "properties": { - "privateIPAllocationMethod": "Dynamic", - "subnet": { - "id": "[variables('subnetRef')]" - }, - "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" - } - }, - "name": "ipconfig" - } - ] - } - }, - { - "apiVersion": "[variables('apiVersion')]", - "name": "[parameters('vmName')]", - "type": "Microsoft.Compute/virtualMachines", - "location": "[variables('location')]", - "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" - ], - "properties": { - "diagnosticsProfile": { - "bootDiagnostics": { - "enabled": false - } - }, - "hardwareProfile": { - "vmSize": "[parameters('vmSize')]" - }, - "networkProfile": { - "networkInterfaces": [ - { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" - } - ] - }, - "osProfile": { - "computerName": "[parameters('vmName')]", - "adminUsername": "[parameters('adminUsername')]", - "adminPassword": "[parameters('adminPassword')]", - "linuxConfiguration": { - "ssh": { - "publicKeys": [ - { - "path": "[variables('sshKeyPath')]", - "keyData": "--test-ssh-authorized-key--" - } - ] - } - } - }, - "storageProfile": { - "osDisk": { - "osType": "Linux", - "name": "osdisk", - "vhd": { - "uri": "[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),'/', parameters('osDiskName'),'.vhd')]" - }, - "image": { - "uri": "http://azure/custom.vhd" - }, - "caching": "ReadWrite", - "createOption": "FromImage" - } - } - } - } - ] +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json", + "contentVersion": "1.0.0.0", + "parameters": { + "adminPassword": { + "type": "string" + }, + "adminUsername": { + "type": "string" + }, + "dnsNameForPublicIP": { + "type": "string" + }, + "osDiskName": { + "type": "string" + }, + "storageAccountBlobEndpoint": { + "type": "string" + }, + "vmName": { + "type": "string" + }, + "vmSize": { + "type": "string" + } + }, + "resources": [ + { + "apiVersion": "[variables('apiVersion')]", + "location": "[variables('location')]", + "name": "[variables('publicIPAddressName')]", + "properties": { + "dnsSettings": { + "domainNameLabel": "[parameters('dnsNameForPublicIP')]" + }, + "publicIPAllocationMethod": "[variables('publicIPAddressType')]" + }, + "type": "Microsoft.Network/publicIPAddresses" + }, + { + "apiVersion": "[variables('apiVersion')]", + "location": "[variables('location')]", + "name": "[variables('virtualNetworkName')]", + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[variables('addressPrefix')]" + ] + }, + "subnets": [ + { + "name": "[variables('subnetName')]", + "properties": { + "addressPrefix": "[variables('subnetAddressPrefix')]" + } + } + ] + }, + "type": "Microsoft.Network/virtualNetworks" + }, + { + "apiVersion": "[variables('apiVersion')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" + ], + "location": "[variables('location')]", + "name": "[variables('nicName')]", + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + }, + "subnet": { + "id": "[variables('subnetRef')]" + } + } + } + ] + }, + "type": "Microsoft.Network/networkInterfaces" + }, + { + "apiVersion": "[variables('apiVersion')]", + "dependsOn": [ + "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + ], + "location": "[variables('location')]", + "name": "[parameters('vmName')]", + "properties": { + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": false + } + }, + "hardwareProfile": { + "vmSize": "[parameters('vmSize')]" + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + } + ] + }, + "osProfile": { + "adminPassword": "[parameters('adminPassword')]", + "adminUsername": "[parameters('adminUsername')]", + "computerName": "[parameters('vmName')]", + "linuxConfiguration": { + "ssh": { + "publicKeys": [ + { + "keyData": "--test-ssh-authorized-key--", + "path": "[variables('sshKeyPath')]" + } + ] + } + } + }, + "storageProfile": { + "osDisk": { + "caching": "ReadWrite", + "createOption": "FromImage", + "image": { + "uri": "http://azure/custom.vhd" + }, + "name": "osdisk", + "osType": "Linux", + "vhd": { + "uri": "[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),'/', parameters('osDiskName'),'.vhd')]" + } + } + } + }, + "type": "Microsoft.Compute/virtualMachines" + } + ], + "variables": { + "addressPrefix": "10.0.0.0/16", + "apiVersion": "2015-06-15", + "location": "[resourceGroup().location]", + "nicName": "packerNic", + "publicIPAddressName": "packerPublicIP", + "publicIPAddressType": "Dynamic", + "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", + "subnetAddressPrefix": "10.0.0.0/24", + "subnetName": "packerSubnet", + "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", + "virtualNetworkName": "packerNetwork", + "vmStorageAccountContainerName": "images", + "vnetID": "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" + } } \ No newline at end of file diff --git a/builder/azure/common/template/TestBuildWindows00.approved.txt b/builder/azure/common/template/template_builder_test.TestBuildWindows00.approved.json similarity index 87% rename from builder/azure/common/template/TestBuildWindows00.approved.txt rename to builder/azure/common/template/template_builder_test.TestBuildWindows00.approved.json index 6217322fa..d2460d7b4 100644 --- a/builder/azure/common/template/TestBuildWindows00.approved.txt +++ b/builder/azure/common/template/template_builder_test.TestBuildWindows00.approved.json @@ -1,174 +1,174 @@ -{ - "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json", - "contentVersion": "1.0.0.0", - "parameters": { - "adminPassword": { - "type": "string" - }, - "adminUsername": { - "type": "string" - }, - "dnsNameForPublicIP": { - "type": "string" - }, - "osDiskName": { - "type": "string" - }, - "storageAccountBlobEndpoint": { - "type": "string" - }, - "vmName": { - "type": "string" - }, - "vmSize": { - "type": "string" - } - }, - "variables": { - "addressPrefix": "10.0.0.0/16", - "apiVersion": "2015-06-15", - "location": "[resourceGroup().location]", - "nicName": "packerNic", - "publicIPAddressName": "packerPublicIP", - "publicIPAddressType": "Dynamic", - "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", - "subnetAddressPrefix": "10.0.0.0/24", - "subnetName": "packerSubnet", - "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", - "virtualNetworkName": "packerNetwork", - "vmStorageAccountContainerName": "images", - "vnetID": "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" - }, - "resources": [ - { - "apiVersion": "[variables('apiVersion')]", - "name": "[variables('publicIPAddressName')]", - "type": "Microsoft.Network/publicIPAddresses", - "location": "[variables('location')]", - "properties": { - "dnsSettings": { - "domainNameLabel": "[parameters('dnsNameForPublicIP')]" - }, - "publicIPAllocationMethod": "[variables('publicIPAddressType')]" - } - }, - { - "apiVersion": "[variables('apiVersion')]", - "name": "[variables('virtualNetworkName')]", - "type": "Microsoft.Network/virtualNetworks", - "location": "[variables('location')]", - "properties": { - "addressSpace": { - "addressPrefixes": [ - "[variables('addressPrefix')]" - ] - }, - "subnets": [ - { - "properties": { - "addressPrefix": "[variables('subnetAddressPrefix')]" - }, - "name": "[variables('subnetName')]" - } - ] - } - }, - { - "apiVersion": "[variables('apiVersion')]", - "name": "[variables('nicName')]", - "type": "Microsoft.Network/networkInterfaces", - "location": "[variables('location')]", - "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", - "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" - ], - "properties": { - "ipConfigurations": [ - { - "properties": { - "privateIPAllocationMethod": "Dynamic", - "subnet": { - "id": "[variables('subnetRef')]" - }, - "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" - } - }, - "name": "ipconfig" - } - ] - } - }, - { - "apiVersion": "[variables('apiVersion')]", - "name": "[parameters('vmName')]", - "type": "Microsoft.Compute/virtualMachines", - "location": "[variables('location')]", - "dependsOn": [ - "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" - ], - "properties": { - "diagnosticsProfile": { - "bootDiagnostics": { - "enabled": false - } - }, - "hardwareProfile": { - "vmSize": "[parameters('vmSize')]" - }, - "networkProfile": { - "networkInterfaces": [ - { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" - } - ] - }, - "osProfile": { - "computerName": "[parameters('vmName')]", - "adminUsername": "[parameters('adminUsername')]", - "adminPassword": "[parameters('adminPassword')]", - "windowsConfiguration": { - "provisionVMAgent": true, - "winRM": { - "listeners": [ - { - "protocol": "https", - "certificateUrl": "--test-winrm-certificate-url--" - } - ] - } - }, - "secrets": [ - { - "sourceVault": { - "id": "[resourceId(resourceGroup().name, 'Microsoft.KeyVault/vaults', '--test-key-vault-name')]" - }, - "vaultCertificates": [ - { - "certificateUrl": "--test-winrm-certificate-url--", - "certificateStore": "My" - } - ] - } - ] - }, - "storageProfile": { - "imageReference": { - "publisher": "MicrosoftWindowsServer", - "offer": "WindowsServer", - "sku": "2012-R2-Datacenter", - "version": "latest" - }, - "osDisk": { - "name": "osdisk", - "vhd": { - "uri": "[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),'/', parameters('osDiskName'),'.vhd')]" - }, - "caching": "ReadWrite", - "createOption": "FromImage" - } - } - } - } - ] +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json", + "contentVersion": "1.0.0.0", + "parameters": { + "adminPassword": { + "type": "string" + }, + "adminUsername": { + "type": "string" + }, + "dnsNameForPublicIP": { + "type": "string" + }, + "osDiskName": { + "type": "string" + }, + "storageAccountBlobEndpoint": { + "type": "string" + }, + "vmName": { + "type": "string" + }, + "vmSize": { + "type": "string" + } + }, + "resources": [ + { + "apiVersion": "[variables('apiVersion')]", + "location": "[variables('location')]", + "name": "[variables('publicIPAddressName')]", + "properties": { + "dnsSettings": { + "domainNameLabel": "[parameters('dnsNameForPublicIP')]" + }, + "publicIPAllocationMethod": "[variables('publicIPAddressType')]" + }, + "type": "Microsoft.Network/publicIPAddresses" + }, + { + "apiVersion": "[variables('apiVersion')]", + "location": "[variables('location')]", + "name": "[variables('virtualNetworkName')]", + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[variables('addressPrefix')]" + ] + }, + "subnets": [ + { + "name": "[variables('subnetName')]", + "properties": { + "addressPrefix": "[variables('subnetAddressPrefix')]" + } + } + ] + }, + "type": "Microsoft.Network/virtualNetworks" + }, + { + "apiVersion": "[variables('apiVersion')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" + ], + "location": "[variables('location')]", + "name": "[variables('nicName')]", + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]" + }, + "subnet": { + "id": "[variables('subnetRef')]" + } + } + } + ] + }, + "type": "Microsoft.Network/networkInterfaces" + }, + { + "apiVersion": "[variables('apiVersion')]", + "dependsOn": [ + "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]" + ], + "location": "[variables('location')]", + "name": "[parameters('vmName')]", + "properties": { + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": false + } + }, + "hardwareProfile": { + "vmSize": "[parameters('vmSize')]" + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]" + } + ] + }, + "osProfile": { + "adminPassword": "[parameters('adminPassword')]", + "adminUsername": "[parameters('adminUsername')]", + "computerName": "[parameters('vmName')]", + "secrets": [ + { + "sourceVault": { + "id": "[resourceId(resourceGroup().name, 'Microsoft.KeyVault/vaults', '--test-key-vault-name')]" + }, + "vaultCertificates": [ + { + "certificateStore": "My", + "certificateUrl": "--test-winrm-certificate-url--" + } + ] + } + ], + "windowsConfiguration": { + "provisionVMAgent": true, + "winRM": { + "listeners": [ + { + "certificateUrl": "--test-winrm-certificate-url--", + "protocol": "https" + } + ] + } + } + }, + "storageProfile": { + "imageReference": { + "offer": "WindowsServer", + "publisher": "MicrosoftWindowsServer", + "sku": "2012-R2-Datacenter", + "version": "latest" + }, + "osDisk": { + "caching": "ReadWrite", + "createOption": "FromImage", + "name": "osdisk", + "vhd": { + "uri": "[concat(parameters('storageAccountBlobEndpoint'),variables('vmStorageAccountContainerName'),'/', parameters('osDiskName'),'.vhd')]" + } + } + } + }, + "type": "Microsoft.Compute/virtualMachines" + } + ], + "variables": { + "addressPrefix": "10.0.0.0/16", + "apiVersion": "2015-06-15", + "location": "[resourceGroup().location]", + "nicName": "packerNic", + "publicIPAddressName": "packerPublicIP", + "publicIPAddressType": "Dynamic", + "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", + "subnetAddressPrefix": "10.0.0.0/24", + "subnetName": "packerSubnet", + "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]", + "virtualNetworkName": "packerNetwork", + "vmStorageAccountContainerName": "images", + "vnetID": "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]" + } } \ No newline at end of file diff --git a/builder/azure/common/template/template_builder_test.go b/builder/azure/common/template/template_builder_test.go index d6775d120..f203acace 100644 --- a/builder/azure/common/template/template_builder_test.go +++ b/builder/azure/common/template/template_builder_test.go @@ -1,11 +1,10 @@ package template import ( - "strings" "testing" "github.com/Azure/azure-sdk-for-go/arm/compute" - "github.com/mitchellh/packer/builder/azure/common/approvals" + "github.com/approvals/go-approval-tests" ) // Ensure that a Linux template is configured as expected. @@ -31,9 +30,7 @@ func TestBuildLinux00(t *testing.T) { t.Fatal(err) } - reader := strings.NewReader(*doc) - - err = approvals.Verify(t, reader) + err = approvaltests.VerifyJSONBytes(t, []byte(*doc)) if err != nil { t.Fatal(err) } @@ -61,9 +58,7 @@ func TestBuildLinux01(t *testing.T) { t.Fatal(err) } - reader := strings.NewReader(*doc) - - err = approvals.Verify(t, reader) + err = approvaltests.VerifyJSONBytes(t, []byte(*doc)) if err != nil { t.Fatal(err) } @@ -93,9 +88,7 @@ func TestBuildWindows00(t *testing.T) { t.Fatal(err) } - reader := strings.NewReader(*doc) - - err = approvals.Verify(t, reader) + err = approvaltests.VerifyJSONBytes(t, []byte(*doc)) if err != nil { t.Fatal(err) } diff --git a/vendor/github.com/approvals/go-approval-tests/.gitignore b/vendor/github.com/approvals/go-approval-tests/.gitignore new file mode 100644 index 000000000..6ed91fe2c --- /dev/null +++ b/vendor/github.com/approvals/go-approval-tests/.gitignore @@ -0,0 +1,25 @@ +*.received.* +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof diff --git a/vendor/github.com/approvals/go-approval-tests/LICENSE.md b/vendor/github.com/approvals/go-approval-tests/LICENSE.md new file mode 100644 index 000000000..c0ee81299 --- /dev/null +++ b/vendor/github.com/approvals/go-approval-tests/LICENSE.md @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/approvals/go-approval-tests/README.md b/vendor/github.com/approvals/go-approval-tests/README.md new file mode 100644 index 000000000..ef9b41761 --- /dev/null +++ b/vendor/github.com/approvals/go-approval-tests/README.md @@ -0,0 +1,53 @@ +# ApprovalTests.go + +ApprovalTests for go + +[![Build Status](https://travis-ci.org/approvals/go-approval-tests.png?branch=master)](https://travis-ci.org/approvals/go-approval-tests) + +# Golden master Verification Library +ApprovalTests allows for easy testing of larger objects, strings and anything else that can be saved to a file (images, sounds, csv, etc...) + +#Examples +##In Project +Note: ApprovalTests uses approvaltests to test itself. Therefore there are many examples in the code itself. + + * [approvals_test.go](approvals_test.go) + +##JSON +VerifyJSONBytes - Simple Formatting for easy comparison. Also uses the .json file extension + +```go +func TestVerifyJSON(t *testing.T) { + jsonb := []byte("{ \"foo\": \"bar\", \"age\": 42, \"bark\": \"woof\" }") + VerifyJSONBytes(t, jsonb) +} +``` +Matches file: approvals_test.TestVerifyJSON.received.json + +```json +{ + "age": 42, + "bark": "woof", + "foo": "bar" +} +``` + +##Reporters +ApprovalTests becomes *much* more powerful with reporters. Reporters launch programs on failure to help you understand, fix and approve results. + +You can make your own easily, [here's an example](reporters/beyond_compare.go) +You can also declare which one to use. Either at the +### Method level +```go +r := UseReporter(reporters.NewIntelliJ()) +defer r.Close() +``` +### Test Level +```go +func TestMain(m *testing.M) { + r := UseReporter(reporters.NewBeyondCompareReporter()) + defer r.Close() + + m.Run() +} +``` diff --git a/builder/azure/common/approvals/approvals.go b/vendor/github.com/approvals/go-approval-tests/approval_name.go similarity index 52% rename from builder/azure/common/approvals/approvals.go rename to vendor/github.com/approvals/go-approval-tests/approval_name.go index 605d9c4a9..1ef043efc 100644 --- a/builder/azure/common/approvals/approvals.go +++ b/vendor/github.com/approvals/go-approval-tests/approval_name.go @@ -1,4 +1,4 @@ -package approvals +package approvaltests import ( "bytes" @@ -6,12 +6,12 @@ import ( "io" "io/ioutil" "os" + "path" "runtime" "strings" - "testing" ) -type testState struct { +type approvalName struct { pc uintptr fullName string name string @@ -19,75 +19,18 @@ type testState struct { fileLine int } -func Verify(t *testing.T, reader io.Reader) error { - state, err := findTestMethod() - if err != nil { - return err - } - - return state.compare(state.getApprovalFile(), reader) -} - -func (s *testState) compare(approvalFile string, reader io.Reader) error { - received, err := ioutil.ReadAll(reader) - if err != nil { - return err - } - - // Ideally, this should only be written if - // 1. the approval file does not exist - // 2. the results differ - err = s.dumpReceivedTestResult(received) - if err != nil { - return err - } - - fh, err := os.Open(approvalFile) - if err != nil { - return err - } - defer fh.Close() - - approved, err := ioutil.ReadAll(fh) - if err != nil { - return err - } - - // The two sides are identical, nothing more to do. - if bytes.Compare(received, approved) == 0 { - return nil - } - - return fmt.Errorf("failed to approved %s", s.name) -} - -func (s *testState) dumpReceivedTestResult(bs []byte) error { - fn := s.getReceivedFile() - err := ioutil.WriteFile(fn, bs, 0644) - - return err -} - -func (s *testState) getReceivedFile() string { - return fmt.Sprintf("%s.received.txt", s.name) -} - -func (s *testState) getApprovalFile() string { - return fmt.Sprintf("%s.approved.txt", s.name) -} - -func newTestState(pc uintptr, f *runtime.Func) (*testState, error) { - state := &testState{ +func newApprovalName(pc uintptr, f *runtime.Func) (*approvalName, error) { + namer := &approvalName{ pc: pc, fullName: f.Name(), } - state.fileName, state.fileLine = f.FileLine(pc) + namer.fileName, namer.fileLine = f.FileLine(pc) - splits := strings.Split(state.fullName, ".") - state.name = splits[len(splits)-1] + splits := strings.Split(namer.fullName, ".") + namer.name = splits[len(splits)-1] - return state, nil + return namer, nil } // Walk the call stack, and try to find the test method that was executed. @@ -95,7 +38,7 @@ func newTestState(pc uintptr, f *runtime.Func) (*testState, error) { // *assumed* to be common across all callers. The test runner has a Name() of // 'testing.tRunner'. The method immediately previous to this is the test // method. -func findTestMethod() (*testState, error) { +func getApprovalName() (*approvalName, error) { pc := make([]uintptr, 100) count := runtime.Callers(0, pc) @@ -114,9 +57,74 @@ func findTestMethod() (*testState, error) { } testMethod := runtime.FuncForPC(pc[i-1]) - return newTestState(pc[i-1], testMethod) + return newApprovalName(pc[i-1], testMethod) } func isTestRunner(f *runtime.Func) bool { return f != nil && f.Name() == "testing.tRunner" } + +func (s *approvalName) compare(approvalFile, receivedFile string, reader io.Reader) error { + received, err := ioutil.ReadAll(reader) + if err != nil { + return err + } + + // Ideally, this should only be written if + // 1. the approval file does not exist + // 2. the results differ + err = s.dumpReceivedTestResult(received, receivedFile) + if err != nil { + return err + } + + fh, err := os.Open(approvalFile) + if err != nil { + return err + } + defer fh.Close() + + approved, err := ioutil.ReadAll(fh) + if err != nil { + return err + } + + received = s.normalizeLineEndings(received) + approved = s.normalizeLineEndings(approved) + + // The two sides are identical, nothing more to do. + if bytes.Compare(received, approved) == 0 { + return nil + } + + return fmt.Errorf("failed to approved %s", s.name) +} + +func (s *approvalName) normalizeLineEndings(bs []byte) []byte { + return bytes.Replace(bs, []byte("\r\n"), []byte("\n"), -1) +} + +func (s *approvalName) dumpReceivedTestResult(bs []byte, receivedFile string) error { + err := ioutil.WriteFile(receivedFile, bs, 0644) + + return err +} + +func (s *approvalName) getFileName(extWithDot string, suffix string) string { + if !strings.HasPrefix(extWithDot, ".") { + extWithDot = fmt.Sprintf(".%s", extWithDot) + } + + baseName := path.Base(s.fileName) + baseWithoutExt := baseName[:len(baseName)-len(path.Ext(s.fileName))] + + return fmt.Sprintf("%s.%s.%s%s", baseWithoutExt, s.name, suffix, extWithDot) +} + +func (s *approvalName) getReceivedFile(extWithDot string) string { + return s.getFileName(extWithDot, "received") +} + +func (s *approvalName) getApprovalFile(extWithDot string) string { + return s.getFileName(extWithDot, "approved") +} diff --git a/vendor/github.com/approvals/go-approval-tests/approvals.go b/vendor/github.com/approvals/go-approval-tests/approvals.go new file mode 100644 index 000000000..f4b3a839e --- /dev/null +++ b/vendor/github.com/approvals/go-approval-tests/approvals.go @@ -0,0 +1,204 @@ +package approvaltests + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "os" + "strings" + + "encoding/xml" + "github.com/approvals/go-approval-tests/reporters" + "github.com/approvals/go-approval-tests/utils" + "reflect" +) + +var ( + defaultReporter = reporters.NewDiffReporter() + defaultFrontLoadedReporter = reporters.NewFrontLoadedReporter() +) + +// Failable is an interface wrapper around testing.T +type Failable interface { + Fail() +} + +// VerifyWithExtension Example: +// VerifyWithExtension(t, strings.NewReader("Hello"), ".txt") +func VerifyWithExtension(t Failable, reader io.Reader, extWithDot string) error { + namer, err := getApprovalName() + if err != nil { + return err + } + + reporter := getReporter() + err = namer.compare(namer.getApprovalFile(extWithDot), namer.getReceivedFile(extWithDot), reader) + if err != nil { + reporter.Report(namer.getApprovalFile(extWithDot), namer.getReceivedFile(extWithDot)) + t.Fail() + } else { + os.Remove(namer.getReceivedFile(extWithDot)) + } + + return err +} + +// Verify Example: +// Verify(t, strings.NewReader("Hello")) +func Verify(t Failable, reader io.Reader) error { + return VerifyWithExtension(t, reader, ".txt") +} + +// VerifyString Example: +// VerifyString(t, "Hello") +func VerifyString(t Failable, s string) error { + reader := strings.NewReader(s) + return Verify(t, reader) +} + +// VerifyXMLStruct Example: +// VerifyXMLStruct(t, xml) +func VerifyXMLStruct(t Failable, obj interface{}) error { + xmlb, err := xml.MarshalIndent(obj, "", " ") + if err != nil { + tip := "" + if reflect.TypeOf(obj).Name() == "" { + tip = "when using anonymous types be sure to include\n XMLName xml.Name `xml:\"Your_Name_Here\"`\n" + } + message := fmt.Sprintf("error while pretty printing XML\n%verror:\n %v\nXML:\n %v\n", tip, err, obj) + return VerifyWithExtension(t, strings.NewReader(message), ".xml") + } + + return VerifyWithExtension(t, bytes.NewReader(xmlb), ".xml") +} + +// VerifyXMLBytes Example: +// VerifyXMLBytes(t, []byte("")) +func VerifyXMLBytes(t Failable, bs []byte) error { + type node struct { + Attr []xml.Attr + XMLName xml.Name + Children []node `xml:",any"` + Text string `xml:",chardata"` + } + x := node{} + + err := xml.Unmarshal(bs, &x) + if err != nil { + message := fmt.Sprintf("error while parsing XML\nerror:\n %s\nXML:\n %s\n", err, string(bs)) + return VerifyWithExtension(t, strings.NewReader(message), ".xml") + } + + return VerifyXMLStruct(t, x) +} + +// VerifyJSONStruct Example: +// VerifyJSONStruct(t, json) +func VerifyJSONStruct(t Failable, obj interface{}) error { + jsonb, err := json.MarshalIndent(obj, "", " ") + if err != nil { + message := fmt.Sprintf("error while pretty printing JSON\nerror:\n %s\nJSON:\n %s\n", err, obj) + return VerifyWithExtension(t, strings.NewReader(message), ".json") + } + + return VerifyWithExtension(t, bytes.NewReader(jsonb), ".json") +} + +// VerifyJSONBytes Example: +// VerifyJSONBytes(t, []byte("{ \"Greeting\": \"Hello\" }")) +func VerifyJSONBytes(t Failable, bs []byte) error { + var obj map[string]interface{} + err := json.Unmarshal(bs, &obj) + if err != nil { + message := fmt.Sprintf("error while parsing JSON\nerror:\n %s\nJSON:\n %s\n", err, string(bs)) + return VerifyWithExtension(t, strings.NewReader(message), ".json") + } + + return VerifyJSONStruct(t, obj) +} + +// VerifyMap Example: +// VerifyMap(t, map[string][string] { "dog": "bark" }) +func VerifyMap(t Failable, m interface{}) error { + outputText := utils.PrintMap(m) + return VerifyString(t, outputText) +} + +// VerifyArray Example: +// VerifyArray(t, []string{"dog", "cat"}) +func VerifyArray(t Failable, array interface{}) error { + outputText := utils.PrintArray(array) + return VerifyString(t, outputText) +} + +// VerifyAll Example: +// VerifyAll(t, "uppercase", []string("dog", "cat"}, func(x interface{}) string { return strings.ToUpper(x.(string)) }) +func VerifyAll(t Failable, header string, collection interface{}, transform func(interface{}) string) error { + if len(header) != 0 { + header = fmt.Sprintf("%s\n\n\n", header) + } + + outputText := header + strings.Join(utils.MapToString(collection, transform), "\n") + return VerifyString(t, outputText) +} + +type reporterCloser struct { + reporter *reporters.Reporter +} + +func (s *reporterCloser) Close() error { + defaultReporter = s.reporter + return nil +} + +type frontLoadedReporterCloser struct { + reporter *reporters.Reporter +} + +func (s *frontLoadedReporterCloser) Close() error { + defaultFrontLoadedReporter = s.reporter + return nil +} + +// UseReporter configures which reporter to use on failure. +// Add at the test or method level to configure your reporter. +// +// The following examples shows how to use a reporter for all of your test cases +// in a package directory through go's setup feature. +// +// +// func TestMain(m *testing.M) { +// r := UseReporter(reporters.NewBeyondCompareReporter()) +// defer r.Close() +// +// os.Exit(m.Run()) +// } +// +func UseReporter(reporter reporters.Reporter) io.Closer { + closer := &reporterCloser{ + reporter: defaultReporter, + } + + defaultReporter = &reporter + return closer +} + +// UseFrontLoadedReporter configures reporters ahead of all other reporters to +// handle situations like CI. These reporters usually prevent reporting in +// scenarios that are headless. +func UseFrontLoadedReporter(reporter reporters.Reporter) io.Closer { + closer := &frontLoadedReporterCloser{ + reporter: defaultFrontLoadedReporter, + } + + defaultFrontLoadedReporter = &reporter + return closer +} + +func getReporter() reporters.Reporter { + return reporters.NewFirstWorkingReporter( + *defaultFrontLoadedReporter, + *defaultReporter, + ) +} diff --git a/vendor/github.com/approvals/go-approval-tests/combination_approvals.go b/vendor/github.com/approvals/go-approval-tests/combination_approvals.go new file mode 100644 index 000000000..9c775a823 --- /dev/null +++ b/vendor/github.com/approvals/go-approval-tests/combination_approvals.go @@ -0,0 +1,296 @@ +package approvaltests + +import ( + "fmt" + "strings" + + "reflect" +) + +type emptyType struct{} + +var ( + // SkipThisCombination should be returned if you do not want to process a particular combination + SkipThisCombination = "♬ SKIP THIS COMBINATION ♬" + + empty = emptyType{} + emptyCollection = []emptyType{empty} +) + +// VerifyAllCombinationsFor1 Example: +// VerifyAllCombinationsFor1(t, "uppercase", func(x interface{}) string { return strings.ToUpper(x.(string)) }, []string("dog", "cat"}) +func VerifyAllCombinationsFor1(t Failable, header string, transform func(interface{}) string, collection1 interface{}) error { + transform2 := func(p1, p2, p3, p4, p5, p6, p7, p8, p9 interface{}) string { + return transform(p1) + } + + return VerifyAllCombinationsFor9(t, header, transform2, collection1, + emptyCollection, + emptyCollection, + emptyCollection, + emptyCollection, + emptyCollection, + emptyCollection, + emptyCollection, + emptyCollection) +} + +// VerifyAllCombinationsFor2 Example: +// VerifyAllCombinationsFor2(t, "uppercase", func(x interface{}) string { return strings.ToUpper(x.(string)) }, []string("dog", "cat"}, []int{1,2) +func VerifyAllCombinationsFor2(t Failable, header string, transform func(interface{}, interface{}) string, collection1 interface{}, collection2 interface{}) error { + transform2 := func(p1, p2, p3, p4, p5, p6, p7, p8, p9 interface{}) string { + return transform(p1, p2) + } + + return VerifyAllCombinationsFor9(t, header, transform2, collection1, + collection2, + emptyCollection, + emptyCollection, + emptyCollection, + emptyCollection, + emptyCollection, + emptyCollection, + emptyCollection) +} + +// VerifyAllCombinationsFor3 is for combinations of 3. +func VerifyAllCombinationsFor3( + t Failable, + header string, + transform func(p1, p2, p3 interface{}) string, + collection1, collection2, collection3 interface{}) error { + + kerning := func(p1, p2, p3, p4, p5, p6, p7, p8, p9 interface{}) string { + return transform(p1, p2, p3) + } + + return VerifyAllCombinationsFor9(t, header, kerning, + collection1, + collection2, + collection3, + emptyCollection, + emptyCollection, + emptyCollection, + emptyCollection, + emptyCollection, + emptyCollection) +} + +// VerifyAllCombinationsFor4 is for combinations of 4. +func VerifyAllCombinationsFor4( + t Failable, + header string, + transform func(p1, p2, p3, p4 interface{}) string, + collection1, collection2, collection3, collection4 interface{}) error { + + kerning := func(p1, p2, p3, p4, p5, p6, p7, p8, p9 interface{}) string { + return transform(p1, p2, p3, p4) + } + + return VerifyAllCombinationsFor9(t, header, kerning, + collection1, + collection2, + collection3, + collection4, + emptyCollection, + emptyCollection, + emptyCollection, + emptyCollection, + emptyCollection) +} + +// VerifyAllCombinationsFor5 is for combinations of 5. +func VerifyAllCombinationsFor5( + t Failable, + header string, + transform func(p1, p2, p3, p4, p5 interface{}) string, + collection1, collection2, collection3, collection4, collection5 interface{}) error { + + kerning := func(p1, p2, p3, p4, p5, p6, p7, p8, p9 interface{}) string { + return transform(p1, p2, p3, p4, p5) + } + + return VerifyAllCombinationsFor9(t, header, kerning, + collection1, + collection2, + collection3, + collection4, + collection5, + emptyCollection, + emptyCollection, + emptyCollection, + emptyCollection) +} + +// VerifyAllCombinationsFor6 is for combinations of 6. +func VerifyAllCombinationsFor6( + t Failable, + header string, + transform func(p1, p2, p3, p4, p5, p6 interface{}) string, + collection1, collection2, collection3, collection4, collection5, collection6 interface{}) error { + + kerning := func(p1, p2, p3, p4, p5, p6, p7, p8, p9 interface{}) string { + return transform(p1, p2, p3, p4, p5, p6) + } + + return VerifyAllCombinationsFor9(t, header, kerning, + collection1, + collection2, + collection3, + collection4, + collection5, + collection6, + emptyCollection, + emptyCollection, + emptyCollection) +} + +// VerifyAllCombinationsFor7 is for combinations of 7. +func VerifyAllCombinationsFor7( + t Failable, + header string, + transform func(p1, p2, p3, p4, p5, p6, p7 interface{}) string, + collection1, collection2, collection3, collection4, collection5, collection6, collection7 interface{}) error { + + kerning := func(p1, p2, p3, p4, p5, p6, p7, p8, p9 interface{}) string { + return transform(p1, p2, p3, p4, p5, p6, p7) + } + + return VerifyAllCombinationsFor9(t, header, kerning, + collection1, + collection2, + collection3, + collection4, + collection5, + collection6, + collection7, + emptyCollection, + emptyCollection) +} + +// VerifyAllCombinationsFor8 is for combinations of 8. +func VerifyAllCombinationsFor8( + t Failable, + header string, + transform func(p1, p2, p3, p4, p5, p6, p7, p8 interface{}) string, + collection1, collection2, collection3, collection4, collection5, collection6, collection7, collection8 interface{}) error { + + kerning := func(p1, p2, p3, p4, p5, p6, p7, p8, p9 interface{}) string { + return transform(p1, p2, p3, p4, p5, p6, p7, p8) + } + + return VerifyAllCombinationsFor9(t, header, kerning, + collection1, + collection2, + collection3, + collection4, + collection5, + collection6, + collection7, + collection8, + emptyCollection) +} + +// VerifyAllCombinationsFor9 is for combinations of 9. +func VerifyAllCombinationsFor9( + t Failable, + header string, + transform func(a, b, c, d, e, f, g, h, i interface{}) string, + collection1, + collection2, + collection3, + collection4, + collection5, + collection6, + collection7, + collection8, + collection9 interface{}) error { + + if len(header) != 0 { + header = fmt.Sprintf("%s\n\n\n", header) + } + + var mapped []string + + slice1 := reflect.ValueOf(collection1) + slice2 := reflect.ValueOf(collection2) + slice3 := reflect.ValueOf(collection3) + slice4 := reflect.ValueOf(collection4) + slice5 := reflect.ValueOf(collection5) + slice6 := reflect.ValueOf(collection6) + slice7 := reflect.ValueOf(collection7) + slice8 := reflect.ValueOf(collection8) + slice9 := reflect.ValueOf(collection9) + + for i1 := 0; i1 < slice1.Len(); i1++ { + for i2 := 0; i2 < slice2.Len(); i2++ { + for i3 := 0; i3 < slice3.Len(); i3++ { + for i4 := 0; i4 < slice4.Len(); i4++ { + for i5 := 0; i5 < slice5.Len(); i5++ { + for i6 := 0; i6 < slice6.Len(); i6++ { + for i7 := 0; i7 < slice7.Len(); i7++ { + for i8 := 0; i8 < slice8.Len(); i8++ { + for i9 := 0; i9 < slice9.Len(); i9++ { + p1 := slice1.Index(i1).Interface() + p2 := slice2.Index(i2).Interface() + p3 := slice3.Index(i3).Interface() + p4 := slice4.Index(i4).Interface() + p5 := slice5.Index(i5).Interface() + p6 := slice6.Index(i6).Interface() + p7 := slice7.Index(i7).Interface() + p8 := slice8.Index(i8).Interface() + p9 := slice9.Index(i9).Interface() + + parameterText := getParameterText(p1, p2, p3, p4, p5, p6, p7, p8, p9) + transformText := getTransformText(transform, p1, p2, p3, p4, p5, p6, p7, p8, p9) + if transformText != SkipThisCombination { + mapped = append(mapped, fmt.Sprintf("%s => %s", parameterText, transformText)) + } + } + } + } + } + } + } + } + } + } + + outputText := header + strings.Join(mapped, "\n") + return VerifyString(t, outputText) +} + +func getParameterText(args ...interface{}) string { + parameterText := "[" + for _, x := range args { + if x != empty { + parameterText += fmt.Sprintf("%v,", x) + } + } + + parameterText = parameterText[0 : len(parameterText)-1] + parameterText += "]" + + return parameterText +} + +func getTransformText( + transform func(a, b, c, d, e, f, g, h, i interface{}) string, + p1, + p2, + p3, + p4, + p5, + p6, + p7, + p8, + p9 interface{}) (s string) { + defer func() { + r := recover() + if r != nil { + s = "panic occurred" + } + }() + + return transform(p1, p2, p3, p4, p5, p6, p7, p8, p9) +} diff --git a/vendor/github.com/approvals/go-approval-tests/reporters/all_failing.go b/vendor/github.com/approvals/go-approval-tests/reporters/all_failing.go new file mode 100644 index 000000000..788a1e3b0 --- /dev/null +++ b/vendor/github.com/approvals/go-approval-tests/reporters/all_failing.go @@ -0,0 +1,18 @@ +package reporters + +var ( + clipboardScratchData = "" +) + +type allFailing struct{} + +// NewAllFailingTestReporter copies move file command to your clipboard +func NewAllFailingTestReporter() Reporter { + return &allFailing{} +} + +func (s *allFailing) Report(approved, received string) bool { + move := getMoveCommandText(approved, received) + clipboardScratchData = clipboardScratchData + move + "\n" + return copyToClipboard(clipboardScratchData) +} diff --git a/vendor/github.com/approvals/go-approval-tests/reporters/beyond_compare.go b/vendor/github.com/approvals/go-approval-tests/reporters/beyond_compare.go new file mode 100644 index 000000000..81dccd25c --- /dev/null +++ b/vendor/github.com/approvals/go-approval-tests/reporters/beyond_compare.go @@ -0,0 +1,15 @@ +package reporters + +type beyondCompare struct{} + +// NewBeyondCompareReporter creates a new reporter for Beyond Compare 4. +func NewBeyondCompareReporter() Reporter { + return &beyondCompare{} +} + +func (s *beyondCompare) Report(approved, received string) bool { + xs := []string{received, approved} + programName := "C:/Program Files/Beyond Compare 4/BComp.exe" + + return launchProgram(programName, approved, xs...) +} diff --git a/vendor/github.com/approvals/go-approval-tests/reporters/clipboard.go b/vendor/github.com/approvals/go-approval-tests/reporters/clipboard.go new file mode 100644 index 000000000..4f4f9ffe9 --- /dev/null +++ b/vendor/github.com/approvals/go-approval-tests/reporters/clipboard.go @@ -0,0 +1,66 @@ +package reporters + +import ( + "fmt" + "os/exec" + "path/filepath" + "runtime" +) + +type clipboard struct{} + +// NewClipboardReporter copies move file command to your clipboard +func NewClipboardReporter() Reporter { + return &clipboard{} +} + +func (s *clipboard) Report(approved, received string) bool { + move := getMoveCommandText(approved, received) + return copyToClipboard(move) +} + +func copyToClipboard(move string) bool { + switch runtime.GOOS { + case "windows": + return copyToWindowsClipboard(move) + default: + return copyToDarwinClipboard(move) + } +} + +func getMoveCommandText(approved, received string) string { + receivedFull, _ := filepath.Abs(received) + approvedFull, _ := filepath.Abs(approved) + + var move string + + switch runtime.GOOS { + case "windows": + move = fmt.Sprintf("move /Y \"%s\" \"%s\"", receivedFull, approvedFull) + default: + move = fmt.Sprintf("mv %s %s", receivedFull, approvedFull) + } + + return move +} +func copyToWindowsClipboard(text string) bool { + return pipeToProgram("clip", text) +} + +func copyToDarwinClipboard(text string) bool { + return pipeToProgram("pbcopy", text) +} + +func pipeToProgram(programName, text string) bool { + c := exec.Command(programName) + pipe, err := c.StdinPipe() + if err != nil { + fmt.Printf("StdinPipe: err=%s", err) + return false + } + pipe.Write([]byte(text)) + pipe.Close() + + c.Start() + return true +} diff --git a/vendor/github.com/approvals/go-approval-tests/reporters/continuous_integration.go b/vendor/github.com/approvals/go-approval-tests/reporters/continuous_integration.go new file mode 100644 index 000000000..923feb793 --- /dev/null +++ b/vendor/github.com/approvals/go-approval-tests/reporters/continuous_integration.go @@ -0,0 +1,28 @@ +package reporters + +import ( + "os" + "strconv" +) + +type continuousIntegration struct{} + +// NewContinuousIntegrationReporter creates a new reporter for CI. +// +// The reporter checks the environment variable CI for a value of true. +func NewContinuousIntegrationReporter() Reporter { + return &continuousIntegration{} +} + +func (s *continuousIntegration) Report(approved, received string) bool { + value, exists := os.LookupEnv("CI") + + if exists { + ci, err := strconv.ParseBool(value) + if err == nil { + return ci + } + } + + return false +} diff --git a/vendor/github.com/approvals/go-approval-tests/reporters/diff_reporter.go b/vendor/github.com/approvals/go-approval-tests/reporters/diff_reporter.go new file mode 100644 index 000000000..630548e2a --- /dev/null +++ b/vendor/github.com/approvals/go-approval-tests/reporters/diff_reporter.go @@ -0,0 +1,40 @@ +package reporters + +import ( + "os/exec" + + "github.com/approvals/go-approval-tests/utils" +) + +// NewFrontLoadedReporter creates the default front loaded reporter. +func NewFrontLoadedReporter() *Reporter { + tmp := NewFirstWorkingReporter( + NewContinuousIntegrationReporter(), + ) + + return &tmp +} + +// NewDiffReporter creates the default diff reporter. +func NewDiffReporter() *Reporter { + tmp := NewFirstWorkingReporter( + NewBeyondCompareReporter(), + NewIntelliJReporter(), + NewPrintSupportedDiffProgramsReporter(), + NewQuietReporter(), + ) + + return &tmp +} + +func launchProgram(programName, approved string, args ...string) bool { + if !utils.DoesFileExist(programName) { + return false + } + + utils.EnsureExists(approved) + + cmd := exec.Command(programName, args...) + cmd.Start() + return true +} diff --git a/vendor/github.com/approvals/go-approval-tests/reporters/file_launcher.go b/vendor/github.com/approvals/go-approval-tests/reporters/file_launcher.go new file mode 100644 index 000000000..cb9bd5b2d --- /dev/null +++ b/vendor/github.com/approvals/go-approval-tests/reporters/file_launcher.go @@ -0,0 +1,27 @@ +package reporters + +import ( + "os/exec" + "runtime" +) + +type fileLauncher struct{} + +// NewFileLauncherReporter launches registered application of the received file's type only. +func NewFileLauncherReporter() Reporter { + return &fileLauncher{} +} + +func (s *fileLauncher) Report(approved, received string) bool { + var cmd *exec.Cmd + + switch runtime.GOOS { + case "windows": + cmd = exec.Command("cmd", "/C", "start", "Needed Title", received, "/B") + default: + cmd = exec.Command("open", received) + } + + cmd.Start() + return true +} diff --git a/vendor/github.com/approvals/go-approval-tests/reporters/intellij.go b/vendor/github.com/approvals/go-approval-tests/reporters/intellij.go new file mode 100644 index 000000000..63e9506aa --- /dev/null +++ b/vendor/github.com/approvals/go-approval-tests/reporters/intellij.go @@ -0,0 +1,15 @@ +package reporters + +type intellij struct{} + +// NewIntelliJReporter creates a new reporter for IntelliJ. +func NewIntelliJReporter() Reporter { + return &intellij{} +} + +func (s *intellij) Report(approved, received string) bool { + xs := []string{"diff", received, approved} + programName := "C:/Program Files (x86)/JetBrains/IntelliJ IDEA 2016/bin/idea.exe" + + return launchProgram(programName, approved, xs...) +} diff --git a/vendor/github.com/approvals/go-approval-tests/reporters/newbie.go b/vendor/github.com/approvals/go-approval-tests/reporters/newbie.go new file mode 100644 index 000000000..8e662bf84 --- /dev/null +++ b/vendor/github.com/approvals/go-approval-tests/reporters/newbie.go @@ -0,0 +1,18 @@ +package reporters + +import ( + "fmt" +) + +type printSupportedDiffPrograms struct{} + +// NewPrintSupportedDiffProgramsReporter creates a new reporter that states what reporters are supported. +func NewPrintSupportedDiffProgramsReporter() Reporter { + return &quiet{} +} + +func (s *printSupportedDiffPrograms) Report(approved, received string) bool { + fmt.Printf("no diff reporters found on your system\ncurrently supported reporters are [in order of preference]:\nBeyond Compare\nIntelliJ") + + return false +} diff --git a/vendor/github.com/approvals/go-approval-tests/reporters/quiet.go b/vendor/github.com/approvals/go-approval-tests/reporters/quiet.go new file mode 100644 index 000000000..a715c0eac --- /dev/null +++ b/vendor/github.com/approvals/go-approval-tests/reporters/quiet.go @@ -0,0 +1,29 @@ +package reporters + +import ( + "fmt" + "path/filepath" + + "github.com/approvals/go-approval-tests/utils" +) + +type quiet struct{} + +// NewQuietReporter creates a new reporter that does nothing. +func NewQuietReporter() Reporter { + return &quiet{} +} + +func (s *quiet) Report(approved, received string) bool { + approvedFull, _ := filepath.Abs(approved) + receivedFull, _ := filepath.Abs(received) + + if utils.DoesFileExist(approved) { + fmt.Printf("approval files did not match\napproved: %v\nreceived: %v\n", approvedFull, receivedFull) + + } else { + fmt.Printf("result never approved\napproved: %v\nreceived: %v\n", approvedFull, receivedFull) + } + + return true +} diff --git a/vendor/github.com/approvals/go-approval-tests/reporters/reporter.go b/vendor/github.com/approvals/go-approval-tests/reporters/reporter.go new file mode 100644 index 000000000..99d6866f6 --- /dev/null +++ b/vendor/github.com/approvals/go-approval-tests/reporters/reporter.go @@ -0,0 +1,53 @@ +package reporters + +// Reporter are called on failing approvals. +type Reporter interface { + // Report is called when the approved and received file do not match. + Report(approved, received string) bool +} + +// FirstWorkingReporter reports using the first possible reporter. +type FirstWorkingReporter struct { + Reporters []Reporter +} + +// Report is called when the approved and received file do not match. +func (s *FirstWorkingReporter) Report(approved, received string) bool { + for _, reporter := range s.Reporters { + result := reporter.Report(approved, received) + if result { + return true + } + } + + return false +} + +// NewFirstWorkingReporter creates in the order reporters are passed in. +func NewFirstWorkingReporter(reporters ...Reporter) Reporter { + return &FirstWorkingReporter{ + Reporters: reporters, + } +} + +// MultiReporter reports all reporters. +type MultiReporter struct { + Reporters []Reporter +} + +// Report is called when the approved and received file do not match. +func (s *MultiReporter) Report(approved, received string) bool { + result := false + for _, reporter := range s.Reporters { + result = reporter.Report(approved, received) || result + } + + return result +} + +// NewMultiReporter calls all reporters. +func NewMultiReporter(reporters ...Reporter) Reporter { + return &MultiReporter{ + Reporters: reporters, + } +} diff --git a/vendor/github.com/approvals/go-approval-tests/utils/collection_utils.go b/vendor/github.com/approvals/go-approval-tests/utils/collection_utils.go new file mode 100644 index 000000000..1602fa6e5 --- /dev/null +++ b/vendor/github.com/approvals/go-approval-tests/utils/collection_utils.go @@ -0,0 +1,77 @@ +package utils + +import ( + "fmt" + "reflect" + "sort" + "strings" +) + +// PrintMap prints a map +func PrintMap(m interface{}) string { + var outputText string + + v := reflect.ValueOf(m) + if v.Kind() != reflect.Map { + outputText = fmt.Sprintf("error while printing map\nreceived a %T\n %s\n", m, m) + } else { + + keys := v.MapKeys() + var xs []string + + for _, k := range keys { + xs = append(xs, fmt.Sprintf("[%s]=%s", k, v.MapIndex(k))) + } + + sort.Strings(xs) + if len(xs) == 0 { + outputText = "len(map) == 0" + } else { + outputText = strings.Join(xs, "\n") + } + } + + return outputText +} + +// PrintArray prints an array +func PrintArray(m interface{}) string { + var outputText string + + switch reflect.TypeOf(m).Kind() { + case reflect.Slice: + var xs []string + + slice := reflect.ValueOf(m) + for i := 0; i < slice.Len(); i++ { + xs = append(xs, fmt.Sprintf("[%d]=%s", i, slice.Index(i))) + } + + if len(xs) == 0 { + outputText = "len(array) == 0" + } else { + outputText = strings.Join(xs, "\n") + } + default: + outputText = fmt.Sprintf("error while printing array\nreceived a %T\n %s\n", m, m) + } + + return outputText +} + +// MapToString maps a collection to a string collection +func MapToString(collection interface{}, transform func(x interface{}) string) []string { + switch reflect.TypeOf(collection).Kind() { + case reflect.Slice: + var xs []string + + slice := reflect.ValueOf(collection) + for i := 0; i < slice.Len(); i++ { + xs = append(xs, transform(slice.Index(i).Interface())) + } + + return xs + default: + panic(fmt.Sprintf("error while mapping array to string\nreceived a %T\n %s\n", collection, collection)) + } +} diff --git a/vendor/github.com/approvals/go-approval-tests/utils/file_utils.go b/vendor/github.com/approvals/go-approval-tests/utils/file_utils.go new file mode 100644 index 000000000..bec3b950b --- /dev/null +++ b/vendor/github.com/approvals/go-approval-tests/utils/file_utils.go @@ -0,0 +1,24 @@ +package utils + +import ( + "io/ioutil" + "os" +) + +// DoesFileExist checks if a file exists. +func DoesFileExist(fileName string) bool { + _, err := os.Stat(fileName) + if os.IsNotExist(err) { + return false + } + return true +} + +// EnsureExists creates if the file does not already exist. +func EnsureExists(fileName string) { + if DoesFileExist(fileName) { + return + } + + ioutil.WriteFile(fileName, []byte(""), 0644) +} diff --git a/vendor/github.com/approvals/go-approval-tests/utils/testing_utils.go b/vendor/github.com/approvals/go-approval-tests/utils/testing_utils.go new file mode 100644 index 000000000..c6c9c8ab6 --- /dev/null +++ b/vendor/github.com/approvals/go-approval-tests/utils/testing_utils.go @@ -0,0 +1,11 @@ +package utils + +import "testing" + +// AssertEqual Example: +// AssertEqual(t, 10, number, "number") +func AssertEqual(t *testing.T, expected, actual interface{}, message string) { + if expected != actual { + t.Fatalf(message+"\n[expected != actual]\n[%s != %s]", expected, actual) + } +}