diff --git a/spectrocloud/cluster_common_test.go b/spectrocloud/cluster_common_test.go index b738a64f..cc2936f1 100644 --- a/spectrocloud/cluster_common_test.go +++ b/spectrocloud/cluster_common_test.go @@ -1,128 +1,142 @@ package spectrocloud import ( - "github.com/spectrocloud/hapi/models" "reflect" "testing" + + "github.com/spectrocloud/hapi/models" ) func TestToAdditionalNodePoolLabels(t *testing.T) { - // Test case 1: When 'additional_labels' is nil, the function should return an empty map - result := toAdditionalNodePoolLabels(map[string]interface{}{"additional_labels": nil}) - if len(result) != 0 { - t.Errorf("Expected an empty map, got %v", result) - } - - // Test case 2: When 'additional_labels' is an empty map, the function should return an empty map - result = toAdditionalNodePoolLabels(map[string]interface{}{"additional_labels": map[string]interface{}{}}) - if len(result) != 0 { - t.Errorf("Expected an empty map, got %v", result) - } - - // Test case 3: When 'additional_labels' contains valid data, the function should return the expected result - input := map[string]interface{}{ - "additional_labels": map[string]interface{}{ - "label1": "value1", - "label2": "value2", + tests := []struct { + name string + input map[string]interface{} + expected map[string]string + }{ + { + name: "Nil additional_labels", + input: map[string]interface{}{"additional_labels": nil}, + expected: map[string]string{}, + }, + { + name: "Empty additional_labels", + input: map[string]interface{}{"additional_labels": map[string]interface{}{}}, + expected: map[string]string{}, + }, + { + name: "Valid additional_labels", + input: map[string]interface{}{ + "additional_labels": map[string]interface{}{ + "label1": "value1", + "label2": "value2", + }, + }, + expected: map[string]string{ + "label1": "value1", + "label2": "value2", + }, }, - } - expected := map[string]string{ - "label1": "value1", - "label2": "value2", } - result = toAdditionalNodePoolLabels(input) - if len(result) != len(expected) { - t.Errorf("Expected %v, got %v", expected, result) - } - for key, value := range expected { - if result[key] != value { - t.Errorf("Expected %s=%s, got %s=%s", key, value, key, result[key]) - } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := toAdditionalNodePoolLabels(tt.input) + if !reflect.DeepEqual(result, tt.expected) { + t.Errorf("Expected %v, got %v", tt.expected, result) + } + }) } } func TestToClusterTaints(t *testing.T) { - // Test case 1: When 'taints' is nil, the function should return an empty slice - result := toClusterTaints(map[string]interface{}{"taints": nil}) - if len(result) != 0 { - t.Errorf("Expected an empty slice, got %v", result) - } - - // Test case 2: When 'taints' is an empty slice, the function should return an empty slice - result = toClusterTaints(map[string]interface{}{"taints": []interface{}{}}) - if len(result) != 0 { - t.Errorf("Expected an empty slice, got %v", result) - } - - // Test case 3: When 'taints' contains valid data, the function should return the expected result - input := map[string]interface{}{ - "taints": []interface{}{ - map[string]interface{}{ - "key": "key1", - "value": "value1", - "effect": "NoSchedule", - }, - map[string]interface{}{ - "key": "key2", - "value": "value2", - "effect": "PreferNoSchedule", - }, + tests := []struct { + name string + input map[string]interface{} + expected []*models.V1Taint + }{ + { + name: "Nil taints", + input: map[string]interface{}{"taints": nil}, + expected: nil, }, - } - - expected := []*models.V1Taint{ { - Key: "key1", - Value: "value1", - Effect: "NoSchedule", + name: "Empty taints", + input: map[string]interface{}{"taints": []interface{}{}}, + expected: []*models.V1Taint{}, }, { - Key: "key2", - Value: "value2", - Effect: "PreferNoSchedule", + name: "Valid taints", + input: map[string]interface{}{ + "taints": []interface{}{ + map[string]interface{}{ + "key": "key1", + "value": "value1", + "effect": "NoSchedule", + }, + map[string]interface{}{ + "key": "key2", + "value": "value2", + "effect": "PreferNoSchedule", + }, + }, + }, + expected: []*models.V1Taint{ + { + Key: "key1", + Value: "value1", + Effect: "NoSchedule", + }, + { + Key: "key2", + Value: "value2", + Effect: "PreferNoSchedule", + }, + }, }, } - result = toClusterTaints(input) - if len(result) != len(expected) { - t.Errorf("Expected %v, got %v", expected, result) - } - for i, expectedTaint := range expected { - if *result[i] != *expectedTaint { - t.Errorf("Expected %v, got %v", expectedTaint, result[i]) - } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := toClusterTaints(tt.input) + if !reflect.DeepEqual(result, tt.expected) { + t.Errorf("Expected %v, got %v", tt.expected, result) + } + }) } } func TestToClusterTaint(t *testing.T) { - // Test case 1: When 'clusterTaint' is a valid map, the function should return the expected result - input := map[string]interface{}{ - "key": "key1", - "value": "value1", - "effect": "NoSchedule", - } - - expected := &models.V1Taint{ - Key: "key1", - Value: "value1", - Effect: "NoSchedule", + tests := []struct { + name string + input map[string]interface{} + expected *models.V1Taint + }{ + { + name: "Valid cluster taint", + input: map[string]interface{}{ + "key": "key1", + "value": "value1", + "effect": "NoSchedule", + }, + expected: &models.V1Taint{ + Key: "key1", + Value: "value1", + Effect: "NoSchedule", + }, + }, } - result := toClusterTaint(input) - if *result != *expected { - t.Errorf("Expected %v, got %v", expected, result) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := toClusterTaint(tt.input) + if !reflect.DeepEqual(result, tt.expected) { + t.Errorf("Expected %v, got %v", tt.expected, result) + } + }) } } func TestFlattenClusterTaints(t *testing.T) { - // Test case 1: When 'items' is an empty slice, the function should return an empty slice - result := flattenClusterTaints([]*models.V1Taint{}) - if len(result) != 0 { - t.Errorf("Expected an empty slice, got %v", result) - } - - // Test case 2: When 'items' contains valid taints, the function should return the expected result taint1 := &models.V1Taint{ Key: "key1", Value: "value1", @@ -134,114 +148,113 @@ func TestFlattenClusterTaints(t *testing.T) { Effect: "PreferNoSchedule", } - expected := []interface{}{ - map[string]interface{}{ - "key": "key1", - "value": "value1", - "effect": "NoSchedule", + tests := []struct { + name string + input []*models.V1Taint + expected []interface{} + }{ + { + name: "Empty items", + input: []*models.V1Taint{}, + expected: []interface{}{}, }, - map[string]interface{}{ - "key": "key2", - "value": "value2", - "effect": "PreferNoSchedule", + { + name: "Valid taints", + input: []*models.V1Taint{taint1, taint2}, + expected: []interface{}{ + map[string]interface{}{ + "key": "key1", + "value": "value1", + "effect": "NoSchedule", + }, + map[string]interface{}{ + "key": "key2", + "value": "value2", + "effect": "PreferNoSchedule", + }, + }, }, } - result = flattenClusterTaints([]*models.V1Taint{taint1, taint2}) - if len(result) != len(expected) { - t.Errorf("Expected %v, got %v", expected, result) - } - for i, expectedTaint := range expected { - if !reflect.DeepEqual(result[i], expectedTaint) { - t.Errorf("Expected %v, got %v", expectedTaint, result[i]) - } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := flattenClusterTaints(tt.input) + if !reflect.DeepEqual(result, tt.expected) { + t.Errorf("Expected %v, got %v", tt.expected, result) + } + }) } } func TestFlattenAdditionalLabelsAndTaints(t *testing.T) { - // Test case 1: When 'labels' is empty and 'intaints' is empty, oi should be updated accordingly - oi := make(map[string]interface{}) - FlattenAdditionalLabelsAndTaints(make(map[string]string), []*models.V1Taint{}, oi) - - expectedOi := map[string]interface{}{ - "additional_labels": map[string]interface{}{}, - } - - if !reflect.DeepEqual(oi, expectedOi) { - t.Errorf("Expected %v, got %v", expectedOi, oi) - } - - // Test case 2: When 'labels' is not empty, 'additional_labels' in oi should be updated - labels := map[string]string{ - "label1": "value1", - "label2": "value2", - } - oi = make(map[string]interface{}) - FlattenAdditionalLabelsAndTaints(labels, []*models.V1Taint{}, oi) - - expectedOi = map[string]interface{}{ - "additional_labels": map[string]interface{}{ - "label1": "value1", - "label2": "value2", - }, - } - - if !mapsAreEqual(oi, expectedOi) { - t.Errorf("Expected %v, got %v", expectedOi, oi) - } - - // Test case 3: When 'intaints' is not empty, 'taints' in oi should be updated - taints := []*models.V1Taint{ + tests := []struct { + name string + labels map[string]string + taints []*models.V1Taint + expected map[string]interface{} + }{ { - Key: "key1", - Value: "value1", - Effect: "NoSchedule", + name: "Empty labels and taints", + labels: make(map[string]string), + taints: []*models.V1Taint{}, + expected: map[string]interface{}{"additional_labels": map[string]interface{}{}}, }, { - Key: "key2", - Value: "value2", - Effect: "PreferNoSchedule", - }, - } - oi = make(map[string]interface{}) - FlattenAdditionalLabelsAndTaints(labels, taints, oi) - //var v1 interface{} = "value1" - //var v2 interface{} = "value2" - expectedOi = map[string]interface{}{ - "additional_labels": map[string]interface{}{ - "label1": "value1", - "label2": "value2", + name: "Non-empty labels", + labels: map[string]string{"label1": "value1", "label2": "value2"}, + taints: []*models.V1Taint{}, + expected: map[string]interface{}{ + "additional_labels": map[string]string{ + "label1": "value1", + "label2": "value2", + }, + }, }, - "taints": []interface{}{ - map[string]interface{}{ - "key": "key1", - "value": "value1", - "effect": "NoSchedule", + { + name: "Non-empty labels and taints", + labels: map[string]string{"label1": "value1", "label2": "value2"}, + taints: []*models.V1Taint{ + { + Key: "key1", + Value: "value1", + Effect: "NoSchedule", + }, + { + Key: "key2", + Value: "value2", + Effect: "PreferNoSchedule", + }, }, - map[string]interface{}{ - "key": "key2", - "value": "value2", - "effect": "PreferNoSchedule", + expected: map[string]interface{}{ + "additional_labels": map[string]string{ + "label1": "value1", + "label2": "value2", + }, + "taints": []interface{}{ + map[string]interface{}{ + "key": "key1", + "value": "value1", + "effect": "NoSchedule", + }, + map[string]interface{}{ + "key": "key2", + "value": "value2", + "effect": "PreferNoSchedule", + }, + }, }, }, } - if !mapsAreEqual(oi, expectedOi) { - t.Errorf("Expected %v, got %v", expectedOi, oi) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + oi := make(map[string]interface{}) + FlattenAdditionalLabelsAndTaints(tt.labels, tt.taints, oi) + if !reflect.DeepEqual(oi, tt.expected) { + t.Logf("Expected: %#v\n", tt.expected) + t.Logf("Actual: %#v\n", oi) + t.Errorf("Test %s failed. Expected %#v, got %#v", tt.name, tt.expected, oi) + } + }) } } - -func mapsAreEqual(a, b map[string]interface{}) bool { - if len(a) != len(b) { - return false - } - for key, _ := range a { - _, ok := b[key] - if !ok { - return false - } - - } - - return true -} diff --git a/spectrocloud/resource_cluster_edge_native_test.go b/spectrocloud/resource_cluster_edge_native_test.go index 79058f83..02f15c04 100644 --- a/spectrocloud/resource_cluster_edge_native_test.go +++ b/spectrocloud/resource_cluster_edge_native_test.go @@ -1,277 +1,283 @@ package spectrocloud import ( - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/spectrocloud/hapi/models" - "github.com/spectrocloud/terraform-provider-spectrocloud/types" "reflect" "testing" -) - -func prepareEdgeNativeTestData() *schema.ResourceData { - // Create a TestResourceData object for testing - d := resourceClusterEdgeNative().TestResourceData() - d.Set("name", "cluster-1") - d.Set("context", "project") - d.Set("tags", []string{"tag1:value1", "tag2:value2"}) - d.Set("apply_setting", "apply_setting_value") - d.Set("cloud_account_id", "cloud_account_id_value") - d.Set("os_patch_on_boot", true) - d.Set("os_patch_schedule", "0 0 * * *") - d.Set("os_patch_after", "2023-01-01T00:00:00Z") - mp := map[string]interface{}{ - "name": "pool-1", - "additional_labels": map[string]interface{}{"label1": "value1"}, - "control_plane": true, - "control_plane_as_worker": true, - "update_strategy": "RollingUpdateScaleOut", - "edge_host": []map[string]interface{}{ - { - "host_name": "host-1", - "host_uid": "uid-1", - "static_ip": "ip-1", - }, - }, - } - d.Set("machine_pool", mp) + "github.com/spectrocloud/hapi/models" - return d -} + "github.com/spectrocloud/terraform-provider-spectrocloud/types" +) func TestToEdgeHosts(t *testing.T) { - hostUI1 := "uid1" hostUI2 := "uid2" - // Test case 1: When 'edge_host' is an empty slice, the function should return nil - result := toEdgeHosts(map[string]interface{}{"edge_host": []interface{}{}}) - if result != nil { - t.Errorf("Expected nil, got %v", result) - } - // Test case 2: When 'edge_host' contains valid data, the function should return the expected result - input := map[string]interface{}{ - "edge_host": []interface{}{ - map[string]interface{}{ - "host_name": "host1", - "host_uid": "uid1", - "static_ip": "ip1", - }, - map[string]interface{}{ - "host_name": "host2", - "host_uid": "uid2", - "static_ip": "ip2", - }, + tests := []struct { + name string + input map[string]interface{} + expected *models.V1EdgeNativeMachinePoolCloudConfigEntity + }{ + { + name: "Empty edge_host", + input: map[string]interface{}{"edge_host": []interface{}{}}, + expected: nil, }, - } - expected := &models.V1EdgeNativeMachinePoolCloudConfigEntity{ - EdgeHosts: []*models.V1EdgeNativeMachinePoolHostEntity{ - { - HostName: "host1", - HostUID: &hostUI1, - StaticIP: "ip1", - }, - { - HostName: "host2", - HostUID: &hostUI2, - StaticIP: "ip2", - }, - }, - } - - result = toEdgeHosts(input) - if !reflect.DeepEqual(result, expected) { - t.Errorf("Expected %v, got %v", expected, result) - } - - // Test case 3: When 'edge_host' contains valid data with host_name as empty string, the function should return the expected result - input = map[string]interface{}{ - "edge_host": []interface{}{ - map[string]interface{}{ - "host_name": "", - "host_uid": "uid1", - "static_ip": "ip1", + { + name: "Valid edge_host", + input: map[string]interface{}{ + "edge_host": []interface{}{ + map[string]interface{}{ + "host_name": "host1", + "host_uid": "uid1", + "static_ip": "ip1", + }, + map[string]interface{}{ + "host_name": "host2", + "host_uid": "uid2", + "static_ip": "ip2", + }, + }, }, - map[string]interface{}{ - "host_name": "", - "host_uid": "uid2", - "static_ip": "ip2", + expected: &models.V1EdgeNativeMachinePoolCloudConfigEntity{ + EdgeHosts: []*models.V1EdgeNativeMachinePoolHostEntity{ + { + HostName: "host1", + HostUID: &hostUI1, + StaticIP: "ip1", + }, + { + HostName: "host2", + HostUID: &hostUI2, + StaticIP: "ip2", + }, + }, }, }, - } - expected = &models.V1EdgeNativeMachinePoolCloudConfigEntity{ - EdgeHosts: []*models.V1EdgeNativeMachinePoolHostEntity{ - { - HostName: "", - HostUID: &hostUI1, - StaticIP: "ip1", + { + name: "Edge_host with empty host_name", + input: map[string]interface{}{ + "edge_host": []interface{}{ + map[string]interface{}{ + "host_name": "", + "host_uid": "uid1", + "static_ip": "ip1", + }, + map[string]interface{}{ + "host_name": "", + "host_uid": "uid2", + "static_ip": "ip2", + }, + }, }, - { - HostName: "", - HostUID: &hostUI2, - StaticIP: "ip2", + expected: &models.V1EdgeNativeMachinePoolCloudConfigEntity{ + EdgeHosts: []*models.V1EdgeNativeMachinePoolHostEntity{ + { + HostName: "", + HostUID: &hostUI1, + StaticIP: "ip1", + }, + { + HostName: "", + HostUID: &hostUI2, + StaticIP: "ip2", + }, + }, }, }, } - result = toEdgeHosts(input) - if !reflect.DeepEqual(result, expected) { - t.Errorf("Expected %v, got %v", expected, result) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := toEdgeHosts(tt.input) + if !reflect.DeepEqual(result, tt.expected) { + t.Errorf("Expected %v, got %v", tt.expected, result) + } + }) } } func TestToMachinePoolEdgeNative(t *testing.T) { - // Test case 1: Valid input data - input := map[string]interface{}{ - "control_plane": true, - "control_plane_as_worker": false, - "name": "pool1", - "edge_host": []interface{}{ - map[string]interface{}{ - "host_name": "", - "host_uid": "uid1", - "static_ip": "ip1", - }, - map[string]interface{}{ - "host_name": "", - "host_uid": "uid2", - "static_ip": "ip2", - }, - }, - "additional_labels": map[string]interface{}{ - "label1": "value1", - "label2": "value2", - }, - "taints": []interface{}{ - map[string]interface{}{ - "key": "key1", - "value": "value1", - "effect": "NoSchedule", - }, - map[string]interface{}{ - "key": "key2", - "value": "value2", - "effect": "PreferNoSchedule", + tests := []struct { + name string + input map[string]interface{} + expected *models.V1EdgeNativeMachinePoolConfigEntity + hasError bool + }{ + { + name: "Valid input data", + input: map[string]interface{}{ + "control_plane": true, + "control_plane_as_worker": false, + "name": "pool1", + "edge_host": []interface{}{ + map[string]interface{}{ + "host_name": "", + "host_uid": "uid1", + "static_ip": "ip1", + }, + map[string]interface{}{ + "host_name": "", + "host_uid": "uid2", + "static_ip": "ip2", + }, + }, + "additional_labels": map[string]interface{}{ + "label1": "value1", + "label2": "value2", + }, + "taints": []interface{}{ + map[string]interface{}{ + "key": "key1", + "value": "value1", + "effect": "NoSchedule", + }, + map[string]interface{}{ + "key": "key2", + "value": "value2", + "effect": "PreferNoSchedule", + }, + }, }, - }, - - // Add other relevant fields as needed for your test - } - - expected := &models.V1EdgeNativeMachinePoolConfigEntity{ - CloudConfig: toEdgeHosts(input), - PoolConfig: &models.V1MachinePoolConfigEntity{ - AdditionalLabels: toAdditionalNodePoolLabels(input), - Taints: toClusterTaints(input), - IsControlPlane: true, - Labels: []string{}, - Name: types.Ptr("pool1"), - Size: types.Ptr(int32(len(toEdgeHosts(input).EdgeHosts))), - UpdateStrategy: &models.V1UpdateStrategy{Type: getUpdateStrategy(input)}, - UseControlPlaneAsWorker: false, + expected: nil, + hasError: false, }, } - result, err := toMachinePoolEdgeNative(input) - if err != nil { - t.Fatalf("Expected no error, but got an error: %v", err) - } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + expected := &models.V1EdgeNativeMachinePoolConfigEntity{ + CloudConfig: toEdgeHosts(tt.input), + PoolConfig: &models.V1MachinePoolConfigEntity{ + AdditionalLabels: toAdditionalNodePoolLabels(tt.input), + Taints: toClusterTaints(tt.input), + IsControlPlane: true, + Labels: []string{}, + Name: types.Ptr("pool1"), + Size: types.Ptr(int32(len(toEdgeHosts(tt.input).EdgeHosts))), + UpdateStrategy: &models.V1UpdateStrategy{Type: getUpdateStrategy(tt.input)}, + UseControlPlaneAsWorker: false, + }, + } - if !reflect.DeepEqual(result, expected) { - t.Errorf("Expected %v, got %v", expected, result) + result, err := toMachinePoolEdgeNative(tt.input) + if tt.hasError { + if err == nil { + t.Errorf("Expected an error but got none.") + } + return + } + if err != nil { + t.Fatalf("Expected no error, but got an error: %v", err) + } + if !reflect.DeepEqual(result, expected) { + t.Errorf("Expected %v, got %v", expected, result) + } + }) } - } func TestFlattenMachinePoolConfigsEdgeNative(t *testing.T) { - // Test case 1: When 'machinePools' is nil, the function should return an empty slice - result := flattenMachinePoolConfigsEdgeNative(nil) - if len(result) != 0 { - t.Errorf("Expected an empty slice, got %v", result) - } - - // Test case 2: When 'machinePools' contains valid data, the function should return the expected result hui1 := "uid1" huid2 := "uid2" huid3 := "uid3" - machinePool1 := &models.V1EdgeNativeMachinePoolConfig{ - AdditionalLabels: map[string]string{"label1": "value1"}, - Taints: []*models.V1Taint{}, - UseControlPlaneAsWorker: false, - Name: "pool1", - Hosts: []*models.V1EdgeNativeHost{ - { - HostName: "host1", - HostUID: &hui1, - StaticIP: "ip1", - }, - { - HostName: "host2", - HostUID: &huid2, - StaticIP: "ip2", - }, - }, - UpdateStrategy: &models.V1UpdateStrategy{Type: "strategy1"}, - } - machinePool2 := &models.V1EdgeNativeMachinePoolConfig{ - AdditionalLabels: map[string]string{"label2": "value2"}, - Taints: []*models.V1Taint{}, - UseControlPlaneAsWorker: true, - Name: "pool2", - Hosts: []*models.V1EdgeNativeHost{ - { - HostName: "host3", - HostUID: &huid3, - StaticIP: "ip3", - }, + tests := []struct { + name string + input []*models.V1EdgeNativeMachinePoolConfig + expected []interface{} + }{ + { + name: "When 'machinePools' is nil", + input: nil, + expected: []interface{}{}, }, - UpdateStrategy: &models.V1UpdateStrategy{Type: "strategy2"}, - } - - machinePools := []*models.V1EdgeNativeMachinePoolConfig{machinePool1, machinePool2} - - expected := []interface{}{ - map[string]interface{}{ - "additional_labels": map[string]interface{}{"label1": "value1"}, - "control_plane_as_worker": false, - "name": "pool1", - "edge_host": []map[string]string{ + { + name: "When 'machinePools' contains valid data", + input: []*models.V1EdgeNativeMachinePoolConfig{ { - "host_name": "host1", - "host_uid": "uid1", - "static_ip": "ip1", + AdditionalLabels: map[string]string{"label1": "value1"}, + Taints: []*models.V1Taint{}, + UseControlPlaneAsWorker: false, + Name: "pool1", + Hosts: []*models.V1EdgeNativeHost{ + { + HostName: "host1", + HostUID: &hui1, + StaticIP: "ip1", + }, + { + HostName: "host2", + HostUID: &huid2, + StaticIP: "ip2", + }, + }, + UpdateStrategy: &models.V1UpdateStrategy{Type: "strategy1"}, }, { - "host_name": "host2", - "host_uid": "uid2", - "static_ip": "ip2", + AdditionalLabels: map[string]string{"label2": "value2"}, + Taints: []*models.V1Taint{}, + UseControlPlaneAsWorker: true, + Name: "pool2", + Hosts: []*models.V1EdgeNativeHost{ + { + HostName: "host3", + HostUID: &huid3, + StaticIP: "ip3", + }, + }, + UpdateStrategy: &models.V1UpdateStrategy{Type: "strategy2"}, }, }, - "update_strategy": map[string]interface{}{"type": "strategy1"}, - }, - map[string]interface{}{ - "additional_labels": map[string]interface{}{"label2": "value2"}, - "control_plane_as_worker": true, - "name": "pool2", - "edge_host": []map[string]string{ - { - "host_name": "host3", - "host_uid": "uid3", - "static_ip": "ip3", + expected: []interface{}{ + map[string]interface{}{ + "additional_labels": map[string]string{"label1": "value1"}, + "control_plane_as_worker": false, + "name": "pool1", + "edge_host": []map[string]string{ + { + "host_name": "host1", + "host_uid": "uid1", + "static_ip": "ip1", + }, + { + "host_name": "host2", + "host_uid": "uid2", + "static_ip": "ip2", + }, + }, + "update_strategy": "strategy1", + }, + map[string]interface{}{ + "additional_labels": map[string]string{"label2": "value2"}, + "control_plane_as_worker": true, + "name": "pool2", + "edge_host": []map[string]string{ + { + "host_name": "host3", + "host_uid": "uid3", + "static_ip": "ip3", + }, + }, + "update_strategy": "strategy2", }, }, - "update_strategy": map[string]interface{}{"type": "strategy2"}, }, } - result = flattenMachinePoolConfigsEdgeNative(machinePools) - if len(result) != len(expected) { - t.Errorf("Expected %v, got %v", expected, result) - } - for i, expectedOi := range expected { - if !mapsAreEqual(result[i].(map[string]interface{}), expectedOi.(map[string]interface{})) { - t.Errorf("Expected %v, got %v", expectedOi, result[i]) - } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := flattenMachinePoolConfigsEdgeNative(tt.input) + if len(result) != len(tt.expected) { + t.Errorf("Expected length %v, got %v", len(tt.expected), len(result)) + } + for i, expectedMap := range tt.expected { + if !reflect.DeepEqual(result[i], expectedMap) { + t.Logf("Expected: %#v\n", expectedMap) + t.Logf("Actual: %#v\n", result[i]) + t.Errorf("Test %s failed. Expected %v, got %v", tt.name, expectedMap, result[i]) + } + } + }) } } diff --git a/spectrocloud/resource_cluster_profile.go b/spectrocloud/resource_cluster_profile.go index 0d966f29..6ec188f2 100644 --- a/spectrocloud/resource_cluster_profile.go +++ b/spectrocloud/resource_cluster_profile.go @@ -77,8 +77,8 @@ func resourceClusterProfile() *schema.Resource { Optional: true, Default: "add-on", ValidateFunc: validation.StringInSlice([]string{"add-on", "cluster", "infra", "system"}, false), - Description: "Specify the cluster profile type to use. Allowed values are `cluster`, infra`, `add-on`, and `system`. These values map to the following User Interface (UI) labels. Use the value ' cluster ' for a **Full** cluster profile." + "For an Infrastructure cluster profile, use the value `infra`; for an Add-on cluster profile, use the value `add-on`." + "System cluster profiles can be specified using the value `system`. To learn more about cluster profiles, refer to the [Cluster Profile](https://docs.spectrocloud.com/cluster-profiles) documentation. Default value is `add-on`.", - ForceNew: true, + Description: "Specify the cluster profile type to use. Allowed values are `cluster`, infra`, `add-on`, and `system`. These values map to the following User Interface (UI) labels. Use the value ' cluster ' for a **Full** cluster profile." + "For an Infrastructure cluster profile, use the value `infra`; for an Add-on cluster profile, use the value `add-on`." + "System cluster profiles can be specified using the value `system`. To learn more about cluster profiles, refer to the [Cluster Profile](https://docs.spectrocloud.com/cluster-profiles) documentation. Default value is `add-on`.", + ForceNew: true, }, "pack": schemas.PackSchema(), },