From 9be062e47965addd98b1b90d474377286e302d08 Mon Sep 17 00:00:00 2001 From: tombuildsstuff Date: Mon, 11 Sep 2023 12:23:12 +0200 Subject: [PATCH] New Common IDs: Dedicated Host / Dedicated Host Group --- resourcemanager/commonids/dedicated_host.go | 140 ++++++++ .../commonids/dedicated_host_group.go | 127 +++++++ .../commonids/dedicated_host_group_test.go | 282 +++++++++++++++ .../commonids/dedicated_host_test.go | 327 ++++++++++++++++++ 4 files changed, 876 insertions(+) create mode 100644 resourcemanager/commonids/dedicated_host.go create mode 100644 resourcemanager/commonids/dedicated_host_group.go create mode 100644 resourcemanager/commonids/dedicated_host_group_test.go create mode 100644 resourcemanager/commonids/dedicated_host_test.go diff --git a/resourcemanager/commonids/dedicated_host.go b/resourcemanager/commonids/dedicated_host.go new file mode 100644 index 0000000..b10cae3 --- /dev/null +++ b/resourcemanager/commonids/dedicated_host.go @@ -0,0 +1,140 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package commonids + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +var _ resourceids.ResourceId = DedicatedHostId{} + +// DedicatedHostId is a struct representing the Resource ID for a Dedicated Host +type DedicatedHostId struct { + SubscriptionId string + ResourceGroupName string + HostGroupName string + HostName string +} + +// NewDedicatedHostID returns a new DedicatedHostId struct +func NewDedicatedHostID(subscriptionId string, resourceGroupName string, hostGroupName string, hostName string) DedicatedHostId { + return DedicatedHostId{ + SubscriptionId: subscriptionId, + ResourceGroupName: resourceGroupName, + HostGroupName: hostGroupName, + HostName: hostName, + } +} + +// ParseDedicatedHostID parses 'input' into a DedicatedHostId +func ParseDedicatedHostID(input string) (*DedicatedHostId, error) { + parser := resourceids.NewParserFromResourceIdType(DedicatedHostId{}) + parsed, err := parser.Parse(input, false) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + var ok bool + id := DedicatedHostId{} + + if id.SubscriptionId, ok = parsed.Parsed["subscriptionId"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "subscriptionId", *parsed) + } + + if id.ResourceGroupName, ok = parsed.Parsed["resourceGroupName"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "resourceGroupName", *parsed) + } + + if id.HostGroupName, ok = parsed.Parsed["hostGroupName"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "hostGroupName", *parsed) + } + + if id.HostName, ok = parsed.Parsed["hostName"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "hostName", *parsed) + } + + return &id, nil +} + +// ParseDedicatedHostIDInsensitively parses 'input' case-insensitively into a DedicatedHostId +// note: this method should only be used for API response data and not user input +func ParseDedicatedHostIDInsensitively(input string) (*DedicatedHostId, error) { + parser := resourceids.NewParserFromResourceIdType(DedicatedHostId{}) + parsed, err := parser.Parse(input, true) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + var ok bool + id := DedicatedHostId{} + + if id.SubscriptionId, ok = parsed.Parsed["subscriptionId"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "subscriptionId", *parsed) + } + + if id.ResourceGroupName, ok = parsed.Parsed["resourceGroupName"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "resourceGroupName", *parsed) + } + + if id.HostGroupName, ok = parsed.Parsed["hostGroupName"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "hostGroupName", *parsed) + } + + if id.HostName, ok = parsed.Parsed["hostName"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "hostName", *parsed) + } + + return &id, nil +} + +// ValidateDedicatedHostID checks that 'input' can be parsed as a Dedicated Host ID +func ValidateDedicatedHostID(input interface{}, key string) (warnings []string, errors []error) { + v, ok := input.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected %q to be a string", key)) + return + } + + if _, err := ParseDedicatedHostID(v); err != nil { + errors = append(errors, err) + } + + return +} + +// ID returns the formatted Dedicated Host ID +func (id DedicatedHostId) ID() string { + fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/hostGroups/%s/hosts/%s" + return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroupName, id.HostGroupName, id.HostName) +} + +// Segments returns a slice of Resource ID Segments which comprise this Dedicated Host ID +func (id DedicatedHostId) Segments() []resourceids.Segment { + return []resourceids.Segment{ + resourceids.StaticSegment("staticSubscriptions", "subscriptions", "subscriptions"), + resourceids.SubscriptionIdSegment("subscriptionId", "12345678-1234-9876-4563-123456789012"), + resourceids.StaticSegment("staticResourceGroups", "resourceGroups", "resourceGroups"), + resourceids.ResourceGroupSegment("resourceGroupName", "example-resource-group"), + resourceids.StaticSegment("staticProviders", "providers", "providers"), + resourceids.ResourceProviderSegment("staticMicrosoftCompute", "Microsoft.Compute", "Microsoft.Compute"), + resourceids.StaticSegment("staticHostGroups", "hostGroups", "hostGroups"), + resourceids.UserSpecifiedSegment("hostGroupName", "hostGroupValue"), + resourceids.StaticSegment("staticHosts", "hosts", "hosts"), + resourceids.UserSpecifiedSegment("hostName", "hostValue"), + } +} + +// String returns a human-readable description of this DedicatedHost ID +func (id DedicatedHostId) String() string { + components := []string{ + fmt.Sprintf("Subscription: %q", id.SubscriptionId), + fmt.Sprintf("Resource Group Name: %q", id.ResourceGroupName), + fmt.Sprintf("Host Group Name: %q", id.HostGroupName), + fmt.Sprintf("Host Name: %q", id.HostName), + } + return fmt.Sprintf("Dedicated Host (%s)", strings.Join(components, "\n")) +} diff --git a/resourcemanager/commonids/dedicated_host_group.go b/resourcemanager/commonids/dedicated_host_group.go new file mode 100644 index 0000000..ea85541 --- /dev/null +++ b/resourcemanager/commonids/dedicated_host_group.go @@ -0,0 +1,127 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package commonids + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +var _ resourceids.ResourceId = DedicatedHostGroupId{} + +// DedicatedHostGroupId is a struct representing the Resource ID for a Dedicated Host Group +type DedicatedHostGroupId struct { + SubscriptionId string + ResourceGroupName string + HostGroupName string +} + +// NewDedicatedHostGroupID returns a new HostGroupId struct +func NewDedicatedHostGroupID(subscriptionId string, resourceGroupName string, hostGroupName string) DedicatedHostGroupId { + return DedicatedHostGroupId{ + SubscriptionId: subscriptionId, + ResourceGroupName: resourceGroupName, + HostGroupName: hostGroupName, + } +} + +// ParseDedicatedHostGroupID parses 'input' into a DedicatedHostGroupId +func ParseDedicatedHostGroupID(input string) (*DedicatedHostGroupId, error) { + parser := resourceids.NewParserFromResourceIdType(DedicatedHostGroupId{}) + parsed, err := parser.Parse(input, false) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + var ok bool + id := DedicatedHostGroupId{} + + if id.SubscriptionId, ok = parsed.Parsed["subscriptionId"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "subscriptionId", *parsed) + } + + if id.ResourceGroupName, ok = parsed.Parsed["resourceGroupName"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "resourceGroupName", *parsed) + } + + if id.HostGroupName, ok = parsed.Parsed["hostGroupName"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "hostGroupName", *parsed) + } + + return &id, nil +} + +// ParseDedicatedHostGroupIDInsensitively parses 'input' case-insensitively into a DedicatedHostGroupId +// note: this method should only be used for API response data and not user input +func ParseDedicatedHostGroupIDInsensitively(input string) (*DedicatedHostGroupId, error) { + parser := resourceids.NewParserFromResourceIdType(DedicatedHostGroupId{}) + parsed, err := parser.Parse(input, true) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + var ok bool + id := DedicatedHostGroupId{} + + if id.SubscriptionId, ok = parsed.Parsed["subscriptionId"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "subscriptionId", *parsed) + } + + if id.ResourceGroupName, ok = parsed.Parsed["resourceGroupName"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "resourceGroupName", *parsed) + } + + if id.HostGroupName, ok = parsed.Parsed["hostGroupName"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "hostGroupName", *parsed) + } + + return &id, nil +} + +// ValidateDedicatedHostGroupID checks that 'input' can be parsed as a Dedicated Host Group ID +func ValidateDedicatedHostGroupID(input interface{}, key string) (warnings []string, errors []error) { + v, ok := input.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected %q to be a string", key)) + return + } + + if _, err := ParseDedicatedHostGroupID(v); err != nil { + errors = append(errors, err) + } + + return +} + +// ID returns the formatted Dedicated Host Group ID +func (id DedicatedHostGroupId) ID() string { + fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/hostGroups/%s" + return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroupName, id.HostGroupName) +} + +// Segments returns a slice of Resource ID Segments which comprise this Dedicated Host Group ID +func (id DedicatedHostGroupId) Segments() []resourceids.Segment { + return []resourceids.Segment{ + resourceids.StaticSegment("staticSubscriptions", "subscriptions", "subscriptions"), + resourceids.SubscriptionIdSegment("subscriptionId", "12345678-1234-9876-4563-123456789012"), + resourceids.StaticSegment("staticResourceGroups", "resourceGroups", "resourceGroups"), + resourceids.ResourceGroupSegment("resourceGroupName", "example-resource-group"), + resourceids.StaticSegment("staticProviders", "providers", "providers"), + resourceids.ResourceProviderSegment("staticMicrosoftCompute", "Microsoft.Compute", "Microsoft.Compute"), + resourceids.StaticSegment("staticHostGroups", "hostGroups", "hostGroups"), + resourceids.UserSpecifiedSegment("hostGroupName", "hostGroupValue"), + } +} + +// String returns a human-readable description of this Dedicated Host Group ID +func (id DedicatedHostGroupId) String() string { + components := []string{ + fmt.Sprintf("Subscription: %q", id.SubscriptionId), + fmt.Sprintf("Resource Group Name: %q", id.ResourceGroupName), + fmt.Sprintf("Host Group Name: %q", id.HostGroupName), + } + return fmt.Sprintf("Dedicated Host Group (%s)", strings.Join(components, "\n")) +} diff --git a/resourcemanager/commonids/dedicated_host_group_test.go b/resourcemanager/commonids/dedicated_host_group_test.go new file mode 100644 index 0000000..ee9f297 --- /dev/null +++ b/resourcemanager/commonids/dedicated_host_group_test.go @@ -0,0 +1,282 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package commonids + +import ( + "testing" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +var _ resourceids.ResourceId = DedicatedHostGroupId{} + +func TestNewDedicatedHostGroupID(t *testing.T) { + id := NewDedicatedHostGroupID("12345678-1234-9876-4563-123456789012", "example-resource-group", "hostGroupValue") + + if id.SubscriptionId != "12345678-1234-9876-4563-123456789012" { + t.Fatalf("Expected %q but got %q for Segment 'SubscriptionId'", id.SubscriptionId, "12345678-1234-9876-4563-123456789012") + } + + if id.ResourceGroupName != "example-resource-group" { + t.Fatalf("Expected %q but got %q for Segment 'ResourceGroupName'", id.ResourceGroupName, "example-resource-group") + } + + if id.HostGroupName != "hostGroupValue" { + t.Fatalf("Expected %q but got %q for Segment 'HostGroupName'", id.HostGroupName, "hostGroupValue") + } +} + +func TestFormatDedicatedHostGroupID(t *testing.T) { + actual := NewDedicatedHostGroupID("12345678-1234-9876-4563-123456789012", "example-resource-group", "hostGroupValue").ID() + expected := "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.Compute/hostGroups/hostGroupValue" + if actual != expected { + t.Fatalf("Expected the Formatted ID to be %q but got %q", expected, actual) + } +} + +func TestParseHostGroupID(t *testing.T) { + testData := []struct { + Input string + Error bool + Expected *DedicatedHostGroupId + }{ + { + // Incomplete URI + Input: "", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.Compute", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.Compute/hostGroups", + Error: true, + }, + { + // Valid URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.Compute/hostGroups/hostGroupValue", + Expected: &DedicatedHostGroupId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroupName: "example-resource-group", + HostGroupName: "hostGroupValue", + }, + }, + { + // Invalid (Valid Uri with Extra segment) + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.Compute/hostGroups/hostGroupValue/extra", + Error: true, + }, + } + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Input) + + actual, err := ParseDedicatedHostGroupID(v.Input) + if err != nil { + if v.Error { + continue + } + + t.Fatalf("Expect a value but got an error: %+v", err) + } + if v.Error { + t.Fatal("Expect an error but didn't get one") + } + + if actual.SubscriptionId != v.Expected.SubscriptionId { + t.Fatalf("Expected %q but got %q for SubscriptionId", v.Expected.SubscriptionId, actual.SubscriptionId) + } + + if actual.ResourceGroupName != v.Expected.ResourceGroupName { + t.Fatalf("Expected %q but got %q for ResourceGroupName", v.Expected.ResourceGroupName, actual.ResourceGroupName) + } + + if actual.HostGroupName != v.Expected.HostGroupName { + t.Fatalf("Expected %q but got %q for HostGroupName", v.Expected.HostGroupName, actual.HostGroupName) + } + + } +} + +func TestParseHostGroupIDInsensitively(t *testing.T) { + testData := []struct { + Input string + Error bool + Expected *DedicatedHostGroupId + }{ + { + // Incomplete URI + Input: "", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions", + Error: true, + }, + { + // Incomplete URI (mIxEd CaSe since this is insensitive) + Input: "/sUbScRiPtIoNs", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012", + Error: true, + }, + { + // Incomplete URI (mIxEd CaSe since this is insensitive) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups", + Error: true, + }, + { + // Incomplete URI (mIxEd CaSe since this is insensitive) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group", + Error: true, + }, + { + // Incomplete URI (mIxEd CaSe since this is insensitive) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-rEsOuRcE-GrOuP", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers", + Error: true, + }, + { + // Incomplete URI (mIxEd CaSe since this is insensitive) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-rEsOuRcE-GrOuP/pRoViDeRs", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.Compute", + Error: true, + }, + { + // Incomplete URI (mIxEd CaSe since this is insensitive) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-rEsOuRcE-GrOuP/pRoViDeRs/mIcRoSoFt.cOmPuTe", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.Compute/hostGroups", + Error: true, + }, + { + // Incomplete URI (mIxEd CaSe since this is insensitive) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-rEsOuRcE-GrOuP/pRoViDeRs/mIcRoSoFt.cOmPuTe/hOsTgRoUpS", + Error: true, + }, + { + // Valid URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.Compute/hostGroups/hostGroupValue", + Expected: &DedicatedHostGroupId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroupName: "example-resource-group", + HostGroupName: "hostGroupValue", + }, + }, + { + // Invalid (Valid Uri with Extra segment) + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.Compute/hostGroups/hostGroupValue/extra", + Error: true, + }, + { + // Valid URI (mIxEd CaSe since this is insensitive) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-rEsOuRcE-GrOuP/pRoViDeRs/mIcRoSoFt.cOmPuTe/hOsTgRoUpS/hOsTgRoUpVaLuE", + Expected: &DedicatedHostGroupId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroupName: "eXaMpLe-rEsOuRcE-GrOuP", + HostGroupName: "hOsTgRoUpVaLuE", + }, + }, + { + // Invalid (Valid Uri with Extra segment - mIxEd CaSe since this is insensitive) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-rEsOuRcE-GrOuP/pRoViDeRs/mIcRoSoFt.cOmPuTe/hOsTgRoUpS/hOsTgRoUpVaLuE/extra", + Error: true, + }, + } + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Input) + + actual, err := ParseDedicatedHostGroupIDInsensitively(v.Input) + if err != nil { + if v.Error { + continue + } + + t.Fatalf("Expect a value but got an error: %+v", err) + } + if v.Error { + t.Fatal("Expect an error but didn't get one") + } + + if actual.SubscriptionId != v.Expected.SubscriptionId { + t.Fatalf("Expected %q but got %q for SubscriptionId", v.Expected.SubscriptionId, actual.SubscriptionId) + } + + if actual.ResourceGroupName != v.Expected.ResourceGroupName { + t.Fatalf("Expected %q but got %q for ResourceGroupName", v.Expected.ResourceGroupName, actual.ResourceGroupName) + } + + if actual.HostGroupName != v.Expected.HostGroupName { + t.Fatalf("Expected %q but got %q for HostGroupName", v.Expected.HostGroupName, actual.HostGroupName) + } + + } +} + +func TestSegmentsForDedicatedHostGroupId(t *testing.T) { + segments := DedicatedHostGroupId{}.Segments() + if len(segments) == 0 { + t.Fatalf("HostGroupId has no segments") + } + + uniqueNames := make(map[string]struct{}, 0) + for _, segment := range segments { + uniqueNames[segment.Name] = struct{}{} + } + if len(uniqueNames) != len(segments) { + t.Fatalf("Expected the Segments to be unique but got %q unique segments and %d total segments", len(uniqueNames), len(segments)) + } +} diff --git a/resourcemanager/commonids/dedicated_host_test.go b/resourcemanager/commonids/dedicated_host_test.go new file mode 100644 index 0000000..bb9cf82 --- /dev/null +++ b/resourcemanager/commonids/dedicated_host_test.go @@ -0,0 +1,327 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package commonids + +import ( + "testing" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +var _ resourceids.ResourceId = DedicatedHostId{} + +func TestNewDedicatedHostID(t *testing.T) { + id := NewDedicatedHostID("12345678-1234-9876-4563-123456789012", "example-resource-group", "hostGroupValue", "hostValue") + + if id.SubscriptionId != "12345678-1234-9876-4563-123456789012" { + t.Fatalf("Expected %q but got %q for Segment 'SubscriptionId'", id.SubscriptionId, "12345678-1234-9876-4563-123456789012") + } + + if id.ResourceGroupName != "example-resource-group" { + t.Fatalf("Expected %q but got %q for Segment 'ResourceGroupName'", id.ResourceGroupName, "example-resource-group") + } + + if id.HostGroupName != "hostGroupValue" { + t.Fatalf("Expected %q but got %q for Segment 'HostGroupName'", id.HostGroupName, "hostGroupValue") + } + + if id.HostName != "hostValue" { + t.Fatalf("Expected %q but got %q for Segment 'HostName'", id.HostName, "hostValue") + } +} + +func TestFormatDedicatedHostID(t *testing.T) { + actual := NewDedicatedHostID("12345678-1234-9876-4563-123456789012", "example-resource-group", "hostGroupValue", "hostValue").ID() + expected := "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.Compute/hostGroups/hostGroupValue/hosts/hostValue" + if actual != expected { + t.Fatalf("Expected the Formatted ID to be %q but got %q", expected, actual) + } +} + +func TestParseDedicatedHostID(t *testing.T) { + testData := []struct { + Input string + Error bool + Expected *DedicatedHostId + }{ + { + // Incomplete URI + Input: "", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.Compute", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.Compute/hostGroups", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.Compute/hostGroups/hostGroupValue", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.Compute/hostGroups/hostGroupValue/hosts", + Error: true, + }, + { + // Valid URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.Compute/hostGroups/hostGroupValue/hosts/hostValue", + Expected: &DedicatedHostId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroupName: "example-resource-group", + HostGroupName: "hostGroupValue", + HostName: "hostValue", + }, + }, + { + // Invalid (Valid Uri with Extra segment) + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.Compute/hostGroups/hostGroupValue/hosts/hostValue/extra", + Error: true, + }, + } + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Input) + + actual, err := ParseDedicatedHostID(v.Input) + if err != nil { + if v.Error { + continue + } + + t.Fatalf("Expect a value but got an error: %+v", err) + } + if v.Error { + t.Fatal("Expect an error but didn't get one") + } + + if actual.SubscriptionId != v.Expected.SubscriptionId { + t.Fatalf("Expected %q but got %q for SubscriptionId", v.Expected.SubscriptionId, actual.SubscriptionId) + } + + if actual.ResourceGroupName != v.Expected.ResourceGroupName { + t.Fatalf("Expected %q but got %q for ResourceGroupName", v.Expected.ResourceGroupName, actual.ResourceGroupName) + } + + if actual.HostGroupName != v.Expected.HostGroupName { + t.Fatalf("Expected %q but got %q for HostGroupName", v.Expected.HostGroupName, actual.HostGroupName) + } + + if actual.HostName != v.Expected.HostName { + t.Fatalf("Expected %q but got %q for HostName", v.Expected.HostName, actual.HostName) + } + + } +} + +func TestParseDedicatedHostIDInsensitively(t *testing.T) { + testData := []struct { + Input string + Error bool + Expected *DedicatedHostId + }{ + { + // Incomplete URI + Input: "", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions", + Error: true, + }, + { + // Incomplete URI (mIxEd CaSe since this is insensitive) + Input: "/sUbScRiPtIoNs", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012", + Error: true, + }, + { + // Incomplete URI (mIxEd CaSe since this is insensitive) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups", + Error: true, + }, + { + // Incomplete URI (mIxEd CaSe since this is insensitive) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group", + Error: true, + }, + { + // Incomplete URI (mIxEd CaSe since this is insensitive) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-rEsOuRcE-GrOuP", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers", + Error: true, + }, + { + // Incomplete URI (mIxEd CaSe since this is insensitive) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-rEsOuRcE-GrOuP/pRoViDeRs", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.Compute", + Error: true, + }, + { + // Incomplete URI (mIxEd CaSe since this is insensitive) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-rEsOuRcE-GrOuP/pRoViDeRs/mIcRoSoFt.cOmPuTe", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.Compute/hostGroups", + Error: true, + }, + { + // Incomplete URI (mIxEd CaSe since this is insensitive) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-rEsOuRcE-GrOuP/pRoViDeRs/mIcRoSoFt.cOmPuTe/hOsTgRoUpS", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.Compute/hostGroups/hostGroupValue", + Error: true, + }, + { + // Incomplete URI (mIxEd CaSe since this is insensitive) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-rEsOuRcE-GrOuP/pRoViDeRs/mIcRoSoFt.cOmPuTe/hOsTgRoUpS/hOsTgRoUpVaLuE", + Error: true, + }, + { + // Incomplete URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.Compute/hostGroups/hostGroupValue/hosts", + Error: true, + }, + { + // Incomplete URI (mIxEd CaSe since this is insensitive) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-rEsOuRcE-GrOuP/pRoViDeRs/mIcRoSoFt.cOmPuTe/hOsTgRoUpS/hOsTgRoUpVaLuE/hOsTs", + Error: true, + }, + { + // Valid URI + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.Compute/hostGroups/hostGroupValue/hosts/hostValue", + Expected: &DedicatedHostId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroupName: "example-resource-group", + HostGroupName: "hostGroupValue", + HostName: "hostValue", + }, + }, + { + // Invalid (Valid Uri with Extra segment) + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/example-resource-group/providers/Microsoft.Compute/hostGroups/hostGroupValue/hosts/hostValue/extra", + Error: true, + }, + { + // Valid URI (mIxEd CaSe since this is insensitive) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-rEsOuRcE-GrOuP/pRoViDeRs/mIcRoSoFt.cOmPuTe/hOsTgRoUpS/hOsTgRoUpVaLuE/hOsTs/hOsTvAlUe", + Expected: &DedicatedHostId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroupName: "eXaMpLe-rEsOuRcE-GrOuP", + HostGroupName: "hOsTgRoUpVaLuE", + HostName: "hOsTvAlUe", + }, + }, + { + // Invalid (Valid Uri with Extra segment - mIxEd CaSe since this is insensitive) + Input: "/sUbScRiPtIoNs/12345678-1234-9876-4563-123456789012/rEsOuRcEgRoUpS/eXaMpLe-rEsOuRcE-GrOuP/pRoViDeRs/mIcRoSoFt.cOmPuTe/hOsTgRoUpS/hOsTgRoUpVaLuE/hOsTs/hOsTvAlUe/extra", + Error: true, + }, + } + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Input) + + actual, err := ParseDedicatedHostIDInsensitively(v.Input) + if err != nil { + if v.Error { + continue + } + + t.Fatalf("Expect a value but got an error: %+v", err) + } + if v.Error { + t.Fatal("Expect an error but didn't get one") + } + + if actual.SubscriptionId != v.Expected.SubscriptionId { + t.Fatalf("Expected %q but got %q for SubscriptionId", v.Expected.SubscriptionId, actual.SubscriptionId) + } + + if actual.ResourceGroupName != v.Expected.ResourceGroupName { + t.Fatalf("Expected %q but got %q for ResourceGroupName", v.Expected.ResourceGroupName, actual.ResourceGroupName) + } + + if actual.HostGroupName != v.Expected.HostGroupName { + t.Fatalf("Expected %q but got %q for HostGroupName", v.Expected.HostGroupName, actual.HostGroupName) + } + + if actual.HostName != v.Expected.HostName { + t.Fatalf("Expected %q but got %q for HostName", v.Expected.HostName, actual.HostName) + } + + } +} + +func TestSegmentsForDedicatedHostId(t *testing.T) { + segments := DedicatedHostId{}.Segments() + if len(segments) == 0 { + t.Fatalf("HostId has no segments") + } + + uniqueNames := make(map[string]struct{}, 0) + for _, segment := range segments { + uniqueNames[segment.Name] = struct{}{} + } + if len(uniqueNames) != len(segments) { + t.Fatalf("Expected the Segments to be unique but got %q unique segments and %d total segments", len(uniqueNames), len(segments)) + } +}