diff --git a/cluster-autoscaler/cloudprovider/azure/azure_agent_pool_test.go b/cluster-autoscaler/cloudprovider/azure/azure_agent_pool_test.go index a242e0b7b666d00d00ae8cc4feebf45c941eea91..c4d0007a322c5595d6a314cf8228fe7c321b74c3 100644 --- a/cluster-autoscaler/cloudprovider/azure/azure_agent_pool_test.go +++ b/cluster-autoscaler/cloudprovider/azure/azure_agent_pool_test.go @@ -172,7 +172,7 @@ func TestDeleteOutdatedDeployments(t *testing.T) { } } -func TestGetVMsFromCache(t *testing.T) { +func TestAgentPoolGetVMsFromCache(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() @@ -309,7 +309,7 @@ func TestAgentPoolIncreaseSize(t *testing.T) { assert.NoError(t, err) } -func TestDecreaseTargetSize(t *testing.T) { +func TestAgentPoolDecreaseTargetSize(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() diff --git a/cluster-autoscaler/cloudprovider/azure/azure_scale_set_test.go b/cluster-autoscaler/cloudprovider/azure/azure_scale_set_test.go index db8d8f2eda0b78160df3eb530641da752b36adc3..1a45a6dcdcf66e50d8383294b9992596495ed6e7 100644 --- a/cluster-autoscaler/cloudprovider/azure/azure_scale_set_test.go +++ b/cluster-autoscaler/cloudprovider/azure/azure_scale_set_test.go @@ -151,7 +151,7 @@ func newApiNode(orchmode compute.OrchestrationMode, vmID int64) *apiv1.Node { } return node } -func TestMaxSize(t *testing.T) { +func TestScaleSetMaxSize(t *testing.T) { provider := newTestProvider(t) registered := provider.azureManager.RegisterNodeGroup( newTestScaleSet(provider.azureManager, "test-asg")) @@ -160,7 +160,7 @@ func TestMaxSize(t *testing.T) { assert.Equal(t, provider.NodeGroups()[0].MaxSize(), 5) } -func TestMinSize(t *testing.T) { +func TestScaleSetMinSize(t *testing.T) { provider := newTestProvider(t) registered := provider.azureManager.RegisterNodeGroup( newTestScaleSet(provider.azureManager, "test-asg")) @@ -169,7 +169,7 @@ func TestMinSize(t *testing.T) { assert.Equal(t, provider.NodeGroups()[0].MinSize(), 1) } -func TestMinSizeZero(t *testing.T) { +func TestScaleSetMinSizeZero(t *testing.T) { provider := newTestProvider(t) registered := provider.azureManager.RegisterNodeGroup( newTestScaleSetMinSizeZero(provider.azureManager, testASG)) @@ -178,7 +178,7 @@ func TestMinSizeZero(t *testing.T) { assert.Equal(t, provider.NodeGroups()[0].MinSize(), 0) } -func TestTargetSize(t *testing.T) { +func TestScaleSetTargetSize(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() @@ -248,7 +248,7 @@ func TestTargetSize(t *testing.T) { } } -func TestIncreaseSize(t *testing.T) { +func TestScaleSetIncreaseSize(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() @@ -365,7 +365,7 @@ func TestIncreaseSize(t *testing.T) { // TestIncreaseSizeOnVMProvisioningFailed has been tweeked only for Uniform Orchestration mode. // If ProvisioningState == failed and power state is not running, Status.State == InstanceCreating with errorInfo populated. -func TestIncreaseSizeOnVMProvisioningFailed(t *testing.T) { +func TestScaleSetIncreaseSizeOnVMProvisioningFailed(t *testing.T) { testCases := map[string]struct { expectInstanceRunning bool isMissingInstanceView bool @@ -543,7 +543,7 @@ func TestIncreaseSizeOnVMProvisioningFailedWithFastDelete(t *testing.T) { } } -func TestIncreaseSizeOnVMSSUpdating(t *testing.T) { +func TestScaleSetIncreaseSizeOnVMSSUpdating(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() @@ -593,7 +593,7 @@ func TestIncreaseSizeOnVMSSUpdating(t *testing.T) { assert.NoError(t, err) } -func TestBelongs(t *testing.T) { +func TestScaleSetBelongs(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() @@ -645,7 +645,7 @@ func TestBelongs(t *testing.T) { } } -func TestDeleteNodes(t *testing.T) { +func TestScaleSetDeleteNodes(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() @@ -783,7 +783,7 @@ func TestDeleteNodes(t *testing.T) { } } -func TestDeleteNodeUnregistered(t *testing.T) { +func TestScaleSetDeleteNodeUnregistered(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() @@ -896,7 +896,7 @@ func TestDeleteNodeUnregistered(t *testing.T) { } } -func TestDeleteInstancesWithForceDeleteEnabled(t *testing.T) { +func TestScaleSetDeleteInstancesWithForceDeleteEnabled(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() manager := newTestAzureManager(t) @@ -1010,7 +1010,7 @@ func TestDeleteInstancesWithForceDeleteEnabled(t *testing.T) { } -func TestDeleteNoConflictRequest(t *testing.T) { +func TestScaleSetDeleteNoConflictRequest(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() @@ -1071,7 +1071,7 @@ func TestDeleteNoConflictRequest(t *testing.T) { err = scaleSet.DeleteNodes([]*apiv1.Node{node}) } -func TestId(t *testing.T) { +func TestScaleSetId(t *testing.T) { provider := newTestProvider(t) registered := provider.azureManager.RegisterNodeGroup( newTestScaleSet(provider.azureManager, "test-asg")) @@ -1080,7 +1080,7 @@ func TestId(t *testing.T) { assert.Equal(t, provider.NodeGroups()[0].Id(), "test-asg") } -func TestDebug(t *testing.T) { +func TestAgentPoolDebug(t *testing.T) { asg := ScaleSet{ manager: newTestAzureManager(t), minSize: 5, @@ -1159,7 +1159,7 @@ func TestScaleSetNodes(t *testing.T) { } -func TestEnableVmssFlexNodesFlag(t *testing.T) { +func TestScaleSetEnableVmssFlexNodesFlag(t *testing.T) { // flag set to false ctrl := gomock.NewController(t) @@ -1191,7 +1191,7 @@ func TestEnableVmssFlexNodesFlag(t *testing.T) { assert.NoError(t, err) } -func TestTemplateNodeInfo(t *testing.T) { +func TestScaleSetTemplateNodeInfo(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() @@ -1317,7 +1317,7 @@ func TestTemplateNodeInfo(t *testing.T) { }) } -func TestCseErrors(t *testing.T) { +func TestScaleSetCseErrors(t *testing.T) { errorMessage := to.StringPtr("Error Message Test") vmssVMs := compute.VirtualMachineScaleSetVM{ Name: to.StringPtr("vmTest"), diff --git a/cluster-autoscaler/cloudprovider/azure/azure_vms_pool.go b/cluster-autoscaler/cloudprovider/azure/azure_vms_pool.go index c86eff66ce6ef734ce08d1743f01451ed27bfc7f..ba42654907c6fb226138ebe4b1cfbdbe04c57045 100644 --- a/cluster-autoscaler/cloudprovider/azure/azure_vms_pool.go +++ b/cluster-autoscaler/cloudprovider/azure/azure_vms_pool.go @@ -155,7 +155,7 @@ func (agentPool *VMsPool) Nodes() ([]cloudprovider.Instance, error) { nodes := make([]cloudprovider.Instance, 0, len(vms)) for _, vm := range vms { - if len(*vm.ID) == 0 { + if vm.ID == nil || len(*vm.ID) == 0 { continue } resourceID, err := convertResourceGroupNameToLower("azure://" + *vm.ID) diff --git a/cluster-autoscaler/cloudprovider/azure/azure_vms_pool_test.go b/cluster-autoscaler/cloudprovider/azure/azure_vms_pool_test.go index a3b0ebe45e4a5fa66052d868b1b79c6d4138f276..c1efbcac843bb0e38836614423f6db6dd9a90244 100644 --- a/cluster-autoscaler/cloudprovider/azure/azure_vms_pool_test.go +++ b/cluster-autoscaler/cloudprovider/azure/azure_vms_pool_test.go @@ -18,10 +18,16 @@ package azure import ( "fmt" + "testing" "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2022-08-01/compute" "github.com/Azure/go-autorest/autorest/to" + "github.com/stretchr/testify/assert" apiv1 "k8s.io/api/core/v1" + "k8s.io/autoscaler/cluster-autoscaler/cloudprovider" + "k8s.io/autoscaler/cluster-autoscaler/config" + "k8s.io/autoscaler/cluster-autoscaler/config/dynamic" + providerazure "sigs.k8s.io/cloud-provider-azure/pkg/provider" ) func newTestVMsPool(manager *AzureManager, name string) *VMsPool { @@ -65,3 +71,242 @@ func newVMsNode(vmID int64) *apiv1.Node { } return node } + +func TestNewVMsPool(t *testing.T) { + spec := &dynamic.NodeGroupSpec{ + Name: "test-nodepool", + MinSize: 1, + MaxSize: 5, + } + am := &AzureManager{ + config: &Config{ + Config: providerazure.Config{ + ResourceGroup: "test-resource-group", + }, + }, + } + + nodepool := NewVMsPool(spec, am) + + assert.Equal(t, "test-nodepool", nodepool.azureRef.Name) + assert.Equal(t, "test-resource-group", nodepool.resourceGroup) + assert.Equal(t, int64(-1), nodepool.curSize) + assert.Equal(t, 1, nodepool.minSize) + assert.Equal(t, 5, nodepool.maxSize) + assert.Equal(t, am, nodepool.manager) +} + +func TestMinSize(t *testing.T) { + agentPool := &VMsPool{ + minSize: 1, + } + + assert.Equal(t, 1, agentPool.MinSize()) +} + +func TestExist(t *testing.T) { + agentPool := &VMsPool{} + + assert.True(t, agentPool.Exist()) +} +func TestCreate(t *testing.T) { + agentPool := &VMsPool{} + + nodeGroup, err := agentPool.Create() + assert.Nil(t, nodeGroup) + assert.Equal(t, cloudprovider.ErrAlreadyExist, err) +} + +func TestDelete(t *testing.T) { + agentPool := &VMsPool{} + + err := agentPool.Delete() + assert.Equal(t, cloudprovider.ErrNotImplemented, err) +} + +func TestAutoprovisioned(t *testing.T) { + agentPool := &VMsPool{} + + assert.False(t, agentPool.Autoprovisioned()) +} + +func TestGetOptions(t *testing.T) { + agentPool := &VMsPool{} + defaults := config.NodeGroupAutoscalingOptions{} + + options, err := agentPool.GetOptions(defaults) + assert.Nil(t, options) + assert.Equal(t, cloudprovider.ErrNotImplemented, err) +} +func TestMaxSize(t *testing.T) { + agentPool := &VMsPool{ + maxSize: 10, + } + + assert.Equal(t, 10, agentPool.MaxSize()) +} + +func TestTargetSize(t *testing.T) { + agentPool := &VMsPool{} + + size, err := agentPool.TargetSize() + assert.Equal(t, -1, size) + assert.Equal(t, cloudprovider.ErrNotImplemented, err) +} + +func TestIncreaseSize(t *testing.T) { + agentPool := &VMsPool{} + + err := agentPool.IncreaseSize(1) + assert.Equal(t, cloudprovider.ErrNotImplemented, err) +} + +func TestDeleteNodes(t *testing.T) { + agentPool := &VMsPool{} + + err := agentPool.DeleteNodes(nil) + assert.Equal(t, cloudprovider.ErrNotImplemented, err) +} + +func TestDecreaseTargetSize(t *testing.T) { + agentPool := &VMsPool{} + + err := agentPool.DecreaseTargetSize(1) + assert.Equal(t, cloudprovider.ErrNotImplemented, err) +} + +func TestId(t *testing.T) { + agentPool := &VMsPool{ + azureRef: azureRef{ + Name: "test-id", + }, + } + + assert.Equal(t, "test-id", agentPool.Id()) +} + +func TestDebug(t *testing.T) { + agentPool := &VMsPool{ + azureRef: azureRef{ + Name: "test-debug", + }, + minSize: 1, + maxSize: 5, + } + + expectedDebugString := "test-debug (1:5)" + assert.Equal(t, expectedDebugString, agentPool.Debug()) +} +func TestTemplateNodeInfo(t *testing.T) { + agentPool := &VMsPool{} + + nodeInfo, err := agentPool.TemplateNodeInfo() + assert.Nil(t, nodeInfo) + assert.Equal(t, cloudprovider.ErrNotImplemented, err) +} + +func TestAtomicIncreaseSize(t *testing.T) { + agentPool := &VMsPool{} + + err := agentPool.AtomicIncreaseSize(1) + assert.Equal(t, cloudprovider.ErrNotImplemented, err) +} + +// Test cases for getVMsFromCache() +// Test case 1 - when the vms pool is not found in the cache +// Test case 2 - when the vms pool is found in the cache but has no VMs +// Test case 3 - when the vms pool is found in the cache and has VMs +// Test case 4 - when the vms pool is found in the cache and has VMs with no name +func TestGetVMsFromCache(t *testing.T) { + // Test case 1 + manager := &AzureManager{ + azureCache: &azureCache{ + virtualMachines: make(map[string][]compute.VirtualMachine), + }, + } + agentPool := &VMsPool{ + manager: manager, + azureRef: azureRef{ + Name: "test-vms-pool", + }, + } + + _, err := agentPool.getVMsFromCache() + assert.EqualError(t, err, "vms pool test-vms-pool not found in the cache") + + // Test case 2 + manager.azureCache.virtualMachines["test-vms-pool"] = []compute.VirtualMachine{} + _, err = agentPool.getVMsFromCache() + assert.NoError(t, err) + + // Test case 3 + manager.azureCache.virtualMachines["test-vms-pool"] = newTestVMsPoolVMList(3) + vms, err := agentPool.getVMsFromCache() + assert.NoError(t, err) + assert.Len(t, vms, 3) + + // Test case 4 + manager.azureCache.virtualMachines["test-vms-pool"] = newTestVMsPoolVMList(3) + agentPool.azureRef.Name = "" + _, err = agentPool.getVMsFromCache() + assert.EqualError(t, err, "vms pool not found in the cache") +} + +// Test cases for Nodes() +// Test case 1 - when there are no VMs in the pool +// Test case 2 - when there are VMs in the pool +// Test case 3 - when there are VMs in the pool with no ID +// Test case 4 - when there is an error converting resource group name +// Test case 5 - when there is an error getting VMs from cache +func TestNodes(t *testing.T) { + // Test case 1 + manager := &AzureManager{ + azureCache: &azureCache{ + virtualMachines: make(map[string][]compute.VirtualMachine), + }, + } + agentPool := &VMsPool{ + manager: manager, + azureRef: azureRef{ + Name: "test-vms-pool", + }, + } + + nodes, err := agentPool.Nodes() + assert.EqualError(t, err, "vms pool test-vms-pool not found in the cache") + assert.Empty(t, nodes) + + // Test case 2 + manager.azureCache.virtualMachines["test-vms-pool"] = newTestVMsPoolVMList(3) + nodes, err = agentPool.Nodes() + assert.NoError(t, err) + assert.Len(t, nodes, 3) + + // Test case 3 + manager.azureCache.virtualMachines["test-vms-pool"] = newTestVMsPoolVMList(3) + manager.azureCache.virtualMachines["test-vms-pool"][0].ID = nil + nodes, err = agentPool.Nodes() + assert.NoError(t, err) + assert.Len(t, nodes, 2) + manager.azureCache.virtualMachines["test-vms-pool"] = newTestVMsPoolVMList(3) + emptyString := "" + manager.azureCache.virtualMachines["test-vms-pool"][0].ID = &emptyString + nodes, err = agentPool.Nodes() + assert.NoError(t, err) + assert.Len(t, nodes, 2) + + // Test case 4 + manager.azureCache.virtualMachines["test-vms-pool"] = newTestVMsPoolVMList(3) + bogusID := "foo" + manager.azureCache.virtualMachines["test-vms-pool"][0].ID = &bogusID + nodes, err = agentPool.Nodes() + assert.Empty(t, nodes) + assert.Error(t, err) + + // Test case 5 + manager.azureCache.virtualMachines["test-vms-pool"] = newTestVMsPoolVMList(1) + agentPool.azureRef.Name = "" + nodes, err = agentPool.Nodes() + assert.Empty(t, nodes) + assert.Error(t, err) +}