package chroot import ( "context" "io/ioutil" "net/http" "reflect" "regexp" "strings" "testing" "github.com/hashicorp/packer/builder/azure/common/client" "github.com/hashicorp/packer/packer-plugin-sdk/multistep" packersdk "github.com/hashicorp/packer/packer-plugin-sdk/packer" "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-12-01/compute" "github.com/Azure/go-autorest/autorest" ) func TestStepCreateNewDisk_Run(t *testing.T) { tests := []struct { name string fields StepCreateNewDiskset expectedPutDiskBodies []string want multistep.StepAction verifyDiskset *Diskset }{ { name: "from disk", fields: StepCreateNewDiskset{ OSDiskID: "/subscriptions/SubscriptionID/resourcegroups/ResourceGroupName/providers/Microsoft.Compute/disks/TemporaryOSDiskName", OSDiskSizeGB: 42, OSDiskStorageAccountType: string(compute.PremiumLRS), HyperVGeneration: string(compute.V1), Location: "westus", SourceOSDiskResourceID: "SourceDisk", }, expectedPutDiskBodies: []string{` { "location": "westus", "properties": { "osType": "Linux", "hyperVGeneration": "V1", "creationData": { "createOption": "Copy", "sourceResourceId": "SourceDisk" }, "diskSizeGB": 42 }, "sku": { "name": "Premium_LRS" } }`}, want: multistep.ActionContinue, verifyDiskset: &Diskset{-1: resource("/subscriptions/SubscriptionID/resourceGroups/ResourceGroupName/providers/Microsoft.Compute/disks/TemporaryOSDiskName")}, }, { name: "from platform image", fields: StepCreateNewDiskset{ OSDiskID: "/subscriptions/SubscriptionID/resourcegroups/ResourceGroupName/providers/Microsoft.Compute/disks/TemporaryOSDiskName", OSDiskStorageAccountType: string(compute.StandardLRS), HyperVGeneration: string(compute.V1), Location: "westus", SourcePlatformImage: &client.PlatformImage{ Publisher: "Microsoft", Offer: "Windows", Sku: "2016-DataCenter", Version: "2016.1.4", }, }, expectedPutDiskBodies: []string{` { "location": "westus", "properties": { "osType": "Linux", "hyperVGeneration": "V1", "creationData": { "createOption":"FromImage", "imageReference": { "id":"/subscriptions/SubscriptionID/providers/Microsoft.Compute/locations/westus/publishers/Microsoft/artifacttypes/vmimage/offers/Windows/skus/2016-DataCenter/versions/2016.1.4" } } }, "sku": { "name": "Standard_LRS" } }`}, want: multistep.ActionContinue, verifyDiskset: &Diskset{-1: resource("/subscriptions/SubscriptionID/resourceGroups/ResourceGroupName/providers/Microsoft.Compute/disks/TemporaryOSDiskName")}, }, { name: "from shared image", fields: StepCreateNewDiskset{ OSDiskID: "/subscriptions/SubscriptionID/resourcegroups/ResourceGroupName/providers/Microsoft.Compute/disks/TemporaryOSDiskName", OSDiskStorageAccountType: string(compute.StandardLRS), DataDiskStorageAccountType: string(compute.PremiumLRS), DataDiskIDPrefix: "/subscriptions/SubscriptionID/resourcegroups/ResourceGroupName/providers/Microsoft.Compute/disks/TemporaryDataDisk-", HyperVGeneration: string(compute.V1), Location: "westus", SourceImageResourceID: "/subscriptions/SubscriptionID/resourcegroups/imagegroup/providers/Microsoft.Compute/galleries/MyGallery/images/MyImage/versions/1.2.3", }, expectedPutDiskBodies: []string{` { "location": "westus", "properties": { "osType": "Linux", "hyperVGeneration": "V1", "creationData": { "createOption":"FromImage", "galleryImageReference": { "id":"/subscriptions/SubscriptionID/resourcegroups/imagegroup/providers/Microsoft.Compute/galleries/MyGallery/images/MyImage/versions/1.2.3" } } }, "sku": { "name": "Standard_LRS" } }`, ` { "location": "westus", "properties": { "creationData": { "createOption":"FromImage", "galleryImageReference": { "id": "/subscriptions/SubscriptionID/resourcegroups/imagegroup/providers/Microsoft.Compute/galleries/MyGallery/images/MyImage/versions/1.2.3", "lun": 5 } } }, "sku": { "name": "Premium_LRS" } }`, ` { "location": "westus", "properties": { "creationData": { "createOption":"FromImage", "galleryImageReference": { "id": "/subscriptions/SubscriptionID/resourcegroups/imagegroup/providers/Microsoft.Compute/galleries/MyGallery/images/MyImage/versions/1.2.3", "lun": 9 } } }, "sku": { "name": "Premium_LRS" } }`, ` { "location": "westus", "properties": { "creationData": { "createOption":"FromImage", "galleryImageReference": { "id": "/subscriptions/SubscriptionID/resourcegroups/imagegroup/providers/Microsoft.Compute/galleries/MyGallery/images/MyImage/versions/1.2.3", "lun": 3 } } }, "sku": { "name": "Premium_LRS" } }`}, want: multistep.ActionContinue, verifyDiskset: &Diskset{ -1: resource("/subscriptions/SubscriptionID/resourceGroups/ResourceGroupName/providers/Microsoft.Compute/disks/TemporaryOSDiskName"), 3: resource("/subscriptions/SubscriptionID/resourceGroups/ResourceGroupName/providers/Microsoft.Compute/disks/TemporaryDataDisk-3"), 5: resource("/subscriptions/SubscriptionID/resourceGroups/ResourceGroupName/providers/Microsoft.Compute/disks/TemporaryDataDisk-5"), 9: resource("/subscriptions/SubscriptionID/resourceGroups/ResourceGroupName/providers/Microsoft.Compute/disks/TemporaryDataDisk-9"), }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { s := tt.fields bodyCount := 0 m := compute.NewDisksClient("SubscriptionID") m.Sender = autorest.SenderFunc(func(r *http.Request) (*http.Response, error) { if r.Method != "PUT" { t.Fatal("Expected only a PUT disk call") } b, _ := ioutil.ReadAll(r.Body) expectedPutDiskBody := regexp.MustCompile(`[\s\n]`).ReplaceAllString(tt.expectedPutDiskBodies[bodyCount], "") bodyCount++ if string(b) != expectedPutDiskBody { t.Fatalf("expected body #%d to be %q, but got %q", bodyCount, expectedPutDiskBody, string(b)) } return &http.Response{ Request: r, StatusCode: 200, }, nil }) giv := compute.NewGalleryImageVersionsClient("SubscriptionID") giv.Sender = autorest.SenderFunc(func(r *http.Request) (*http.Response, error) { if r.Method == "GET" && regexp.MustCompile(`(?i)/versions/1\.2\.3$`).MatchString(r.URL.Path) { return &http.Response{ Request: r, Body: ioutil.NopCloser(strings.NewReader(`{ "properties": { "storageProfile": { "dataDiskImages":[ { "lun": 5 }, { "lun": 9 }, { "lun": 3 } ] } } }`)), StatusCode: 200, }, nil } return &http.Response{ Request: r, Status: "Unexpected request", StatusCode: 500, }, nil }) state := new(multistep.BasicStateBag) state.Put("azureclient", &client.AzureClientSetMock{ SubscriptionIDMock: "SubscriptionID", DisksClientMock: m, GalleryImageVersionsClientMock: giv, }) state.Put("ui", packersdk.TestUi(t)) if got := s.Run(context.TODO(), state); !reflect.DeepEqual(got, tt.want) { t.Errorf("StepCreateNewDisk.Run() = %v, want %v", got, tt.want) } ds := state.Get(stateBagKey_Diskset) if tt.verifyDiskset != nil && !reflect.DeepEqual(*tt.verifyDiskset, ds) { t.Errorf("Error verifying diskset after Run(), got %v, want %v", ds, *tt.verifyDiskset) } }) } } func resource(id string) client.Resource { v, err := client.ParseResourceID(id) if err != nil { panic(err) } return v }